r5100 - trunk/data/qcsrc/server
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Wed Nov 26 03:29:34 EST 2008
Author: div0
Date: 2008-11-26 03:29:31 -0500 (Wed, 26 Nov 2008)
New Revision: 5100
Modified:
trunk/data/qcsrc/server/arena.qc
trunk/data/qcsrc/server/assault.qc
trunk/data/qcsrc/server/clientcommands.qc
trunk/data/qcsrc/server/ctf.qc
trunk/data/qcsrc/server/g_world.qc
trunk/data/qcsrc/server/scores_rules.qc
trunk/data/qcsrc/server/teamplay.qc
Log:
assault: fix lots of bugs, initial waypointsprites support
Modified: trunk/data/qcsrc/server/arena.qc
===================================================================
--- trunk/data/qcsrc/server/arena.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/arena.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -18,6 +18,8 @@
void onslaught_generator_reset();
void onslaught_controlpoint_reset();
void func_breakable_reset();
+void assault_objective_reset();
+void target_assault_roundend_reset();
/**
* Resets the state of all clients, items, flags, runes, keys, weapons, waypoints, ... of the map.
@@ -108,10 +110,26 @@
{
self.team = self.team_saved;
}
- else if(self.classname == "func_breakable" || self.classname == "func_assault_destructible")
+ else if(self.classname == "func_breakable")
{
func_breakable_reset();
}
+ else if(self.classname == "func_assault_destructible")
+ {
+ func_breakable_reset();
+ }
+ else if(self.classname == "target_objective")
+ {
+ assault_objective_reset();
+ }
+ else if(self.classname == "target_assault_roundend")
+ {
+ target_assault_roundend_reset();
+ }
+ else if(self.classname == "target_assault_roundstart")
+ {
+ self.use();
+ }
}
// Waypoints come LAST (keyhunt keys reference them)
Modified: trunk/data/qcsrc/server/assault.qc
===================================================================
--- trunk/data/qcsrc/server/assault.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/assault.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -1,39 +1,24 @@
void spawnfunc_func_breakable();
+void target_objective_decrease_activate();
+.entity assault_decreaser;
+.entity sprite;
-//=============================================================================
-
-/*QUAKED spawnfunc_info_player_attacker (1 0 0) (-16 -16 -24) (16 16 45) INITIAL
-Normal attacker spawning location for Nexuiz Asssault
--------- KEYS --------
-angle : direction in which player will look when spawning in the game. Does not apply to bots.
-target : this should point to a spawnfunc_target_objective to decide when this spawning point is active.
-nobots : when set to 1, bots will never use this spawn point to respawn in the game.
-nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
-notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
-notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
-notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
--------- SPAWNFLAGS --------
-INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
void spawnfunc_info_player_attacker() {
+ if(!g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM1; // red, gets swapped every round
spawnfunc_info_player_deathmatch();
}
-//=============================================================================
-
-/*QUAKED spawnfunc_info_player_defender (0 1 0) (-16 -16 -24) (16 16 45) INITIAL
-Normal defender spawning location for Nexuiz Asssault
--------- KEYS --------
-angle : direction in which player will look when spawning in the game. Does not apply to bots.
-target : this should point to a spawnfunc_target_objective to decide when this spawning point is active.
-nobots : when set to 1, bots will never use this spawn point to respawn in the game.
-nohumans : when set to 1, human players will never use this spawn point to respawn in the game.
-notfree : when set to 1, entity will not spawn in "Free for all" and "Tournament" modes.
-notteam : when set to 1, entity will not spawn in "Teamplay" and "CTF" modes.
-notsingle : when set to 1, entity will not spawn in Single Player mode (bot play mode).
--------- SPAWNFLAGS --------
-INITIAL : makes the spawnpoint the initial place for the player to spawn at the beginning of the game.*/
void spawnfunc_info_player_defender() {
+ if(!g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM2; // blue, gets swapped every round
spawnfunc_info_player_deathmatch();
}
@@ -45,123 +30,127 @@
}
void assault_objective_use() {
+ if(other.classname == "info_player_deathmatch") // a spawn, a spawn
+ return;
+
// activate objective
self.health = 100;
- self.nextthink = time + 0.1;
-}
+ print("^2Activated objective ", self.targetname, "=", etos(self), "\n");
+ print("Activator is ", activator.classname, "\n");
-void assault_objective_think() {
- if(self.health < 0) {
- //self.effects = 0;
- activator = self;
- SUB_UseTargets();
- } else {
- //self.effects = EF_STARDUST;
- self.nextthink = time + 0.1;
+ entity oldself;
+ oldself = self;
+
+ for(self = world; (self = find(self, target, oldself.targetname)); )
+ {
+ if(self.classname == "target_objective_decrease")
+ target_objective_decrease_activate();
}
+ self = oldself;
}
-//=============================================================================
-/*QUAKED spawnfunc_target_objective (0 .5 0) (-8 -8 -8) (8 8 8)
-Objective controller for Nexuiz Assault. When active it has 100 health. If it falls below 0 then
-it'll trigger the next targeted entity (usually the next objective or spawnfunc_target_assault_roundend etc.)
--------- KEYS --------
-targetname : point to e.g. next objective*/
void spawnfunc_target_objective() {
self.classname = "target_objective";
- self.think = assault_objective_think;
self.use = assault_objective_use;
assault_objective_reset();
}
-float assault_objective_decrease_customizeforclient() {
- if(!self.spawnflags)
- return FALSE;
- if(self.cnt == 0) {
- if(other.team == assault_attacker_team)
- if(self.spawnflags == 1)
- setmodel(self, "models/sprites/push.sp2");
- else
- setmodel(self, "models/sprites/destroy.sp2");
- else
- setmodel(self, "models/sprites/defend.sp2");
- } else {
- return FALSE;
+// decrease the health of targeted objectives
+void assault_objective_decrease_use() {
+ if(activator.team != assault_attacker_team) {
+ // wrong team triggered decrease
+ return;
}
- return TRUE;
-}
+ if(other.sprite.classname == "assault_decreaser_sprite")
+ WaypointSprite_Disown(other.sprite, waypointsprite_deadlifetime);
-void assault_objective_decrease_think() {
+ if(self.enemy.health < ASSAULT_VALUE_INACTIVE)
+ {
+ if(self.enemy.health - self.dmg > 0.5)
+ {
+ PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.dmg);
+ self.enemy.health = self.enemy.health - self.dmg;
+ }
+ else
+ {
+ PlayerTeamScore_Add(activator, SP_SCORE, ST_SCORE, self.enemy.health);
+ PlayerTeamScore_Add(activator, SP_ASSAULT_OBJECTIVES, ST_ASSAULT_OBJECTIVES, 1);
+ self.enemy.health = -1;
- local entity objective;
- local float found;
- found = 0;
- objective = find(world, targetname, self.target);
- while(objective && found == 0) {
- if(objective.classname == "target_objective") {
- found = 1;
- if(objective.health < ASSAULT_VALUE_INACTIVE) { // targeted objective is active
- if(self.cnt == 1 && self.max_health >= ASSAULT_VALUE_INACTIVE) {
- // decrease was fired already, but objective did recover (round reset)
- self.cnt = 0;
- }
- } else { // objective isn't active
- self.cnt = 1;
- }
- self.max_health = objective.health; // save current objective status for next think
+ entity oldself, oldactivator;
+
+ oldself = self;
+ self = oldself.enemy;
+ oldactivator = activator;
+ activator = oldself;
+ SUB_UseTargets();
+ activator = oldactivator;
+ self = oldself;
}
}
+}
- if(!self.spawnflags) {
- local entity ent;
- ent = find(world, target, self.targetname);
- if(ent) {
- if(ent.classname == "func_assault_destructible")
- self.spawnflags = 2;
+void assault_setenemytoobjective()
+{
+ local entity objective;
+ for(objective = world; (objective = find(objective, targetname, self.target)); ) {
+ if(objective.classname == "target_objective") {
+ if(self.enemy == world)
+ self.enemy = objective;
else
- self.spawnflags = 1;
+ objerror("more than one objective as target - fix the map!");
+ break;
}
}
- self.nextthink = time + 0.2;
+ if(self.enemy == world)
+ objerror("no objective as target - fix the map!");
}
+float assault_decreaser_sprite_visible(entity e)
+{
+ entity decreaser;
+ entity object;
-// decrease the health of targeted objectives
-void assault_objective_decrease_use() {
- if(other.classname == "info_player_deathmatch") // a spawn, a spawn
- return;
+ decreaser = self.assault_decreaser;
- if(self.cnt > 0) {
- // did already fire
- return;
- }
+ if(decreaser.enemy.health >= ASSAULT_VALUE_INACTIVE)
+ return FALSE;
- if(activator.team != assault_attacker_team) {
- // wrong team triggered decrease
- return;
- }
+ return TRUE;
+}
- local entity ent;
- ent = find(world, targetname, self.target);
- while(ent) {
- if(ent.health > 0 && ent.health < ASSAULT_VALUE_INACTIVE)
- ent.health = ent.health - self.dmg;
- ent = find(ent, targetname, self.target);
+void target_objective_decrease_activate()
+{
+ entity ent, spr;
+ self.owner = world;
+ for(ent = world; (ent = find(ent, target, self.targetname)); )
+ {
+ if(ent.sprite != world)
+ WaypointSprite_Disown(ent.sprite, waypointsprite_deadlifetime);
+
+ spr = WaypointSprite_SpawnFixed("<placeholder>", 0.5 * (ent.absmin + ent.absmax), ent, sprite);
+ spr.assault_decreaser = self;
+ spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
+ spr.classname = "assault_decreaser_sprite";
+ WaypointSprite_UpdateRule(spr, assault_attacker_team, SPRITERULE_TEAMPLAY);
+ if(ent.classname == "func_assault_destructible")
+ WaypointSprite_UpdateSprites(spr, "as-defend", "as-destroy", "as-destroy");
+ else
+ WaypointSprite_UpdateSprites(spr, "as-defend", "as-push", "as-push");
}
+}
- self.cnt = 1;
+void target_objective_decrease_findtarget()
+{
+ assault_setenemytoobjective();
}
//=============================================================================
-/*QUAKED target_objective_decrease (0 .5 0) (-8 -8 -8) (8 8 8)
-When triggered decreases health of the targeted spawnfunc_target_objective.
--------- KEYS --------
-targetname : point to a spawnfunc_target_objective entity*/
void spawnfunc_target_objective_decrease() {
self.classname = "target_objective_decrease";
@@ -173,29 +162,12 @@
if(!self.dmg) {
self.dmg = 101;
}
- self.cnt = 0; // not used yet
self.use = assault_objective_decrease_use;
- self.mdl = "models/sprites/here.sp2";
- self.effects = EF_NODEPTHTEST;
self.health = ASSAULT_VALUE_INACTIVE;
self.max_health = ASSAULT_VALUE_INACTIVE;
- self.think = assault_objective_decrease_think;
- self.customizeentityforclient = assault_objective_decrease_customizeforclient;
- self.nextthink = time;
-}
+ self.enemy = world;
-
-void assault_destructible_reset() {
- self.health = self.max_health;
- self.model = self.mdl;
- self.solid = SOLID_BSP;
- self.colormod = '1 1 1';
- self.cnt = 0; // not active
- if(self.spawnflags)
- {
- activator = self;
- self.use();
- }
+ InitializeEntity(self, target_objective_decrease_findtarget, INITPRIO_FINDTARGET);
}
// destructible walls that can be used to trigger target_objective_decrease
@@ -205,17 +177,7 @@
}
void assault_wall_think() {
- local entity ent;
- local float notvisible;
- notvisible = 0;
- ent = find(world, targetname, self.target);
- while(ent) {
- if(ent.classname == "target_objective" && ent.health < 0)
- notvisible = 1;
- ent = find(ent, targetname, self.target);
- }
-
- if(notvisible) {
+ if(self.enemy.health < 0) {
self.model = "";
self.solid = SOLID_NOT;
} else {
@@ -233,6 +195,7 @@
self.solid = SOLID_BSP;
self.think = assault_wall_think;
self.nextthink = time;
+ InitializeEntity(self, assault_setenemytoobjective, INITPRIO_FINDTARGET);
}
@@ -261,27 +224,27 @@
activator = self;
SUB_UseTargets();
-/*
+ /*
#ifdef TTURRETS_ENABLED
- entity ent,oldself;
+entity ent,oldself;
//(Re)spawn all turrets
oldself = self;
ent = find(world, classname, "turret_main");
while(ent) {
- // Swap turret teams
- if(ent.team == COLOR_TEAM1)
- ent.team = COLOR_TEAM2;
- else
- ent.team = COLOR_TEAM1;
+ // Swap turret teams
+ if(ent.team == COLOR_TEAM1)
+ ent.team = COLOR_TEAM2;
+ else
+ ent.team = COLOR_TEAM1;
- self = ent;
+ self = ent;
- // Dubbles as teamchange
- turret_stdproc_respawn();
- //ent.turret_spawnfunc();
+ // Dubbles as teamchange
+ turret_stdproc_respawn();
+ //ent.turret_spawnfunc();
- ent = find(ent, classname, "turret_main");
+ ent = find(ent, classname, "turret_main");
}
self = oldself;
#endif
@@ -300,25 +263,13 @@
// trigger new round
// reset objectives, toggle spawnpoints, reset triggers, ...
void assault_new_round() {
+ bprint("ASSAULT: new round\n");
// up round counter
self.winning = self.winning + 1;
// set end time for next round
self.cnt = time + self.health;
- // swap spawn point teams
- local entity ent;
- local entity oldself;
-
- // reward attackers for winning the round
- ent = find(world, classname, "player");
- while(ent) {
- if(ent.team == assault_attacker_team) {
- UpdateFrags(ent, 10);
- }
- ent = find(ent, classname, "player");
- }
-
// swap attacker/defender roles
if(assault_attacker_team == COLOR_TEAM1) {
assault_attacker_team = COLOR_TEAM2;
@@ -326,92 +277,32 @@
assault_attacker_team = COLOR_TEAM1;
}
+ // swap spawn point teams
+ local entity ent;
+ local entity oldself;
ent = find(world, classname, "info_player_deathmatch");
while (ent)
{
- oldself = self;
- self = ent;
- if(self.team == COLOR_TEAM1) {
- self.team = COLOR_TEAM2;
+ if(ent.team == COLOR_TEAM1) {
+ ent.team = COLOR_TEAM2;
} else {
- self.team = COLOR_TEAM1;
+ ent.team = COLOR_TEAM1;
}
- self = oldself;
-
ent = find(ent, classname, "info_player_deathmatch");
}
- // reset all objectives
- ent = find(world, classname, "target_objective");
- while (ent)
- {
- oldself = self;
- self = ent;
- assault_objective_reset();
- self = oldself;
-
- ent = find(ent, classname, "target_objective");
- }
-
- // reset round end triggers
- ent = find(world, classname, "target_assault_roundend");
- while (ent)
- {
- oldself = self;
- self = ent;
- target_assault_roundend_reset();
- self = oldself;
-
- ent = find(ent, classname, "target_assault_roundend");
- }
-
- // reset all target_object_decrease
- ent = find(world, classname, "target_objective_decrease");
- while (ent)
- {
- ent.cnt = 0;
- ent = find(ent, classname, "target_objective_decrease");
- }
-
- // reset all spawnfunc_func_assault_destructible
+ // swap all destructibles
ent = find(world, classname, "func_assault_destructible");
while (ent)
{
- oldself = self;
- self = ent;
-
- if(ent.team == COLOR_TEAM1)
- ent.team = COLOR_TEAM2;
- else
- ent.team = COLOR_TEAM1;
-
- assault_destructible_reset();
- self = oldself;
+ if(ent.team == COLOR_TEAM1)
+ ent.team = COLOR_TEAM2;
+ else
+ ent.team = COLOR_TEAM1;
ent = find(ent, classname, "func_assault_destructible");
}
- ent = find(world, classname, "target_assault_roundstart");
- while (ent)
- {
- oldself = self;
- self = ent;
- self.use();
- self = oldself;
- ent = find(ent, classname, "target_assault_roundstart");
- }
-
- // actually restart round... how to do that?
- ent = find(world, classname, "player");
- while(ent) {
- oldself = self;
- self = ent;
- PutClientInServer();
- self = oldself;
- ent = find(ent, classname, "player");
-
- }
-
-
+ // reset the level with a countdown
+ cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
+ ReadyRestartForce(); // sets game_starttime
}
-
-
Modified: trunk/data/qcsrc/server/clientcommands.qc
===================================================================
--- trunk/data/qcsrc/server/clientcommands.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/clientcommands.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -480,7 +480,7 @@
}
}
-void ReadyRestart()
+void ReadyRestartForce()
{
local entity e;
@@ -488,10 +488,6 @@
VoteReset();
- // no arena, assault support yet...
- if(g_arena | g_assault | gameover | intermission_running | race_completing)
- localcmd("restart\n");
-
// clear overtime
if(checkrules_overtimeend)
checkrules_overtimeend = 0;
@@ -539,14 +535,23 @@
//reset map immediately if this cvar is not set
if (!cvar("sv_ready_restart_after_countdown"))
reset_map();
-
- // reset ALL scores
- Score_ClearAll();
if(cvar("sv_eventlog"))
GameLogEcho(":restart");
}
+void ReadyRestart()
+{
+ // no arena, assault support yet...
+ if(g_arena | g_assault | gameover | intermission_running | race_completing)
+ localcmd("restart\n");
+
+ // reset ALL scores
+ Score_ClearAll();
+
+ ReadyRestartForce();
+}
+
/**
* Counts how many players are ready. If not enough players are ready, the function
* does nothing. If all players are ready, the timelimit will be extended and the
Modified: trunk/data/qcsrc/server/ctf.qc
===================================================================
--- trunk/data/qcsrc/server/ctf.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/ctf.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -569,6 +569,11 @@
*/
void spawnfunc_info_player_team1()
{
+ if(g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM1; // red
spawnfunc_info_player_deathmatch();
};
@@ -584,6 +589,11 @@
*/
void spawnfunc_info_player_team2()
{
+ if(g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM2; // blue
spawnfunc_info_player_deathmatch();
};
@@ -599,6 +609,11 @@
*/
void spawnfunc_info_player_team3()
{
+ if(g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM3; // purple
spawnfunc_info_player_deathmatch();
};
@@ -614,6 +629,11 @@
*/
void spawnfunc_info_player_team4()
{
+ if(g_assault)
+ {
+ remove(self);
+ return;
+ }
self.team = COLOR_TEAM4; // yellow
spawnfunc_info_player_deathmatch();
};
Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/g_world.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -1270,16 +1270,11 @@
{
if(ent.winning) // round end has been triggered by attacking team
{
+ bprint("ASSAULT: round completed...\n");
SetWinners(team, assault_attacker_team);
- if(assault_attacker_team == COLOR_TEAM1)
- {
- team1_score = team1_score + 50;
- }
- else
- {
- team2_score = team2_score + 50;
- }
+ TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
+
if(ent.cnt == 1) // this was the second round
{
status = WINNING_YES;
@@ -1289,7 +1284,6 @@
local entity oldself;
oldself = self;
self = ent;
- cvar_set("timelimit", ftos((2*time)/60)); // FIXME use game_starttime here
assault_new_round();
self = oldself;
}
@@ -1297,7 +1291,6 @@
}
return status;
-
}
// LMS winning condition: game terminates if and only if there's at most one
Modified: trunk/data/qcsrc/server/scores_rules.qc
===================================================================
--- trunk/data/qcsrc/server/scores_rules.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/scores_rules.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -161,3 +161,14 @@
}
ScoreRules_basics_end();
}
+
+// Assault stuff
+#define ST_ASSAULT_OBJECTIVES 1
+#define SP_ASSAULT_OBJECTIVES 4
+void ScoreRules_assault()
+{
+ ScoreRules_basics(2, SFL_SORT_PRIO_SECONDARY, SFL_SORT_PRIO_SECONDARY, TRUE);
+ ScoreInfo_SetLabel_TeamScore( ST_ASSAULT_OBJECTIVES, "objectives", SFL_SORT_PRIO_PRIMARY);
+ ScoreInfo_SetLabel_PlayerScore(SP_ASSAULT_OBJECTIVES, "objectives", SFL_SORT_PRIO_PRIMARY);
+ ScoreRules_basics_end();
+}
Modified: trunk/data/qcsrc/server/teamplay.qc
===================================================================
--- trunk/data/qcsrc/server/teamplay.qc 2008-11-26 08:28:42 UTC (rev 5099)
+++ trunk/data/qcsrc/server/teamplay.qc 2008-11-26 08:29:31 UTC (rev 5100)
@@ -284,6 +284,7 @@
game = GAME_ASSAULT;
gamemode_name = "Assault";
ActivateTeamplay();
+ ScoreRules_assault();
}
if(g_onslaught)
More information about the nexuiz-commits
mailing list