]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/assault.qc
func_assault_destructible now show their damage with color tinting.
[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.75)
169                         self.colormod = '1 1 0';
170                 else
171                         self.colormod = '1 1 1';
172         }
173
174         if(self.health < 0) {
175                 activator = attacker;
176                 assault_destructible_destroy();
177         }
178 }
179
180 // destructible walls that can be used to trigger target_objective_decrease
181 void func_assault_destructible() {
182         if(!self.health)
183                 self.health = 100;
184
185         self.max_health = self.health;
186         
187         self.cnt = 0; // not yet activated
188
189         self.classname = "func_assault_destructible";
190         self.mdl = self.model;
191         setmodel(self, self.mdl);
192
193         self.solid = SOLID_BSP;
194         self.use = assault_destructible_use;
195         self.event_damage = assault_destructible_damage;
196
197 }
198
199
200 // trigger new round
201 // reset objectives, toggle spawnpoints, reset triggers, ...
202 void assault_new_round() {
203         
204         // this assumes self.classname == "func_assault_roundend"!
205         self.cnt = self.cnt + 1;
206
207         // swap spawn point teams
208         local entity ent;
209         local entity oldself;
210
211         // reward attackers for winning the round
212         ent = find(world, classname, "player");
213         while(ent) {
214                 if(ent.team == assault_attacker_team) {
215                         UpdateFrags(ent, 10);
216                 }
217                 ent = find(ent, classname, "player");
218         }
219
220         // swap attacker/defender roles
221         if(assault_attacker_team == COLOR_TEAM1) {
222                 assault_attacker_team = COLOR_TEAM2;
223         } else {
224                 assault_attacker_team = COLOR_TEAM1;
225         }
226
227         ent = find(world, classname, "info_player_deathmatch");
228         while (ent)
229         {
230                 oldself = self;
231                 self = ent;
232                 if(self.team == COLOR_TEAM1) {
233                         self.team = COLOR_TEAM2;
234                 } else {
235                         self.team = COLOR_TEAM1;
236                 }
237                 self = oldself;
238
239                 ent = find(ent, classname, "info_player_deathmatch");
240         } 
241
242         // reset all objectives
243         ent = find(world, classname, "target_objective");
244         while (ent)
245         {
246                 oldself = self;
247                 self = ent;
248                 assault_objective_reset();
249                 self = oldself;
250
251                 ent = find(ent, classname, "target_objective");
252         } 
253
254         // reset all target_object_decrease
255         ent = find(world, classname, "target_objective_decrease");
256         while (ent)
257         {
258                 ent.cnt = 0;
259                 ent = find(ent, classname, "target_objective_decrease");
260         } 
261
262         // reset all func_assault_destructible
263         ent = find(world, classname, "func_assault_destructible");
264         while (ent)
265         {
266                 oldself = self;
267                 self = ent;
268                 assault_destructible_reset();
269                 self = oldself;
270                 ent = find(ent, classname, "func_assault_destructible");
271         }
272
273         ent = find(world, classname, "target_assault_roundstart");
274         while (ent)
275         {
276                 oldself = self;
277                 self = ent;
278                 self.use();
279                 self = oldself;
280                 ent = find(ent, classname, "target_assault_roundstart");
281         }
282
283         // actually restart round... how to do that?
284         ent = find(world, classname, "player");
285         while(ent) {
286                 oldself = self;
287                 self = ent;
288                 PutClientInServer();
289                 self = oldself;
290                 ent = find(ent, classname, "player");
291         }
292
293
294 }
295
296 void target_assault_roundend() {
297         self.cnt = 0; // round counter
298         self.classname = "target_assault_roundend";
299         self.use = assault_new_round;
300 }
301
302 void assault_roundstart_use() {
303         local entity ent;
304         local entity oldself;
305         ent = find(world, targetname, self.target);
306         while(ent) {
307                 oldself = self;
308                 self = ent;
309                 self.use();
310                 self = oldself;
311                 ent = find(ent, targetname, self.target);
312         }
313 }
314
315 void target_assault_roundstart() {
316         assault_attacker_team = COLOR_TEAM1;
317         self.classname = "target_assault_roundstart";
318         self.use = assault_roundstart_use;
319         self.think = assault_roundstart_use;
320         self.nextthink = time + 0.1;
321 }
322
323