fixed various small bugs. fixed fair spawning system

This commit is contained in:
Magnus Auvinen 2007-12-18 23:21:57 +00:00
parent 3c0615b835
commit ffa923bbeb
6 changed files with 111 additions and 14 deletions

View file

@ -1 +1 @@
@explorer %APPDATA%\Teewars @start explorer %APPDATA%\Teewars

View file

@ -209,6 +209,10 @@ void server_setbrowseinfo(int game_type, int progression)
{ {
browseinfo_gametype = game_type; browseinfo_gametype = game_type;
browseinfo_progression = progression; 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) void server_kick(int client_id, const char *reason)

View file

@ -345,7 +345,10 @@ static void ui2_draw_browse_icon(int what, const RECT *r)
gfx_texture_set(data->images[IMAGE_BROWSEICONS].id); gfx_texture_set(data->images[IMAGE_BROWSEICONS].id);
gfx_quads_begin(); gfx_quads_begin();
select_sprite(SPRITE_BROWSE_PROGRESS1); // default select_sprite(SPRITE_BROWSE_PROGRESS1); // default
if(what <= 100) if(what == -1)
{
}
else if(what <= 100)
{ {
if(what < 66) if(what < 66)
select_sprite(SPRITE_BROWSE_PROGRESS2); select_sprite(SPRITE_BROWSE_PROGRESS2);
@ -1137,6 +1140,8 @@ static void menu2_render_serverbrowser(RECT main_view)
} }
else if(id == COL_PROGRESS) else if(id == COL_PROGRESS)
{ {
if(item->progression > 100)
item->progression = 100;
ui2_draw_browse_icon(item->progression, &button); ui2_draw_browse_icon(item->progression, &button);
} }
else if(id == COL_GAMETYPE) else if(id == COL_GAMETYPE)

View file

@ -151,6 +151,7 @@ public:
virtual void snap(int snapping_client); virtual void snap(int snapping_client);
virtual int getteam(int notthisid); virtual int getteam(int notthisid);
int clampteam(int team);
}; };
extern gameobject *gameobj; extern gameobject *gameobj;
@ -285,6 +286,7 @@ public:
bool spawning; bool spawning;
bool dead; bool dead;
int die_tick; int die_tick;
vec2 die_pos;
// latency calculations // latency calculations
int latency_accum; int latency_accum;

View file

@ -209,7 +209,7 @@ void gameobject::tick()
if(warmup) if(warmup)
prog = -1; prog = -1;
server_setbrowseinfo(gametype, prog); 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; gameobject *gameobj = 0;

View file

@ -451,6 +451,7 @@ void player::reset()
clear_flag(entity::FLAG_PHYSICS); clear_flag(entity::FLAG_PHYSICS);
spawning = false; spawning = false;
die_tick = 0; die_tick = 0;
die_pos = vec2(0,0);
damage_taken = 0; damage_taken = 0;
state = STATE_UNKNOWN; state = STATE_UNKNOWN;
@ -508,6 +509,8 @@ const char *get_team_name(int team)
void player::set_team(int new_team) void player::set_team(int new_team)
{ {
// clamp the team
new_team = gameobj->clampteam(new_team);
if(team == new_team) if(team == new_team)
return; return;
@ -521,19 +524,79 @@ void player::set_team(int new_team)
dbg_msg("game", "cid=%d team=%d", client_id, 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 // get spawn point
int start, num; int start, num;
map_get_type(t, &start, &num); map_get_type(t, &start, &num);
if(!num) if(!num)
return false; return;
int id = rand()%num; for(int i = 0; i < num; i++)
mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + id, NULL, NULL); {
*outpos = vec2((float)sp->x, (float)sp->y); mapres_spawnpoint *sp = (mapres_spawnpoint*)map_get_item(start + i, NULL, NULL);
return true; 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() void player::try_respawn()
@ -541,20 +604,33 @@ void player::try_respawn()
vec2 spawnpos = vec2(100.0f, -60.0f); vec2 spawnpos = vec2(100.0f, -60.0f);
// get spawn point // get spawn point
spawneval eval;
eval.die_pos = die_pos;
if(gameobj->gametype == GAMETYPE_CTF) if(gameobj->gametype == GAMETYPE_CTF)
{ {
eval.friendly_team = team;
// try first try own team spawn, then normal spawn and then enemy // 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)) evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT);
try_spawntype(MAPRES_SPAWNPOINT_RED+((team+1)&1), &spawnpos); if(!eval.got)
evaluate_spawn_type(&eval, MAPRES_SPAWNPOINT_RED+((team+1)&1));
} }
} }
else else
{ {
if(!try_spawntype(MAPRES_SPAWNPOINT, &spawnpos)) if(gameobj->gametype == GAMETYPE_TDM)
try_spawntype(MAPRES_SPAWNPOINT_RED+(rand()&1), &spawnpos); 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 // check if the position is occupado
entity *ents[2] = {0}; entity *ents[2] = {0};
@ -1246,6 +1322,7 @@ void player::die(int killer, int weapon)
create_sound(pos, SOUND_PLAYER_DIE); create_sound(pos, SOUND_PLAYER_DIE);
// set dead state // set dead state
die_pos = pos;
dead = true; dead = true;
die_tick = server_tick(); die_tick = server_tick();
clear_flag(FLAG_PHYSICS); clear_flag(FLAG_PHYSICS);