about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--datasrc/client.dts3
-rw-r--r--datasrc/server.dts7
-rw-r--r--src/editor/editor.cpp143
-rw-r--r--src/engine/datafile.c7
-rw-r--r--src/game/client/game_client.cpp6
-rw-r--r--src/game/game.h22
-rw-r--r--src/game/server/game_server.cpp135
-rw-r--r--src/game/server/game_server.h4
8 files changed, 197 insertions, 130 deletions
diff --git a/datasrc/client.dts b/datasrc/client.dts
index 7b2cec99..61bacd54 100644
--- a/datasrc/client.dts
+++ b/datasrc/client.dts
@@ -119,5 +119,4 @@ const array:int sound = sounds.*
 const array:int image = images.*
 const array:int sprite = sprites.*.*
 const array:int anim = animations.*
-const array:int gametype = playerstats.*
-const array:int powerup = powerups.*
\ No newline at end of file
+const array:int powerup = powerups.*
diff --git a/datasrc/server.dts b/datasrc/server.dts
index e4b6935f..d229894b 100644
--- a/datasrc/server.dts
+++ b/datasrc/server.dts
@@ -1,6 +1,5 @@
 const array:int sound = sounds.*
 const array:int weapon = weapons.*
-const array:int gametype = playerstats.*
 const array:int powerup = powerups.*
 
 struct weapon {
@@ -21,13 +20,7 @@ struct powerupinf {
 	int startspawntime = startspawntime@1
 }
 
-struct playerstats {
-	int maxhealth = maxhealth@1
-	int maxarmor = maxarmor@1
-}
-
 struct data_container {
 	array:weapon weapons = weapons.*
-	array:playerstats playerinfo = playerstats.*
 	array:powerupinf powerupinfo = powerups.*
 }
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp
index 8e039f2a..c2633778 100644
--- a/src/editor/editor.cpp
+++ b/src/editor/editor.cpp
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 
 extern "C" {
 	#include <engine/system.h>
@@ -21,28 +22,31 @@ struct ent_type
 {
 	const char *name;
 	int id;
-	int item_id;
+	int numfields;
+	int fields[8];
 };
 
 static ent_type ent_types[] = {
-	{"spawn", MAPRES_SPAWNPOINT, 0},
-	{"spawn_red", MAPRES_SPAWNPOINT_RED, 0},
-	{"spawn_blue", MAPRES_SPAWNPOINT_BLUE, 0},
-	{"---", 0, 0},
-	{"flagstand_red", MAPRES_SPAWNPOINT_RED, 0},
-	{"flagstand_blue", MAPRES_SPAWNPOINT_BLUE, 0},
-	{"---", 0, 0},
-	{"gun", MAPRES_ITEM, ITEM_WEAPON_GUN},
-	{"shotgun", MAPRES_ITEM, ITEM_WEAPON_SHOTGUN},
-	{"rocket", MAPRES_ITEM, ITEM_WEAPON_ROCKET},
-	{"sniper", MAPRES_ITEM, ITEM_WEAPON_SNIPER},
-	{"hammer", MAPRES_ITEM, ITEM_WEAPON_HAMMER},
-	{"---", 0, 0},
-	{"health", MAPRES_ITEM, ITEM_HEALTH},
-	{"armor", MAPRES_ITEM, ITEM_ARMOR},
-	{"---", 0, 0},
-	{"ninja", MAPRES_ITEM, ITEM_NINJA},
-	{0, 0}
+	{"null", 0, 0, {0}},
+	{"---", 0, 0, {0}},
+	{"spawn", MAPRES_SPAWNPOINT, 0, {0}},
+	{"spawn_red", MAPRES_SPAWNPOINT_RED, 0, {0}},
+	{"spawn_blue", MAPRES_SPAWNPOINT_BLUE, 0, {0}},
+	{"---", 0, 0, {0}},
+	{"flagstand_red", MAPRES_FLAGSTAND_RED, 0, {0}},
+	{"flagstand_blue", MAPRES_FLAGSTAND_BLUE, 0, {0}},
+	{"---", 0, 0, {0}},
+	{"gun", MAPRES_ITEM, 1, {ITEM_WEAPON_GUN,0}},
+	{"shotgun", MAPRES_ITEM, 1, {ITEM_WEAPON_SHOTGUN,0}},
+	{"rocket", MAPRES_ITEM, 1, {ITEM_WEAPON_ROCKET,0}},
+	{"sniper", MAPRES_ITEM, 1, {ITEM_WEAPON_SNIPER,0}},
+	{"hammer", MAPRES_ITEM, 1, {ITEM_WEAPON_HAMMER,0}},
+	{"---", 0, 0, {0}},
+	{"health", MAPRES_ITEM, 1, {ITEM_HEALTH,0}},
+	{"armor", MAPRES_ITEM, 1, {ITEM_ARMOR,0}},
+	{"---", 0, 0, {0}},
+	{"ninja", MAPRES_ITEM, 1, {ITEM_NINJA,0}},
+	{0, 0, 0, {0}}
 };
 
 
@@ -904,7 +908,11 @@ static void editor_render()
 		{
 			int x = (int)(world_offset_x+400*zoom/2)/32*32+16;
 			int y = (int)(world_offset_y+300*zoom/2)/32*32+16;
-			ents_new(0, x, y);
+			
+			if(editor_selected_ent >= 0 && editor_selected_ent < ents_count())
+				ents_new(ents_get(editor_selected_ent)->type, x, y);
+			else
+				ents_new(0, x, y);
 		}
 		
 		y += 8;
@@ -955,46 +963,33 @@ int editor_load(const char *filename)
 	}
 	
 	// load entities
+	for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
 	{
-		int type = -1;
-		for(int i = 0; ent_types[i].name; i++)
-		{
-			if(ent_types[i].id == MAPRES_SPAWNPOINT)
-			{
-				type = i;
-				break;
-			}
-		}
-		
-		int start, num;
-		datafile_get_type(df, MAPRES_SPAWNPOINT, &start, &num);
-		for(int t = 0; t < num; t++)
-		{
-			mapres_spawnpoint *sp = (mapres_spawnpoint *)datafile_get_item(df, start+t,0,0);
-			ents_new(type, sp->x, sp->y);
-		}
-	}
-	
-	{
+		// fetch entities of this class
 		int start, num;
-		datafile_get_type(df, MAPRES_ITEM, &start, &num);
-		for(int t = 0; t < num; t++)
+		datafile_get_type(df, t, &start, &num);
+
+		for(int i = 0; i < num; i++)
 		{
-			mapres_item *it = (mapres_item *)datafile_get_item(df, start+t,0,0);
+			mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0);
 			
-			int type = -1;
-			for(int i = 0; ent_types[i].name; i++)
+			// map type	
+			int type = 0;
+			for(int k = 0; ent_types[k].name; k++)
 			{
-				if(ent_types[i].id == MAPRES_ITEM && ent_types[i].item_id == it->type)
+				if(ent_types[k].id == t &&
+					memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0)
 				{
-					type = i;
+					type = k;
 					break;
 				}
 			}
-		
-			ents_new(type, it->x, it->y);
+			
+			//dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y);
+			ents_new(type, e->x, e->y);
 		}
-	}	
+	}
+
 	return 1;
 }
 
@@ -1056,33 +1051,23 @@ int editor_save(const char *filename)
 		}
 	}
 	
-	// add spawnpoints
-	for(int i = 0, id = 0; i < ents_count(); i++)
+	// add entities
+	for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++)
 	{
-		entity *ent = ents_get(i);
-		if(ent->type >= 0 && ent_types[ent->type].id == MAPRES_SPAWNPOINT)
-		{
-			mapres_spawnpoint sp;
-			sp.x = ent->x;
-			sp.y = ent->y;
-			sp.type = 0;
-			datafile_add_item(df, MAPRES_SPAWNPOINT, id, sizeof(sp), &sp);
-			id++;
-		}
-	}
-
-	// add items
-	for(int i = 0, id = 0; i < ents_count(); i++)
-	{
-		entity *ent = ents_get(i);
-		if(ent->type >= 0 && ent_types[ent->type].id == MAPRES_ITEM)
+		int id = 0;
+		for(int i = 0; i < ents_count(); i++)
 		{
-			mapres_item it;
-			it.x = ent->x;
-			it.y = ent->y;
-			it.type = ent_types[ent->type].item_id;
-			dbg_msg("editor", "i mapped=%d type=%x", ent->type, it.type);
-			datafile_add_item(df, MAPRES_ITEM, id, sizeof(it), &it);
+			entity *ent = ents_get(i);
+			if(ent_types[ent->type].id != t)
+				continue;
+				
+			int savebuf[64];
+			mapres_entity *mapent = (mapres_entity *)savebuf;
+			mapent->x = ent->x;
+			mapent->y = ent->y;
+			dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y);
+			memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int));
+			datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent);
 			id++;
 		}
 	}
@@ -1099,7 +1084,7 @@ static int editor_loop()
 	int mouse_x = 0;
 	int mouse_y = 0;
 	
-	//input::set_mouse_mode(input::mode_relative);
+	inp_mouse_mode_relative();
 	
 	while(!(inp_key_pressed(KEY_LCTRL) && inp_key_pressed('Q')))
 	{	
@@ -1164,12 +1149,10 @@ static int editor_loop()
 		gfx_swap();
 		
 		//
-		/*
 		if(inp_key_pressed(KEY_F1))
-			input::set_mouse_mode(input::mode_absolute);
+			inp_mouse_mode_absolute();
 		if(inp_key_pressed(KEY_F2))
-			input::set_mouse_mode(input::mode_relative);
-			*/
+			inp_mouse_mode_relative();
 
 		// mode switch
 		if(inp_key_down(KEY_TAB))
diff --git a/src/engine/datafile.c b/src/engine/datafile.c
index 2c8e8e44..ce835b46 100644
--- a/src/engine/datafile.c
+++ b/src/engine/datafile.c
@@ -399,6 +399,13 @@ int datafile_add_item(DATAFILE_OUT *df, int type, int id, int size, void *data)
 	df->items[df->num_items].id = id;
 	df->items[df->num_items].size = size;
 	
+	/*
+	dbg_msg("datafile", "added item type=%d id=%d size=%d", type, id, size);
+	int i;
+	for(i = 0; i < size/4; i++)
+		dbg_msg("datafile", "\t%d: %08x %d", i, ((int*)data)[i], ((int*)data)[i]);
+	*/
+	
 	/* copy data */
 	df->items[df->num_items].data = mem_alloc(size, 1);
 	mem_copy(df->items[df->num_items].data, data, size);
diff --git a/src/game/client/game_client.cpp b/src/game/client/game_client.cpp
index 0c20ab66..87fe767c 100644
--- a/src/game/client/game_client.cpp
+++ b/src/game/client/game_client.cpp
@@ -789,7 +789,7 @@ static void render_flag(const obj_flag *prev, const obj_flag *current)
 	float size = 64.0f;
 
     gfx_blend_normal();
-    gfx_texture_set(0);
+    gfx_texture_set(-1);
     gfx_quads_begin();
 	
 	gfx_quads_setrotation(angle);
@@ -805,7 +805,7 @@ static void render_flag(const obj_flag *prev, const obj_flag *current)
 		0, // starty
 		1, // endx
 		1); // endy								
-    gfx_quads_drawTL(pos.x,pos.y,size,size);
+    gfx_quads_draw(pos.x,pos.y,size,size);
     gfx_quads_end();
 }
 
@@ -1075,7 +1075,7 @@ static void render_player(const obj_player *prev, const obj_player *player)
 	if(player->health < 0) // dont render dead players
 		return;
 		
-	int skin = gametype == GAMETYPE_TDM ? skinseed + player->team : player->clientid;
+	int skin = gametype == GAMETYPE_DM ? player->clientid : skinseed + player->team;
 
 	vec2 direction = get_direction(player->angle);
 	float angle = player->angle/256.0f;
diff --git a/src/game/game.h b/src/game/game.h
index 3a1af48f..e3e4e99e 100644
--- a/src/game/game.h
+++ b/src/game/game.h
@@ -27,10 +27,15 @@ inline float get_angle(vec2 dir)
 inline bool col_check_point(float x, float y) { return col_check_point((int)x, (int)y) != 0; }
 inline bool col_check_point(vec2 p) { return col_check_point(p.x, p.y); }
 
+struct mapres_entity
+{
+	int x, y;
+	int data[];
+};
+
 struct mapres_spawnpoint
 {
 	int x, y;
-	int type;
 };
 
 struct mapres_item
@@ -39,14 +44,21 @@ struct mapres_item
 	int type;
 };
 
+struct mapres_flagstand
+{
+	int x, y;
+};
+
 enum
 {
+	MAPRES_ENTS_START=1,
 	MAPRES_SPAWNPOINT=1,
 	MAPRES_ITEM=2,
-	MAPRES_SPAWNPOINT_RED=2,
-	MAPRES_SPAWNPOINT_BLUE=3,
-	MAPRES_FLAGSTAND_RED=4,
-	MAPRES_FLAGSTAND_BLUE=5,
+	MAPRES_SPAWNPOINT_RED=3,
+	MAPRES_SPAWNPOINT_BLUE=4,
+	MAPRES_FLAGSTAND_RED=5,
+	MAPRES_FLAGSTAND_BLUE=6,
+	MAPRES_ENTS_END,
 	
 	ITEM_NULL=0,
 	ITEM_WEAPON_GUN=0x00010001,
diff --git a/src/game/server/game_server.cpp b/src/game/server/game_server.cpp
index a962f8d7..ebb35cf1 100644
--- a/src/game/server/game_server.cpp
+++ b/src/game/server/game_server.cpp
@@ -409,12 +409,26 @@ game_world world;
 gameobject::gameobject()
 : entity(OBJTYPE_GAME)
 {
-	gametype = GAMETYPE_DM;
+	// select gametype
 	if(strcmp(config.gametype, "ctf") == 0)
+	{
 		gametype = GAMETYPE_CTF;
+		dbg_msg("game", "-- Capture The Flag --");
+	}
 	else if(strcmp(config.gametype, "tdm") == 0)
+	{
 		gametype = GAMETYPE_TDM;
+		dbg_msg("game", "-- Team Death Match --");
+	}
+	else
+	{
+		gametype = GAMETYPE_DM;
+		dbg_msg("game", "-- Death Match --");
+	}
+		
+	//
 	
+	//
 	game_over_tick = -1;
 	sudden_death = 0;
 	round_start_tick = server_tick();
@@ -451,6 +465,10 @@ void gameobject::post_reset()
 	}
 }
 
+void gameobject::tick_ctf()
+{
+}
+
 void gameobject::tick_dm()
 {
 	if(game_over_tick == -1)
@@ -533,6 +551,11 @@ void gameobject::tick()
 {
 	switch(gametype)
 	{
+	case GAMETYPE_CTF:
+		{
+			tick_ctf();
+			break;
+		}
 	case GAMETYPE_TDM:
 		{
 			tick_tdm();
@@ -794,19 +817,40 @@ void player::respawn()
 	spawning = true;
 }
 
-void player::try_respawn()
+bool try_spawntype(int t, vec2 *pos)
 {
 	// get spawn point
 	int start, num;
-	map_get_type(1, &start, &num);
+	map_get_type(t, &start, &num);
+	if(!num)
+		return false;
+		
+	mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + (rand()%num), NULL, NULL);
+	*pos = vec2((float)sp->x, (float)sp->y);
+	return true;
+}
 
+
+void player::try_respawn()
+{
 	vec2 spawnpos = vec2(100.0f, -60.0f);
-	if(num)
+	
+	// get spawn point
+	if(gameobj->gametype == GAMETYPE_CTF)
 	{
-		mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + (rand()%num), NULL, NULL);
-		spawnpos = vec2((float)sp->x, (float)sp->y);
+		// try first try own team spawn, then normal spawn and then enemy
+		if(!try_spawntype(MAPRES_SPAWNPOINT_RED+(team&1), &spawnpos))
+		{
+			if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos))
+				try_spawntype(MAPRES_SPAWNPOINT_RED+((team+1)&1), &spawnpos);
+		}
 	}
-	
+	else
+	{
+		if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos))
+			try_spawntype(MAPRES_SPAWNPOINT_RED+(rand()&1), &spawnpos);
+	}
+		
 	// check if the position is occupado
 	entity *ents[2] = {0};
 	int types[] = {OBJTYPE_PLAYER};
@@ -822,7 +866,7 @@ void player::try_respawn()
 	defered_pos = pos;
 	
 
-	health = data->playerinfo[gameobj->gametype].maxhealth;
+	health = 10;
 	armor = 0;
 	jumped = 0;
 	dead = false;
@@ -1642,18 +1686,18 @@ void powerup::tick()
 		switch (type)
 		{
 		case POWERUP_HEALTH:
-			if(pplayer->health < data->playerinfo[gameobj->gametype].maxhealth)
+			if(pplayer->health < 10)
 			{
 				create_sound(pos, SOUND_PICKUP_HEALTH, 0);
-				pplayer->health = min((int)data->playerinfo[gameobj->gametype].maxhealth, pplayer->health + data->powerupinfo[type].amount);
+				pplayer->health = min(10, pplayer->health + data->powerupinfo[type].amount);
 				respawntime = data->powerupinfo[type].respawntime;
 			}
 			break;
 		case POWERUP_ARMOR:
-			if(pplayer->armor < data->playerinfo[gameobj->gametype].maxarmor)
+			if(pplayer->armor < 10)
 			{
 				create_sound(pos, SOUND_PICKUP_ARMOR, 0);
-				pplayer->armor = min((int)data->playerinfo[gameobj->gametype].maxarmor, pplayer->armor + data->powerupinfo[type].amount);
+				pplayer->armor = min(10, pplayer->armor + data->powerupinfo[type].amount);
 				respawntime = data->powerupinfo[type].respawntime;
 			}
 			break;
@@ -1753,6 +1797,8 @@ void flag::reset()
 
 void flag::tick()
 {
+	// THIS CODE NEEDS TO BE REWRITTEN. ITS NOT SAVE AT ALL
+	
 	// wait for respawn
 	if(spawntick > 0)
 	{
@@ -1763,17 +1809,34 @@ void flag::tick()
 	}
 
 	// Check if a player intersected us
-	vec2 meh;
-	player* pplayer = intersect_player(pos, pos + vel, meh, 0);
-	if (pplayer)
+	if(!carrying_player)
 	{
-		if (!carrying_player)
-			carrying_player = pplayer;
+		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;
 
-		// TODO: something..?
-	}
+			col_intersect_line(pos, new_pos, &new_pos);
+
+			pos = new_pos;
 
-	if (carrying_player)
+			if (is_grounded())
+				vel.x = vel.y = 0;
+		}
+	}
+	else
 	{
 		if (carrying_player->dead)
 			carrying_player = 0x0;
@@ -1783,19 +1846,6 @@ void flag::tick()
 			pos = carrying_player->pos;
 		}
 	}
-	
-	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;
-	}
 }
 
 bool flag::is_grounded()
@@ -1973,6 +2023,8 @@ void mods_tick()
 				{
 					mods_client_enter(MAX_CLIENTS-i-1);
 					strcpy(players[MAX_CLIENTS-i-1].name, "(bot)");
+					if(gameobj->gametype != GAMETYPE_DM)
+						players[MAX_CLIENTS-i-1].team = count&1;
 				}
 				count = -1;
 			}
@@ -2189,6 +2241,23 @@ void mods_init()
 		}
 	}
 	
+	if(gameobj->gametype == GAMETYPE_CTF)
+	{
+		// fetch flagstands
+		for(int i = 0; i < 2; i++)
+		{
+			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);
+		}
+	}
+	
 	world.insert_entity(gameobj);
 }
 
diff --git a/src/game/server/game_server.h b/src/game/server/game_server.h
index 3722713b..b691e0de 100644
--- a/src/game/server/game_server.h
+++ b/src/game/server/game_server.h
@@ -112,12 +112,16 @@ class gameobject : public entity
 	int sudden_death;
 	
 public:
+	class flag *flags[2];
+	vec2 flagsstands[2];
+	
 	int gametype;
 	gameobject();
 	virtual void post_reset();
 	virtual void tick();
 	virtual void tick_dm();
 	virtual void tick_tdm();
+	virtual void tick_ctf();
 	virtual void snap(int snapping_client);
 	virtual int getteam(int notthisid);
 };