PHP Code:
#define BONUS
#define LOGS
#define START_DISTANCE 32
#define MAX_ATTEMPTS 128
#include < amxmodx >
#include < hamsandwich >
#include < fakemeta >
#include < fun >
#include < engine >
/*================================================================================
[Start...]
=================================================================================*/
enum Coord_e { Float:x, Float:y, Float:z }
enum CsTeams
{
CS_TEAM_UNASSIGNED = 0,
CS_TEAM_T = 1,
CS_TEAM_CT = 2,
CS_TEAM_SPECTATOR = 3
}
#define TASK_TEAM 59813
#define ID_TEAM (taskid - TASK_TEAM)
new const CS_TEAM_NAMES[ ][ ] = { "UNASSIGNED", "TERRORIST", "CT", "SPECTATOR" }
#define GetPlayerHullSize(%1) ( ( pev ( %1, pev_flags ) & FL_DUCKING ) ? HULL_HEAD : HULL_HUMAN )
#define IsPlayer(%1) ( 1 <= %1 <= g_iMaxPlayers )
#define DMG_FALL (1<<5)
new Float:g_fTeamsUpdates
new g_iMaxPlayers
new g_iMsgTeamInfo
new g_iHamCZbots
new g_iMsgSayText
new g_iIsNewTs[ 33 ], g_iIsAlive[ 33 ], g_iIsConnected[ 33 ]
#if defined BONUS
new g_iMsgScoreInfo
#endif
new g_pBotQuota
new g_iOrigin[ 33 ][ 3 ]
/*================================================================================
[Init]
=================================================================================*/
public plugin_init()
{
register_plugin( "[DR] FIX Round", "1.0", "P.Of.Pw" )
register_cvar( "dr_fixround", "1.0/P.Of.Pw", FCVAR_SERVER | FCVAR_SPONLY )
RegisterHam( Ham_Spawn, "player", "fw_PlayerSpawn_Post", 1 )
RegisterHam( Ham_Killed, "player", "fw_PlayerKilled" )
RegisterHam( Ham_TakeDamage, "player", "fw_TakeDamage" )
register_forward( FM_ClientDisconnect, "fw_ClientDisconnect" )
g_iMaxPlayers = get_maxplayers()
g_iMsgTeamInfo = get_user_msgid( "TeamInfo" )
g_iMsgSayText = get_user_msgid( "SayText" )
g_iMsgScoreInfo = get_user_msgid( "ScoreInfo" )
g_pBotQuota = get_cvar_pointer( "bot_quota" )
}
/*================================================================================
[Client put in server]
=================================================================================*/
public client_putinserver( id )
{
g_iIsConnected[ id ] = true
if( is_user_bot( id ) )
{
if( !g_iHamCZbots && g_pBotQuota )
{
set_task( 0.1, "register_ham_czbots", id )
}
}
}
/*================================================================================
[Register Ham forwards for CZ bots]
=================================================================================*/
public register_ham_czbots( id )
{
if( g_iHamCZbots || !is_user_connected( id ) || !get_pcvar_num( g_pBotQuota ) )
return;
RegisterHamFromEntity( Ham_Spawn, id, "fw_PlayerSpawn_Post", 1 )
RegisterHamFromEntity( Ham_Killed, id, "fw_PlayerKilled" )
RegisterHamFromEntity( Ham_TakeDamage, id, "fw_TakeDamage" )
g_iHamCZbots = true
if( is_user_alive( id ) ) fw_PlayerSpawn_Post( id )
}
/*================================================================================
[Ham player spawn post forward]
=================================================================================*/
public fw_PlayerSpawn_Post( id )
{
if( !is_user_alive( id ) || !fm_cs_get_user_team( id ) )
return;
g_iIsAlive[ id ] = true
remove_task( id+TASK_TEAM )
}
/*================================================================================
[Ham player killed forward]
=================================================================================*/
public fw_PlayerKilled( victim )
{
g_iIsAlive[ victim ] = false
}
/*================================================================================
[Ham player damage forward]
=================================================================================*/
public fw_TakeDamage( id, inflictor, attacker, Float:damage, damage_type )
{
if( g_iIsNewTs[ id ] && ( damage_type & DMG_FALL ) )
{
g_iIsNewTs[ id ] = false
return HAM_SUPERCEDE
}
return HAM_IGNORED
}
/*================================================================================
[Eng get user origin] ; not very good method ;(
=================================================================================*/
public client_PreThink( id )
{
if( !g_iIsAlive[ id ] )
return;
get_user_origin( id, g_iOrigin[ id ] )
}
/*================================================================================
[Fm client disconnecting]
=================================================================================*/
public fw_ClientDisconnect( id )
{
if( g_iIsAlive[ id ] ) check_round( id )
remove_task( id+TASK_TEAM )
g_iIsAlive[ id ] = false
g_iIsConnected[ id ] = false
}
/*================================================================================
[Set new Ts]
=================================================================================*/
public check_round( leaving_player )
{
static iPlayersnum, id
iPlayersnum = fnGetPlaying()
if( iPlayersnum < 2 )
return;
new iTnum = fnGetTeamCount( CS_TEAM_T )
new iCTnum = fnGetTeamCount( CS_TEAM_CT )
if( iTnum < 1 )
{
if( iCTnum == 1 )
return;
id = fnGetRandomPlayer()
if( !is_user_alive( id ) )
ExecuteHamB( Ham_CS_RoundRespawn, id )
set_terrorist_team( id )
g_iIsNewTs[ id ] = true
DispatchSpawn( id )
g_iOrigin[ leaving_player ][ 2 ] += 20
set_user_origin( id, g_iOrigin[ leaving_player ] )
new name[ 32 ]
get_user_name( id, name, 31 )
static Float:newOrigin[ 3 ]
entity_get_vector( id, EV_VEC_origin, newOrigin )
IVecFVec( g_iOrigin[ id ], newOrigin )
if( IsUserStuck( id, newOrigin, entity_get_int( id, EV_INT_flags ) ) )
{
UTIL_UnstickPlayer( id, START_DISTANCE, MAX_ATTEMPTS )
}
ColorChatSimple( 0, "^4[DR] ^3%s ^1este terrorist nou!", name )
#if defined BONUS
set_user_frags( id, get_user_frags( id ) + 10 )
set_user_frags_update( id )
#endif
#if defined LOGS
static buffer[ 200 ]
new name_leav[ 32 ]
get_user_name( leaving_player, name_leav, 31 )
formatex( buffer, charsmax( buffer ), "%s a fost mutat la Ts, deoarece %s s-a deconectat!", name, name_leav )
log_to_file( "dr_last_t_disc.txt", buffer )
#endif
}
}
/*================================================================================
[Fn stocks]
=================================================================================*/
fnGetPlaying()
{
static iPlaying, id, CsTeams:team
iPlaying = 0
for( id = 1; id <= g_iMaxPlayers; id++ )
{
if( g_iIsConnected[ id ] && IsPlayer( id ) )
{
team = fm_cs_get_user_team( id )
if( team != CS_TEAM_UNASSIGNED && team != CS_TEAM_SPECTATOR )
iPlaying++
}
}
return iPlaying;
}
fnGetRandomPlayer( const flags[ ] = "", const teamORname[ ] = "" )
{
new players[ 32 ], pnum
get_players( players, pnum, flags, teamORname )
return ( pnum > 0 ) ? players[ random( pnum ) ] : 0
}
fnGetTeamCount( CsTeams:iTeam )
{
new iPlayers[ 32 ], iPlayerCount
new iTeamPlayers[ CsTeams ]
get_players( iPlayers, iPlayerCount )
for ( new i = 0; i < iPlayerCount; i++ )
iTeamPlayers[ fm_cs_get_user_team( iPlayers[ i ] ) ]++
return iTeamPlayers[ iTeam ]
}
/*================================================================================
[......]
=================================================================================*/
set_terrorist_team( id )
{
if( fm_cs_get_user_team( id ) != CS_TEAM_T )
{
remove_task( id+TASK_TEAM )
fm_cs_set_user_team( id, CS_TEAM_T )
user_team_update( id )
}
}
ColorChatSimple( id, const message[ ], any:...)
{
new Buffer[ 512 ], bBuffer[ 512 ]
formatex( bBuffer, charsmax( bBuffer ), "%s", message )
vformat( Buffer, charsmax( Buffer ), bBuffer, 3 )
new MSG_TARGET = id ? MSG_ONE : MSG_ALL
message_begin( MSG_TARGET, g_iMsgSayText, .player = MSG_TARGET )
{
write_byte( id ? id : 1 )
write_string( Buffer )
}
message_end()
}
/*================================================================================
[Stocks]
=================================================================================*/
stock CsTeams:fm_cs_get_user_team( id )
{
return CsTeams:get_pdata_int( id, 114, 5 )
}
stock fm_cs_set_user_team( id, { CsTeams, _ }:team )
{
set_pdata_int( id, 114, _:team, 5 )
}
stock user_team_update( id )
{
static Float:current_time
current_time = get_gametime()
if( current_time - g_fTeamsUpdates >= 0.1 )
{
set_task( 0.1, "set_user_team_msg", id+TASK_TEAM )
g_fTeamsUpdates = current_time + 0.1
}
else
{
set_task( ( g_fTeamsUpdates + 0.1 ) - current_time, "set_user_team_msg", id+TASK_TEAM )
g_fTeamsUpdates = g_fTeamsUpdates + 0.1
}
}
public set_user_team_msg( taskid )
{
emessage_begin( MSG_ALL, g_iMsgTeamInfo )
ewrite_byte( ID_TEAM )
ewrite_string( CS_TEAM_NAMES[ _:fm_cs_get_user_team( ID_TEAM ) ] )
emessage_end()
}
#if defined BONUS
set_user_frags_update( id )
{
message_begin( MSG_ALL, g_iMsgScoreInfo )
write_byte( id )
write_short( get_user_frags( id ) )
write_short( get_user_deaths( id ) )
write_short( 0 )
write_short( get_user_team( id ) )
message_end()
}
#endif
// by Arkshine
bool:IsUserStuck( const id, const Float:vOrigin[ 3 ], const iFlags )
return bool:( trace_hull( vOrigin, iFlags & FL_DUCKING ? HULL_HEAD : HULL_HUMAN, id, IGNORE_MONSTERS ) & 2 )
UTIL_UnstickPlayer( const id, const i_StartDistance, const i_MaxAttempts )
{
if( !is_user_alive( id ) ) return -1
static Float:vf_OriginalOrigin[ Coord_e ], Float:vf_NewOrigin[ Coord_e ]
static i_Attempts, i_Distance
pev( id, pev_origin, vf_OriginalOrigin )
i_Distance = i_StartDistance
while( i_Distance < 1000 )
{
i_Attempts = i_MaxAttempts
while( i_Attempts-- )
{
vf_NewOrigin[ x ] = random_float( vf_OriginalOrigin[ x ] - i_Distance, vf_OriginalOrigin[ x ] + i_Distance )
vf_NewOrigin[ y ] = random_float( vf_OriginalOrigin[ y ] - i_Distance, vf_OriginalOrigin[ y ] + i_Distance )
vf_NewOrigin[ z ] = random_float( vf_OriginalOrigin[ z ] - i_Distance, vf_OriginalOrigin[ z ] + i_Distance )
engfunc( EngFunc_TraceHull, vf_NewOrigin, vf_NewOrigin, DONT_IGNORE_MONSTERS, GetPlayerHullSize( id ), id, 0 )
if( get_tr2( 0, TR_InOpen ) && !get_tr2( 0, TR_AllSolid ) && !get_tr2( 0, TR_StartSolid ) )
{
engfunc( EngFunc_SetOrigin, id, vf_NewOrigin )
return 1;
}
}
i_Distance += i_StartDistance
}
return 0;
}