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