]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/assault.qc
when a round ends (last objective fulfilled) all players in the
[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.cnt = 0; // not active
135         if(self.spawnflags)
136                 self.use();
137 }
138
139 void assault_destructible_use() {
140         self.cnt = 1; // mark active
141         self.takedamage = DAMAGE_YES;
142 }
143
144 void assault_destructible_destroy() {
145         local entity oldself;
146         
147         self.model = "";
148         self.takedamage = DAMAGE_NO;
149         self.solid = SOLID_NOT;
150         local entity ent;
151         ent = find(world, targetname, self.target);
152         while(ent) {
153                 oldself = self;
154                 self = ent;
155                 self.use();
156                 self = oldself;
157                 ent = find(ent, targetname, self.target);
158         }
159 }
160
161 void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
162
163         if(self.cnt > 0 && assault_attacker_team == attacker.team) {
164                 self.health = self.health - damage;
165         }
166
167         if(self.health < 0) {
168                 activator = attacker;
169                 assault_destructible_destroy();
170         }
171 }
172
173 // destructible walls that can be used to trigger target_objective_decrease
174 void func_assault_destructible() {
175         if(!self.health)
176                 self.health = 100;
177
178         self.max_health = self.health;
179         
180         self.cnt = 0; // not yet activated
181
182         self.classname = "func_assault_destructible";
183         self.mdl = self.model;
184         setmodel(self, self.mdl);
185
186         self.solid = SOLID_BSP;
187         self.use = assault_destructible_use;
188         self.event_damage = assault_destructible_damage;
189
190 }
191
192
193 // trigger new round
194 // reset objectives, toggle spawnpoints, reset triggers, ...
195 void assault_new_round() {
196         
197         // this assumes self.classname == "func_assault_roundend"!
198         self.cnt = self.cnt + 1;
199
200         // swap spawn point teams
201         local entity ent;
202         local entity oldself;
203
204         ent = find(world, classname, "info_player_deathmatch");
205         while (ent)
206         {
207                 oldself = self;
208                 self = ent;
209                 if(self.team == COLOR_TEAM1) {
210                         self.team = COLOR_TEAM2;
211                 } else {
212                         self.team = COLOR_TEAM1;
213                 }
214                 self = oldself;
215
216                 ent = find(ent, classname, "info_player_deathmatch");
217         } 
218
219         // reset all objectives
220         ent = find(world, classname, "target_objective");
221         while (ent)
222         {
223                 oldself = self;
224                 self = ent;
225                 assault_objective_reset();
226                 self = oldself;
227
228                 ent = find(ent, classname, "target_objective");
229         } 
230
231         // reset all target_object_decrease
232         ent = find(world, classname, "target_objective_decrease");
233         while (ent)
234         {
235                 ent.cnt = 0;
236                 ent = find(ent, classname, "target_objective_decrease");
237         } 
238
239         // reset all func_assault_destructible
240         ent = find(world, classname, "func_assault_destructible");
241         while (ent)
242         {
243                 oldself = self;
244                 self = ent;
245                 assault_destructible_reset();
246                 self = oldself;
247                 ent = find(ent, classname, "func_assault_destructible");
248         }
249
250         ent = find(world, classname, "target_assault_roundstart");
251         while (ent)
252         {
253                 oldself = self;
254                 self = ent;
255                 self.use();
256                 self = oldself;
257                 ent = find(ent, classname, "target_assault_roundstart");
258         }
259
260         // actually restart round... how to do that?
261         ent = find(world, classname, "player");
262         while(ent) {
263                 oldself = self;
264                 self = ent;
265                 if(self.team == assault_attacker_team) {
266                         UpdateFrags(self, 10);
267                 }
268                 PutClientInServer();
269                 self = oldself;
270                 ent = find(ent, classname, "player");
271         }
272
273         // swap attacker/defender roles
274         if(assault_attacker_team == COLOR_TEAM1) {
275                 assault_attacker_team = COLOR_TEAM2;
276         } else {
277                 assault_attacker_team = COLOR_TEAM1;
278         }
279 }
280
281 void target_assault_roundend() {
282         self.cnt = 0; // round counter
283         self.classname = "target_assault_roundend";
284         self.use = assault_new_round;
285 }
286
287 void assault_roundstart_use() {
288         local entity ent;
289         local entity oldself;
290         ent = find(world, targetname, self.target);
291         while(ent) {
292                 oldself = self;
293                 self = ent;
294                 self.use();
295                 self = oldself;
296                 ent = find(ent, targetname, self.target);
297         }
298 }
299
300 void target_assault_roundstart() {
301         assault_attacker_team = COLOR_TEAM1;
302         self.classname = "target_assault_roundstart";
303         self.use = assault_roundstart_use;
304         self.think = assault_roundstart_use;
305         self.nextthink = time + 0.1;
306 }
307
308