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() {
141 if(activator.team != assault_attacker_team) {
142 // wrong team triggered decrease
147 ent = find(world, targetname, self.target);
149 if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
150 ent.health = ent.health - self.dmg;
151 ent = find(ent, targetname, self.target);
157 //=============================================================================
159 /*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
160 When triggered decreases health of the targeted spawnfunc_target_objective.
161 -------- KEYS --------
162 targetname : point to a spawnfunc_target_objective entity*/
163 void spawnfunc_target_objective_decrease() {
165 self.classname = "target_objective_decrease";
167 precache_model("models/sprites/defend.sp2");
168 precache_model("models/sprites/destroy.sp2");
169 precache_model("models/sprites/push.sp2");
174 self.cnt = 0; // not used yet
175 self.use = assault_objective_decrease_use;
176 self.mdl = "models/sprites/here.sp2";
177 self.effects = EF_NODEPTHTEST;
178 self.health = ASSAULT_VALUE_INACTIVE;
179 self.max_health = ASSAULT_VALUE_INACTIVE;
180 self.think = assault_objective_decrease_think;
181 self.customizeentityforclient = assault_objective_decrease_customizeforclient;
182 self.nextthink = time;
186 void assault_destructible_reset() {
187 self.health = self.max_health;
188 self.model = self.mdl;
189 self.solid = SOLID_BSP;
190 self.colormod = '1 1 1';
191 self.cnt = 0; // not active
199 // destructible walls that can be used to trigger target_objective_decrease
200 void spawnfunc_func_assault_destructible() {
202 spawnfunc_func_breakable();
205 void assault_wall_think() {
207 local float notvisible;
209 ent = find(world, targetname, self.target);
211 if(ent.classname == "target_objective" && ent.health < 0)
213 ent = find(ent, targetname, self.target);
218 self.solid = SOLID_NOT;
220 self.model = self.mdl;
221 self.solid = SOLID_BSP;
224 self.nextthink = time + 0.2;
227 void spawnfunc_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;
237 void target_assault_roundend_reset() {
238 self.cnt = self.cnt + 1; // up round counter
239 self.winning = 0; // up round
242 void target_assault_roundend_use() {
243 self.winning = 1; // round has been won by attackers
246 void spawnfunc_target_assault_roundend() {
248 self.health = 300; // 5 minutes
250 cvar_set("timelimit", ftos(self.health/60));
251 self.winning = 0; // round not yet won by attackers
252 self.classname = "target_assault_roundend";
253 self.use = target_assault_roundend_use;
254 self.cnt = 0; // first round
257 void assault_roundstart_use() {
262 #ifdef TTURRETS_ENABLED
265 //(Re)spawn all turrets
267 ent = find(world, classname, "turret_main");
270 if(ent.team == COLOR_TEAM1)
271 ent.team = COLOR_TEAM2;
273 ent.team = COLOR_TEAM1;
277 // Dubbles as teamchange
278 turret_stdproc_respawn();
279 //ent.turret_spawnfunc();
281 ent = find(ent, classname, "turret_main");
288 void spawnfunc_target_assault_roundstart() {
289 assault_attacker_team = COLOR_TEAM1;
290 self.classname = "target_assault_roundstart";
291 self.use = assault_roundstart_use;
292 self.think = assault_roundstart_use;
293 self.nextthink = time + 0.1;
297 // reset objectives, toggle spawnpoints, reset triggers, ...
298 void assault_new_round() {
301 self.winning = self.winning + 1;
302 // set end time for next round
303 self.cnt = time + self.health;
305 // swap spawn point teams
307 local entity oldself;
309 // reward attackers for winning the round
310 ent = find(world, classname, "player");
312 if(ent.team == assault_attacker_team) {
313 UpdateFrags(ent, 10);
315 ent = find(ent, classname, "player");
318 // swap attacker/defender roles
319 if(assault_attacker_team == COLOR_TEAM1) {
320 assault_attacker_team = COLOR_TEAM2;
322 assault_attacker_team = COLOR_TEAM1;
325 ent = find(world, classname, "info_player_deathmatch");
330 if(self.team == COLOR_TEAM1) {
331 self.team = COLOR_TEAM2;
333 self.team = COLOR_TEAM1;
337 ent = find(ent, classname, "info_player_deathmatch");
340 // reset all objectives
341 ent = find(world, classname, "target_objective");
346 assault_objective_reset();
349 ent = find(ent, classname, "target_objective");
352 // reset round end triggers
353 ent = find(world, classname, "target_assault_roundend");
358 target_assault_roundend_reset();
361 ent = find(ent, classname, "target_assault_roundend");
364 // reset all target_object_decrease
365 ent = find(world, classname, "target_objective_decrease");
369 ent = find(ent, classname, "target_objective_decrease");
372 // reset all spawnfunc_func_assault_destructible
373 ent = find(world, classname, "func_assault_destructible");
379 if(ent.team == COLOR_TEAM1)
380 ent.team = COLOR_TEAM2;
382 ent.team = COLOR_TEAM1;
384 assault_destructible_reset();
386 ent = find(ent, classname, "func_assault_destructible");
389 ent = find(world, classname, "target_assault_roundstart");
396 ent = find(ent, classname, "target_assault_roundstart");
399 // actually restart round... how to do that?
400 ent = find(world, classname, "player");
406 ent = find(ent, classname, "player");