Portable Half-Life SDK. GoldSource and Xash3D. Crossplatform.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

571 lines
14 KiB

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
/*****************************************************
******************************************************
THREEWAVE CTF FLAG CODE
******************************************************
*****************************************************/
#include "extdll.h"
#include "util.h"
#include "cbase.h"
#include "player.h"
#include "weapons.h"
#include "gamerules.h"
#include "items.h"
#include "threewave_gamerules.h"
#include "flags.h"
unsigned short g_usCarried;
unsigned short g_usFlagSpawn;
enum Flag_Anims
{
ON_GROUND = 0,
NOT_CARRIED,
CARRIED,
WAVE_IDLE,
FLAG_POSITION
};
void CItemFlag::Spawn()
{
Precache();
SET_MODEL( ENT( pev ), "models/flag.mdl" );
pev->movetype = MOVETYPE_TOSS;
pev->solid = SOLID_TRIGGER;
UTIL_SetOrigin( pev, pev->origin );
UTIL_SetSize( pev, Vector( -16, -16, 0 ), Vector( 16, 16, 16 ) );
SetThink( &CItemFlag::FlagThink );
SetTouch( &CItemFlag::FlagTouch );
pev->nextthink = gpGlobals->time + 0.3;
//Set the Skin based on the team.
pev->skin = pev->team;
Dropped = FALSE;
m_flDroppedTime = 0.0;
pev->sequence = NOT_CARRIED;
pev->framerate = 1.0;
// if( !DROP_TO_FLOOR( ENT( pev ) ) )
// ResetFlag( pev->team );
}
void CItemFlag::FlagTouch( CBaseEntity *pToucher )
{
if( !pToucher )
return;
if( !pToucher->IsPlayer() )
return;
if( FBitSet( pev->effects, EF_NODRAW ) )
return;
if( pToucher->pev->health <= 0 )
return;
if( pToucher->pev->team == 0 )
return;
CBasePlayer *pPlayer = (CBasePlayer *)pToucher;
//Same team as the flag
if( pev->team == pToucher->pev->team )
{
//Flag is dropped, let's return it
if( Dropped )
{
Dropped = FALSE;
pPlayer->AddPoints( TEAM_CAPTURE_RECOVERY_BONUS, TRUE );
if( pPlayer->pev->team == RED )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Returned_Red_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
if( ( (CThreeWave*)g_pGameRules )->iBlueFlagStatus == BLUE_FLAG_STOLEN )
{
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pTeamMate = (CBasePlayer*)UTIL_PlayerByIndex( i );
if( pTeamMate )
{
if( pTeamMate->m_bHasFlag )
{
pTeamMate->pFlagReturner = pPlayer;
pTeamMate->m_flFlagReturnTime = gpGlobals->time + TEAM_CAPTURE_RETURN_FLAG_ASSIST_TIMEOUT;
}
}
}
}
}
if( pPlayer->pev->team == BLUE )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Returned_Blue_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
if( ( (CThreeWave*)g_pGameRules )->iRedFlagStatus == RED_FLAG_STOLEN )
{
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBasePlayer *pTeamMate = (CBasePlayer*)UTIL_PlayerByIndex( i );
if( pTeamMate )
{
if( pTeamMate->m_bHasFlag )
{
pTeamMate->pFlagReturner = pPlayer;
pTeamMate->m_flFlagReturnTime = gpGlobals->time + TEAM_CAPTURE_RETURN_FLAG_ASSIST_TIMEOUT;
}
}
}
}
}
//Back at home!
ResetFlag( pev->team );
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL );
if( pev->team == RED )
WRITE_BYTE( RED_FLAG_RETURNED_PLAYER );
else if( pev->team == BLUE )
WRITE_BYTE( BLUE_FLAG_RETURNED_PLAYER );
WRITE_STRING( STRING( pToucher->pev->netname ) );
MESSAGE_END();
// Remove this one
UTIL_Remove( this );
return;
}
// Not Dropped, means it's the one in our base
else
{
// We have the enemy flag!
// Capture it!
if( pPlayer->m_bHasFlag )
{
if( pev->team == RED )
Capture( pPlayer, BLUE );
else if( pev->team == BLUE )
Capture( pPlayer, RED );
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE,
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero,
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 1, 0 );
return;
}
}
}
else
{
if( Dropped )
{
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL );
if( pev->team == RED )
WRITE_BYTE( RED_FLAG_STOLEN );
else if( pev->team == BLUE )
WRITE_BYTE( BLUE_FLAG_STOLEN );
WRITE_STRING( STRING( pToucher->pev->netname ) );
MESSAGE_END();
pPlayer->m_bHasFlag = TRUE;
CBaseEntity *pEnt = NULL;
if( pev->team == RED )
{
pEnt = CBaseEntity::Create( "carried_flag_team1", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Picked_Up_Red_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
else if( pev->team == BLUE )
{
pEnt = CBaseEntity::Create( "carried_flag_team2", pPlayer->pev->origin, pPlayer->pev->angles, pPlayer->edict() );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Picked_Up_Blue_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
CCarriedFlag *pCarriedFlag = (CCarriedFlag *)pEnt;
pCarriedFlag->Owner = pPlayer;
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE,
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero,
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 0, 0 );
UTIL_Remove( this );
}
else
{
pev->effects |= EF_NODRAW;
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL );
if( pev->team == RED )
WRITE_BYTE( RED_FLAG_STOLEN );
else if( pev->team == BLUE )
WRITE_BYTE( BLUE_FLAG_STOLEN );
WRITE_STRING( STRING( pToucher->pev->netname ) );
MESSAGE_END();
pPlayer->m_bHasFlag = TRUE;
pPlayer->m_flCarrierPickupTime = gpGlobals->time + TEAM_CAPTURE_CARRIER_FLAG_SINCE_TIMEOUT;
CBaseEntity *pEnt = NULL;
if( pev->team == RED )
{
pEnt = CBaseEntity::Create( "carried_flag_team1", pev->origin, pev->angles, pPlayer->edict() );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Stole_Red_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
else if( pev->team == BLUE )
{
pEnt = CBaseEntity::Create( "carried_flag_team2", pev->origin, pev->angles, pPlayer->edict() );
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Stole_Blue_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
CCarriedFlag *pCarriedFlag = (CCarriedFlag *)pEnt;
pCarriedFlag->Owner = pPlayer;
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE,
pPlayer->edict(), g_usCarried, 0, (float*)&g_vecZero, (float*)&g_vecZero,
0.0, 0.0, pPlayer->entindex(), pPlayer->pev->team, 0, 0 );
}
( (CThreeWave*)g_pGameRules )->m_flFlagStatusTime = gpGlobals->time + 0.1;
}
}
void CItemFlag::Capture( CBasePlayer *pPlayer, int iTeam )
{
CBaseEntity *pFlag1 = NULL;
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL );
if( iTeam == RED )
WRITE_BYTE( RED_FLAG_CAPTURED );
else if ( iTeam == BLUE )
WRITE_BYTE( BLUE_FLAG_CAPTURED );
WRITE_STRING( STRING( pPlayer->pev->netname ) );
MESSAGE_END();
if( pPlayer->pFlagCarrierKiller )
{
if( pPlayer->m_flFlagCarrierKillTime > gpGlobals->time )
{
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pPlayer->pFlagCarrierKiller->pev->netname ) );
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " gets an assist for fragging the flag carrier!\n" );
pPlayer->pFlagCarrierKiller->AddPoints( TEAM_CAPTURE_FRAG_CARRIER_ASSIST_BONUS, TRUE );
pPlayer->pFlagCarrierKiller = NULL;
pPlayer->m_flFlagCarrierKillTime = 0.0;
}
}
if( pPlayer->pFlagReturner )
{
if( pPlayer->m_flFlagReturnTime > gpGlobals->time )
{
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, STRING( pPlayer->pFlagReturner->pev->netname ) );
UTIL_ClientPrintAll( HUD_PRINTNOTIFY, " gets an assist for returning his flag!\n");
pPlayer->pFlagReturner->AddPoints( TEAM_CAPTURE_RETURN_FLAG_ASSIST_BONUS, TRUE );
pPlayer->pFlagReturner = NULL;
pPlayer->m_flFlagReturnTime = 0.0;
}
}
if( iTeam != pPlayer->pev->team )
{
if( iTeam == RED )
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Captured_Red_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
else
{
UTIL_LogPrintf( "\"%s<%i><%s><%s>\" triggered \"Captured_Blue_Flag\"\n",
STRING( pPlayer->pev->netname ),
GETPLAYERUSERID( pPlayer->edict() ),
GETPLAYERAUTHID( pPlayer->edict() ),
GetTeamName( pPlayer->pev->team ) );
}
}
if( iTeam == RED )
{
( (CThreeWave *)g_pGameRules )->iBlueTeamScore++;
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "carried_flag_team1" ) ) != NULL )
{
if( pFlag1 )
UTIL_Remove( pFlag1 );
}
}
else if( iTeam == BLUE )
{
( (CThreeWave*)g_pGameRules )->iRedTeamScore++;
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "carried_flag_team2" ) ) != NULL )
{
if ( pFlag1 )
UTIL_Remove( pFlag1 );
}
}
pPlayer->m_bHasFlag = FALSE;
pPlayer->AddPoints( TEAM_CAPTURE_CAPTURE_BONUS, TRUE );
for( int i = 1; i <= gpGlobals->maxClients; i++ )
{
CBaseEntity *pTeamMate = UTIL_PlayerByIndex( i );
if( pTeamMate )
{
if( pTeamMate->pev->team == pPlayer->pev->team )
pTeamMate->AddPoints( TEAM_CAPTURE_TEAM_BONUS, TRUE );
}
}
ResetFlag( iTeam );
}
void CItemFlag::Materialize()
{
if ( pev->effects & EF_NODRAW )
{
pev->effects &= ~EF_NODRAW;
pev->effects |= EF_MUZZLEFLASH;
}
PLAYBACK_EVENT_FULL( FEV_GLOBAL | FEV_RELIABLE,
edict(), g_usFlagSpawn, 0, (float*)&g_vecZero, (float*)&g_vecZero,
0.0, 0.0, pev->team, 0, 0, 0 );
Dropped = FALSE;
SetTouch( &CItemFlag::FlagTouch );
SetThink( &CItemFlag::FlagThink );
}
void CItemFlag::ResetFlag( int iTeam )
{
CBaseEntity *pFlag1 = NULL;
if( iTeam == BLUE )
{
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "item_flag_team2" ) ) != NULL )
{
CItemFlag *pFlag2 = (CItemFlag*)pFlag1;
if( pFlag2->Dropped )
continue;
if( pFlag2->pev->effects & EF_NODRAW )
pFlag2->Materialize();
}
}
else if( iTeam == RED )
{
while( ( pFlag1 = UTIL_FindEntityByClassname( pFlag1, "item_flag_team1" ) ) != NULL )
{
CItemFlag *pFlag2 = (CItemFlag*)pFlag1;
if( pFlag2->Dropped )
continue;
if( pFlag2->pev->effects & EF_NODRAW )
pFlag2->Materialize();
}
}
( (CThreeWave*)g_pGameRules )->m_flFlagStatusTime = gpGlobals->time + 0.1;
}
void CItemFlag::FlagThink()
{
if( Dropped )
{
if( m_flDroppedTime <= gpGlobals->time )
{
ResetFlag( pev->team );
MESSAGE_BEGIN( MSG_ALL, gmsgCTFMsgs, NULL );
if( pev->team == RED )
WRITE_BYTE( RED_FLAG_RETURNED );
else if( pev->team == BLUE )
WRITE_BYTE( BLUE_FLAG_RETURNED );
WRITE_STRING( "" );
MESSAGE_END();
UTIL_Remove( this );
return;
}
}
//Using 0.2 just in case we might lag the server.
pev->nextthink = gpGlobals->time + 0.2;
}
void CItemFlag::Precache()
{
PRECACHE_MODEL( "models/flag.mdl" );
PRECACHE_SOUND( "ctf/flagcap.wav" );
PRECACHE_SOUND( "ctf/flagtk.wav" );
PRECACHE_SOUND( "ctf/flagret.wav" );
}
class CItemFlagTeam1 : public CItemFlag
{
void Spawn()
{
pev->classname = MAKE_STRING( "item_flag_team1" );
pev->team = RED;
CItemFlag::Spawn();
}
};
class CItemFlagTeam2 : public CItemFlag
{
void Spawn()
{
pev->classname = MAKE_STRING( "item_flag_team2" );
pev->team = BLUE;
CItemFlag::Spawn();
}
};
LINK_ENTITY_TO_CLASS( item_flag_team1, CItemFlagTeam1 )
LINK_ENTITY_TO_CLASS( ctf_redflag, CItemFlagTeam1 )
LINK_ENTITY_TO_CLASS( item_flag_team2, CItemFlagTeam2 )
LINK_ENTITY_TO_CLASS( ctf_blueflag, CItemFlagTeam2 )
void CCarriedFlag::Spawn()
{
Precache();
SET_MODEL( ENT( pev ), "models/flag.mdl" );
UTIL_SetOrigin( pev, pev->origin );
pev->movetype = MOVETYPE_NONE;
pev->solid = SOLID_NOT;
pev->effects |= EF_NODRAW;
pev->sequence = WAVE_IDLE;
pev->framerate = 1.0;
/*
if( pev->team == RED )
pev->skin = 1;
else if( pev->team == BLUE )
pev->skin = 2;*/
pev->skin = pev->team;
m_iOwnerOldVel = 0;
SetThink( &CCarriedFlag::FlagThink );
pev->nextthink = gpGlobals->time + 0.1;
}
void CCarriedFlag::Precache()
{
PRECACHE_MODEL( "models/flag.mdl" );
}
void CCarriedFlag::FlagThink()
{
// Make it visible
pev->effects &= ~EF_NODRAW;
// And let if follow
pev->aiment = ENT( Owner->pev );
pev->movetype = MOVETYPE_FOLLOW;
// If owner is death or lost flag, remove
if( !Owner->IsAlive() || !Owner->m_bHasFlag )
UTIL_Remove( this );
else
{
// If owners speed is low, go in idle mode
if( Owner->pev->velocity.Length() <= 75 && pev->sequence != WAVE_IDLE )
{
pev->sequence = WAVE_IDLE;
}
// Else let the flag go wild
else if( Owner->pev->velocity.Length() >= 75 && pev->sequence != CARRIED )
{
pev->sequence = CARRIED;
}
pev->frame += pev->framerate;
if( pev->frame < 0.0 || pev->frame >= 256.0 )
{
pev->frame -= (int)( pev->frame / 256.0 ) * 256.0;
}
pev->nextthink = gpGlobals->time + 0.1;
}
}
class CCarriedFlagTeam1 : public CCarriedFlag
{
void Spawn()
{
pev->team = RED;
CCarriedFlag::Spawn();
}
};
class CCarriedFlagTeam2 : public CCarriedFlag
{
void Spawn()
{
pev->team = BLUE;
CCarriedFlag::Spawn();
}
};
LINK_ENTITY_TO_CLASS( carried_flag_team1, CCarriedFlagTeam1 )
LINK_ENTITY_TO_CLASS( carried_flag_team2, CCarriedFlagTeam2 )