]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/assault.qc
only fire target_objective_decrease *once*
[divverent/nexuiz.git] / data / qcsrc / server / assault.qc
1
2 // attacker spawn point
3 void info_player_attacker() {
4         info_player_deathmatch();
5         self.team = COLOR_TEAM1; // red, gets swapped every round
6 }
7
8 // defender spawn point
9 void info_player_defender() {
10         info_player_deathmatch();
11         self.team = COLOR_TEAM2; // blue, gets swapped every round
12 }
13
14 // reset this objective. Used when spawning an objective
15 // and when a new round starts
16 void assault_objective_reset() {
17         self.health = ASSAULT_VALUE_INACTIVE;
18 }
19
20 void assault_objective_use() {
21         // activate objective
22         self.health = 100; 
23         self.nextthink = time + 0.1;
24 }
25
26 void assault_objective_think() {
27         local entity oldself;   
28         if(self.health < 0) {
29                 //self.effects = 0;
30                 local entity ent;
31                 ent = find(world, targetname, self.target);
32                 while(ent) {
33                         oldself = self;
34                         self = ent;
35                         self.use();
36                         self = oldself;
37                         ent = find(ent, targetname, self.target);
38                         
39                 }
40         } else {
41                 //self.effects = EF_STARDUST;
42                 self.nextthink = time + 0.1;
43         }
44         
45 }
46
47 void target_objective() {
48         self.classname = "target_objective";
49         self.think = assault_objective_think;
50         self.use = assault_objective_use;
51         assault_objective_reset();
52 }
53
54 float assault_objective_decrease_customizeforclient() {
55         if(self.cnt == 0) {
56                 if(other.team == assault_attacker_team)
57                         setmodel(self, "models/sprites/here.sp2");
58                 else
59                         setmodel(self, "models/sprites/helpme.sp2");
60         } else {
61                 return FALSE;
62         }
63         return TRUE;
64 }
65
66
67 void assault_objective_decrease_think() {
68
69         local entity objective;
70         local float found;
71         found = 0;
72         objective = find(world, targetname, self.target);
73         while(objective && found == 0) {
74                 if(objective.classname == "target_objective") {
75                         found = 1;
76                         if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
77                                 if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) { 
78                                         // decrease was fired already, but objective did recover (round reset)
79                                         self.cnt = 0;
80                                 }
81                         } else { // objective isn't active
82                                 self.cnt = 1;
83                         }
84                         self.max_health = objective.health; // save current objective status for next think
85                 }
86         }
87
88
89         self.nextthink = time + 0.2;
90 }
91
92
93 // decrease the health of targeted objectives
94 void assault_objective_decrease_use() {
95
96         if(self.cnt > 0)
97                 return;
98
99         if(activator.team != assault_attacker_team)
100                 return;
101
102         local entity ent;
103         ent = find(world, targetname, self.target);
104         while(ent) {
105                 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
106                         ent.health = ent.health - self.dmg;
107                 ent = find(ent, targetname, self.target);
108         }
109
110         self.cnt = 1;
111 }
112
113 // this entity should target an objective and be targeted by triggers
114 void target_objective_decrease() {
115
116         self.classname = "target_objective_decrease";
117
118         if(!self.dmg) {
119                 self.dmg = 101;
120         }
121         self.cnt = 0; // not used yet
122         self.use = assault_objective_decrease_use;
123         self.mdl = "models/sprites/here.sp2";
124         self.effects = EF_NODEPTHTEST;
125         self.health = ASSAULT_VALUE_INACTIVE;
126         self.max_health = ASSAULT_VALUE_INACTIVE;
127         self.think = assault_objective_decrease_think;
128         self.customizeentityforclient = assault_objective_decrease_customizeforclient;
129         self.nextthink = time;
130 }
131
132
133 void assault_destructible_reset() {
134         self.health = self.max_health;
135         self.model = self.mdl;
136         self.solid = SOLID_BSP;
137         self.colormod = '1 1 1';
138         self.cnt = 0; // not active
139         if(self.spawnflags)
140                 self.use();
141 }
142
143 void assault_destructible_use() {
144         self.cnt = 1; // mark active
145         self.takedamage = DAMAGE_YES;
146 }
147
148 void assault_destructible_destroy() {
149         local entity oldself;
150         
151         self.model = "";
152         self.takedamage = DAMAGE_NO;
153         self.solid = SOLID_NOT;
154         local entity ent;
155         ent = find(world, targetname, self.target);
156         while(ent) {
157                 oldself = self;
158                 self = ent;
159                 self.use();
160                 self = oldself;
161                 ent = find(ent, targetname, self.target);
162         }
163 }
164
165 void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
166
167         if(self.cnt > 0 && assault_attacker_team == attacker.team) {
168                 self.health = self.health - damage;
169                 if(self.health / self.max_health < 0.25)
170                         self.colormod = '1 0 0';
171                 else if(self.health / self.max_health < 0.375)
172                         self.colormod = '1 0.25 0';
173                 else if(self.health / self.max_health < 0.50)
174                         self.colormod = '1 0.5 0';
175                 else if(self.health / self.max_health < 0.625)
176                         self.colormod = '1 0.75 0';
177                 else if(self.health / self.max_health < 0.75)
178                         self.colormod = '1 1 0';
179                 else
180                         self.colormod = '1 1 1';
181         }
182
183         if(self.health < 0) {
184                 activator = attacker;
185                 assault_destructible_destroy();
186         }
187 }
188
189 // destructible walls that can be used to trigger target_objective_decrease
190 void func_assault_destructible() {
191         if(!self.health)
192                 self.health = 100;
193
194         self.max_health = self.health;
195         
196         self.cnt = 0; // not yet activated
197
198         self.classname = "func_assault_destructible";
199         self.mdl = self.model;
200         setmodel(self, self.mdl);
201
202         self.solid = SOLID_BSP;
203         self.use = assault_destructible_use;
204         self.event_damage = assault_destructible_damage;
205
206 }
207
208 void assault_wall_think() {
209         local entity ent;
210         local float notvisible;
211         notvisible = 0;
212         ent = find(world, targetname, self.target);
213         while(ent) {
214                 if(ent.classname == "target_objective" && ent.health < 0)
215                         notvisible = 1;
216                 ent = find(ent, targetname, self.target);
217         }
218
219         if(notvisible) {
220                 self.model = "";
221                 self.solid = SOLID_NOT;
222         } else {
223                 self.model = self.mdl;
224                 self.solid = SOLID_BSP;
225         }
226
227         self.nextthink = time + 0.2;
228 }
229
230 void func_assault_wall() {
231         self.classname = "func_assault_wall";
232         self.mdl = self.model;
233         setmodel(self, self.mdl);
234         self.solid = SOLID_BSP;
235         self.think = assault_wall_think;
236         self.nextthink = time;
237 }
238
239 // trigger new round
240 // reset objectives, toggle spawnpoints, reset triggers, ...
241 void assault_new_round() {
242         
243         // this assumes self.classname == "func_assault_roundend"!
244         self.cnt = self.cnt + 1;
245
246         // swap spawn point teams
247         local entity ent;
248         local entity oldself;
249
250         // reward attackers for winning the round
251         ent = find(world, classname, "player");
252         while(ent) {
253                 if(ent.team == assault_attacker_team) {
254                         UpdateFrags(ent, 10);
255                 }
256                 ent = find(ent, classname, "player");
257         }
258
259         // swap attacker/defender roles
260         if(assault_attacker_team == COLOR_TEAM1) {
261                 assault_attacker_team = COLOR_TEAM2;
262         } else {
263                 assault_attacker_team = COLOR_TEAM1;
264         }
265
266         ent = find(world, classname, "info_player_deathmatch");
267         while (ent)
268         {
269                 oldself = self;
270                 self = ent;
271                 if(self.team == COLOR_TEAM1) {
272                         self.team = COLOR_TEAM2;
273                 } else {
274                         self.team = COLOR_TEAM1;
275                 }
276                 self = oldself;
277
278                 ent = find(ent, classname, "info_player_deathmatch");
279         } 
280
281         // reset all objectives
282         ent = find(world, classname, "target_objective");
283         while (ent)
284         {
285                 oldself = self;
286                 self = ent;
287                 assault_objective_reset();
288                 self = oldself;
289
290                 ent = find(ent, classname, "target_objective");
291         } 
292
293         // reset all target_object_decrease
294         ent = find(world, classname, "target_objective_decrease");
295         while (ent)
296         {
297                 ent.cnt = 0;
298                 ent = find(ent, classname, "target_objective_decrease");
299         } 
300
301         // reset all func_assault_destructible
302         ent = find(world, classname, "func_assault_destructible");
303         while (ent)
304         {
305                 oldself = self;
306                 self = ent;
307                 assault_destructible_reset();
308                 self = oldself;
309                 ent = find(ent, classname, "func_assault_destructible");
310         }
311
312         ent = find(world, classname, "target_assault_roundstart");
313         while (ent)
314         {
315                 oldself = self;
316                 self = ent;
317                 self.use();
318                 self = oldself;
319                 ent = find(ent, classname, "target_assault_roundstart");
320         }
321
322         // actually restart round... how to do that?
323         ent = find(world, classname, "player");
324         while(ent) {
325                 oldself = self;
326                 self = ent;
327                 PutClientInServer();
328                 self = oldself;
329                 ent = find(ent, classname, "player");
330         }
331
332
333 }
334
335 void target_assault_roundend() {
336         self.cnt = 0; // round counter
337         self.classname = "target_assault_roundend";
338         self.use = assault_new_round;
339 }
340
341 void assault_roundstart_use() {
342         local entity ent;
343         local entity oldself;
344         ent = find(world, targetname, self.target);
345         while(ent) {
346                 oldself = self;
347                 self = ent;
348                 self.use();
349                 self = oldself;
350                 ent = find(ent, targetname, self.target);
351         }
352 }
353
354 void target_assault_roundstart() {
355         assault_attacker_team = COLOR_TEAM1;
356         self.classname = "target_assault_roundstart";
357         self.use = assault_roundstart_use;
358         self.think = assault_roundstart_use;
359         self.nextthink = time + 0.1;
360 }
361
362