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