about summary refs log tree commit diff
path: root/src/game
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-14 22:35:00 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2007-07-14 22:35:00 +0000
commit94fe893150ee9d3a64cee9cf6d94241a0eada5d5 (patch)
tree208b782f3b6e790d581ca1c3e90390d34ba0f97a /src/game
parent14e612249c44eb0d9c4d00df00d5da2e18438729 (diff)
downloadzcatch-94fe893150ee9d3a64cee9cf6d94241a0eada5d5.tar.gz
zcatch-94fe893150ee9d3a64cee9cf6d94241a0eada5d5.zip
kill messages and other fixes and features
Diffstat (limited to 'src/game')
-rw-r--r--src/game/client/game_client.cpp241
-rw-r--r--src/game/game.h2
-rw-r--r--src/game/server/game_server.cpp42
3 files changed, 161 insertions, 124 deletions
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 031c0ac7..6b67e677 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -365,12 +365,37 @@ void chat_add_line(int client_id, const char *line)
 	chat_lines[chat_current_line].tick = client_tick();
 	sprintf(chat_lines[chat_current_line].text, "%s: %s", client_datas[client_id].name, line); // TODO: abit nasty
 }
- 
+
+struct killmsg
+{
+	int weapon;
+	int victim;
+	int killer;
+	int tick;
+};
+
+static const int killmsg_max = 5;
+killmsg killmsgs[killmsg_max];
+static int killmsg_current = 0;
+
 void modc_init()
 {
 	// load the data container
 	data = load_data_container("data/client.dat");
 	
+	for(int i = 0; i < data->gui.num_boxes; i++)
+	{
+		dbg_msg("gui", "%d %d %d %d",
+			data->gui.boxes[i].rect.x,
+			data->gui.boxes[i].rect.y,
+			data->gui.boxes[i].center.x,
+			data->gui.boxes[i].center.y);
+	}
+	
+	dbg_msg("gui", "%d %d",	data->gui.boxes[GUI_BOX_BUTTON].rect.x, data->gui.boxes[GUI_BOX_BUTTON].rect.y);
+	dbg_msg("gui", "%d %d",
+		data->gui.misc[GUI_MISC_CHECKBOX_UNCHECKED].x, data->gui.misc[GUI_MISC_CHECKBOX_UNCHECKED].y);
+	
 	// load sounds
 	for(int s = 0; s < data->num_sounds; s++)
 		for(int i = 0; i < data->sounds[s].num_sounds; i++)
@@ -390,6 +415,10 @@ void modc_entergame()
 	
 	for(int i = 0; i < MAX_CLIENTS; i++)
 		client_datas[i].name[0] = 0;
+		
+	for(int i = 0; i < killmsg_max; i++)
+		killmsgs[i].tick = -100000;
+
 }
 
 void modc_shutdown()
@@ -622,7 +651,6 @@ static void anim_eval_add(animstate *state, animation *anim, float time, float a
 static void render_tee(animstate *anim, int skin, vec2 dir, vec2 pos)
 {
 	vec2 direction =  dir;
-	//float angle = info->angle;
 	vec2 position = pos;
 	
 	gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
@@ -633,7 +661,6 @@ static void render_tee(animstate *anim, int skin, vec2 dir, vec2 pos)
 	{
 		// first pass we draw the outline
 		// second pass we draw the filling
-		
 		int outline = p==0 ? 1 : 0;
 		int shift = charids[skin%16];
 		
@@ -642,6 +669,7 @@ static void render_tee(animstate *anim, int skin, vec2 dir, vec2 pos)
 			float basesize = 10.0f;
 			if(f == 1)
 			{
+				gfx_quads_setrotation(anim->body.angle*pi*2);
 				// draw body
 				select_sprite(outline?SPRITE_TEE_BODY_OUTLINE:SPRITE_TEE_BODY, 0, 0, shift*4);
 				gfx_quads_draw(position.x+anim->body.x, position.y+anim->body.y, 4*basesize, 4*basesize);
@@ -664,7 +692,7 @@ static void render_tee(animstate *anim, int skin, vec2 dir, vec2 pos)
 			float w = basesize*2.5f;
 			float h = basesize*1.425f;
 			
-			gfx_quads_setrotation(foot->angle);
+			gfx_quads_setrotation(foot->angle*pi*2);
 			gfx_quads_draw(position.x+foot->x, position.y+foot->y, w, h);
 		}
 	}
@@ -769,66 +797,54 @@ static void render_player(obj_player *prev, obj_player *player)
 		// TODO: draw muzzleflare
 		gfx_quads_end();
 	}
-	
+
+	// render the tee	
 	render_tee(&state, player->clientid, direction, position);
-	
-	/*
-	gfx_texture_set(data->images[IMAGE_CHAR_DEFAULT].id);
+}
+
+
+void render_sun(float x, float y)
+{
+	vec2 pos(x, y);
+
+	gfx_texture_set(-1);
+	gfx_blend_additive();
 	gfx_quads_begin();
-	
-	// draw foots
-	for(int p = 0; p < 2; p++)
+	const int rays = 10;
+	gfx_quads_setcolor(1.0f,1.0f,1.0f,0.025f);
+	for(int r = 0; r < rays; r++)
 	{
-		// first pass we draw the outline
-		// second pass we draw the filling
+		float a = r/(float)rays + client_localtime()*0.025f;
+		float size = (1.0f/(float)rays)*0.25f;
+		vec2 dir0(sinf((a-size)*pi*2.0f), cosf((a-size)*pi*2.0f));
+		vec2 dir1(sinf((a+size)*pi*2.0f), cosf((a+size)*pi*2.0f));
 		
-		int outline = p==0 ? 1 : 0;
-		int shift = charids[player->clientid%16];
-		
-		for(int f = 0; f < 2; f++)
-		{
-			float basesize = 10.0f;
-			if(f == 1)
-			{
-				// draw body
-				select_sprite(outline?SPRITE_TEE_BODY_OUTLINE:SPRITE_TEE_BODY, 0, 0, shift*4);
-				gfx_quads_draw(position.x+state.body.x, position.y+state.body.y, 4*basesize, 4*basesize);
-				
-				// draw eyes
-				if(p == 1)
-				{
-					vec2 md = get_direction(player->angle);
-					float mouse_dir_x = md.x;
-					float mouse_dir_y = md.y;
-					
-					// normal
-					select_sprite(SPRITE_TEE_EYE_NORMAL, 0, 0, shift*4);
-					gfx_quads_draw(position.x-4+mouse_dir_x*4, position.y-8+mouse_dir_y*3, basesize, basesize);
-					gfx_quads_draw(position.x+4+mouse_dir_x*4, position.y-8+mouse_dir_y*3, basesize, basesize);
-				}
-			}
-
-			// draw feet
-			select_sprite(outline?SPRITE_TEE_FOOT_OUTLINE:SPRITE_TEE_FOOT, 0, 0, shift*4);
-			
-			keyframe *foot = f ? &state.front_foot : &state.back_foot;
-			
-			float w = basesize*2.5f;
-			float h = basesize*1.425f;
-			
-			gfx_quads_setrotation(foot->angle);
-			gfx_quads_draw(position.x+foot->x, position.y+foot->y, w, h);
-		}
+		gfx_quads_setcolorvertex(0, 1.0f,1.0f,1.0f,0.025f);
+		gfx_quads_setcolorvertex(1, 1.0f,1.0f,1.0f,0.025f);
+		gfx_quads_setcolorvertex(2, 1.0f,1.0f,1.0f,0.0f);
+		gfx_quads_setcolorvertex(3, 1.0f,1.0f,1.0f,0.0f);
+		const float range = 1000.0f;
+		gfx_quads_draw_freeform(
+			pos.x+dir0.x, pos.y+dir0.y,
+			pos.x+dir1.x, pos.y+dir1.y,
+			pos.x+dir0.x*range, pos.y+dir0.y*range,
+			pos.x+dir1.x*range, pos.y+dir1.y*range);
 	}
-	
 	gfx_quads_end();
-	*/
+	gfx_blend_normal();
+	
+	gfx_texture_set(data->images[IMAGE_SUN].id);
+	gfx_quads_begin();
+	gfx_quads_draw(pos.x, pos.y, 256, 256);
+	gfx_quads_end();	
 }
 
-
-
 void modc_render()
 {	
+	animstate idlestate;
+	anim_eval(&data->animations[ANIM_BASE], 0, &idlestate);
+	anim_eval_add(&idlestate, &data->animations[ANIM_IDLE], 0, 1.0f);	
+	
 	if(inp_key_down(input::enter))
 	{
 		if(chat_active)
@@ -973,38 +989,7 @@ void modc_render()
 
 	// draw the sun	
 	{
-		vec2 pos(local_player_pos.x*0.5f, local_player_pos.y*0.5f);
-
-		gfx_texture_set(-1);
-		gfx_blend_additive();
-		gfx_quads_begin();
-		const int rays = 10;
-		gfx_quads_setcolor(1.0f,1.0f,1.0f,0.025f);
-		for(int r = 0; r < rays; r++)
-		{
-			float a = r/(float)rays + client_localtime()*0.05f;
-			float size = (1.0f/(float)rays)*0.25f;
-			vec2 dir0(sinf((a-size)*pi*2.0f), cosf((a-size)*pi*2.0f));
-			vec2 dir1(sinf((a+size)*pi*2.0f), cosf((a+size)*pi*2.0f));
-			
-			gfx_quads_setcolorvertex(0, 1.0f,1.0f,1.0f,0.025f);
-			gfx_quads_setcolorvertex(1, 1.0f,1.0f,1.0f,0.025f);
-			gfx_quads_setcolorvertex(2, 1.0f,1.0f,1.0f,0.0f);
-			gfx_quads_setcolorvertex(3, 1.0f,1.0f,1.0f,0.0f);
-			const float range = 1000.0f;
-			gfx_quads_draw_freeform(
-				pos.x+dir0.x, pos.y+dir0.y,
-				pos.x+dir1.x, pos.y+dir1.y,
-				pos.x+dir0.x*range, pos.y+dir0.y*range,
-				pos.x+dir1.x*range, pos.y+dir1.y*range);
-		}
-		gfx_quads_end();
-		gfx_blend_normal();
-		
-		gfx_texture_set(data->images[IMAGE_SUN].id);
-		gfx_quads_begin();
-		gfx_quads_draw(pos.x, pos.y, 256, 256);
-		gfx_quads_end();
+		render_sun(local_player_pos.x*0.5f, local_player_pos.y*0.5f);
 	}
 	
 	// render map
@@ -1090,22 +1075,64 @@ void modc_render()
 		gfx_quads_end();
 	}
 	
-	// render gui stuff
-	gfx_mapscreen(0,0,400,300);
+	// render kill messages
+	{
+		gfx_mapscreen(0, 0, width*1.5f, height*1.5f);
+		float startx = width*1.5f-10.0f;
+		float y = 10.0f;
+		
+		for(int i = 0; i < killmsg_max; i++)
+		{
+			
+			int r = (killmsg_current+i+1)%killmsg_max;
+			if(client_tick() > killmsgs[r].tick+50*10)
+				continue;
+			
+			float font_size = 48.0f;
+			float killername_w = gfx_pretty_text_width(font_size, client_datas[killmsgs[r].killer].name);
+			float victimname_w = gfx_pretty_text_width(font_size, client_datas[killmsgs[r].victim].name);
+			
+			float x = startx;
+			
+			// render victim name
+			x -= victimname_w;
+			gfx_pretty_text(x, y, font_size, client_datas[killmsgs[r].victim].name);
+			
+			// render victim tee
+			x -= 24.0f;
+			render_tee(&idlestate, killmsgs[r].victim, vec2(1,0), vec2(x, y+28));
+			x -= 32.0f;
+
+			// render weapon
+			x -= 44.0f;
+			gfx_texture_set(data->images[IMAGE_WEAPONS].id);
+			gfx_quads_begin();
+			select_sprite(data->weapons[killmsgs[r].weapon].sprite_body);
+			draw_sprite(x, y+28, 96);
+			gfx_quads_end();
+			x -= 52.0f;
+
+			// render killer tee
+			x -= 24.0f;
+			render_tee(&idlestate, killmsgs[r].killer, vec2(1,0), vec2(x, y+28));
+			x -= 32.0f;
+			
+			// render killer name
+			x -= killername_w;
+			gfx_pretty_text(x, y, font_size, client_datas[killmsgs[r].killer].name);
+			
+			y += 44;
+		}
+	}
 	
+	// render chat
 	{
+		gfx_mapscreen(0,0,400,300);
 		float x = 10.0f;
 		float y = 300.0f-50.0f;
 		float starty = -1;
 		if(chat_active)
 		{
-			
-			/*gfx_texture_set(-1); // TODO: remove when the font looks better
-			gfx_quads_begin();
-			gfx_quads_setcolor(0,0,0,0.4f);
-			gfx_quads_drawTL(x-2, y+1, 300, 8);
-			gfx_quads_end();*/
-			
 			// render chat input
 			char buf[sizeof(chat_input)+16];
 			sprintf(buf, "Chat: %s_", chat_input);
@@ -1122,21 +1149,13 @@ void modc_render()
 			if(client_tick() > chat_lines[r].tick+50*15)
 				break;
 
-			/*
-			gfx_texture_set(-1); // TODO: remove when the font looks better
-			gfx_quads_begin();
-			gfx_quads_setcolor(0,0,0,0.4f);
-			gfx_quads_drawTL(x-2, y+1, gfx_pretty_text_width(10, chat_lines[r].text)+3, 8);
-			gfx_quads_end();
-			*/
-
 			gfx_pretty_text(x, y, 10, chat_lines[r].text);
 			y -= 8;
 		}
 	}
 	
 	// render score board
-	if(inp_key_pressed(baselib::input::tab))
+	if(inp_key_pressed(baselib::input::tab) || (local_player && local_player->health == -1))
 	{
 		gfx_mapscreen(0, 0, width, height);
 
@@ -1157,10 +1176,6 @@ void modc_render()
 		
 		//gfx_texture_set(-1);
 		//gfx_quads_text(10, 50, 8, "Score Board");
-		animstate state;
-		anim_eval(&data->animations[ANIM_BASE], 0, &state);
-		anim_eval_add(&state, &data->animations[ANIM_IDLE], 0, 1.0f);
-
 		int num = snap_num_items(SNAP_CURRENT);
 		for(int i = 0; i < num; i++)
 		{
@@ -1177,7 +1192,7 @@ void modc_render()
 					gfx_pretty_text(x+60-gfx_pretty_text_width(48,buf), y, 48, buf);
 					gfx_pretty_text(x+128, y, 48, client_datas[player->clientid].name);
 
-					render_tee(&state, player->clientid, vec2(1,0), vec2(x+90, y+24));
+					render_tee(&idlestate, player->clientid, vec2(1,0), vec2(x+90, y+24));
 					y += 58.0f;
 				}
 			}
@@ -1200,4 +1215,12 @@ void modc_message(int msg)
 		const char *name = msg_unpack_string();
 		strncpy(client_datas[cid].name, name, 64);
 	}
+	else if(msg == MSG_KILLMSG)
+	{
+		killmsg_current = (killmsg_current+1)%killmsg_max;
+		killmsgs[killmsg_current].killer = msg_unpack_int();
+		killmsgs[killmsg_current].victim = msg_unpack_int();
+		killmsgs[killmsg_current].weapon = msg_unpack_int();
+		killmsgs[killmsg_current].tick = client_tick();
+	}
 }
diff --git a/src/game/game.h b/src/game/game.h
index f9f41d13..16a30e44 100644
--- a/src/game/game.h
+++ b/src/game/game.h
@@ -41,6 +41,7 @@ enum
 	MSG_SAY,
 	MSG_CHAT,
 	MSG_SETNAME,
+	MSG_KILLMSG,
 };
 
 enum
@@ -64,6 +65,7 @@ struct player_input
 	int activeweapon;
 };
 
+
 struct ev_explosion
 {
 	int x, y;
diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp
index 4b06470e..0b6804ac 100644
--- a/src/game/server/game_server.cpp
+++ b/src/game/server/game_server.cpp
@@ -24,7 +24,7 @@ const float gravity = 0.5f;
 
 class player* get_player(int index);
 void create_damageind(vec2 p, vec2 dir, int amount);
-void create_explosion(vec2 p, int owner = -1, bool bnodamage = false);
+void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
 void create_smoke(vec2 p);
 void create_sound(vec2 pos, int sound, int loopflags = 0);
 class player* intersect_player(vec2 pos0, vec2 pos1, vec2& new_pos, class entity* notthis = 0);
@@ -225,7 +225,7 @@ public:
 		
 	virtual void snap(int snapping_client) {}
 		
-	virtual bool take_damage(vec2 force, int dmg, int from) { return true; }
+	virtual bool take_damage(vec2 force, int dmg, int from, int weapon) { return true; }
 };
 
 int entity::current_id = 1;
@@ -397,9 +397,10 @@ public:
 	int flags;
 	int damage;
 	int sound_impact;
+	int weapon;
 	float force;
 	
-	projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner, int damage, int flags = 0, float force = 0.0f, int sound_impact = -1)
+	projectile(int type, int owner, vec2 pos, vec2 vel, int span, entity* powner, int damage, int flags, float force, int sound_impact, int weapon)
 	: entity(OBJTYPE_PROJECTILE)
 	{
 		this->type = type;
@@ -412,6 +413,7 @@ public:
 		this->force = force;
 		this->damage = damage;
 		this->sound_impact = sound_impact;
+		this->weapon = weapon;
 		world.insert_entity(this);
 	}
 
@@ -430,9 +432,9 @@ public:
 				create_sound(pos, sound_impact);
 				
 			if (flags & PROJECTILE_FLAGS_EXPLODE)
-				create_explosion(oldpos, owner);
+				create_explosion(oldpos, owner, weapon, false);
 			else if (targetplayer)
-				targetplayer->take_damage(normalize(vel) * max(0.001f, force), damage, owner);
+				targetplayer->take_damage(normalize(vel) * max(0.001f, force), damage, owner, weapon);
 				
 			world.destroy_entity(this);
 		}
@@ -642,7 +644,7 @@ public:
 								direction*30.0f,
 								100,
 								this,
-								1, 0, 0, -1);
+								1, 0, 0, -1, WEAPON_GUN);
 							break;
 						case WEAPON_ROCKET:
 							new projectile(WEAPON_PROJECTILETYPE_ROCKET,
@@ -651,7 +653,7 @@ public:
 								direction*15.0f,
 								100,
 								this,
-								1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, -1);						
+								1, projectile::PROJECTILE_FLAGS_EXPLODE, 0, -1, WEAPON_ROCKET);						
 							break;
 						case WEAPON_SHOTGUN:
 							for(int i = 0; i < 3; i++)
@@ -662,7 +664,7 @@ public:
 									direction*(20.0f+(i+1)*2.0f),
 									100,
 									this,
-									1, 0, 0, -1);
+									1, 0, 0, -1, WEAPON_SHOTGUN);
 							}
 							break;
 					}
@@ -799,7 +801,7 @@ public:
 			if(ent && ent->objtype == OBJTYPE_PLAYER)
 			{
 				player *p = (player*)ent;
-				if(p == this)
+				if(p == this || !(p->flags&FLAG_ALIVE))
 					continue; // make sure that we don't nudge our self
 				
 				// handle player <-> player collision
@@ -842,20 +844,30 @@ public:
 		pos = defered_pos;
 	}
 	
-	void die()
+	void die(int killer, int weapon)
 	{
+		// send the kill message
+		msg_pack_start(MSG_KILLMSG, MSGFLAG_VITAL);
+		msg_pack_int(killer);
+		msg_pack_int(client_id);
+		msg_pack_int(weapon);
+		msg_pack_end();
+		server_send_msg(-1);
+		
+		// a nice sound
 		create_sound(pos, SOUND_PLAYER_DIE);
 		
+		// release all hooks
 		release_hooked();
 		release_hooks();
 		
-		// TODO: insert timer here
+		// set dead state
 		dead = true;
 		die_tick = server_tick();
 		clear_flag(entity::FLAG_ALIVE);
 	}
 	
-	virtual bool take_damage(vec2 force, int dmg, int from)
+	virtual bool take_damage(vec2 force, int dmg, int from, int weapon)
 	{
 		vel += force;
 
@@ -894,7 +906,7 @@ public:
 				}
 			}
 			
-			die();
+			die(from, weapon);
 			return false;
 		}
 
@@ -1062,7 +1074,7 @@ void create_damageind(vec2 p, vec2 dir, int amount)
 	}
 }
 
-void create_explosion(vec2 p, int owner, bool bnodamage)
+void create_explosion(vec2 p, int owner, int weapon, bool bnodamage)
 {
 	// create the event
 	ev_explosion *ev = (ev_explosion *)events.create(EVENT_EXPLOSION, sizeof(ev_explosion));
@@ -1084,7 +1096,7 @@ void create_explosion(vec2 p, int owner, bool bnodamage)
 			float l = length(diff);
 			float dmg = 5 * (1 - (l/radius));
 			if((int)dmg)
-				ents[i]->take_damage(forcedir*dmg*2, (int)dmg, owner);
+				ents[i]->take_damage(forcedir*dmg*2, (int)dmg, owner, weapon);
 		}
 	}
 }