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