1 void spawnfunc_func_breakable();
3 //=============================================================================
5 /*QUAKED spawnfunc_info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL
6 Normal attacker spawning location for Nexuiz Asssault
8 angle : direction in which player will look when spawning in the game. Does not apply to bots.
9 target : this should point to a spawnfunc_target_objective to decide when this spawning point is active.
10 nobots : when set to 1, bots will never use this spawn point to respawn in the game.
11 nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
12 notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
13 notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
14 notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
15 -------- SPAWNFLAGS --------
16 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
17 void spawnfunc_info_player_attacker() {
18 self.team = COLOR_TEAM1; // red, gets swapped every round
19 spawnfunc_info_player_deathmatch();
22 //=============================================================================
24 /*QUAKED spawnfunc_info_player_defender (0 1 0) (-16 -16 -24) (16 16 45) INITIAL
25 Normal defender spawning location for Nexuiz Asssault
26 -------- KEYS --------
27 angle : direction in which player will look when spawning in the game. Does not apply to bots.
28 target : this should point to a spawnfunc_target_objective to decide when this spawning point is active.
29 nobots : when set to 1, bots will never use this spawn point to respawn in the game.
30 nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
31 notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
32 notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
33 notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
34 -------- SPAWNFLAGS --------
35 INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
36 void spawnfunc_info_player_defender() {
37 self.team = COLOR_TEAM2; // blue, gets swapped every round
38 spawnfunc_info_player_deathmatch();
41 // reset this objective. Used when spawning an objective
42 // and when a new round starts
43 void assault_objective_reset() {
44 self.health = ASSAULT_VALUE_INACTIVE;
47 void assault_objective_use() {
50 self.nextthink = time + 0.1;
53 void assault_objective_think() {
59 //self.effects = EF_STARDUST;
60 self.nextthink = time + 0.1;
64 //=============================================================================
66 /*QUAKED spawnfunc_target_objective (0 .5 0) (-8 -8 -8) (8 8 8)
67 Objective controller for Nexuiz Assault. When active it has 100 health. If it falls below 0 then
68 it'll trigger the next targeted entity (usually the next objective or spawnfunc_target_assault_roundend etc.)
69 -------- KEYS --------
70 targetname : point to e.g. next objective*/
71 void spawnfunc_target_objective() {
72 self.classname = "target_objective";
73 self.think = assault_objective_think;
74 self.use = assault_objective_use;
75 assault_objective_reset();
78 float assault_objective_decrease_customizeforclient() {
83 if(other.team == assault_attacker_team)
84 if(self.spawnflags == 1)
85 setmodel(self, "models/sprites/push.sp2");
87 setmodel(self, "models/sprites/destroy.sp2");
89 setmodel(self, "models/sprites/defend.sp2");
97 void assault_objective_decrease_think() {
99 local entity objective;
102 objective = find(world, targetname, self.target);
103 while(objective && found == 0) {
104 if(objective.classname == "target_objective") {
106 if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
107 if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) {
108 // decrease was fired already, but objective did recover (round reset)
111 } else { // objective isn't active
114 self.max_health = objective.health; // save current objective status for next think
118 if(!self.spawnflags) {
120 ent = find(world, target, self.targetname);
122 if(ent.classname == "func_assault_destructible")
129 self.nextthink = time + 0.2;
133 // decrease the health of targeted objectives
134 void assault_objective_decrease_use() {
135 if(other.classname == "info_player_deathmatch") // a spawn, a spawn
143 if(activator.team != assault_attacker_team) {
144 // wrong team triggered decrease
149 ent = find(world, targetname, self.target);
151 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
152 ent.health = ent.health - self.dmg;
153 ent = find(ent, targetname, self.target);
159 //=============================================================================
161 /*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
162 When triggered decreases health of the targeted spawnfunc_target_objective.
163 -------- KEYS --------
164 targetname : point to a spawnfunc_target_objective entity*/
165 void spawnfunc_target_objective_decrease() {
167 self.classname = "target_objective_decrease";
169 precache_model("models/sprites/defend.sp2");
170 precache_model("models/sprites/destroy.sp2");
171 precache_model("models/sprites/push.sp2");
176 self.cnt = 0; // not used yet
177 self.use = assault_objective_decrease_use;
178 self.mdl = "models/sprites/here.sp2";
179 self.effects = EF_NODEPTHTEST;
180 self.health = ASSAULT_VALUE_INACTIVE;
181 self.max_health = ASSAULT_VALUE_INACTIVE;
182 self.think = assault_objective_decrease_think;
183 self.customizeentityforclient = assault_objective_decrease_customizeforclient;
184 self.nextthink = time;
188 void assault_destructible_reset() {
189 self.health = self.max_health;
190 self.model = self.mdl;
191 self.solid = SOLID_BSP;
192 self.colormod = '1 1 1';
193 self.cnt = 0; // not active
201 // destructible walls that can be used to trigger target_objective_decrease
202 void spawnfunc_func_assault_destructible() {
204 spawnfunc_func_breakable();
207 void assault_wall_think() {
209 local float notvisible;
211 ent = find(world, targetname, self.target);
213 if(ent.classname == "target_objective" && ent.health < 0)
215 ent = find(ent, targetname, self.target);
220 self.solid = SOLID_NOT;
222 self.model = self.mdl;
223 self.solid = SOLID_BSP;
226 self.nextthink = time + 0.2;
229 void spawnfunc_func_assault_wall() {
230 self.classname = "func_assault_wall";
231 self.mdl = self.model;
232 setmodel(self, self.mdl);
233 self.solid = SOLID_BSP;
234 self.think = assault_wall_think;
235 self.nextthink = time;
239 void target_assault_roundend_reset() {
240 self.cnt = self.cnt + 1; // up round counter
241 self.winning = 0; // up round
244 void target_assault_roundend_use() {
245 self.winning = 1; // round has been won by attackers
248 void spawnfunc_target_assault_roundend() {
250 self.health = 300; // 5 minutes
252 cvar_set("timelimit", ftos(self.health/60));
253 self.winning = 0; // round not yet won by attackers
254 self.classname = "target_assault_roundend";
255 self.use = target_assault_roundend_use;
256 self.cnt = 0; // first round
259 void assault_roundstart_use() {
265 #ifdef TTURRETS_ENABLED
268 //(Re)spawn all turrets
270 ent = find(world, classname, "turret_main");
273 if(ent.team == COLOR_TEAM1)
274 ent.team = COLOR_TEAM2;
276 ent.team = COLOR_TEAM1;
280 // Dubbles as teamchange
281 turret_stdproc_respawn();
282 //ent.turret_spawnfunc();
284 ent = find(ent, classname, "turret_main");
292 void spawnfunc_target_assault_roundstart() {
293 assault_attacker_team = COLOR_TEAM1;
294 self.classname = "target_assault_roundstart";
295 self.use = assault_roundstart_use;
296 self.think = assault_roundstart_use;
297 self.nextthink = time + 0.1;
301 // reset objectives, toggle spawnpoints, reset triggers, ...
302 void assault_new_round() {
305 self.winning = self.winning + 1;
306 // set end time for next round
307 self.cnt = time + self.health;
309 // swap spawn point teams
311 local entity oldself;
313 // reward attackers for winning the round
314 ent = find(world, classname, "player");
316 if(ent.team == assault_attacker_team) {
317 UpdateFrags(ent, 10);
319 ent = find(ent, classname, "player");
322 // swap attacker/defender roles
323 if(assault_attacker_team == COLOR_TEAM1) {
324 assault_attacker_team = COLOR_TEAM2;
326 assault_attacker_team = COLOR_TEAM1;
329 ent = find(world, classname, "info_player_deathmatch");
334 if(self.team == COLOR_TEAM1) {
335 self.team = COLOR_TEAM2;
337 self.team = COLOR_TEAM1;
341 ent = find(ent, classname, "info_player_deathmatch");
344 // reset all objectives
345 ent = find(world, classname, "target_objective");
350 assault_objective_reset();
353 ent = find(ent, classname, "target_objective");
356 // reset round end triggers
357 ent = find(world, classname, "target_assault_roundend");
362 target_assault_roundend_reset();
365 ent = find(ent, classname, "target_assault_roundend");
368 // reset all target_object_decrease
369 ent = find(world, classname, "target_objective_decrease");
373 ent = find(ent, classname, "target_objective_decrease");
376 // reset all spawnfunc_func_assault_destructible
377 ent = find(world, classname, "func_assault_destructible");
383 if(ent.team == COLOR_TEAM1)
384 ent.team = COLOR_TEAM2;
386 ent.team = COLOR_TEAM1;
388 assault_destructible_reset();
390 ent = find(ent, classname, "func_assault_destructible");
393 ent = find(world, classname, "target_assault_roundstart");
400 ent = find(ent, classname, "target_assault_roundstart");
403 // actually restart round... how to do that?
404 ent = find(world, classname, "player");
410 ent = find(ent, classname, "player");