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.
736 lines
17 KiB
736 lines
17 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Contains entities for implementing/changing game rules dynamically within each BSP. |
|
// |
|
//=============================================================================// |
|
|
|
#include "cbase.h" |
|
#include "datamap.h" |
|
#include "gamerules.h" |
|
#include "maprules.h" |
|
#include "player.h" |
|
#include "entitylist.h" |
|
#include "ai_hull.h" |
|
#include "entityoutput.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
class CRuleEntity : public CBaseEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CRuleEntity, CBaseEntity ); |
|
|
|
void Spawn( void ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
void SetMaster( string_t iszMaster ) { m_iszMaster = iszMaster; } |
|
|
|
protected: |
|
bool CanFireForActivator( CBaseEntity *pActivator ); |
|
|
|
private: |
|
string_t m_iszMaster; |
|
}; |
|
|
|
BEGIN_DATADESC( CRuleEntity ) |
|
|
|
DEFINE_KEYFIELD( m_iszMaster, FIELD_STRING, "master" ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
|
|
void CRuleEntity::Spawn( void ) |
|
{ |
|
SetSolid( SOLID_NONE ); |
|
SetMoveType( MOVETYPE_NONE ); |
|
AddEffects( EF_NODRAW ); |
|
} |
|
|
|
|
|
bool CRuleEntity::CanFireForActivator( CBaseEntity *pActivator ) |
|
{ |
|
if ( m_iszMaster != NULL_STRING ) |
|
{ |
|
if ( UTIL_IsMasterTriggered( m_iszMaster, pActivator ) ) |
|
return true; |
|
else |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
// |
|
// CRulePointEntity -- base class for all rule "point" entities (not brushes) |
|
// |
|
class CRulePointEntity : public CRuleEntity |
|
{ |
|
public: |
|
DECLARE_DATADESC(); |
|
DECLARE_CLASS( CRulePointEntity, CRuleEntity ); |
|
|
|
int m_Score; |
|
void Spawn( void ); |
|
}; |
|
|
|
//--------------------------------------------------------- |
|
// Save/Restore |
|
//--------------------------------------------------------- |
|
BEGIN_DATADESC( CRulePointEntity ) |
|
|
|
DEFINE_FIELD( m_Score, FIELD_INTEGER ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
void CRulePointEntity::Spawn( void ) |
|
{ |
|
BaseClass::Spawn(); |
|
SetModelName( NULL_STRING ); |
|
m_Score = 0; |
|
} |
|
|
|
// |
|
// CRuleBrushEntity -- base class for all rule "brush" entities (not brushes) |
|
// Default behavior is to set up like a trigger, invisible, but keep the model for volume testing |
|
// |
|
class CRuleBrushEntity : public CRuleEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CRuleBrushEntity, CRuleEntity ); |
|
|
|
void Spawn( void ); |
|
|
|
private: |
|
}; |
|
|
|
void CRuleBrushEntity::Spawn( void ) |
|
{ |
|
SetModel( STRING( GetModelName() ) ); |
|
BaseClass::Spawn(); |
|
} |
|
|
|
|
|
// CGameScore / game_score -- award points to player / team |
|
// Points +/- total |
|
// Flag: Allow negative scores SF_SCORE_NEGATIVE |
|
// Flag: Award points to team in teamplay SF_SCORE_TEAM |
|
|
|
#define SF_SCORE_NEGATIVE 0x0001 |
|
#define SF_SCORE_TEAM 0x0002 |
|
|
|
class CGameScore : public CRulePointEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGameScore, CRulePointEntity ); |
|
DECLARE_DATADESC(); |
|
|
|
void Spawn( void ); |
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
bool KeyValue( const char *szKeyName, const char *szValue ); |
|
|
|
inline int Points( void ) { return m_Score; } |
|
inline bool AllowNegativeScore( void ) { return m_spawnflags & SF_SCORE_NEGATIVE; } |
|
inline int AwardToTeam( void ) { return (m_spawnflags & SF_SCORE_TEAM); } |
|
|
|
inline void SetPoints( int points ) { m_Score = points; } |
|
|
|
void InputApplyScore( inputdata_t &inputdata ); |
|
|
|
private: |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_score, CGameScore ); |
|
|
|
BEGIN_DATADESC( CGameScore ) |
|
// Inputs |
|
DEFINE_INPUTFUNC( FIELD_VOID, "ApplyScore", InputApplyScore ), |
|
END_DATADESC() |
|
|
|
void CGameScore::Spawn( void ) |
|
{ |
|
int iScore = Points(); |
|
BaseClass::Spawn(); |
|
SetPoints( iScore ); |
|
} |
|
|
|
|
|
bool CGameScore::KeyValue( const char *szKeyName, const char *szValue ) |
|
{ |
|
if (FStrEq(szKeyName, "points")) |
|
{ |
|
SetPoints( atoi(szValue) ); |
|
} |
|
else |
|
return BaseClass::KeyValue( szKeyName, szValue ); |
|
|
|
return true; |
|
} |
|
|
|
void CGameScore::InputApplyScore( inputdata_t &inputdata ) |
|
{ |
|
CBaseEntity *pActivator = inputdata.pActivator; |
|
|
|
if ( pActivator == NULL ) |
|
return; |
|
|
|
if ( CanFireForActivator( pActivator ) == false ) |
|
return; |
|
|
|
// Only players can use this |
|
if ( pActivator->IsPlayer() ) |
|
{ |
|
if ( AwardToTeam() ) |
|
{ |
|
pActivator->AddPointsToTeam( Points(), AllowNegativeScore() ); |
|
} |
|
else |
|
{ |
|
pActivator->AddPoints( Points(), AllowNegativeScore() ); |
|
} |
|
} |
|
} |
|
|
|
void CGameScore::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
if ( !CanFireForActivator( pActivator ) ) |
|
return; |
|
|
|
// Only players can use this |
|
if ( pActivator->IsPlayer() ) |
|
{ |
|
if ( AwardToTeam() ) |
|
{ |
|
pActivator->AddPointsToTeam( Points(), AllowNegativeScore() ); |
|
} |
|
else |
|
{ |
|
pActivator->AddPoints( Points(), AllowNegativeScore() ); |
|
} |
|
} |
|
} |
|
|
|
|
|
// CGameEnd / game_end -- Ends the game in MP |
|
|
|
class CGameEnd : public CRulePointEntity |
|
{ |
|
DECLARE_CLASS( CGameEnd, CRulePointEntity ); |
|
|
|
public: |
|
DECLARE_DATADESC(); |
|
|
|
void InputGameEnd( inputdata_t &inputdata ); |
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
private: |
|
}; |
|
|
|
BEGIN_DATADESC( CGameEnd ) |
|
|
|
// inputs |
|
DEFINE_INPUTFUNC( FIELD_VOID, "EndGame", InputGameEnd ), |
|
|
|
END_DATADESC() |
|
|
|
LINK_ENTITY_TO_CLASS( game_end, CGameEnd ); |
|
|
|
|
|
void CGameEnd::InputGameEnd( inputdata_t &inputdata ) |
|
{ |
|
g_pGameRules->EndMultiplayerGame(); |
|
} |
|
|
|
void CGameEnd::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
if ( !CanFireForActivator( pActivator ) ) |
|
return; |
|
|
|
g_pGameRules->EndMultiplayerGame(); |
|
} |
|
|
|
|
|
// |
|
// CGameText / game_text -- NON-Localized HUD Message (use env_message to display a titles.txt message) |
|
// Flag: All players SF_ENVTEXT_ALLPLAYERS |
|
// |
|
#define SF_ENVTEXT_ALLPLAYERS 0x0001 |
|
|
|
|
|
class CGameText : public CRulePointEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGameText, CRulePointEntity ); |
|
|
|
bool KeyValue( const char *szKeyName, const char *szValue ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
inline bool MessageToAll( void ) { return (m_spawnflags & SF_ENVTEXT_ALLPLAYERS); } |
|
inline void MessageSet( const char *pMessage ) { m_iszMessage = AllocPooledString(pMessage); } |
|
inline const char *MessageGet( void ) { return STRING( m_iszMessage ); } |
|
|
|
void InputDisplay( inputdata_t &inputdata ); |
|
void Display( CBaseEntity *pActivator ); |
|
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
Display( pActivator ); |
|
} |
|
|
|
private: |
|
|
|
string_t m_iszMessage; |
|
hudtextparms_t m_textParms; |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_text, CGameText ); |
|
|
|
// Save parms as a block. Will break save/restore if the structure changes, but this entity didn't ship with Half-Life, so |
|
// it can't impact saved Half-Life games. |
|
BEGIN_DATADESC( CGameText ) |
|
|
|
DEFINE_KEYFIELD( m_iszMessage, FIELD_STRING, "message" ), |
|
|
|
DEFINE_KEYFIELD( m_textParms.channel, FIELD_INTEGER, "channel" ), |
|
DEFINE_KEYFIELD( m_textParms.x, FIELD_FLOAT, "x" ), |
|
DEFINE_KEYFIELD( m_textParms.y, FIELD_FLOAT, "y" ), |
|
DEFINE_KEYFIELD( m_textParms.effect, FIELD_INTEGER, "effect" ), |
|
DEFINE_KEYFIELD( m_textParms.fadeinTime, FIELD_FLOAT, "fadein" ), |
|
DEFINE_KEYFIELD( m_textParms.fadeoutTime, FIELD_FLOAT, "fadeout" ), |
|
DEFINE_KEYFIELD( m_textParms.holdTime, FIELD_FLOAT, "holdtime" ), |
|
DEFINE_KEYFIELD( m_textParms.fxTime, FIELD_FLOAT, "fxtime" ), |
|
|
|
DEFINE_ARRAY( m_textParms, FIELD_CHARACTER, sizeof(hudtextparms_t) ), |
|
|
|
// Inputs |
|
DEFINE_INPUTFUNC( FIELD_VOID, "Display", InputDisplay ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
|
|
bool CGameText::KeyValue( const char *szKeyName, const char *szValue ) |
|
{ |
|
if (FStrEq(szKeyName, "color")) |
|
{ |
|
int color[4]; |
|
UTIL_StringToIntArray( color, 4, szValue ); |
|
m_textParms.r1 = color[0]; |
|
m_textParms.g1 = color[1]; |
|
m_textParms.b1 = color[2]; |
|
m_textParms.a1 = color[3]; |
|
} |
|
else if (FStrEq(szKeyName, "color2")) |
|
{ |
|
int color[4]; |
|
UTIL_StringToIntArray( color, 4, szValue ); |
|
m_textParms.r2 = color[0]; |
|
m_textParms.g2 = color[1]; |
|
m_textParms.b2 = color[2]; |
|
m_textParms.a2 = color[3]; |
|
} |
|
else |
|
return BaseClass::KeyValue( szKeyName, szValue ); |
|
|
|
return true; |
|
} |
|
|
|
|
|
void CGameText::InputDisplay( inputdata_t &inputdata ) |
|
{ |
|
Display( inputdata.pActivator ); |
|
} |
|
|
|
void CGameText::Display( CBaseEntity *pActivator ) |
|
{ |
|
if ( !CanFireForActivator( pActivator ) ) |
|
return; |
|
|
|
if ( MessageToAll() ) |
|
{ |
|
UTIL_HudMessageAll( m_textParms, MessageGet() ); |
|
} |
|
else |
|
{ |
|
// If we're in singleplayer, show the message to the player. |
|
if ( gpGlobals->maxClients == 1 ) |
|
{ |
|
CBasePlayer *pPlayer = UTIL_GetLocalPlayer(); |
|
UTIL_HudMessage( pPlayer, m_textParms, MessageGet() ); |
|
} |
|
// Otherwise show the message to the player that triggered us. |
|
else if ( pActivator && pActivator->IsNetClient() ) |
|
{ |
|
UTIL_HudMessage( ToBasePlayer( pActivator ), m_textParms, MessageGet() ); |
|
} |
|
} |
|
} |
|
|
|
|
|
/* TODO: Replace with an entity I/O version |
|
// |
|
// CGameTeamSet / game_team_set -- Changes the team of the entity it targets to the activator's team |
|
// Flag: Fire once |
|
// Flag: Clear team -- Sets the team to "NONE" instead of activator |
|
|
|
#define SF_TEAMSET_FIREONCE 0x0001 |
|
#define SF_TEAMSET_CLEARTEAM 0x0002 |
|
|
|
class CGameTeamSet : public CRulePointEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGameTeamSet, CRulePointEntity ); |
|
|
|
inline bool RemoveOnFire( void ) { return (m_spawnflags & SF_TEAMSET_FIREONCE) ? true : false; } |
|
inline bool ShouldClearTeam( void ) { return (m_spawnflags & SF_TEAMSET_CLEARTEAM) ? true : false; } |
|
void InputTrigger( inputdata_t &inputdata ); |
|
|
|
private: |
|
COutputEvent m_OnTrigger; |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_team_set, CGameTeamSet ); |
|
|
|
|
|
void CGameTeamSet::InputTrigger( inputdata_t &inputdata ) |
|
{ |
|
if ( !CanFireForActivator( inputdata.pActivator ) ) |
|
return; |
|
|
|
if ( ShouldClearTeam() ) |
|
{ |
|
// clear the team of our target |
|
} |
|
else |
|
{ |
|
// set the team of our target to our activator's team |
|
} |
|
|
|
m_OnTrigger.FireOutput(pActivator, this); |
|
|
|
if ( RemoveOnFire() ) |
|
{ |
|
UTIL_Remove( this ); |
|
} |
|
} |
|
*/ |
|
|
|
|
|
// |
|
// CGamePlayerZone / game_player_zone -- players in the zone fire my target when I'm fired |
|
// |
|
// Needs master? |
|
class CGamePlayerZone : public CRuleBrushEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGamePlayerZone, CRuleBrushEntity ); |
|
void InputCountPlayersInZone( inputdata_t &inputdata ); |
|
|
|
DECLARE_DATADESC(); |
|
|
|
private: |
|
|
|
COutputEvent m_OnPlayerInZone; |
|
COutputEvent m_OnPlayerOutZone; |
|
|
|
COutputInt m_PlayersInCount; |
|
COutputInt m_PlayersOutCount; |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_zone_player, CGamePlayerZone ); |
|
BEGIN_DATADESC( CGamePlayerZone ) |
|
|
|
// Inputs |
|
DEFINE_INPUTFUNC(FIELD_VOID, "CountPlayersInZone", InputCountPlayersInZone), |
|
|
|
// Outputs |
|
DEFINE_OUTPUT(m_OnPlayerInZone, "OnPlayerInZone"), |
|
DEFINE_OUTPUT(m_OnPlayerOutZone, "OnPlayerOutZone"), |
|
DEFINE_OUTPUT(m_PlayersInCount, "PlayersInCount"), |
|
DEFINE_OUTPUT(m_PlayersOutCount, "PlayersOutCount"), |
|
|
|
END_DATADESC() |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Counts all the players in the zone. Fires one output per player |
|
// in the zone, one output per player out of the zone, and outputs |
|
// with the total counts of players in and out of the zone. |
|
//----------------------------------------------------------------------------- |
|
void CGamePlayerZone::InputCountPlayersInZone( inputdata_t &inputdata ) |
|
{ |
|
int playersInCount = 0; |
|
int playersOutCount = 0; |
|
|
|
if ( !CanFireForActivator( inputdata.pActivator ) ) |
|
return; |
|
|
|
CBaseEntity *pPlayer = NULL; |
|
|
|
for ( int i = 1; i <= gpGlobals->maxClients; i++ ) |
|
{ |
|
pPlayer = UTIL_PlayerByIndex( i ); |
|
if ( pPlayer ) |
|
{ |
|
trace_t trace; |
|
Hull_t hullType; |
|
|
|
hullType = HULL_HUMAN; |
|
if ( pPlayer->GetFlags() & FL_DUCKING ) |
|
{ |
|
hullType = HULL_SMALL_CENTERED; |
|
} |
|
|
|
UTIL_TraceModel( pPlayer->GetAbsOrigin(), pPlayer->GetAbsOrigin(), NAI_Hull::Mins(hullType), |
|
NAI_Hull::Maxs(hullType), this, COLLISION_GROUP_NONE, &trace ); |
|
|
|
if ( trace.startsolid ) |
|
{ |
|
playersInCount++; |
|
m_OnPlayerInZone.FireOutput(pPlayer, this); |
|
} |
|
else |
|
{ |
|
playersOutCount++; |
|
m_OnPlayerOutZone.FireOutput(pPlayer, this); |
|
} |
|
} |
|
} |
|
|
|
m_PlayersInCount.Set(playersInCount, inputdata.pActivator, this); |
|
m_PlayersOutCount.Set(playersOutCount, inputdata.pActivator, this); |
|
} |
|
|
|
|
|
/* |
|
// Disable. Eventually will be replace by new activator filter entities. (LHL) |
|
// |
|
// CGamePlayerHurt / game_player_hurt -- Damages the player who fires it |
|
// Flag: Fire once |
|
|
|
#define SF_PKILL_FIREONCE 0x0001 |
|
class CGamePlayerHurt : public CRulePointEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGamePlayerHurt, CRulePointEntity ); |
|
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
inline bool RemoveOnFire( void ) { return (m_spawnflags & SF_PKILL_FIREONCE) ? true : false; } |
|
|
|
DECLARE_DATADESC(); |
|
|
|
private: |
|
|
|
float m_flDamage; // Damage to inflict, negative values give health. |
|
|
|
COutputEvent m_OnUse; |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_player_hurt, CGamePlayerHurt ); |
|
|
|
|
|
BEGIN_DATADESC( CGamePlayerHurt ) |
|
|
|
DEFINE_KEYFIELD( m_flDamage, FIELD_FLOAT, "dmg" ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
|
|
void CGamePlayerHurt::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
if ( !CanFireForActivator( pActivator ) ) |
|
return; |
|
|
|
if ( pActivator->IsPlayer() ) |
|
{ |
|
if ( m_flDamage < 0 ) |
|
{ |
|
pActivator->TakeHealth( -m_flDamage, DMG_GENERIC ); |
|
} |
|
else |
|
{ |
|
pActivator->TakeDamage( this, this, m_flDamage, DMG_GENERIC ); |
|
} |
|
} |
|
|
|
SUB_UseTargets( pActivator, useType, value ); |
|
m_OnUse.FireOutput(pActivator, this); // dvsents2: handle useType and value here - they are passed through |
|
|
|
if ( RemoveOnFire() ) |
|
{ |
|
UTIL_Remove( this ); |
|
} |
|
} |
|
*/ |
|
|
|
// |
|
// CGamePlayerEquip / game_playerequip -- Sets the default player equipment |
|
// Flag: USE Only |
|
|
|
#define SF_PLAYEREQUIP_USEONLY 0x0001 |
|
#define MAX_EQUIP 32 |
|
|
|
class CGamePlayerEquip : public CRulePointEntity |
|
{ |
|
DECLARE_DATADESC(); |
|
|
|
public: |
|
DECLARE_CLASS( CGamePlayerEquip, CRulePointEntity ); |
|
|
|
bool KeyValue( const char *szKeyName, const char *szValue ); |
|
void Touch( CBaseEntity *pOther ); |
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
|
|
inline bool UseOnly( void ) { return (m_spawnflags & SF_PLAYEREQUIP_USEONLY) ? true : false; } |
|
|
|
private: |
|
|
|
void EquipPlayer( CBaseEntity *pPlayer ); |
|
|
|
string_t m_weaponNames[MAX_EQUIP]; |
|
int m_weaponCount[MAX_EQUIP]; |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_player_equip, CGamePlayerEquip ); |
|
|
|
//--------------------------------------------------------- |
|
// Save/Restore |
|
//--------------------------------------------------------- |
|
BEGIN_DATADESC( CGamePlayerEquip ) |
|
|
|
DEFINE_AUTO_ARRAY( m_weaponNames, FIELD_STRING ), |
|
DEFINE_AUTO_ARRAY( m_weaponCount, FIELD_INTEGER ), |
|
|
|
END_DATADESC() |
|
|
|
|
|
|
|
|
|
bool CGamePlayerEquip::KeyValue( const char *szKeyName, const char *szValue ) |
|
{ |
|
if ( !BaseClass::KeyValue( szKeyName, szValue ) ) |
|
{ |
|
for ( int i = 0; i < MAX_EQUIP; i++ ) |
|
{ |
|
if ( !m_weaponNames[i] ) |
|
{ |
|
char tmp[128]; |
|
UTIL_StripToken( szKeyName, tmp, Q_ARRAYSIZE( tmp ) ); |
|
|
|
m_weaponNames[i] = AllocPooledString(tmp); |
|
m_weaponCount[i] = atoi(szValue); |
|
m_weaponCount[i] = MAX(1,m_weaponCount[i]); |
|
return true; |
|
} |
|
} |
|
} |
|
|
|
return false; |
|
} |
|
|
|
|
|
void CGamePlayerEquip::Touch( CBaseEntity *pOther ) |
|
{ |
|
if ( !CanFireForActivator( pOther ) ) |
|
return; |
|
|
|
if ( UseOnly() ) |
|
return; |
|
|
|
EquipPlayer( pOther ); |
|
} |
|
|
|
void CGamePlayerEquip::EquipPlayer( CBaseEntity *pEntity ) |
|
{ |
|
CBasePlayer *pPlayer = ToBasePlayer(pEntity); |
|
|
|
if ( !pPlayer ) |
|
return; |
|
|
|
for ( int i = 0; i < MAX_EQUIP; i++ ) |
|
{ |
|
if ( !m_weaponNames[i] ) |
|
break; |
|
for ( int j = 0; j < m_weaponCount[i]; j++ ) |
|
{ |
|
pPlayer->GiveNamedItem( STRING(m_weaponNames[i]) ); |
|
} |
|
} |
|
} |
|
|
|
|
|
void CGamePlayerEquip::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
EquipPlayer( pActivator ); |
|
} |
|
|
|
|
|
// |
|
// CGamePlayerTeam / game_player_team -- Changes the team of the player who fired it |
|
// Flag: Fire once |
|
// Flag: Kill Player |
|
// Flag: Gib Player |
|
|
|
#define SF_PTEAM_FIREONCE 0x0001 |
|
#define SF_PTEAM_KILL 0x0002 |
|
#define SF_PTEAM_GIB 0x0004 |
|
|
|
class CGamePlayerTeam : public CRulePointEntity |
|
{ |
|
public: |
|
DECLARE_CLASS( CGamePlayerTeam, CRulePointEntity ); |
|
|
|
void Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ); |
|
|
|
private: |
|
|
|
inline bool RemoveOnFire( void ) { return (m_spawnflags & SF_PTEAM_FIREONCE) ? true : false; } |
|
inline bool ShouldKillPlayer( void ) { return (m_spawnflags & SF_PTEAM_KILL) ? true : false; } |
|
inline bool ShouldGibPlayer( void ) { return (m_spawnflags & SF_PTEAM_GIB) ? true : false; } |
|
|
|
const char *TargetTeamName( const char *pszTargetName, CBaseEntity *pActivator ); |
|
}; |
|
|
|
LINK_ENTITY_TO_CLASS( game_player_team, CGamePlayerTeam ); |
|
|
|
|
|
const char *CGamePlayerTeam::TargetTeamName( const char *pszTargetName, CBaseEntity *pActivator ) |
|
{ |
|
CBaseEntity *pTeamEntity = NULL; |
|
|
|
while ((pTeamEntity = gEntList.FindEntityByName( pTeamEntity, pszTargetName, NULL, pActivator )) != NULL) |
|
{ |
|
if ( FClassnameIs( pTeamEntity, "game_team_master" ) ) |
|
return pTeamEntity->TeamID(); |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
|
|
void CGamePlayerTeam::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) |
|
{ |
|
if ( !CanFireForActivator( pActivator ) ) |
|
return; |
|
|
|
if ( pActivator->IsPlayer() ) |
|
{ |
|
const char *pszTargetTeam = TargetTeamName( STRING(m_target), pActivator ); |
|
if ( pszTargetTeam ) |
|
{ |
|
CBasePlayer *pPlayer = (CBasePlayer *)pActivator; |
|
g_pGameRules->ChangePlayerTeam( pPlayer, pszTargetTeam, ShouldKillPlayer(), ShouldGibPlayer() ); |
|
} |
|
} |
|
|
|
if ( RemoveOnFire() ) |
|
{ |
|
UTIL_Remove( this ); |
|
} |
|
} |
|
|
|
|
|
|