about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-09-25 21:53:14 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-09-25 21:53:14 +0000
commitdbf425f1aa767de7f6415b45d1321d8dd6c05e97 (patch)
tree7ab92e9c5bae5f914e814746c203b4bdc4ef44bd
parenta554203943cde311a93090805b40f3d39ccc75d2 (diff)
downloadzcatch-dbf425f1aa767de7f6415b45d1321d8dd6c05e97.tar.gz
zcatch-dbf425f1aa767de7f6415b45d1321d8dd6c05e97.zip
updated ctf a bit
-rw-r--r--src/engine/client/client.c9
-rw-r--r--src/game/client/game_client.cpp3
-rw-r--r--src/game/game.cpp4
-rw-r--r--src/game/server/game_server.cpp269
-rw-r--r--src/game/server/game_server.h41
5 files changed, 117 insertions, 209 deletions
diff --git a/src/engine/client/client.c b/src/engine/client/client.c
index 1fce3833..a518fe39 100644
--- a/src/engine/client/client.c
+++ b/src/engine/client/client.c
@@ -18,6 +18,8 @@
 
 #include <mastersrv/mastersrv.h>
 
+const int prediction_margin = 5;
+
 /*
 	Server Time
 	Client Mirror Time
@@ -726,9 +728,8 @@ static void client_process_packet(NETPACKET *packet)
 						if(inputs[k].tick == input_predtick)
 						{
 							//-1000/50
-							int margin = 1000/50;
 							int64 target = inputs[k].game_time + (time_get() - inputs[k].time);
-							st_update(&predicted_time, target - (int64)(((time_left-margin)/1000.0f)*time_freq()));
+							st_update(&predicted_time, target - (int64)(((time_left-prediction_margin)/1000.0f)*time_freq()));
 							break;
 						}
 					}
@@ -839,14 +840,14 @@ static void client_process_packet(NETPACKET *packet)
 						{
 							// start at 200ms and work from there
 							st_init(&predicted_time, (game_tick+10)*time_freq()/50);
-							st_init(&game_time, (game_tick-2)*time_freq()/50);
+							st_init(&game_time, (game_tick-1)*time_freq()/50);
 							snapshots[SNAP_PREV] = snapshot_storage.first;
 							snapshots[SNAP_CURRENT] = snapshot_storage.last;
 							local_start_time = time_get();
 							client_set_state(CLIENTSTATE_ONLINE);
 						}
 						
-						st_update(&game_time, (game_tick-2)*time_freq()/50);
+						st_update(&game_time, (game_tick-1)*time_freq()/50);
 						
 						// ack snapshot
 						ack_game_tick = game_tick;
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 983a84b6..aad2ed27 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -731,6 +731,7 @@ extern "C" void modc_newsnapshot()
 		if((client_tick()%250) == 0)
 		{
 			msg_pack_start(MSG_SAY, MSGFLAG_VITAL);
+			msg_pack_int(-1);
 			msg_pack_string("galenskap!!!!", 512);
 			msg_pack_end();
 			client_send_msg();
@@ -1654,6 +1655,7 @@ void render_game()
 						else
 						{
 							msg_pack_start(MSG_SAY, MSGFLAG_VITAL);
+							msg_pack_int(-1);
 							msg_pack_string(chat_input, 512);
 							msg_pack_end();
 							client_send_msg();
@@ -2177,6 +2179,7 @@ extern "C" void modc_message(int msg)
 	if(msg == MSG_CHAT)
 	{
 		int cid = msg_unpack_int();
+		int targets = msg_unpack_int();
 		const char *message = msg_unpack_string();
 		dbg_msg("message", "chat cid=%d msg='%s'", cid, message);
 		chat_add_line(cid, message);
diff --git a/src/game/game.cpp b/src/game/game.cpp
index d5b74a92..c8c6acb3 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -79,13 +79,13 @@ void move_box(vec2 *inout_pos, vec2 *inout_vel, vec2 size, float elasticity)
 				if(test_box(vec2(pos.x, new_pos.y), size))
 				{
 					new_pos.y = pos.y;
-					vel.y = 0;
+					vel.y *= -elasticity;
 				}
 				
 				if(test_box(vec2(new_pos.x, pos.y), size))
 				{
 					new_pos.x = pos.x;
-					vel.x = 0;
+					vel.x *= -elasticity;
 				}
 			}
 			
diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp
index 9d28a38c..4647318a 100644
--- a/src/game/server/game_server.cpp
+++ b/src/game/server/game_server.cpp
@@ -317,8 +317,74 @@ void gameobject::post_reset()
 	}
 }
 
+
+
+void gameobject::on_player_spawn(class player *p)
+{
+}
+
+void gameobject::on_player_death(class player *victim, class player *killer, int weapon)
+{
+	// drop flags
+	for(int fi = 0; fi < 2; fi++)
+	{
+		flag *f = flags[fi];
+		if(f && f->carrying_player == victim)
+			f->carrying_player = 0;
+	}
+}
+
 void gameobject::tick_ctf()
 {
+	// do flags
+	for(int fi = 0; fi < 2; fi++)
+	{
+		flag *f = flags[fi];
+		
+		//
+		if(f->carrying_player)
+		{
+			// update flag position
+			f->pos = f->carrying_player->pos;
+			
+			if(gameobj->flags[fi^1]->at_stand)
+			{
+				if(distance(f->pos, gameobj->flags[fi^1]->pos) < 24)
+				{
+					// CAPTURE! \o/
+					for(int i = 0; i < 2; i++)
+						gameobj->flags[i]->reset();
+				}
+			}			
+		}
+		else
+		{
+			player *players[MAX_CLIENTS];
+			int types[] = {OBJTYPE_PLAYER};
+			int num = world->find_entities(f->pos, 32.0f, (entity**)players, MAX_CLIENTS, types, 1);
+			for(int i = 0; i < num; i++)
+			{
+				if(players[i]->team == f->team)
+				{
+					// return the flag
+					f->reset();
+				}
+				else
+				{
+					// take the flag
+					f->at_stand = 0;
+					f->carrying_player = players[i];
+					break;
+				}
+			}
+			
+			if(!f->carrying_player)
+			{
+				f->vel.y += gravity;
+				move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
+			}
+		}
+	}
 }
 
 void gameobject::tick_dm()
@@ -528,74 +594,6 @@ void projectile::snap(int snapping_client)
 	proj->type = type;
 }
 
-
-//////////////////////////////////////////////////
-// projectile_backpackrocket
-//////////////////////////////////////////////////
-projectile_backpackrocket::projectile_backpackrocket(vec2 pos, vec2 target, int owner, entity* powner)
-: projectile(WEAPON_PROJECTILETYPE_ROCKET, owner, pos, vec2(0,0), 100, powner, 0, 0, 0, -1, WEAPON_ROCKET_BACKPACK)
-{
-	stage = 0;
-	start_tick = server_tick();
-	vel = vec2(0,-10.0f);
-	this->target = target;
-	start = pos;
-	midpoint = pos;
-	midpoint.y = target.y;
-	direction = normalize(target-midpoint);
-	deply_ticks = (int)( distance(start, midpoint)/(float)server_tickspeed() * 5.0f );
-	dbg_msg("rocket_bp", "%f %d", distance(start, midpoint), deply_ticks);
-}
-
-void projectile_backpackrocket::tick()
-{
-	lifespan--;
-	if(!lifespan)
-		world->destroy_entity(this);
-		
-	vec2 oldpos = pos;
-		
-	if(stage == 0)
-	{
-		float time = (server_tick()-start_tick)/(float)(deply_ticks);
-		if(midpoint.y > start.y)
-			pos.y = mix(start.y, midpoint.y, 1-sinf((1-time)*pi/2));
-		else
-			pos.y = mix(start.y, midpoint.y, sinf(time*pi/2));
-
-		float a = (server_tick()-start_tick)/(float)server_tickspeed()*pi*7.5f;
-		vel.x = sinf(a)*30.0f;
-		vel.y = cosf(a)*30.0f;
-		
-		if(server_tick() > start_tick+deply_ticks)
-		{
-			pos = midpoint;
-			direction = normalize(target-pos);
-			vel = vec2(0,0);
-			stage = 1;
-		}
-	}
-	else if(stage == 1)
-	{
-		vel += direction*1.5f;
-		vel.x = clamp(vel.x, -20.0f, 20.0f);
-		pos += vel;
-	}
-
-	// check player intersection as well
-	vec2 new_pos;
-	entity *targetplayer = (entity*)intersect_player(oldpos, pos, new_pos, powner);
-	if(targetplayer || lifespan < 0 || col_check_point((int)pos.x, (int)pos.y))
-	{
-		if (lifespan >= 0)
-			create_sound(pos, sound_impact);
-			
-		create_explosion(oldpos, owner, weapon, false);
-			
-		world->destroy_entity(this);
-	}	
-}
-
 //////////////////////////////////////////////////
 // player
 //////////////////////////////////////////////////
@@ -619,7 +617,6 @@ void player::init()
 	extrapowerflags = 0;
 	ninjaactivationtick = 0;
 
-
 	latency_accum = 0;
 	latency_accum_min = 0;
 	latency_accum_max = 0;
@@ -632,9 +629,6 @@ void player::init()
 
 void player::reset()
 {
-	release_hooked();
-	release_hooks();
-	
 	pos = vec2(0.0f, 0.0f);
 	core.vel = vec2(0.0f, 0.0f);
 	//direction = vec2(0.0f, 1.0f);
@@ -747,6 +741,8 @@ void player::try_respawn()
 	// Create sound and spawn effects
 	create_sound(pos, SOUND_PLAYER_SPAWN);
 	create_spawn(pos);
+	
+	gameobj->on_player_spawn(this);
 }
 
 bool player::is_grounded()
@@ -758,29 +754,6 @@ bool player::is_grounded()
 	return false;
 }
 
-// releases the hooked player
-void player::release_hooked()
-{
-	//hook_state = HOOK_RETRACTED;
-	//hooked_player = 0x0;
-}
-
-// release all hooks to this player	
-void player::release_hooks()
-{
-	/*
-	// TODO: loop thru players only
-	for(entity *ent = world->first_entity; ent; ent = ent->next_entity)
-	{
-		if(ent && ent->objtype == OBJTYPE_PLAYER)
-		{
-			player *p = (player*)ent;
-			if(p->hooked_player == this)
-				p->release_hooked();
-		}
-	}*/
-}
-
 int player::handle_ninja()
 {
 	vec2 direction = normalize(vec2(input.target_x, input.target_y));
@@ -806,8 +779,8 @@ int player::handle_ninja()
 		create_sound(pos, SOUND_NINJA_FIRE);
 		
 		// release all hooks when ninja is activated
-		release_hooked();
-		release_hooks();
+		//release_hooked();
+		//release_hooks();
 	}
 
 	currentmovetime--;
@@ -966,14 +939,7 @@ int player::handle_weapons()
 						}
 						create_sound(pos, SOUND_SHOTGUN_FIRE);
 						break;
-					}
-					case WEAPON_ROCKET_BACKPACK:
-						new projectile_backpackrocket(
-							pos+vec2(0,0),
-							pos+vec2(input.target_x,input.target_y),
-							client_id,
-							this);
-						break;						
+					}	
 				}
 				
 				weapons[active_weapon].ammo--;
@@ -1141,6 +1107,8 @@ void player::tick_defered()
 
 void player::die(int killer, int weapon)
 {
+	gameobj->on_player_death(this, get_player(killer), weapon);
+	
 	dbg_msg("game", "kill killer='%d:%s' victim='%d:%s' weapon=%d", killer, players[killer].name, client_id, name, weapon);
 	
 	// send the kill message
@@ -1154,10 +1122,6 @@ void player::die(int killer, int weapon)
 	// a nice sound
 	create_sound(pos, SOUND_PLAYER_DIE);
 	
-	// release all hooks
-	release_hooked();
-	release_hooks();
-	
 	// set dead state
 	dead = true;
 	die_tick = server_tick();
@@ -1173,9 +1137,9 @@ bool player::take_damage(vec2 force, int dmg, int from, int weapon)
 	if(from == client_id)
 		dmg = max(1, dmg/2);
 
-	// CTF and TDM,
-	if (gameobj->gametype != GAMETYPE_DM && from >= 0 && players[from].team == team)
-		return false;
+	// CTF and TDM (TODO: check for FF)
+	//if (gameobj->gametype != GAMETYPE_DM && from >= 0 && players[from].team == team)
+		//return false;
 
 	damage_taken++;
 
@@ -1472,60 +1436,14 @@ flag::flag(int _team)
 
 void flag::reset()
 {
+	carrying_player = 0;
+	at_stand = 1;
+	pos = stand_pos;
 	spawntick = -1;
 }
 
 void flag::tick()
 {
-	// THIS CODE NEEDS TO BE REWRITTEN. ITS NOT SAFE AT ALL
-	
-	// wait for respawn
-	if(spawntick > 0)
-	{
-		if(server_tick() > spawntick)
-			spawntick = -1;
-		else
-			return;
-	}
-
-	// Check if a player intersected us
-	if(!carrying_player)
-	{
-		player *players[MAX_CLIENTS];
-		int types[] = {OBJTYPE_PLAYER};
-		int num = world->find_entities(pos, 32.0f, (entity**)players, MAX_CLIENTS, types, 1);
-		for(int i = 0; i < num; i++)
-		{
-			if(players[i]->team != team)
-			{
-				carrying_player = players[i];
-				break;
-			}
-		}
-		
-		if(!carrying_player)
-		{
-			vel.y += 0.25f;
-			vec2 new_pos = pos + vel;
-
-			col_intersect_line(pos, new_pos, &new_pos);
-
-			pos = new_pos;
-
-			if (is_grounded())
-				vel.x = vel.y = 0;
-		}
-	}
-	else
-	{
-		if (carrying_player->dead)
-			carrying_player = 0x0;
-		else
-		{
-			vel = carrying_player->pos - pos;
-			pos = carrying_player->pos;
-		}
-	}
 }
 
 bool flag::is_grounded()
@@ -1731,15 +1649,16 @@ void mods_client_input(int client_id, void *input)
 	}
 }
 
-void send_chat_all(int cid, const char *msg)
+void send_chat(int cid, int team, const char *msg)
 {
 	if(cid >= 0 && cid < MAX_CLIENTS)
-		dbg_msg("chat", "%d:%s: %s", cid, players[cid].name, msg);
+		dbg_msg("chat", "%d:%d:%s: %s", cid, team, players[cid].name, msg);
 	else
 		dbg_msg("chat", "*** %s", msg);
 	
 	msg_pack_start(MSG_CHAT, MSGFLAG_VITAL);
 	msg_pack_int(cid);
+	msg_pack_int(team);
 	msg_pack_string(msg, 512);
 	msg_pack_end();
 	server_send_msg(-1);
@@ -1755,7 +1674,7 @@ void send_set_name(int cid, const char *old_name, const char *new_name)
 
 	char msg[256];
 	sprintf(msg, "*** %s changed name to %s", old_name, new_name);
-	send_chat_all(-1, msg);
+	send_chat(-1, -1, msg);
 }
 
 void send_emoticon(int cid, int emoticon)
@@ -1811,17 +1730,18 @@ void mods_client_enter(int client_id)
 
 	char buf[512];
 	sprintf(buf, "%s has joined the game", players[client_id].name);
-	send_chat_all(-1, buf);
+	send_chat(-1, -1, buf);
 }
 
 void mods_client_drop(int client_id)
 {
 	char buf[512];
 	sprintf(buf, "%s has left the game", players[client_id].name);
-	send_chat_all(-1, buf);
+	send_chat(-1, -1, buf);
 
 	dbg_msg("game", "leave player='%d:%s'", client_id, players[client_id].name);
 	
+	gameobj->on_player_death(&players[client_id], 0, -1);
 	world->remove_entity(&players[client_id]);
 	players[client_id].client_id = -1;
 }
@@ -1830,7 +1750,9 @@ void mods_message(int msg, int client_id)
 {
 	if(msg == MSG_SAY)
 	{
-		send_chat_all(client_id, msg_unpack_string());
+		int team = msg_unpack_int();
+		const char *text = msg_unpack_string();
+		send_chat(client_id, team, text);
 	}
 	else if (msg == MSG_SWITCHTEAM)
 	{
@@ -1941,12 +1863,13 @@ void mods_init()
 			mapres_flagstand *stand;
 			stand = (mapres_flagstand *)map_find_item(MAPRES_FLAGSTAND_RED+i, 0);
 			if(stand)
-				gameobj->flagsstands[i] = vec2(stand->x, stand->y);
-
-			flag *f = new flag(i);
-			f->pos = gameobj->flagsstands[i];
-			//world->insert_entity(f);
-			dbg_msg("game", "flag at %f,%f", f->pos.x, f->pos.y);
+			{
+				flag *f = new flag(i);
+				f->stand_pos = vec2(stand->x, stand->y);
+				f->pos = f->stand_pos;
+				gameobj->flags[i] = f;
+				dbg_msg("game", "flag at %f,%f", f->pos.x, f->pos.y);
+			}
 		}
 	}
 	
diff --git a/src/game/server/game_server.h b/src/game/server/game_server.h
index 59044a4c..22cc1f93 100644
--- a/src/game/server/game_server.h
+++ b/src/game/server/game_server.h
@@ -115,7 +115,6 @@ class gameobject : public entity
 	
 public:
 	class flag *flags[2];
-	vec2 flagsstands[2];
 	
 	int gametype;
 	gameobject();
@@ -124,6 +123,10 @@ public:
 	virtual void tick_dm();
 	virtual void tick_tdm();
 	virtual void tick_ctf();
+	
+	virtual void on_player_spawn(class player *p);
+	virtual void on_player_death(class player *victim, class player *killer, int weapon);
+	
 	virtual void snap(int snapping_client);
 	virtual int getteam(int notthisid);
 };
@@ -181,20 +184,6 @@ public:
 	virtual void snap(int snapping_client);
 };
 
-class projectile_backpackrocket : public projectile
-{
-	int stage;
-	int start_tick;
-	int deply_ticks;
-	vec2 target;
-	vec2 start;
-	vec2 midpoint;
-	vec2 direction;
-public:
-	projectile_backpackrocket(vec2 pos, vec2 target, int owner, entity* powner);
-	virtual void tick();
-};
-
 // player entity
 class player : public entity
 {
@@ -230,11 +219,6 @@ public:
 
 	int last_action;
 	
-	// we need a defered position so we can handle the physics correctly
-	//vec2 defered_pos;
-	//vec2 vel;
-	//vec2 direction;
-
 	//
 	int client_id;
 	char name[64];
@@ -257,6 +241,7 @@ public:
 	int currentactivation;
 	int currentmovetime;
 
+	//
 	int score;
 	int team;
 	int state;
@@ -265,20 +250,16 @@ public:
 	bool dead;
 	int die_tick;
 	
+	// latency calculations
 	int latency_accum;
 	int latency_accum_min;
 	int latency_accum_max;
 	int latency_avg;
 	int latency_min;
 	int latency_max;
-	
+
+	// the player core for the physics	
 	player_core core;
-	
-	//int hook_state;
-	//int hook_tick;
-	//player *hooked_player;
-	//vec2 hook_pos;
-	//vec2 hook_dir;
 
 	//
 	player();
@@ -292,9 +273,6 @@ public:
 	bool is_grounded();
 	
 	void set_weapon(int w);
-
-	void release_hooked();
-	void release_hooks();
 	
 	int handle_weapons();
 	int handle_ninja();
@@ -317,9 +295,12 @@ public:
 	static const int phys_size = 14;
 	player *carrying_player;
 	vec2 vel;
+	vec2 stand_pos;
 	
 	int team;
 	int spawntick;
+	int at_stand;
+	
 	flag(int _team);
 
 	bool is_grounded();