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