about summary refs log tree commit diff
path: root/src/game/server
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-10-06 18:05:01 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-10-06 18:05:01 +0000
commit12472ef7f405f5e8eb620059cbf95926a458538a (patch)
tree712cc453e491ff46c96b48785a94093b1d17cb1f /src/game/server
parentd1b55351ccc2252917ad494b74bb6ad562df34ce (diff)
downloadzcatch-12472ef7f405f5e8eb620059cbf95926a458538a.tar.gz
zcatch-12472ef7f405f5e8eb620059cbf95926a458538a.zip
major update. continued on ban support. added demo recording (client and server side). added demo player. added demo menu. demos have some quirks and file size optimizations havn't been done yet. some interface tweaks
Diffstat (limited to 'src/game/server')
-rw-r--r--src/game/server/entities/character.cpp2
-rw-r--r--src/game/server/entities/laser.cpp2
-rw-r--r--src/game/server/entities/projectile.cpp4
-rw-r--r--src/game/server/entity.cpp14
-rw-r--r--src/game/server/entity.hpp38
-rw-r--r--src/game/server/eventhandler.cpp4
-rw-r--r--src/game/server/gamecontext.cpp26
-rw-r--r--src/game/server/gamecontext.hpp2
-rw-r--r--src/game/server/gamecontroller.cpp15
9 files changed, 84 insertions, 23 deletions
diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp
index 071407b1..0516ddc5 100644
--- a/src/game/server/entities/character.cpp
+++ b/src/game/server/entities/character.cpp
@@ -828,7 +828,7 @@ bool CHARACTER::take_damage(vec2 force, int dmg, int from, int weapon)
 
 void CHARACTER::snap(int snaping_client)
 {
-	if(distance(game.players[snaping_client]->view_pos, pos) > 1000.0f)
+	if(networkclipped(snaping_client))
 		return;
 	
 	NETOBJ_CHARACTER *character = (NETOBJ_CHARACTER *)snap_new_item(NETOBJTYPE_CHARACTER, player->client_id, sizeof(NETOBJ_CHARACTER));
diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp
index 4e9909ba..8b512d82 100644
--- a/src/game/server/entities/laser.cpp
+++ b/src/game/server/entities/laser.cpp
@@ -100,7 +100,7 @@ void LASER::tick()
 
 void LASER::snap(int snapping_client)
 {
-	if(distance(game.players[snapping_client]->view_pos, pos) > 1000.0f)
+	if(networkclipped(snapping_client))
 		return;
 
 	NETOBJ_LASER *obj = (NETOBJ_LASER *)snap_new_item(NETOBJTYPE_LASER, id, sizeof(NETOBJ_LASER));
diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp
index a2e10437..cd15ba10 100644
--- a/src/game/server/entities/projectile.cpp
+++ b/src/game/server/entities/projectile.cpp
@@ -78,9 +78,7 @@ void PROJECTILE::tick()
 		if(flags & PROJECTILE_FLAGS_EXPLODE)
 			game.create_explosion(curpos, owner, weapon, false);
 		else if(targetchr)
-		{
 			targetchr->take_damage(direction * max(0.001f, force), damage, owner, weapon);
-		}
 
 		game.world.destroy_entity(this);
 	}
@@ -100,7 +98,7 @@ void PROJECTILE::snap(int snapping_client)
 {
 	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
 	
-	if(distance(game.players[snapping_client]->view_pos, get_pos(ct)) > 1000.0f)
+	if(networkclipped(snapping_client, get_pos(ct)))
 		return;
 
 	NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
diff --git a/src/game/server/entity.cpp b/src/game/server/entity.cpp
index 2cc7c8f7..1af5f60a 100644
--- a/src/game/server/entity.cpp
+++ b/src/game/server/entity.cpp
@@ -26,3 +26,17 @@ ENTITY::~ENTITY()
 	game.world.remove_entity(this);
 	snap_free_id(id);
 }
+
+int ENTITY::networkclipped(int snapping_client)
+{
+	return networkclipped(snapping_client, pos);
+}
+
+int ENTITY::networkclipped(int snapping_client, vec2 check_pos)
+{
+	if(snapping_client == -1)
+		return 0;
+	if(distance(game.players[snapping_client]->view_pos, check_pos) > 1000.0f)
+		return 1;
+	return 0;
+}
diff --git a/src/game/server/entity.hpp b/src/game/server/entity.hpp
index 8ccb2d9a..debe57b6 100644
--- a/src/game/server/entity.hpp
+++ b/src/game/server/entity.hpp
@@ -74,34 +74,34 @@ public:
 
 	/*
 		Function: destroy
-		Destorys the entity.
+			Destorys the entity.
 	*/
 	virtual void destroy() { delete this; }
 		
 	/*
 		Function: reset
-		Called when the game resets the map. Puts the entity
-		back to it's starting state or perhaps destroys it.
+			Called when the game resets the map. Puts the entity
+			back to it's starting state or perhaps destroys it.
 	*/
 	virtual void reset() {}
 	
 	/*
 		Function: tick
-		Called progress the entity to the next tick. Updates
-		and moves the entity to it's new state and position.
+			Called progress the entity to the next tick. Updates
+			and moves the entity to it's new state and position.
 	*/
 	virtual void tick() {}
 
 	/*
 		Function: tick_defered
-		Called after all entities tick() function has been called.
+			Called after all entities tick() function has been called.
 	*/
 	virtual void tick_defered() {}
 	
 	/*
 		Function: snap
-		Called when a new snapshot is being generated for a specific
-		client.
+			Called when a new snapshot is being generated for a specific
+			client.
 		
 		Arguments:
 			snapping_client - ID of the client which snapshot is
@@ -110,16 +110,34 @@ public:
 				recording.
 	*/
 	virtual void snap(int snapping_client) {}
+	
+	/*
+		Function: networkclipped(int snapping_client)
+			Performs a series of test to see if a client can see the
+			entity.
+
+		Arguments:
+			snapping_client - ID of the client which snapshot is
+				being generated. Could be -1 to create a complete
+				snapshot of everything in the game for demo
+				recording.
+			
+		Returns:
+			Non-zero if the entity doesn't have to be in the snapshot.
+	*/
+	int networkclipped(int snapping_client);
+	int networkclipped(int snapping_client, vec2 check_pos);
+		
 
 	/*
 		Variable: proximity_radius
-		Contains the physical size of the entity.
+			Contains the physical size of the entity.
 	*/
 	float proximity_radius;
 	
 	/*
 		Variable: pos
-		Contains the current posititon of the entity.
+			Contains the current posititon of the entity.
 	*/
 	vec2 pos;
 };
diff --git a/src/game/server/eventhandler.cpp b/src/game/server/eventhandler.cpp
index ce6a3b71..761eaf2c 100644
--- a/src/game/server/eventhandler.cpp
+++ b/src/game/server/eventhandler.cpp
@@ -36,10 +36,10 @@ void EVENTHANDLER::snap(int snapping_client)
 {
 	for(int i = 0; i < num_events; i++)
 	{
-		if(cmask_is_set(client_masks[i], snapping_client))
+		if(snapping_client == -1 || cmask_is_set(client_masks[i], snapping_client))
 		{
 			NETEVENT_COMMON *ev = (NETEVENT_COMMON *)&data[offsets[i]];
-			if(distance(game.players[snapping_client]->view_pos, vec2(ev->x, ev->y)) < 1500.0f)
+			if(snapping_client == -1 || distance(game.players[snapping_client]->view_pos, vec2(ev->x, ev->y)) < 1500.0f)
 			{
 				void *d = snap_new_item(types[i], i, sizes[i]);
 				mem_copy(d, &data[offsets[i]], sizes[i]);
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp
index fb426ad6..0cdd4227 100644
--- a/src/game/server/gamecontext.cpp
+++ b/src/game/server/gamecontext.cpp
@@ -171,7 +171,7 @@ void GAMECONTEXT::send_chat(int chatter_cid, int team, const char *text)
 }
 
 
-void GAMECONTEXT::send_info(int who, int to_who)
+void GAMECONTEXT::send_info(int who, int to_who, bool recordonly)
 {
 	NETMSG_SV_SETINFO msg;
 	msg.cid = who;
@@ -180,9 +180,17 @@ void GAMECONTEXT::send_info(int who, int to_who)
 	msg.use_custom_color = players[who]->use_custom_color;
 	msg.color_body = players[who]->color_body;
 	msg.color_feet = players[who]->color_feet;
-	msg.pack(MSGFLAG_VITAL);
 	
-	server_send_msg(to_who);
+	if(recordonly)
+	{
+		msg.pack(MSGFLAG_NOSEND);
+		server_send_msg(to_who);
+	}
+	else
+	{
+		msg.pack(MSGFLAG_VITAL);
+		server_send_msg(to_who);
+	}
 }
 
 void GAMECONTEXT::send_emoticon(int cid, int emoticon)
@@ -333,6 +341,18 @@ void GAMECONTEXT::tick()
 
 void GAMECONTEXT::snap(int client_id)
 {
+	// check if we are recording a demo
+	if(client_id == -1)
+	{
+		// we are recording, make sure that we set
+		// the info for all players all the time
+		for(int i = 0; i < MAX_CLIENTS; i++)
+		{
+			if(game.players[i])
+				send_info(i, -1, true);
+		}
+	}
+	
 	world.snap(client_id);
 	controller->snap(client_id);
 	events.snap(client_id);
diff --git a/src/game/server/gamecontext.hpp b/src/game/server/gamecontext.hpp
index 124df645..8a1ff918 100644
--- a/src/game/server/gamecontext.hpp
+++ b/src/game/server/gamecontext.hpp
@@ -77,7 +77,7 @@ public:
 	void send_emoticon(int cid, int emoticon);
 	void send_weapon_pickup(int cid, int weapon);
 	void send_broadcast(const char *text, int cid);
-	void send_info(int who, int to_who);
+	void send_info(int who, int to_who, bool recordonly = false);
 
 };
 
diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp
index 7329240b..aa8c09b7 100644
--- a/src/game/server/gamecontroller.cpp
+++ b/src/game/server/gamecontroller.cpp
@@ -457,8 +457,19 @@ void GAMECONTROLLER::snap(int snapping_client)
 	gameobj->round_num = (strlen(config.sv_maprotation) || config.sv_rounds_per_map > 1) ? config.sv_rounds_per_map : 0;
 	gameobj->round_current = round_count+1;
 	
-	gameobj->teamscore_red = is_teamplay() ? teamscore[0] : game.players[snapping_client]->score;
-	gameobj->teamscore_blue = teamscore[1];
+	
+	if(snapping_client == -1)
+	{
+		// we are recording a demo, just set the scores
+		gameobj->teamscore_red = teamscore[0];
+		gameobj->teamscore_blue = teamscore[1];
+	}
+	else
+	{
+		// TODO: this little hack should be removed
+		gameobj->teamscore_red = is_teamplay() ? teamscore[0] : game.players[snapping_client]->score;
+		gameobj->teamscore_blue = teamscore[1];
+	}
 }
 
 int GAMECONTROLLER::get_auto_team(int notthisid)