diff --git a/entitydata/PointClass/player_percent.json b/entitydata/PointClass/player_percent.json new file mode 100644 index 000000000..1990ade7e --- /dev/null +++ b/entitydata/PointClass/player_percent.json @@ -0,0 +1,37 @@ +{ + "player_percent": + { + "atributes": + { + "base": "Target", + "title": "Trigger when meet percent", + "description": "Triggers it's target when the percentage of players that fires this entity is greater than 'Percentage required'" + }, + "message": + { + "title": "Fire for each player", + "type": "target_destination", + "description": "Fires this target passing the given activator player, this is done only once per player." + }, + "iuser1": + { + "title": "Percentage required", + "default": "66", + "type": "integer", + "description": "Requires this percentage of players to trigger this entity before firing 'target'" + }, + "spawnflags": + { + "1": { + "title": "Reset on fire", + "description": "After firing it's target, if this flag is set the entity is restored to it's initial state, else the entity is removed from the world" + } + }, + "target": + { + "title": "Fire after action", + "type": "target_destination", + "description": "Fires this target after this entity has been triggered for the Percentage required of players" + } + } +} diff --git a/src/game/server/entities/player_entities.cpp b/src/game/server/entities/player_entities.cpp index de7facefb..6aa93d399 100644 --- a/src/game/server/entities/player_entities.cpp +++ b/src/game/server/entities/player_entities.cpp @@ -657,4 +657,81 @@ void CPlayerCommand :: Use( CBaseEntity* pActivator, CBaseEntity* pCaller, USE_T { FireTargets( STRING( pev->target ), pActivator, this, USE_TOGGLE, 0 ); } -} \ No newline at end of file +} + +#define SF_PPERCENT_RESET ( 1 << 0 ) + +class CPlayerPercent : public CPointEntity +{ + public: + void Spawn() override; + bool CanFire( CBasePlayer* pPlayer ); + void Use( CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value ) override; +}; + +LINK_ENTITY_TO_CLASS( player_percent, CPlayerPercent ); + +void CPlayerPercent :: Spawn() +{ + pev->solid = SOLID_NOT; + + pev->iuser1 = ( pev->iuser1 <= 0 ? 66 : pev->iuser1 ); + pev->iuser2 = 0; +} + +bool CPlayerPercent :: CanFire( CBasePlayer* pPlayer ) +{ + if( pPlayer && pPlayer->IsPlayer() ) + { + return true; + } + return false; +} + +void CPlayerPercent :: Use( CBaseEntity* pActivator, CBaseEntity* pCaller, USE_TYPE useType, float value ) +{ + auto player = ToBasePlayer( pActivator ); + + if( CanFire( player ) ) + { + if( !FStringNull( pev->message ) ) + { + FireTargets( STRING( pev->message ), player, this, USE_TOGGLE, 0 ); + } + pev->iuser2++; + } + + int iPlayers = 0; + + for( auto pPlayer : UTIL_FindPlayers() ) + { + if( pPlayer && pPlayer->IsPlayer() && pPlayer->IsConnected() ) + { + iPlayers++; + } + } + + if( iPlayers > 0 ) + { + float fPlayersTriggered = pev->iuser2; + + float CurrentPercentage = ( fPlayersTriggered / iPlayers ) * 100; + + if( CurrentPercentage >= pev->iuser1 ) + { + if( !FStringNull( pev->target ) ) + { + FireTargets( STRING( pev->target ), this, this, USE_TOGGLE, 0 ); + } + + if( FBitSet( pev->spawnflags, SF_PPERCENT_RESET ) ) + { + pev->iuser2 = 0; + } + else + { + UTIL_Remove( this ); + } + } + } +}