]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/assault.qc
added func_assault_wall, which disappears once its targeted
[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(activator.team != assault_attacker_team)
97                 return;
98
99         local entity ent;
100         ent = find(world, targetname, self.target);
101         while(ent) {
102                 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
103                         ent.health = ent.health - self.dmg;
104                 ent = find(ent, targetname, self.target);
105         }
106
107         self.cnt = 1;
108 }
109
110 // this entity should target an objective and be targeted by triggers
111 void target_objective_decrease() {
112
113         self.classname = "target_objective_decrease";
114
115         if(!self.dmg) {
116                 self.dmg = 101;
117         }
118         self.cnt = 0; // not used yet
119         self.use = assault_objective_decrease_use;
120         self.mdl = "models/sprites/here.sp2";
121         self.effects = EF_NODEPTHTEST;
122         self.health = ASSAULT_VALUE_INACTIVE;
123         self.max_health = ASSAULT_VALUE_INACTIVE;
124         self.think = assault_objective_decrease_think;
125         self.customizeentityforclient = assault_objective_decrease_customizeforclient;
126         self.nextthink = time;
127 }
128
129
130 void assault_destructible_reset() {
131         self.health = self.max_health;
132         self.model = self.mdl;
133         self.solid = SOLID_BSP;
134         self.colormod = '1 1 1';
135         self.cnt = 0; // not active
136         if(self.spawnflags)
137                 self.use();
138 }
139
140 void assault_destructible_use() {
141         self.cnt = 1; // mark active
142         self.takedamage = DAMAGE_YES;
143 }
144
145 void assault_destructible_destroy() {
146         local entity oldself;
147         
148         self.model = "";
149         self.takedamage = DAMAGE_NO;
150         self.solid = SOLID_NOT;
151         local entity ent;
152         ent = find(world, targetname, self.target);
153         while(ent) {
154                 oldself = self;
155                 self = ent;
156                 self.use();
157                 self = oldself;
158                 ent = find(ent, targetname, self.target);
159         }
160 }
161
162 void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
163
164         if(self.cnt > 0 && assault_attacker_team == attacker.team) {
165                 self.health = self.health - damage;
166                 if(self.health / self.max_health < 0.25)
167                         self.colormod = '1 0 0';
168                 else if(self.health / self.max_health < 0.375)
169                         self.colormod = '1 0.25 0';
170                 else if(self.health / self.max_health < 0.50)
171                         self.colormod = '1 0.5 0';
172                 else if(self.health / self.max_health < 0.625)
173                         self.colormod = '1 0.75 0';
174                 else if(self.health / self.max_health < 0.75)
175                         self.colormod = '1 1 0';
176                 else
177                         self.colormod = '1 1 1';
178         }
179
180         if(self.health < 0) {
181                 activator = attacker;
182                 assault_destructible_destroy();
183         }
184 }
185
186 // destructible walls that can be used to trigger target_objective_decrease
187 void func_assault_destructible() {
188         if(!self.health)
189                 self.health = 100;
190
191         self.max_health = self.health;
192         
193         self.cnt = 0; // not yet activated
194
195         self.classname = "func_assault_destructible";
196         self.mdl = self.model;
197         setmodel(self, self.mdl);
198
199         self.solid = SOLID_BSP;
200         self.use = assault_destructible_use;
201         self.event_damage = assault_destructible_damage;
202
203 }
204
205 void assault_wall_think() {
206         local entity ent;
207         local float notvisible;
208         notvisible = 0;
209         ent = find(world, targetname, self.target);
210         while(ent) {
211                 if(ent.classname == "target_objective" && ent.health < 0)
212                         notvisible = 1;
213                 ent = find(ent, targetname, self.target);
214         }
215
216         if(notvisible) {
217                 self.model = "";
218                 self.solid = SOLID_NOT;
219         } else {
220                 self.model = self.mdl;
221                 self.solid = SOLID_BSP;
222         }
223
224         self.nextthink = time + 0.2;
225 }
226
227 void func_assault_wall() {
228         self.classname = "func_assault_wall";
229         self.mdl = self.model;
230         setmodel(self, self.mdl);
231         self.solid = SOLID_BSP;
232         self.think = assault_wall_think;
233         self.nextthink = time;
234 }
235
236 // trigger new round
237 // reset objectives, toggle spawnpoints, reset triggers, ...
238 void assault_new_round() {
239         
240         // this assumes self.classname == "func_assault_roundend"!
241         self.cnt = self.cnt + 1;
242
243         // swap spawn point teams
244         local entity ent;
245         local entity oldself;
246
247         // reward attackers for winning the round
248         ent = find(world, classname, "player");
249         while(ent) {
250                 if(ent.team == assault_attacker_team) {
251                         UpdateFrags(ent, 10);
252                 }
253                 ent = find(ent, classname, "player");
254         }
255
256         // swap attacker/defender roles
257         if(assault_attacker_team == COLOR_TEAM1) {
258                 assault_attacker_team = COLOR_TEAM2;
259         } else {
260                 assault_attacker_team = COLOR_TEAM1;
261         }
262
263         ent = find(world, classname, "info_player_deathmatch");
264         while (ent)
265         {
266                 oldself = self;
267                 self = ent;
268                 if(self.team == COLOR_TEAM1) {
269                         self.team = COLOR_TEAM2;
270                 } else {
271                         self.team = COLOR_TEAM1;
272                 }
273                 self = oldself;
274
275                 ent = find(ent, classname, "info_player_deathmatch");
276         } 
277
278         // reset all objectives
279         ent = find(world, classname, "target_objective");
280         while (ent)
281         {
282                 oldself = self;
283                 self = ent;
284                 assault_objective_reset();
285                 self = oldself;
286
287                 ent = find(ent, classname, "target_objective");
288         } 
289
290         // reset all target_object_decrease
291         ent = find(world, classname, "target_objective_decrease");
292         while (ent)
293         {
294                 ent.cnt = 0;
295                 ent = find(ent, classname, "target_objective_decrease");
296         } 
297
298         // reset all func_assault_destructible
299         ent = find(world, classname, "func_assault_destructible");
300         while (ent)
301         {
302                 oldself = self;
303                 self = ent;
304                 assault_destructible_reset();
305                 self = oldself;
306                 ent = find(ent, classname, "func_assault_destructible");
307         }
308
309         ent = find(world, classname, "target_assault_roundstart");
310         while (ent)
311         {
312                 oldself = self;
313                 self = ent;
314                 self.use();
315                 self = oldself;
316                 ent = find(ent, classname, "target_assault_roundstart");
317         }
318
319         // actually restart round... how to do that?
320         ent = find(world, classname, "player");
321         while(ent) {
322                 oldself = self;
323                 self = ent;
324                 PutClientInServer();
325                 self = oldself;
326                 ent = find(ent, classname, "player");
327         }
328
329
330 }
331
332 void target_assault_roundend() {
333         self.cnt = 0; // round counter
334         self.classname = "target_assault_roundend";
335         self.use = assault_new_round;
336 }
337
338 void assault_roundstart_use() {
339         local entity ent;
340         local entity oldself;
341         ent = find(world, targetname, self.target);
342         while(ent) {
343                 oldself = self;
344                 self = ent;
345                 self.use();
346                 self = oldself;
347                 ent = find(ent, targetname, self.target);
348         }
349 }
350
351 void target_assault_roundstart() {
352         assault_attacker_team = COLOR_TEAM1;
353         self.classname = "target_assault_roundstart";
354         self.use = assault_roundstart_use;
355         self.think = assault_roundstart_use;
356         self.nextthink = time + 0.1;
357 }
358
359