2010-05-29 07:25:38 +00:00
// copyright (c) 2007 magnus auvinen, see licence.txt for more info
# include <game/mapitems.h>
# include <game/server/entities/character.h>
# include <game/server/player.h>
# include <game/server/gamecontext.h>
# include "ctf.h"
2007-09-25 23:03:15 +00:00
2010-05-29 07:25:38 +00:00
CGameControllerCTF : : CGameControllerCTF ( class CGameContext * pGameServer )
: IGameController ( pGameServer )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
m_apFlags [ 0 ] = 0 ;
m_apFlags [ 1 ] = 0 ;
m_pGameType = " CTF " ;
m_GameFlags = GAMEFLAG_TEAMS | GAMEFLAG_FLAGS ;
2007-09-25 23:03:15 +00:00
}
2010-05-29 07:25:38 +00:00
bool CGameControllerCTF : : OnEntity ( int Index , vec2 Pos )
2008-01-13 11:43:43 +00:00
{
2010-05-29 07:25:38 +00:00
if ( IGameController : : OnEntity ( Index , Pos ) )
2008-01-13 11:43:43 +00:00
return true ;
2010-05-29 07:25:38 +00:00
int Team = - 1 ;
if ( Index = = ENTITY_FLAGSTAND_RED ) Team = 0 ;
if ( Index = = ENTITY_FLAGSTAND_BLUE ) Team = 1 ;
if ( Team = = - 1 )
2008-01-13 11:43:43 +00:00
return false ;
2010-05-29 07:25:38 +00:00
CFlag * F = new CFlag ( & GameServer ( ) - > m_World , Team ) ;
F - > m_StandPos = Pos ;
F - > m_Pos = Pos ;
m_apFlags [ Team ] = F ;
GameServer ( ) - > m_World . InsertEntity ( F ) ;
2008-01-13 11:43:43 +00:00
return true ;
}
2010-05-29 07:25:38 +00:00
int CGameControllerCTF : : OnCharacterDeath ( class CCharacter * pVictim , class CPlayer * pKiller , int WeaponID )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
IGameController : : OnCharacterDeath ( pVictim , pKiller , WeaponID ) ;
int HadFlag = 0 ;
2007-11-18 23:29:34 +00:00
2007-09-25 23:03:15 +00:00
// drop flags
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < 2 ; i + + )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
CFlag * F = m_apFlags [ i ] ;
2010-05-29 11:26:17 +00:00
if ( F & & pKiller & & pKiller - > GetCharacter ( ) & & F - > m_pCarryingCharacter = = pKiller - > GetCharacter ( ) )
2010-05-29 07:25:38 +00:00
HadFlag | = 2 ;
2010-05-29 11:26:17 +00:00
if ( F & & F - > m_pCarryingCharacter = = pVictim )
2007-11-18 23:29:34 +00:00
{
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_DROP ) ;
F - > m_DropTick = Server ( ) - > Tick ( ) ;
2010-05-29 11:26:17 +00:00
F - > m_pCarryingCharacter = 0 ;
2010-05-29 07:25:38 +00:00
F - > m_Vel = vec2 ( 0 , 0 ) ;
2007-12-11 21:19:52 +00:00
2010-05-29 07:25:38 +00:00
if ( pKiller & & pKiller - > GetTeam ( ) ! = pVictim - > GetPlayer ( ) - > GetTeam ( ) )
pKiller - > m_Score + + ;
2007-12-11 21:19:52 +00:00
2010-05-29 07:25:38 +00:00
HadFlag | = 1 ;
2007-11-18 23:29:34 +00:00
}
2007-09-25 23:03:15 +00:00
}
2007-11-18 23:29:34 +00:00
2010-05-29 07:25:38 +00:00
return HadFlag ;
}
bool CGameControllerCTF : : CanBeMovedOnBalance ( int Cid )
{
CCharacter * Character = GameServer ( ) - > m_apPlayers [ Cid ] - > GetCharacter ( ) ;
if ( Character )
{
for ( int fi = 0 ; fi < 2 ; fi + + )
{
CFlag * F = m_apFlags [ fi ] ;
2010-05-29 11:26:17 +00:00
if ( F - > m_pCarryingCharacter = = Character )
2010-05-29 07:25:38 +00:00
return false ;
}
}
return true ;
2007-09-25 23:03:15 +00:00
}
2010-05-29 07:25:38 +00:00
void CGameControllerCTF : : Tick ( )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
IGameController : : Tick ( ) ;
2007-11-26 20:47:49 +00:00
2010-05-29 07:25:38 +00:00
DoTeamScoreWincheck ( ) ;
2007-09-25 23:03:15 +00:00
for ( int fi = 0 ; fi < 2 ; fi + + )
{
2010-05-29 07:25:38 +00:00
CFlag * F = m_apFlags [ fi ] ;
2007-09-25 23:03:15 +00:00
2010-05-29 07:25:38 +00:00
if ( ! F )
2007-12-09 09:47:05 +00:00
continue ;
2008-10-18 20:37:41 +00:00
// flag hits death-tile, reset it
2010-05-29 07:25:38 +00:00
if ( GameServer ( ) - > Collision ( ) - > GetCollisionAt ( F - > m_Pos . x , F - > m_Pos . y ) & CCollision : : COLFLAG_DEATH )
2008-10-18 20:37:41 +00:00
{
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_RETURN ) ;
F - > Reset ( ) ;
2008-10-18 20:37:41 +00:00
continue ;
}
2007-09-25 23:03:15 +00:00
//
2010-05-29 11:26:17 +00:00
if ( F - > m_pCarryingCharacter )
2007-09-25 23:03:15 +00:00
{
// update flag position
2010-05-29 11:26:17 +00:00
F - > m_Pos = F - > m_pCarryingCharacter - > m_Pos ;
2007-09-25 23:03:15 +00:00
2010-05-29 07:25:38 +00:00
if ( m_apFlags [ fi ^ 1 ] & & m_apFlags [ fi ^ 1 ] - > m_AtStand )
2007-09-25 23:03:15 +00:00
{
2010-06-03 14:42:37 +00:00
if ( distance ( F - > m_Pos , m_apFlags [ fi ^ 1 ] - > m_Pos ) < 28 )
2007-09-25 23:03:15 +00:00
{
// CAPTURE! \o/
2010-05-29 07:25:38 +00:00
m_aTeamscore [ fi ^ 1 ] + = 100 ;
2010-05-29 11:26:17 +00:00
F - > m_pCarryingCharacter - > GetPlayer ( ) - > m_Score + = 5 ;
2008-01-30 13:15:58 +00:00
2008-07-06 11:21:21 +00:00
dbg_msg ( " game " , " flag_capture player='%d:%s' " ,
2010-05-29 11:26:17 +00:00
F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ,
Server ( ) - > ClientName ( F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ) ) ;
2008-01-30 13:15:58 +00:00
2010-05-29 07:25:38 +00:00
char Buf [ 512 ] ;
float CaptureTime = ( Server ( ) - > Tick ( ) - F - > m_GrabTick ) / ( float ) Server ( ) - > TickSpeed ( ) ;
if ( CaptureTime < = 60 )
2008-11-08 15:17:59 +00:00
{
2010-05-29 11:26:17 +00:00
str_format ( Buf , sizeof ( Buf ) , " The %s flag was captured by %s (%d.%s%d seconds) " , fi ? " blue " : " red " , Server ( ) - > ClientName ( F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ) , ( int ) CaptureTime % 60 , ( ( int ) ( CaptureTime * 100 ) % 100 ) < 10 ? " 0 " : " " , ( int ) ( CaptureTime * 100 ) % 100 ) ;
2008-11-08 15:17:59 +00:00
}
else
{
2010-05-29 11:26:17 +00:00
str_format ( Buf , sizeof ( Buf ) , " The %s flag was captured by %s " , fi ? " blue " : " red " , Server ( ) - > ClientName ( F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ) ) ;
2008-11-08 15:17:59 +00:00
}
2010-05-29 07:25:38 +00:00
GameServer ( ) - > SendChat ( - 1 , - 2 , Buf ) ;
2007-09-25 23:03:15 +00:00
for ( int i = 0 ; i < 2 ; i + + )
2010-05-29 07:25:38 +00:00
m_apFlags [ i ] - > Reset ( ) ;
2007-11-27 19:32:35 +00:00
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_CAPTURE ) ;
2007-09-25 23:03:15 +00:00
}
2010-05-29 07:25:38 +00:00
}
2007-09-25 23:03:15 +00:00
}
else
{
2010-05-29 07:25:38 +00:00
CCharacter * apCloseCCharacters [ MAX_CLIENTS ] ;
2010-06-03 14:42:37 +00:00
int Num = GameServer ( ) - > m_World . FindEntities ( F - > m_Pos , 7.0f , ( CEntity * * ) apCloseCCharacters , MAX_CLIENTS , NETOBJTYPE_CHARACTER ) ;
2010-05-29 07:25:38 +00:00
for ( int i = 0 ; i < Num ; i + + )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
if ( ! apCloseCCharacters [ i ] - > IsAlive ( ) | | apCloseCCharacters [ i ] - > GetPlayer ( ) - > GetTeam ( ) = = - 1 | | GameServer ( ) - > Collision ( ) - > IntersectLine ( F - > m_Pos , apCloseCCharacters [ i ] - > m_Pos , NULL , NULL ) )
2008-11-04 16:35:48 +00:00
continue ;
2010-05-29 07:25:38 +00:00
if ( apCloseCCharacters [ i ] - > GetPlayer ( ) - > GetTeam ( ) = = F - > m_Team )
2007-09-25 23:03:15 +00:00
{
// return the flag
2010-05-29 07:25:38 +00:00
if ( ! F - > m_AtStand )
2007-11-27 19:32:35 +00:00
{
2010-05-29 07:25:38 +00:00
CCharacter * pChr = apCloseCCharacters [ i ] ;
pChr - > GetPlayer ( ) - > m_Score + = 1 ;
2008-01-30 13:15:58 +00:00
2008-07-06 11:21:21 +00:00
dbg_msg ( " game " , " flag_return player='%d:%s' " ,
2010-05-29 07:25:38 +00:00
pChr - > GetPlayer ( ) - > GetCID ( ) ,
Server ( ) - > ClientName ( pChr - > GetPlayer ( ) - > GetCID ( ) ) ) ;
2008-01-30 13:15:58 +00:00
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_RETURN ) ;
F - > Reset ( ) ;
2007-11-27 19:32:35 +00:00
}
2007-09-25 23:03:15 +00:00
}
2008-11-08 09:02:35 +00:00
else
2007-09-25 23:03:15 +00:00
{
// take the flag
2010-05-29 07:25:38 +00:00
if ( F - > m_AtStand )
2008-11-08 15:17:59 +00:00
{
2010-05-29 07:25:38 +00:00
m_aTeamscore [ fi ^ 1 ] + + ;
F - > m_GrabTick = Server ( ) - > Tick ( ) ;
2008-11-08 15:17:59 +00:00
}
2010-05-29 07:25:38 +00:00
F - > m_AtStand = 0 ;
2010-05-29 11:26:17 +00:00
F - > m_pCarryingCharacter = apCloseCCharacters [ i ] ;
F - > m_pCarryingCharacter - > GetPlayer ( ) - > m_Score + = 1 ;
2008-01-30 13:15:58 +00:00
2008-07-06 11:21:21 +00:00
dbg_msg ( " game " , " flag_grab player='%d:%s' " ,
2010-05-29 11:26:17 +00:00
F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ,
Server ( ) - > ClientName ( F - > m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ) ) ;
2007-12-15 15:35:50 +00:00
for ( int c = 0 ; c < MAX_CLIENTS ; c + + )
{
2010-05-29 07:25:38 +00:00
if ( ! GameServer ( ) - > m_apPlayers [ c ] )
2007-12-15 15:35:50 +00:00
continue ;
2010-05-29 07:25:38 +00:00
if ( GameServer ( ) - > m_apPlayers [ c ] - > GetTeam ( ) = = fi )
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_GRAB_EN , GameServer ( ) - > m_apPlayers [ c ] - > GetCID ( ) ) ;
2007-12-15 15:35:50 +00:00
else
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_GRAB_PL , GameServer ( ) - > m_apPlayers [ c ] - > GetCID ( ) ) ;
2007-12-15 15:35:50 +00:00
}
2007-09-25 23:03:15 +00:00
break ;
}
}
2010-05-29 11:26:17 +00:00
if ( ! F - > m_pCarryingCharacter & & ! F - > m_AtStand )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
if ( Server ( ) - > Tick ( ) > F - > m_DropTick + Server ( ) - > TickSpeed ( ) * 30 )
2007-11-27 19:32:35 +00:00
{
2010-05-29 07:25:38 +00:00
GameServer ( ) - > CreateSoundGlobal ( SOUND_CTF_RETURN ) ;
F - > Reset ( ) ;
2007-11-27 19:32:35 +00:00
}
2007-11-26 19:32:02 +00:00
else
{
2010-05-29 07:25:38 +00:00
F - > m_Vel . y + = GameServer ( ) - > m_World . m_Core . m_Tuning . m_Gravity ;
GameServer ( ) - > Collision ( ) - > MoveBox ( & F - > m_Pos , & F - > m_Vel , vec2 ( F - > m_PhysSize , F - > m_PhysSize ) , 0.5f ) ;
2007-11-26 19:32:02 +00:00
}
2007-09-25 23:03:15 +00:00
}
}
}
}
2007-10-28 11:30:25 +00:00
// Flag
2010-05-29 07:25:38 +00:00
CFlag : : CFlag ( CGameWorld * pGameWorld , int Team )
: CEntity ( pGameWorld , NETOBJTYPE_FLAG )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
m_Team = Team ;
m_ProximityRadius = m_PhysSize ;
2010-05-29 11:26:17 +00:00
m_pCarryingCharacter = 0x0 ;
2010-05-29 07:25:38 +00:00
m_GrabTick = 0 ;
2007-09-25 23:03:15 +00:00
2010-05-29 07:25:38 +00:00
Reset ( ) ;
2007-09-25 23:03:15 +00:00
}
2010-05-29 07:25:38 +00:00
void CFlag : : Reset ( )
2007-09-25 23:03:15 +00:00
{
2010-05-29 11:26:17 +00:00
m_pCarryingCharacter = 0x0 ;
2010-05-29 07:25:38 +00:00
m_AtStand = 1 ;
m_Pos = m_StandPos ;
m_Vel = vec2 ( 0 , 0 ) ;
m_GrabTick = 0 ;
2007-09-25 23:03:15 +00:00
}
2010-05-29 07:25:38 +00:00
void CFlag : : Snap ( int SnappingClient )
2007-09-25 23:03:15 +00:00
{
2010-05-29 07:25:38 +00:00
CNetObj_Flag * pFlag = ( CNetObj_Flag * ) Server ( ) - > SnapNewItem ( NETOBJTYPE_FLAG , m_Team , sizeof ( CNetObj_Flag ) ) ;
pFlag - > m_X = ( int ) m_Pos . x ;
pFlag - > m_Y = ( int ) m_Pos . y ;
pFlag - > m_Team = m_Team ;
pFlag - > m_CarriedBy = - 1 ;
2007-09-25 23:03:15 +00:00
2010-05-29 07:25:38 +00:00
if ( m_AtStand )
pFlag - > m_CarriedBy = - 2 ;
2010-05-29 11:26:17 +00:00
else if ( m_pCarryingCharacter & & m_pCarryingCharacter - > GetPlayer ( ) )
pFlag - > m_CarriedBy = m_pCarryingCharacter - > GetPlayer ( ) - > GetCID ( ) ;
2007-09-25 23:03:15 +00:00
}