From ffa923bbebd5318ed2b5c805662b71f141fbdaf2 Mon Sep 17 00:00:00 2001 From: Magnus Auvinen Date: Tue, 18 Dec 2007 23:21:57 +0000 Subject: [PATCH] fixed various small bugs. fixed fair spawning system --- other/config_directory.bat | 2 +- src/engine/server/es_server.c | 4 ++ src/game/client/gc_menu.cpp | 7 ++- src/game/server/gs_common.h | 2 + src/game/server/gs_game.cpp | 11 +++- src/game/server/gs_server.cpp | 99 +++++++++++++++++++++++++++++++---- 6 files changed, 111 insertions(+), 14 deletions(-) diff --git a/other/config_directory.bat b/other/config_directory.bat index e93a7138b..0aab3cdad 100644 --- a/other/config_directory.bat +++ b/other/config_directory.bat @@ -1 +1 @@ -@explorer %APPDATA%\Teewars \ No newline at end of file +@start explorer %APPDATA%\Teewars diff --git a/src/engine/server/es_server.c b/src/engine/server/es_server.c index bafe0ec29..233295f16 100644 --- a/src/engine/server/es_server.c +++ b/src/engine/server/es_server.c @@ -209,6 +209,10 @@ void server_setbrowseinfo(int game_type, int progression) { browseinfo_gametype = game_type; browseinfo_progression = progression; + if(browseinfo_progression > 100) + browseinfo_progression = 100; + if(browseinfo_progression < -1) + browseinfo_progression = -1; } void server_kick(int client_id, const char *reason) diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp index 693cbcb80..11428ae7f 100644 --- a/src/game/client/gc_menu.cpp +++ b/src/game/client/gc_menu.cpp @@ -345,7 +345,10 @@ static void ui2_draw_browse_icon(int what, const RECT *r) gfx_texture_set(data->images[IMAGE_BROWSEICONS].id); gfx_quads_begin(); select_sprite(SPRITE_BROWSE_PROGRESS1); // default - if(what <= 100) + if(what == -1) + { + } + else if(what <= 100) { if(what < 66) select_sprite(SPRITE_BROWSE_PROGRESS2); @@ -1137,6 +1140,8 @@ static void menu2_render_serverbrowser(RECT main_view) } else if(id == COL_PROGRESS) { + if(item->progression > 100) + item->progression = 100; ui2_draw_browse_icon(item->progression, &button); } else if(id == COL_GAMETYPE) diff --git a/src/game/server/gs_common.h b/src/game/server/gs_common.h index 7df0a9c4b..cd2652fbb 100644 --- a/src/game/server/gs_common.h +++ b/src/game/server/gs_common.h @@ -151,6 +151,7 @@ public: virtual void snap(int snapping_client); virtual int getteam(int notthisid); + int clampteam(int team); }; extern gameobject *gameobj; @@ -285,6 +286,7 @@ public: bool spawning; bool dead; int die_tick; + vec2 die_pos; // latency calculations int latency_accum; diff --git a/src/game/server/gs_game.cpp b/src/game/server/gs_game.cpp index 844a4851a..badabee65 100644 --- a/src/game/server/gs_game.cpp +++ b/src/game/server/gs_game.cpp @@ -209,7 +209,7 @@ void gameobject::tick() if(warmup) prog = -1; - + server_setbrowseinfo(gametype, prog); } @@ -262,4 +262,13 @@ void gameobject::do_team_wincheck() } } +int gameobject::clampteam(int team) +{ + if(team < 0) // spectator + return -1; + if(is_teamplay) + return team&1; + return 0; +} + gameobject *gameobj = 0; diff --git a/src/game/server/gs_server.cpp b/src/game/server/gs_server.cpp index f2e204419..0fbbb0021 100644 --- a/src/game/server/gs_server.cpp +++ b/src/game/server/gs_server.cpp @@ -451,6 +451,7 @@ void player::reset() clear_flag(entity::FLAG_PHYSICS); spawning = false; die_tick = 0; + die_pos = vec2(0,0); damage_taken = 0; state = STATE_UNKNOWN; @@ -508,6 +509,8 @@ const char *get_team_name(int team) void player::set_team(int new_team) { + // clamp the team + new_team = gameobj->clampteam(new_team); if(team == new_team) return; @@ -521,19 +524,79 @@ void player::set_team(int new_team) dbg_msg("game", "cid=%d team=%d", client_id, team); } +struct spawneval +{ + spawneval() + { + got = false; + friendly_team = -1; + die_pos = vec2(0,0); + pos = vec2(100,100); + } + + vec2 pos; + bool got; + int friendly_team; + float score; + vec2 die_pos; +}; -bool try_spawntype(int t, vec2 *outpos) +static float evaluate_spawn(spawneval *eval, vec2 pos) +{ + float score = 0.0f; + + for(int c = 0; c < MAX_CLIENTS; c++) + { + if(players[c].client_id == -1) + continue; + + // don't count dead people + if(!(players[c].flags&entity::FLAG_PHYSICS)) + continue; + + // don't count friends + if(eval->friendly_team != -1 && players[c].team == eval->friendly_team) + continue; + + float d = distance(pos, players[c].pos); + if(d == 0) + score += 1000000000.0f; + else + score += 1.0f/d; + } + + // weight in the die posititon + float d = distance(pos, eval->die_pos); + if(d == 0) + score += 1000000000.0f; + else + score += 1.0f/d; + + dbg_msg("", "(%f,%f) = %f", pos.x, pos.y, score); + + return score; +} + +static void evaluate_spawn_type(spawneval *eval, int t) { // get spawn point int start, num; map_get_type(t, &start, &num); if(!num) - return false; + return; - int id = rand()%num; - mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + id, NULL, NULL); - *outpos = vec2((float)sp->x, (float)sp->y); - return true; + for(int i = 0; i < num; i++) + { + mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + i, NULL, NULL); + vec2 p = vec2((float)sp->x, (float)sp->y); + float s = evaluate_spawn(eval, p); + if(!eval->got || eval->score > s) + { + eval->got = true; + eval->score = s; + eval->pos = p; + } + } } void player::try_respawn() @@ -541,20 +604,33 @@ void player::try_respawn() vec2 spawnpos = vec2(100.0f, -60.0f); // get spawn point + spawneval eval; + eval.die_pos = die_pos; + if(gameobj->gametype == GAMETYPE_CTF) { + eval.friendly_team = team; + // try first try own team spawn, then normal spawn and then enemy - if(!try_spawntype(MAPRES_SPAWNPOINT_RED+(team&1), &spawnpos)) + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT_RED+(team&1)); + if(!eval.got) { - if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos)) - try_spawntype(MAPRES_SPAWNPOINT_RED+((team+1)&1), &spawnpos); + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT); + if(!eval.got) + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT_RED+((team+1)&1)); } } else { - if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos)) - try_spawntype(MAPRES_SPAWNPOINT_RED+(rand()&1), &spawnpos); + if(gameobj->gametype == GAMETYPE_TDM) + eval.friendly_team = team; + + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT); + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT_RED); + evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT_BLUE); } + + spawnpos = eval.pos; // check if the position is occupado entity *ents[2] = {0}; @@ -1246,6 +1322,7 @@ void player::die(int killer, int weapon) create_sound(pos, SOUND_PLAYER_DIE); // set dead state + die_pos = pos; dead = true; die_tick = server_tick(); clear_flag(FLAG_PHYSICS);