Всем привет, есть Bomb Objective Manager, периодически сыпет ошибкой:
Код
L 03/17/2015 - 16:39:13: [CSTRIKE] Invalid player 7
L 03/17/2015 - 16:39:13: [AMXX] Displaying debug trace (plugin "bombobj_checker.amxx")
L 03/17/2015 - 16:39:13: [AMXX] Run time error 10: native error (native "cs_set_user_bpammo")
L 03/17/2015 - 16:39:13: [AMXX] [0] bombobj_checker.sma::UTIL_GiveBombToOtherPlayer (line 517)
L 03/17/2015 - 16:39:13: [AMXX] [1] bombobj_checker.sma::UTIL_PunishUser (line 437)
L 03/17/2015 - 16:39:13: [AMXX] [2] bombobj_checker.sma::CBaseEntity_Think (line 191)
Я так понял это происходит когда игрока уже нет на сервере/он мертв и нужно добавить проверки?
Код:
#include < amxmodx >
#include < amxmisc >
#include < hamsandwich >
#include < fakemeta >
#include < fun >
#include < engine >
#include < cstrike >
#include < colorchat >
#define PLUGIN "Bomb Objective"
#define VERSION "0.1"
#define AUTHOR "HamletEagle"
#define FBitSet(%1,%2) (%1 |= (1 << (%2 & 31)))
#define FBitClear(%1,%2) (%1 &= ~(1 << (%2 & 31)))
#define FBitGet(%1,%2) (%1 & (1 << (%2 & 31)))
enum _: eSeconds
{
BUYZONE_CAMP,
MAP_CAMP,
BOMBZONE_CAMP
}
enum _: eCvars
{
cvar_BuyCamp,
cvar_MapCamp,
cvar_BombCamp,
cvar_BuyCampPunish,
cvar_MapCampPunish,
cvar_BombCampPunish,
cvar_LostRoundPunish,
cvar_BombRounds,
cvar_Kill
}
const m_fMapZone = 234
const XO_PLAYER = 5
const m_pPlayer = 41
const MAPZONE_BUY = 1 << 0
const MAPZONE_BOMB = 1 << 1
new g_iCarrierId
new g_iDropperId
new g_iRounds
new g_iCampSeconds[ eSeconds ]
new g_iCvars[ eCvars ]
new g_iCachedCvars[ eCvars ]
new bs_is_alive
new bs_should_slay
new bs_shouldnot_receive
new bool: g_bThrowed
new bool: g_bPlanted
new bool: g_bPlanting
new bool: g_bStart
new Float: g_fCarrierOrigin[ 3 ]
new Float: g_fCarrierOldOrigin[ 3 ]
public plugin_init( )
{
register_plugin
(
.plugin_name = PLUGIN,
.version = VERSION,
.author = AUTHOR
)
new iEnt
do
{
iEnt = create_entity( "info_target" )
}
while( !pev_valid( iEnt ) )
set_pev( iEnt, pev_classname, "BombObj_Checker" )
set_pev( iEnt, pev_nextthink, get_gametime( ) + 1.0 )
register_think( "BombObj_Checker", "CBaseEntity_Think" )
RegisterHam( Ham_AddPlayerItem, "player", "CBasePlayer_AddPlayerItem", false )
RegisterHam( Ham_Spawn, "player", "CBasePlayer_Spawn", true )
RegisterHam( Ham_Killed, "player", "CBasePlayer_Killed", false )
RegisterHam( Ham_Item_Holster, "weapon_c4", "CBasePlayer_ItemHolster", false )
register_event( "BarTime", "Event_BombPlantingCanceled", "b", "1=0" )
register_event( "SendAudio", "Event_CounterTerroristsWin", "a", "2=%!MRAD_ctwin" )
register_event( "HLTV", "Event_NewRound", "a", "1=0", "2=0" )
register_logevent( "LogEvent_RoundStart", 2, "1=Round_Start" )
register_logevent( "LogEvent_RoundEnd" , 2, "1=Round_End" )
register_forward( FM_ClientKill, "pfnClient_Kill" )
register_clcmd( "drop", "ClientCommand_Drop" )
g_iCvars[ cvar_BombCamp ] = register_cvar( "bombobj_bombcamp_seconds", "25" )
g_iCvars[ cvar_BuyCamp ] = register_cvar( "bombobj_buycamp_seconds", "20" )
g_iCvars[ cvar_MapCamp ] = register_cvar( "bombobj_mapcamp_seconds", "30" )
g_iCvars[ cvar_BuyCampPunish ] = register_cvar( "bombobj_buycamp_punish", "1" )
g_iCvars[ cvar_MapCampPunish ] = register_cvar( "bombobj_mapcamp_punish", "1" )
g_iCvars[ cvar_BombCampPunish ] = register_cvar( "bombobj_bombcamp_punish", "0" )
g_iCvars[ cvar_LostRoundPunish ] = register_cvar( "bombobj_lostround_punish", "2" )
g_iCvars[ cvar_BombRounds ] = register_cvar( "bombobj_lostround_rounds", "3" )
g_iCvars[ cvar_Kill ] = register_cvar( "bombobj_carrier_kill", "1" )
UTIL_CheckMapType( )
}
public plugin_cfg( )
{
UTIL_CacheCvars( )
}
public CBaseEntity_Think( iEnt )
{
set_pev( iEnt, pev_nextthink, get_gametime( ) + 1.0 )
if( g_bThrowed || g_bPlanted || !g_bStart )
{
return
}
new bool: bSameOrigins[ 33 ]
if( FBitGet( bs_is_alive, g_iCarrierId ) )
{
pev( g_iCarrierId, pev_origin, g_fCarrierOrigin )
for( new i; i < 3; i++ )
{
if( g_fCarrierOrigin[ i ] == g_fCarrierOldOrigin[ i ] )
{
bSameOrigins[ g_iCarrierId ] = true
break
}
else
{
bSameOrigins[ g_iCarrierId ] = false
break
}
}
//is camping ?
if( bSameOrigins[ g_iCarrierId ] )
{
//The player with the bomb is in buyzone ?
if( get_pdata_int( g_iCarrierId, m_fMapZone, XO_PLAYER ) & MAPZONE_BUY )
{
//player is camping on buyzone
g_iCampSeconds[ BUYZONE_CAMP ] ++
if( g_iCampSeconds[ BUYZONE_CAMP ] > g_iCachedCvars[ cvar_BuyCamp ] )
{
UTIL_PunishUser( g_iCarrierId, 0 )
g_iCampSeconds[ BUYZONE_CAMP ] = 0
}
}
//he is not camping in buy zone, go to next check
else
{
if( get_pdata_int( g_iCarrierId, m_fMapZone, XO_PLAYER ) & MAPZONE_BOMB )
{
if( !g_bPlanting )
{
//player is camping in bombsite and he is not planting the bomb
g_iCampSeconds[ BOMBZONE_CAMP ] ++
if( g_iCampSeconds[ BOMBZONE_CAMP ] > g_iCachedCvars[ cvar_BombCamp ] )
{
UTIL_PunishUser( g_iCarrierId, 2 )
g_iCampSeconds[ BOMBZONE_CAMP ] = 0
}
}
}
else
{
//player is camping somewhere on the map
g_iCampSeconds[ MAP_CAMP ] ++
if( g_iCampSeconds[ MAP_CAMP ] > g_iCachedCvars[ cvar_MapCamp ] )
{
UTIL_PunishUser( g_iCarrierId, 1 )
g_iCampSeconds[ MAP_CAMP ] = 0
}
}
}
}
else
{
for( new i; i < sizeof( g_iCampSeconds ); i++ )
{
g_iCampSeconds[ i ] = 0
}
}
for( new i; i < 3; i ++ )
{
//Save the old origins, so we can compare
g_fCarrierOldOrigin[ i ] = g_fCarrierOrigin[ i ]
}
}
}
public CBasePlayer_AddPlayerItem( id, iWeapon )
{
new iId = cs_get_weapon_id( iWeapon )
if( iId == CSW_C4 )
{
if( FBitGet( bs_shouldnot_receive, id ) )
{
UTIL_GiveBombToOtherPlayer( id )
}
else
{
/*
| This will be triggered when a player receive a C4
| I think that it's better to just save player id instead
| of checking every time if the given player has the bomb
*/
g_iCarrierId = id
/*
| Someone just picked up the bomb
| So the round will not be lost due to bomb drop
*/
if( g_bThrowed )
{
g_bThrowed = false
g_iDropperId = 0
}
}
}
}
public CBasePlayer_Spawn( id )
{
if( is_user_alive( id ) )
{
if( FBitGet( bs_should_slay, id ) )
{
UTIL_SlayUser( id, get_user_userid( id ) )
FBitClear( bs_should_slay, id )
g_iDropperId = 0
}
else
{
FBitSet( bs_is_alive, id )
}
}
}
public CBasePlayer_Killed( id )
{
FBitClear( bs_is_alive, id )
}
public CBasePlayer_ItemHolster ( iEnt )
{
/*
| I already hooked BarTime event for detecting when
| bomb planting is canceled, but it can be easy hacked
| by switching weapons, so here is the fix
*/
g_bPlanting = false
}
public Event_BombPlantingCanceled ( )
{
g_bPlanting = false
}
public Event_CounterTerroristsWin( )
{
if( g_bThrowed )
{
//the round had been lost due to bomb drop
g_bThrowed = false
UTIL_PunishUser( g_iDropperId, 3 )
}
}
public Event_NewRound( )
{
UTIL_CacheCvars( )
for( new i; i < 3; i++ )
{
g_iCampSeconds[ i ] = 0
}
g_bPlanted = false
g_bThrowed = false
if( g_iRounds < g_iCachedCvars[ cvar_BombRounds ] )
{
g_iRounds ++
}
else
{
new iPlayers[ 32 ], iNum, id
get_players( iPlayers, iNum, "ae", "TERRORIST" )
for( new i; i < iNum; i++ )
{
id = iPlayers[ i ]
if( FBitGet( bs_shouldnot_receive, id ) )
{
FBitClear( bs_shouldnot_receive, id )
break
}
}
}
}
public LogEvent_RoundStart( )
{
g_bStart = true
}
public LogEvent_RoundEnd( )
{
g_bStart = false
}
public pfnClient_Kill( id )
{
if( !is_user_alive( id ) )
{
return 0
}
if( id == g_iCarrierId )
{
if( g_iCachedCvars[ cvar_Kill ] == 1 )
{
return FMRES_SUPERCEDE
}
}
return FMRES_IGNORED
}
public bomb_planting( )
{
g_bPlanting = true
}
public bomb_planted( )
{
g_bPlanted = true
}
public ClientCommand_Drop( id )
{
if( !is_user_alive( id ) )
{
//let game decide
return 0
}
if( get_user_weapon( id ) == CSW_C4 )
{
//the carrier dropped the bomb
g_bThrowed = true
g_iDropperId = id
g_iCarrierId = 0
}
return 0
}
UTIL_CacheCvars( )
{
for( new i; i < sizeof g_iCvars; i ++ )
{
g_iCachedCvars[ i ] = get_pcvar_num( g_iCvars[ i ] )
}
}
UTIL_PunishUser( g_iCarrierId, iType )
{
new userid = get_user_userid( g_iCarrierId )
switch( iType )
{
case 0:
{
switch( g_iCachedCvars[ cvar_BuyCampPunish ] )
{
case 0:
{
//give the bomb to other player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
}
case 1:
{
//slay the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_SlayUser( g_iCarrierId, userid )
}
case 2:
{
//kick the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_KickUser( userid )
}
}
}
case 1:
{
switch( g_iCachedCvars[ cvar_MapCampPunish ] )
{
case 0:
{
//give the bomb to other player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
}
case 1:
{
//slay the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_SlayUser( g_iCarrierId, userid )
}
case 2:
{
//kick the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_KickUser( userid )
}
}
}
case 2:
{
switch( g_iCachedCvars[ cvar_BombCampPunish ] )
{
case 0:
{
//give the bomb to other player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
}
case 1:
{
//slay the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_SlayUser( g_iCarrierId, userid )
}
case 2:
{
//kick the player
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
UTIL_KickUser( userid )
}
}
}
case 3:
{
switch( g_iCachedCvars[ cvar_LostRoundPunish ] )
{
case 0:
{
//slay the player next round
FBitSet( bs_should_slay, g_iDropperId )
}
case 1:
{
//kick the player
UTIL_KickUser( userid )
}
case 2:
{
//he can't have the bomb for x round the player
FBitSet( bs_shouldnot_receive, g_iDropperId )
}
}
}
}
}
UTIL_GiveBombToOtherPlayer( g_iCarrierId )
{
new iPlayers[ 32 ], iNum, id
get_players( iPlayers, iNum, "ae", "TERRORIST" )
if( iNum >= 2 )
{
do
{
id = iPlayers[ random( iNum ) ]
}
while( id == g_iCarrierId )
engclient_cmd( g_iCarrierId, "weapon_c4" )
cs_set_user_bpammo( g_iCarrierId, CSW_C4, 0 )
engclient_cmd( g_iCarrierId, "lastinv" )
cs_set_user_plant( g_iCarrierId, 0, 0 )
give_item( id, "weapon_c4" )
cs_set_user_plant( id, 1, 1 )
set_hudmessage( 255, 0, 0, 0.28, 0.26, 0, 6.0, 12.0 )
show_hudmessage( g_iCarrierId, "Вы потеряли бомбу!" )
show_hudmessage( id, "Вы получили бомбу!" )
}
}
UTIL_SlayUser( g_iCarrierId, userid )
{
client_print_color( g_iCarrierId, DontChange, "^3[CSHUB.RU] ^1Вы не должны кемпирить с бомбой!" )
server_cmd( "amx_slap #%i 0", userid )
}
UTIL_KickUser( userid )
{
server_cmd( "kick #%i You can't camp.", userid )
}
UTIL_CheckMapType( )
{
if( !find_ent_by_class( -1, "func_bomb_target" ) && !find_ent_by_class( -1, "info_bomb_target") )
{
log_amx( "Plugin paused, this is not a bomb map" )
pause( "a" )
}
}