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