diff --git a/datasrc/client.dts b/datasrc/client.dts index 7b2cec995..61bacd54a 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 e4b6935fd..d229894b0 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 8e039f2a7..c26337787 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -1,4 +1,5 @@ #include +#include extern "C" { #include @@ -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; - } - } - + // fetch entities of this class int start, num; - datafile_get_type(df, MAPRES_SPAWNPOINT, &start, &num); - for(int t = 0; t < num; t++) + datafile_get_type(df, t, &start, &num); + + for(int i = 0; i < num; i++) { - mapres_spawnpoint *sp = (mapres_spawnpoint *)datafile_get_item(df, start+t,0,0); - ents_new(type, sp->x, sp->y); - } - } - - { - int start, num; - datafile_get_type(df, MAPRES_ITEM, &start, &num); - for(int t = 0; t < num; t++) - { - 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) + int id = 0; + for(int i = 0; i < ents_count(); i++) { - 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) - { - 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 2c8e8e443..ce835b46d 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 0c20ab667..87fe767c2 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 3a1af48f8..e3e4e99e1 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 a962f8d74..ebb35cf15 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) - { - mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + (rand()%num), NULL, NULL); - spawnpos = vec2((float)sp->x, (float)sp->y); - } + // get spawn point + if(gameobj->gametype == GAMETYPE_CTF) + { + // 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 (is_grounded()) + vel.x = vel.y = 0; + } } - - if (carrying_player) + 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 3722713bc..b691e0de5 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); };