]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/triggers/func/door_secret.qc
Ensure headers are always #included
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / triggers / func / door_secret.qc
1 #include "door_secret.qh"
2 #ifdef SVQC
3 void fd_secret_move1(entity this);
4 void fd_secret_move2(entity this);
5 void fd_secret_move3(entity this);
6 void fd_secret_move4(entity this);
7 void fd_secret_move5(entity this);
8 void fd_secret_move6(entity this);
9 void fd_secret_done(entity this);
10
11 const float SECRET_OPEN_ONCE = 1;               // stays open
12 const float SECRET_1ST_LEFT = 2;                // 1st move is left of arrow
13 const float SECRET_1ST_DOWN = 4;                // 1st move is down from arrow
14 const float SECRET_NO_SHOOT = 8;                // only opened by trigger
15 const float SECRET_YES_SHOOT = 16;      // shootable even if targeted
16
17 void fd_secret_use(entity this, entity actor, entity trigger)
18 {
19         float temp;
20         string message_save;
21
22         this.health = 10000;
23         this.bot_attack = true;
24
25         // exit if still moving around...
26         if (this.origin != this.oldorigin)
27                 return;
28
29         message_save = this.message;
30         this.message = ""; // no more message
31         SUB_UseTargets(this, actor, trigger);                           // fire all targets / killtargets
32         this.message = message_save;
33
34         this.velocity = '0 0 0';
35
36         // Make a sound, wait a little...
37
38         if (this.noise1 != "")
39                 _sound(this, CH_TRIGGER_SINGLE, this.noise1, VOL_BASE, ATTEN_NORM);
40         this.SUB_NEXTTHINK = this.SUB_LTIME + 0.1;
41
42         temp = 1 - (this.spawnflags & SECRET_1ST_LEFT); // 1 or -1
43         makevectors(this.mangle);
44
45         if (!this.t_width)
46         {
47                 if (this.spawnflags & SECRET_1ST_DOWN)
48                         this.t_width = fabs(v_up * this.size);
49                 else
50                         this.t_width = fabs(v_right * this.size);
51         }
52
53         if (!this.t_length)
54                 this.t_length = fabs(v_forward * this.size);
55
56         if (this.spawnflags & SECRET_1ST_DOWN)
57                 this.dest1 = this.origin - v_up * this.t_width;
58         else
59                 this.dest1 = this.origin + v_right * (this.t_width * temp);
60
61         this.dest2 = this.dest1 + v_forward * this.t_length;
62         SUB_CalcMove(this, this.dest1, TSPEED_LINEAR, this.speed, fd_secret_move1);
63         if (this.noise2 != "")
64                 _sound(this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
65 }
66
67 void fd_secret_damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
68 {
69         fd_secret_use(this, NULL, NULL);
70 }
71
72 // Wait after first movement...
73 void fd_secret_move1(entity this)
74 {
75         this.SUB_NEXTTHINK = this.SUB_LTIME + 1.0;
76         setthink(this, fd_secret_move2);
77         if (this.noise3 != "")
78                 _sound(this, CH_TRIGGER_SINGLE, this.noise3, VOL_BASE, ATTEN_NORM);
79 }
80
81 // Start moving sideways w/sound...
82 void fd_secret_move2(entity this)
83 {
84         if (this.noise2 != "")
85                 _sound(this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
86         SUB_CalcMove(this, this.dest2, TSPEED_LINEAR, this.speed, fd_secret_move3);
87 }
88
89 // Wait here until time to go back...
90 void fd_secret_move3(entity this)
91 {
92         if (this.noise3 != "")
93                 _sound(this, CH_TRIGGER_SINGLE, this.noise3, VOL_BASE, ATTEN_NORM);
94         if (!(this.spawnflags & SECRET_OPEN_ONCE))
95         {
96                 this.SUB_NEXTTHINK = this.SUB_LTIME + this.wait;
97                 setthink(this, fd_secret_move4);
98         }
99 }
100
101 // Move backward...
102 void fd_secret_move4(entity this)
103 {
104         if (this.noise2 != "")
105                 _sound(this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
106         SUB_CalcMove(this, this.dest1, TSPEED_LINEAR, this.speed, fd_secret_move5);
107 }
108
109 // Wait 1 second...
110 void fd_secret_move5(entity this)
111 {
112         this.SUB_NEXTTHINK = this.SUB_LTIME + 1.0;
113         setthink(this, fd_secret_move6);
114         if (this.noise3 != "")
115                 _sound(this, CH_TRIGGER_SINGLE, this.noise3, VOL_BASE, ATTEN_NORM);
116 }
117
118 void fd_secret_move6(entity this)
119 {
120         if (this.noise2 != "")
121                 _sound(this, CH_TRIGGER_SINGLE, this.noise2, VOL_BASE, ATTEN_NORM);
122         SUB_CalcMove(this, this.oldorigin, TSPEED_LINEAR, this.speed, fd_secret_done);
123 }
124
125 void fd_secret_done(entity this)
126 {
127         if (this.spawnflags&SECRET_YES_SHOOT)
128         {
129                 this.health = 10000;
130                 this.takedamage = DAMAGE_YES;
131                 //this.th_pain = fd_secret_use;
132         }
133         if (this.noise3 != "")
134                 _sound(this, CH_TRIGGER_SINGLE, this.noise3, VOL_BASE, ATTEN_NORM);
135 }
136
137 .float door_finished;
138
139 void secret_blocked(entity this, entity blocker)
140 {
141         if (time < this.door_finished)
142                 return;
143         this.door_finished = time + 0.5;
144         //T_Damage (other, this, this, this.dmg, this.dmg, this.deathtype, DT_IMPACT, (this.absmin + this.absmax) * 0.5, '0 0 0', Obituary_Generic);
145 }
146
147 /*
148 ==============
149 secret_touch
150
151 Prints messages
152 ================
153 */
154 void secret_touch(entity this, entity toucher)
155 {
156         if (!toucher.iscreature)
157                 return;
158         if (this.door_finished > time)
159                 return;
160
161         this.door_finished = time + 2;
162
163         if (this.message)
164         {
165                 if (IS_CLIENT(toucher))
166                         centerprint(toucher, this.message);
167                 play2(toucher, this.noise);
168         }
169 }
170
171 void secret_reset(entity this)
172 {
173         if (this.spawnflags & SECRET_YES_SHOOT)
174         {
175                 this.health = 10000;
176                 this.takedamage = DAMAGE_YES;
177         }
178         setorigin(this, this.oldorigin);
179         setthink(this, func_null);
180         this.SUB_NEXTTHINK = 0;
181 }
182
183 /*QUAKED spawnfunc_func_door_secret (0 .5 .8) ? open_once 1st_left 1st_down no_shoot always_shoot
184 Basic secret door. Slides back, then to the side. Angle determines direction.
185 wait  = # of seconds before coming back
186 1st_left = 1st move is left of arrow
187 1st_down = 1st move is down from arrow
188 always_shoot = even if targeted, keep shootable
189 t_width = override WIDTH to move back (or height if going down)
190 t_length = override LENGTH to move sideways
191 "dmg"           damage to inflict when blocked (2 default)
192
193 If a secret door has a targetname, it will only be opened by it's botton or trigger, not by damage.
194 "sounds"
195 1) medieval
196 2) metal
197 3) base
198 */
199
200 spawnfunc(func_door_secret)
201 {
202         /*if (!this.deathtype) // map makers can override this
203                 this.deathtype = " got in the way";*/
204
205         if (!this.dmg) this.dmg = 2;
206
207         // Magic formula...
208         this.mangle = this.angles;
209         this.angles = '0 0 0';
210         this.classname = "door";
211         if (!InitMovingBrushTrigger(this)) return;
212         this.effects |= EF_LOWPRECISION;
213
214         if (this.noise == "") this.noise = "misc/talk.wav";
215         precache_sound(this.noise);
216
217         settouch(this, secret_touch);
218         setblocked(this, secret_blocked);
219         this.speed = 50;
220         this.use = fd_secret_use;
221         IFTARGETED
222         {
223         }
224         else
225                 this.spawnflags |= SECRET_YES_SHOOT;
226
227         if (this.spawnflags & SECRET_YES_SHOOT)
228         {
229                 this.health = 10000;
230                 this.takedamage = DAMAGE_YES;
231                 this.event_damage = fd_secret_damage;
232         }
233         this.oldorigin = this.origin;
234         if (!this.wait) this.wait = 5; // seconds before closing
235
236         this.reset = secret_reset;
237         this.reset(this);
238 }
239 #endif