ddnet/src/game/server/gs_game_ctf.cpp

188 lines
3.7 KiB
C++
Raw Normal View History

2007-11-25 19:42:40 +00:00
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#include <engine/e_server_interface.h>
2008-01-13 11:43:43 +00:00
#include <game/g_mapitems.h>
2007-12-15 10:24:49 +00:00
#include "gs_common.h"
#include "gs_game_ctf.h"
gameobject_ctf::gameobject_ctf()
{
is_teamplay = true;
}
2008-01-13 11:43:43 +00:00
bool gameobject_ctf::on_entity(int index, vec2 pos)
{
if(gameobject::on_entity(index, pos))
return true;
int team = -1;
if(index == ENTITY_FLAGSTAND_RED) team = 0;
if(index == ENTITY_FLAGSTAND_BLUE) team = 1;
if(team == -1)
return false;
flag *f = new flag(team);
f->stand_pos = pos;
f->pos = pos;
flags[team] = f;
return true;
}
void gameobject_ctf::on_player_spawn(class player *p)
{
}
int gameobject_ctf::on_player_death(class player *victim, class player *killer, int weaponid)
{
2007-09-26 07:31:14 +00:00
gameobject::on_player_death(victim, killer, weaponid);
int had_flag = 0;
// drop flags
for(int fi = 0; fi < 2; fi++)
{
flag *f = flags[fi];
if(f && f->carrying_player == killer)
had_flag |= 2;
if(f && f->carrying_player == victim)
{
create_sound_global(SOUND_CTF_DROP);
f->drop_tick = server_tick();
f->carrying_player = 0;
f->vel = vec2(0,0);
2007-12-11 21:19:52 +00:00
2007-12-13 22:17:36 +00:00
if(killer && killer->team != victim->team)
2007-12-11 21:19:52 +00:00
killer->score++;
had_flag |= 1;
}
}
return had_flag;
}
void gameobject_ctf::tick()
{
gameobject::tick();
2007-11-26 20:47:49 +00:00
2008-01-17 23:09:49 +00:00
do_team_score_wincheck();
// do flags
for(int fi = 0; fi < 2; fi++)
{
flag *f = flags[fi];
2007-12-09 09:47:05 +00:00
if(!f)
continue;
//
if(f->carrying_player)
{
// update flag position
f->pos = f->carrying_player->pos;
if(flags[fi^1]->at_stand)
{
2007-12-19 21:03:29 +00:00
if(distance(f->pos, flags[fi^1]->pos) < 32)
{
// CAPTURE! \o/
2007-12-11 21:08:21 +00:00
teamscore[fi^1] += 100;
2007-12-11 21:19:52 +00:00
f->carrying_player->score += 5;
for(int i = 0; i < 2; i++)
flags[i]->reset();
create_sound_global(SOUND_CTF_CAPTURE);
}
}
}
else
{
2007-12-15 15:39:16 +00:00
player *close_players[MAX_CLIENTS];
int types[] = {OBJTYPE_PLAYER_CHARACTER};
2007-12-15 15:39:16 +00:00
int num = world->find_entities(f->pos, 32.0f, (entity**)close_players, MAX_CLIENTS, types, 1);
for(int i = 0; i < num; i++)
{
2007-12-15 15:39:16 +00:00
if(close_players[i]->team == f->team)
{
// return the flag
2007-09-26 07:31:14 +00:00
if(!f->at_stand)
{
2007-12-15 15:39:16 +00:00
close_players[i]->score += 1;
create_sound_global(SOUND_CTF_RETURN);
2007-09-26 07:31:14 +00:00
f->reset();
}
}
else
{
// take the flag
2007-12-11 21:08:21 +00:00
if(f->at_stand)
teamscore[fi^1]++;
f->at_stand = 0;
2007-12-15 15:39:16 +00:00
f->carrying_player = close_players[i];
2007-12-11 21:19:52 +00:00
f->carrying_player->score += 1;
2007-12-15 15:35:50 +00:00
for(int c = 0; c < MAX_CLIENTS; c++)
{
2007-12-15 15:41:31 +00:00
if(players[c].client_id == -1)
2007-12-15 15:35:50 +00:00
continue;
2007-12-15 15:39:16 +00:00
if(players[c].team == fi)
2007-12-15 15:41:31 +00:00
create_sound_global(SOUND_CTF_GRAB_EN, players[c].client_id);
2007-12-15 15:35:50 +00:00
else
2007-12-15 15:41:31 +00:00
create_sound_global(SOUND_CTF_GRAB_PL, players[c].client_id);
2007-12-15 15:35:50 +00:00
}
break;
}
}
if(!f->carrying_player && !f->at_stand)
{
if(server_tick() > f->drop_tick + server_tickspeed()*30)
{
create_sound_global(SOUND_CTF_RETURN);
f->reset();
}
else
{
f->vel.y += gravity;
move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
}
}
}
}
}
// Flag
flag::flag(int _team)
: entity(OBJTYPE_FLAG)
{
team = _team;
proximity_radius = phys_size;
carrying_player = 0x0;
reset();
// TODO: should this be done here?
world->insert_entity(this);
}
void flag::reset()
{
carrying_player = 0;
at_stand = 1;
pos = stand_pos;
vel = vec2(0,0);
}
void flag::snap(int snapping_client)
{
obj_flag *flag = (obj_flag *)snap_new_item(OBJTYPE_FLAG, team, sizeof(obj_flag));
flag->x = (int)pos.x;
flag->y = (int)pos.y;
flag->team = team;
flag->carried_by = -1;
if(at_stand)
flag->carried_by = -2;
else if(carrying_player)
flag->carried_by = carrying_player->client_id;
}