1 //=============================================================================
\r
3 /*QUAKED info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL
\r
4 Normal attacker spawning location for Nexuiz Asssault
\r
5 -------- KEYS --------
\r
6 angle : direction in which player will look when spawning in the game. Does not apply to bots.
\r
7 target : this should point to a target_objective to decide when this spawning point is active.
\r
8 nobots : when set to 1, bots will never use this spawn point to respawn in the game.
\r
9 nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
\r
10 notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
\r
11 notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
\r
12 notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
\r
13 -------- SPAWNFLAGS --------
\r
14 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
15 void info_player_attacker() {
16 info_player_deathmatch();
17 self.team = COLOR_TEAM1; // red, gets swapped every round
20 //=============================================================================
\r
22 /*QUAKED info_player_defender (0 1 0) (-16 -16 -24) (16 16 45) INITIAL
\r
23 Normal defender spawning location for Nexuiz Asssault
\r
24 -------- KEYS --------
\r
25 angle : direction in which player will look when spawning in the game. Does not apply to bots.
\r
26 target : this should point to a target_objective to decide when this spawning point is active.
\r
27 nobots : when set to 1, bots will never use this spawn point to respawn in the game.
\r
28 nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
\r
29 notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
\r
30 notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
\r
31 notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
\r
32 -------- SPAWNFLAGS --------
\r
33 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
34 void info_player_defender() {
35 info_player_deathmatch();
36 self.team = COLOR_TEAM2; // blue, gets swapped every round
39 // reset this objective. Used when spawning an objective
40 // and when a new round starts
41 void assault_objective_reset() {
42 self.health = ASSAULT_VALUE_INACTIVE;
45 void assault_objective_use() {
48 self.nextthink = time + 0.1;
51 void assault_objective_think() {
56 ent = find(world, targetname, self.target);
62 ent = find(ent, targetname, self.target);
66 //self.effects = EF_STARDUST;
67 self.nextthink = time + 0.1;
71 //=============================================================================
\r
73 /*QUAKED target_objective (0 .5 0) (-8 -8 -8) (8 8 8)
\r
74 Objective controller for Nexuiz Assault. When active it has 100 health. If it falls below 0 then
75 it'll trigger the next targeted entity (usually the next objective or target_assault_roundend etc.)
\r
76 -------- KEYS --------
\r
77 targetname : point to e.g. next objective*/
78 void target_objective() {
79 self.classname = "target_objective";
80 self.think = assault_objective_think;
81 self.use = assault_objective_use;
82 assault_objective_reset();
85 float assault_objective_decrease_customizeforclient() {
90 if(other.team == assault_attacker_team)
91 if(self.spawnflags == 1)
92 setmodel(self, "models/sprites/push.sp2");
94 setmodel(self, "models/sprites/destroy.sp2");
96 setmodel(self, "models/sprites/defend.sp2");
104 void assault_objective_decrease_think() {
106 local entity objective;
109 objective = find(world, targetname, self.target);
110 while(objective && found == 0) {
111 if(objective.classname == "target_objective") {
113 if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
114 if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) {
115 // decrease was fired already, but objective did recover (round reset)
118 } else { // objective isn't active
121 self.max_health = objective.health; // save current objective status for next think
125 if(!self.spawnflags) {
127 ent = find(world, target, self.targetname);
129 if(ent.classname == "func_assault_destructible")
136 self.nextthink = time + 0.2;
140 // decrease the health of targeted objectives
141 void assault_objective_decrease_use() {
146 if(activator.team != assault_attacker_team)
150 ent = find(world, targetname, self.target);
152 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
153 ent.health = ent.health - self.dmg;
154 ent = find(ent, targetname, self.target);
160 //=============================================================================
\r
162 /*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
\r
163 When triggered decreases health of the targeted target_objective.
164 -------- KEYS --------
\r
165 targetname : point to a target_objective entity*/
166 void target_objective_decrease() {
168 self.classname = "target_objective_decrease";
170 precache_model("models/sprites/defend.sp2");
171 precache_model("models/sprites/destroy.sp2");
172 precache_model("models/sprites/push.sp2");
177 self.cnt = 0; // not used yet
178 self.use = assault_objective_decrease_use;
179 self.mdl = "models/sprites/here.sp2";
180 self.effects = EF_NODEPTHTEST;
181 self.health = ASSAULT_VALUE_INACTIVE;
182 self.max_health = ASSAULT_VALUE_INACTIVE;
183 self.think = assault_objective_decrease_think;
184 self.customizeentityforclient = assault_objective_decrease_customizeforclient;
185 self.nextthink = time;
189 void assault_destructible_reset() {
190 self.health = self.max_health;
191 self.model = self.mdl;
192 self.solid = SOLID_BSP;
193 self.colormod = '1 1 1';
194 self.cnt = 0; // not active
199 void assault_destructible_use() {
200 self.cnt = 1; // mark active
201 self.takedamage = DAMAGE_YES;
204 void assault_destructible_destroy() {
205 local entity oldself;
208 self.takedamage = DAMAGE_NO;
209 self.solid = SOLID_NOT;
211 ent = find(world, targetname, self.target);
217 ent = find(ent, targetname, self.target);
221 void assault_destructible_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) {
223 if(self.cnt > 0 && assault_attacker_team == attacker.team) {
224 self.health = self.health - damage;
225 if(self.health / self.max_health < 0.25)
226 self.colormod = '1 0 0';
227 else if(self.health / self.max_health < 0.375)
228 self.colormod = '1 0.25 0';
229 else if(self.health / self.max_health < 0.50)
230 self.colormod = '1 0.5 0';
231 else if(self.health / self.max_health < 0.625)
232 self.colormod = '1 0.75 0';
233 else if(self.health / self.max_health < 0.75)
234 self.colormod = '1 1 0';
236 self.colormod = '1 1 1';
239 if(self.health < 0) {
240 activator = attacker;
241 assault_destructible_destroy();
245 // destructible walls that can be used to trigger target_objective_decrease
246 void func_assault_destructible() {
250 self.max_health = self.health;
252 self.cnt = 0; // not yet activated
254 self.classname = "func_assault_destructible";
255 self.mdl = self.model;
256 setmodel(self, self.mdl);
258 self.solid = SOLID_BSP;
259 self.use = assault_destructible_use;
260 self.event_damage = assault_destructible_damage;
264 void assault_wall_think() {
266 local float notvisible;
268 ent = find(world, targetname, self.target);
270 if(ent.classname == "target_objective" && ent.health < 0)
272 ent = find(ent, targetname, self.target);
277 self.solid = SOLID_NOT;
279 self.model = self.mdl;
280 self.solid = SOLID_BSP;
283 self.nextthink = time + 0.2;
286 void func_assault_wall() {
287 self.classname = "func_assault_wall";
288 self.mdl = self.model;
289 setmodel(self, self.mdl);
290 self.solid = SOLID_BSP;
291 self.think = assault_wall_think;
292 self.nextthink = time;
296 void target_assault_roundend_reset() {
297 self.cnt = self.cnt + 1; // up round counter
298 self.winning = 0; // up round
301 void target_assault_roundend_use() {
302 self.winning = 1; // round has been won by attackers
305 void target_assault_roundend() {
307 self.health = 300; // 5 minutes
309 cvar_set("timelimit", ftos(self.health/60));
310 self.winning = 0; // round not yet won by attackers
311 self.classname = "target_assault_roundend";
312 self.use = target_assault_roundend_use;
313 self.cnt = 0; // first round
316 void assault_roundstart_use() {
318 local entity oldself;
319 ent = find(world, targetname, self.target);
325 ent = find(ent, targetname, self.target);
329 void target_assault_roundstart() {
330 assault_attacker_team = COLOR_TEAM1;
331 self.classname = "target_assault_roundstart";
332 self.use = assault_roundstart_use;
333 self.think = assault_roundstart_use;
334 self.nextthink = time + 0.1;
338 // reset objectives, toggle spawnpoints, reset triggers, ...
339 void assault_new_round() {
342 self.winning = self.winning + 1;
343 // set end time for next round
344 self.cnt = time + self.health;
346 // swap spawn point teams
348 local entity oldself;
350 // reward attackers for winning the round
351 ent = find(world, classname, "player");
353 if(ent.team == assault_attacker_team) {
354 UpdateFrags(ent, 10);
356 ent = find(ent, classname, "player");
359 // swap attacker/defender roles
360 if(assault_attacker_team == COLOR_TEAM1) {
361 assault_attacker_team = COLOR_TEAM2;
363 assault_attacker_team = COLOR_TEAM1;
366 ent = find(world, classname, "info_player_deathmatch");
371 if(self.team == COLOR_TEAM1) {
372 self.team = COLOR_TEAM2;
374 self.team = COLOR_TEAM1;
378 ent = find(ent, classname, "info_player_deathmatch");
381 // reset all objectives
382 ent = find(world, classname, "target_objective");
387 assault_objective_reset();
390 ent = find(ent, classname, "target_objective");
393 // reset round end triggers
394 ent = find(world, classname, "target_assault_roundend");
399 target_assault_roundend_reset();
402 ent = find(ent, classname, "target_assault_roundend");
405 // reset all target_object_decrease
406 ent = find(world, classname, "target_objective_decrease");
410 ent = find(ent, classname, "target_objective_decrease");
413 // reset all func_assault_destructible
414 ent = find(world, classname, "func_assault_destructible");
419 assault_destructible_reset();
421 ent = find(ent, classname, "func_assault_destructible");
424 ent = find(world, classname, "target_assault_roundstart");
431 ent = find(ent, classname, "target_assault_roundstart");
434 // actually restart round... how to do that?
435 ent = find(world, classname, "player");
441 ent = find(ent, classname, "player");