This plugin allows Ability to drop weapons up and down - where you aim, in that direction weapon will be thrown.
This plugin works very well but it has a detail, which allows to give a speed boost to the weapons while you jump and drop the weapon.
Which I do not know how to solve
PHP Code:
/**
*
* Real Weapon Drop
* by Numb
*
*
* Description:
* This plugin introduces into the game more features related to dropped weapons. Features
* such as:
* + Ability to drop weapons up and down - where you aim, in that direction weapon will be
* thrown.
* + Ability to manually drop grenades.
* + Drop all weapons at death. Including grenades and a special box of ammunition.
* + Drop all weapons on disconnect. Including grenades and a special box of ammunition.
* + Barrel of dropped weapons is always facing in the same direction as player was looking.
*
*
* Requires:
* FakeMeta
* HamSandWich
*
*
* Cvars:
*
* + "rwd_aimdrop" - Counter-Strike:Source style manual weapon drop.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_grenadedrop" - ability to manually drop grenades.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_deathdrop" - drop all weapons on death.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_disconnectdrop" - drop all weapons on disconnect.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_modelanglefix[/U]" - barrel of the weapon angle fix.
* - "1" - enabled. [default]
* - "0" - disabled.
*
*
* Additional info:
* Tested in Counter-Strike 1.6 with amxmodx 1.8.2. Various features can be enabled and
* disabled via cvars. This plugin also has support VIP objectives and grenade trail
* plugins.
*
*
* Notes:
* Barrel of dropped weapons may be facing in wrong direction if client is using custom
* weapon models.
*
*
* WARNINGS:
* In some cases pausing this plugin may lead to glitches, therefor if when needed please
* use cvars instead. That is if paused in certain moments by other plugins. Manual pauses
* won't do much harm, except dropped flashes will fill up your flashbang slot to maximum,
* and ammunition box will be touchable only once.
*
*
* Credits:
* Special thanks to Arkshine ( http://forums.alliedmods.net/member.php?u=7779 ) for
* Counter-Strike SDK ( https://github.com/Arkshine/CSSDK/ ) and big help what he have
* provided by delivering very useful information! Also big thanks goes to eDark for
* calculation functions!
*
*
* Change-Log:
*
* + 2.3
* - Fixed: Crash at mapchange if there's too many players and other entities.
* - Changed: More reliability when saving number of dropped bullets and flash grenades.
*
* + 2.2
* - Fixed: VIPs drop all their weapons on escape.
* - Changed: Minor performance improvement.
*
* + 2.1
* - Changed: Minor performance improvement.
*
* + 2.0
* - Fixed: Grenades do not bounce insane when dropped.
* - Fixed: VIPs can't no longer pick-up ammunition.
* - Fixed: VIPs also do drop their weapons if have any.
* - Changed: Full plugin rewrite - plugin is now much more stable.
*
* + 1.4
* - Fixed: "grenade bounce for ever" by adding gravitation level manually. // had issues
*
* + 1.3
* - Fixed: Explode grenade on death if it's not armed.
* - Added: Grenade drop.
*
* + 1.2
* - Fixed: Due to bug in standard ArrayDeleteItem(Array:which, item) native I created my
* own working one.
*
* + 1.1
* - Changed: (code) Modified array clear (less cpu usage - I think).
* - Changed: (code) Entity scan (less cpu usage).
* - Changed: (code) Unneeded data getting from array - removed (less cpu usage).
*
* + 1.0
* - First release.
*
*
* Downloads:
* Amx Mod X forums: http://forums.alliedmods.net/showthread.php?p=619788#post619788
*
**/
//#define FAST_METHOD // saves AllocString value at mapstart, but isn't as reliable
new g_iBulletsDropped[33][15];
#if defined FAST_METHOD
new m_rgiszAmmoNames[15];
#endif
new g_iMaxPlayers;
new g_iConnected;
new g_iAlive;
new g_iMsgId_AmmoPickup;
new g_iMsgId_WeapPickup;
new g_iCvar_AimDrop;
new g_iCvar_GrenadeDrop;
new g_iCvar_DeathDrop;
new g_iCvar_DisconnectDrop;
new g_iCvar_ModelAngleFix;
new g_bInAutoDrop;
new HamHook:g_iHamHook_Think;
new g_iHamHook_Active;
new g_iDeathDrops[33][29];
new g_iDeathDropsNum[33];
new Float:g_fPlayerAngle[33];
new bool:g_bVipDrop;
new bool:g_bChangingMap;
public client_connect(iPlrId)
{
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iConnected, iPlrId);
}
public client_putinserver(iPlrId)
SetPlayerBit(g_iConnected, iPlrId);
public Event_MapChangeScoreboard()
g_bChangingMap = true;
public Message_AmmoPickup(iMsgId, iMsgType, iPlrId) // modify given ammo on hud when needed
{
static s_iAmmoNum;
s_iAmmoNum = g_iBulletsDropped[iPlrId][get_msg_arg_int(1)];
if( s_iAmmoNum )
set_msg_arg_int(2, ARG_BYTE, s_iAmmoNum);
}
public Message_Block(iMsgId, iMsgType, iPlrId) // block ammo and weaponpickup hud update when needed
return PLUGIN_HANDLED;
public FM_ClientDisconnect_Pre(iPlrId)
{
ClearPlayerBit(g_iConnected, iPlrId);
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iHamHook_Active, iPlrId);
if( equal(s_iClassName, "weaponbox") ) // is this a weaponbox with what we can work
{
static s_iOwner, Float:s_fVelocity[3], s_bAlive, Float:s_fAngle[3];
s_iOwner = pev(iEnt, pev_owner);
if( 0<s_iOwner<=g_iMaxPlayers )
s_bAlive = (CheckPlayerBit(g_iAlive, s_iOwner)?true:false);
else
s_bAlive = false;
if( s_bAlive && !g_bVipDrop ) // alive user dropped weapons
{
if( get_pcvar_num(g_iCvar_AimDrop) ) // should we change drop direction via player by aim
{
static Float:s_fOrigin[3], Float:s_fResult[3];
pev(s_iOwner, pev_origin, s_fOrigin);
pev(s_iOwner, pev_v_angle, s_fAngle);
SphereToCartesian(s_fResult, s_fOrigin, s_fAngle, Float:{0.0, 0.0, 200.0}); // some extraterrestrial math by eDark
pev(s_iOwner, pev_velocity, s_fVelocity);
s_fVelocity[0] += (s_fResult[0]-s_fOrigin[0]);
s_fVelocity[1] += (s_fResult[1]-s_fOrigin[1]);
s_fVelocity[2] -= (s_fResult[2]-s_fOrigin[2]);
set_pev(iEnt, pev_velocity, s_fVelocity);
}
}
else if( is_player_connected(s_iOwner) ) // weapon is dropped due to death
{
if( get_pcvar_num(g_iCvar_DeathDrop) )
{
if( CheckPlayerBit(g_iHamHook_Active, s_iOwner) && 0<=g_iDeathDropsNum[s_iOwner] && g_iDeathDropsNum[s_iOwner]<29 )
{
g_iDeathDrops[s_iOwner][g_iDeathDropsNum[s_iOwner]] = iEnt; // sometimes not all the weapons have speed set right,
g_iDeathDropsNum[s_iOwner]++; // therefor we'll set their speed to again, when we'll be sure it's right
if( 0<s_iOwner<=g_iMaxPlayers ) // should we work a bit more with the weaponbox
{
if( !s_bAlive )
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] = g_fPlayerAngle[s_iOwner];
set_pev(iEnt, pev_angles, s_fAngle);
}
if( equal(iModel[9], "flashbang.mdl") ) // this weaponbox includes information about flash grenade
{
#if defined FAST_METHOD
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), m_rgiszAmmoNames[AMMO_FLASHBANG], 4);
#else
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), engfunc(EngFunc_AllocString, g_iAmmoNames[AMMO_FLASHBANG]), 4);
#endif
if( s_bAlive )
{
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), 1, 4); // not working (glitch with grenades)
if( g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG]>0 )
{
static s_iFwdMsg_AmmoPickup, s_iFwdMsg_WeapPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_Block");
s_iFwdMsg_WeapPickup = register_message(g_iMsgId_WeapPickup, "Message_Block");
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
unregister_message(g_iMsgId_WeapPickup, s_iFwdMsg_WeapPickup);
}
}
else
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG], 4); // not working (glitch with grenades)
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
}
else if( equal(iModel[9], "hegrenade.mdl") ) // this weaponbox includes information about he grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 90.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "smokegrenade.mdl") ) // this weaponbox includes information about smoke grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 45.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "knife.mdl") ) // dropped knife - lets set bullets info into it
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 180.0;
set_pev(iEnt, pev_angles, s_fAngle);
engfunc(EngFunc_SetModel, iEnt, AMMO_MODEL); // and change model to custom one of course
return FMRES_SUPERCEDE;
}
else if( get_pcvar_num(g_iCvar_ModelAngleFix) ) // lets fix angle of the weaponbox model
{
pev(iEnt, pev_angles, s_fAngle);
public Ham_Item_CanDrop_Pre(iEnt) // allow drop of various items when needed
{
if( g_bInAutoDrop )
SetHamReturnInteger(1);
else if( get_pcvar_num(g_iCvar_GrenadeDrop) )
{
static s_iOwner;
s_iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4);
if( 0<s_iOwner<=g_iMaxPlayers )
{
if( get_pdata_int(s_iOwner, m_bIsVIP, 5)&FLAG_VIP ) // yep, if somehow VIP gets a grenade, don't allow it to be dropped
return HAM_IGNORED;
public Ham_Touch_wpnbox_Pre(iEnt, iPlrId) // when weaponbox is touched
{
if( 0<iPlrId<=g_iMaxPlayers )
{
if( get_pdata_int(iPlrId, m_bIsVIP, 5)&FLAG_VIP || ~pev(iEnt, pev_flags)&FL_ONGROUND ) // weaponbox can have an effect on the player
return HAM_SUPERCEDE;
return HAM_IGNORED;
}
else // now check for actual bullets
{
static s_iTemp;
s_iTemp = get_pdata_cbase(iEnt, (m_rgpPlayerItems+3), 4);
if( s_iTemp>0 && pev_valid(s_iTemp) )
{
if( get_pdata_int(s_iTemp, m_iId, 4)==CSW_KNIFE ) // check passed - this weaponbox should include information about the bullets
{
static s_iFwdMsg_AmmoPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_AmmoPickup"); // yes, we'll have to edit hud value
g_iBulletsDropped[0][0] = g_iBulletsDropped[iPlrId][0] = 0;
for( s_iTemp=1; s_iTemp<11; s_iTemp++ )
{
if( (s_iBoxAmmo=get_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 4))>0 )
{
if( (s_iUserAmmo=clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), 5), 0, g_iMaxAmmo[s_iTemp]))>=g_iMaxAmmo[s_iTemp] )
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
else
{
if( (s_iUserAmmo+s_iBoxAmmo)<=g_iMaxAmmo[s_iTemp] )
{
g_iBulletsDropped[iPlrId][s_iTemp] = s_iBoxAmmo;
s_iUserAmmo += s_iBoxAmmo;
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 0, 4);
}
else
{
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
g_iBulletsDropped[iPlrId][s_iTemp] = (g_iMaxAmmo[s_iTemp]-s_iUserAmmo);
s_iUserAmmo = g_iMaxAmmo[s_iTemp];
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), (s_iBoxAmmo-g_iBulletsDropped[iPlrId][s_iTemp]), 4);
}
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iTemp]; // we need to save that some bullets were given
fm_give_item(iPlrId, g_iAmmoEntityNames[s_iTemp]); // we must give ammo this way, else weapon
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), s_iUserAmmo, 5); // wont be able to reload
}
}
}
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
if( g_iBulletsDropped[iPlrId][0] ) // bullets were given - emit bullet pick-up sound
emit_sound(iPlrId, CHAN_ITEM, AMMO_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
if( !g_iBulletsDropped[0][0] ) // weaponbox has no more ammo - remove it
{
set_pev(iEnt, pev_solid, SOLID_NOT);
set_pev(iEnt, pev_effects, EF_NODRAW);
dllfunc(DLLFunc_Think, iEnt);
}
if( iArmedGrenade==CSW_FLASHBANG ) // oh, ya, by dropping one flash, we disarm the other one, so we have to bypass it
{
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // just to be on the safe side, in case user had more than 2 flashes
iArmedGrenade = ham_give_item(iPlrId, "weapon_flashbang");
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // if magically user doesn't die, let him have one flash (not two)
if( iArmedGrenade>0 && pev_valid(iArmedGrenade) )
{
set_pdata_cbase(iPlrId, m_pActiveItem, iArmedGrenade, 5); // yep, lets set it to be the active item
set_pdata_float(iArmedGrenade, m_flStartThrow, 1.0, 3); // now arm the grenade, so at death it'll be dropped
set_pdata_float(iArmedGrenade, m_flTimeWeaponIdle, -0.001, 4);
}
iArmedGrenade = 0;
}
}
static s_iLoop;
g_iBulletsDropped[iPlrId][0] = 0; // this will be higher, if player has any bullets at all
for( s_iLoop=1; s_iLoop<11; s_iLoop++ ) // yep, here we get information of specific bullet types
{
g_iBulletsDropped[iPlrId][s_iLoop] = clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 5), 0, g_iMaxAmmo[s_iLoop]);
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 0, 5);
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iLoop];
}
if( g_iBulletsDropped[iPlrId][0] ) // if player has any bullets at all
{
if( ~s_iUserWeapons&(1<<CSW_KNIFE) ) // if user has no knife - give one
ham_give_item(iPlrId, "weapon_knife");
engclient_cmd(iPlrId, "drop", "weapon_knife");
ham_give_item(iPlrId, "weapon_knife"); // after dropping the knife, to be safe, lets give 1 knife back
}
g_bInAutoDrop = false; // disallow death drop of grenades and knife
ham_give_item(iPlrId, iClassName[]) // ham fowrad is useful, cause it doesn't emit no item sound
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( iEnt<=0 || !pev_valid(iEnt) )
return 0;
fm_give_item(iPlrId, iClassName[]) // fakemeta forward is useful, cause it can be used with ammo_ items
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( !pev_valid(iEnt) )
return 0;
bool:SphereToCartesian(Float:fDest[3], Float:fOrigin[3], Float:fView[3], Float:fAngle[3])
{
fView[1] *= (M_PI/180.0); // and now angle[0] and angle[1] has no effect?
fView[0] *= (M_PI/180.0); // yes, this code is eDarks, so I don't remember why I added that comment above
/**
*
* Real Weapon Drop
* by Numb
*
*
* Description:
* This plugin introduces into the game more features related to dropped weapons. Features
* such as:
* + Ability to drop weapons up and down - where you aim, in that direction weapon will be
* thrown.
* + Ability to manually drop grenades.
* + Drop all weapons at death. Including grenades and a special box of ammunition.
* + Drop all weapons on disconnect. Including grenades and a special box of ammunition.
* + Barrel of dropped weapons is always facing in the same direction as player was looking.
*
*
* Requires:
* FakeMeta
* HamSandWich
*
*
* Cvars:
*
* + "rwd_aimdrop" - Counter-Strike:Source style manual weapon drop.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_grenadedrop" - ability to manually drop grenades.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_deathdrop" - drop all weapons on death.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_disconnectdrop" - drop all weapons on disconnect.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_modelanglefix[/U]" - barrel of the weapon angle fix.
* - "1" - enabled. [default]
* - "0" - disabled.
*
*
* Additional info:
* Tested in Counter-Strike 1.6 with amxmodx 1.8.2. Various features can be enabled and
* disabled via cvars. This plugin also has support VIP objectives and grenade trail
* plugins.
*
*
* Notes:
* Barrel of dropped weapons may be facing in wrong direction if client is using custom
* weapon models.
*
*
* WARNINGS:
* In some cases pausing this plugin may lead to glitches, therefor if when needed please
* use cvars instead. That is if paused in certain moments by other plugins. Manual pauses
* won't do much harm, except dropped flashes will fill up your flashbang slot to maximum,
* and ammunition box will be touchable only once.
*
*
* Credits:
* Special thanks to Arkshine ( http://forums.alliedmods.net/member.php?u=7779 ) for
* Counter-Strike SDK ( https://github.com/Arkshine/CSSDK/ ) and big help what he have
* provided by delivering very useful information! Also big thanks goes to eDark for
* calculation functions!
*
*
* Change-Log:
*
* + 2.3
* - Fixed: Crash at mapchange if there's too many players and other entities.
* - Changed: More reliability when saving number of dropped bullets and flash grenades.
*
* + 2.2
* - Fixed: VIPs drop all their weapons on escape.
* - Changed: Minor performance improvement.
*
* + 2.1
* - Changed: Minor performance improvement.
*
* + 2.0
* - Fixed: Grenades do not bounce insane when dropped.
* - Fixed: VIPs can't no longer pick-up ammunition.
* - Fixed: VIPs also do drop their weapons if have any.
* - Changed: Full plugin rewrite - plugin is now much more stable.
*
* + 1.4
* - Fixed: "grenade bounce for ever" by adding gravitation level manually. // had issues
*
* + 1.3
* - Fixed: Explode grenade on death if it's not armed.
* - Added: Grenade drop.
*
* + 1.2
* - Fixed: Due to bug in standard ArrayDeleteItem(Array:which, item) native I created my
* own working one.
*
* + 1.1
* - Changed: (code) Modified array clear (less cpu usage - I think).
* - Changed: (code) Entity scan (less cpu usage).
* - Changed: (code) Unneeded data getting from array - removed (less cpu usage).
*
* + 1.0
* - First release.
*
*
* Downloads:
* Amx Mod X forums: http://forums.alliedmods.net/showthread.php?p=619788#post619788
*
**/
//#define FAST_METHOD // saves AllocString value at mapstart, but isn't as reliable
new g_iBulletsDropped[33][15];
#if defined FAST_METHOD
new m_rgiszAmmoNames[15];
#endif
new g_iMaxPlayers;
new g_iConnected;
new g_iAlive;
new g_iMsgId_AmmoPickup;
new g_iMsgId_WeapPickup;
new g_iCvar_AimDrop;
new g_iCvar_GrenadeDrop;
new g_iCvar_DeathDrop;
new g_iCvar_DisconnectDrop;
new g_iCvar_ModelAngleFix;
new g_iCvar_MaxDropVel;
new g_bInAutoDrop;
new HamHook:g_iHamHook_Think;
new g_iHamHook_Active;
new g_iDeathDrops[33][29];
new g_iDeathDropsNum[33];
new Float:g_fPlayerAngle[33];
new bool:g_bVipDrop;
new bool:g_bChangingMap;
public client_connect(iPlrId)
{
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iConnected, iPlrId);
}
public client_putinserver(iPlrId)
SetPlayerBit(g_iConnected, iPlrId);
public Event_MapChangeScoreboard()
g_bChangingMap = true;
public Message_AmmoPickup(iMsgId, iMsgType, iPlrId) // modify given ammo on hud when needed
{
static s_iAmmoNum;
s_iAmmoNum = g_iBulletsDropped[iPlrId][get_msg_arg_int(1)];
if( s_iAmmoNum )
set_msg_arg_int(2, ARG_BYTE, s_iAmmoNum);
}
public Message_Block(iMsgId, iMsgType, iPlrId) // block ammo and weaponpickup hud update when needed
return PLUGIN_HANDLED;
public FM_ClientDisconnect_Pre(iPlrId)
{
ClearPlayerBit(g_iConnected, iPlrId);
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iHamHook_Active, iPlrId);
if( equal(s_iClassName, "weaponbox") ) // is this a weaponbox with what we can work
{
static s_iOwner, Float:s_fVelocity[3], s_bAlive, Float:s_fAngle[3];
s_iOwner = pev(iEnt, pev_owner);
if( 0<s_iOwner<=g_iMaxPlayers )
s_bAlive = (CheckPlayerBit(g_iAlive, s_iOwner)?true:false);
else
s_bAlive = false;
if( s_bAlive && !g_bVipDrop ) // alive user dropped weapons
{
if( get_pcvar_num(g_iCvar_AimDrop) ) // should we change drop direction via player by aim
{
static Float:fMaxDropVel;
fMaxDropVel = get_pcvar_float(g_iCvar_MaxDropVel);
set_pev(iEnt, pev_velocity, s_fVelocity);
}
}
else if( is_player_connected(s_iOwner) ) // weapon is dropped due to death
{
if( get_pcvar_num(g_iCvar_DeathDrop) )
{
if( CheckPlayerBit(g_iHamHook_Active, s_iOwner) && 0<=g_iDeathDropsNum[s_iOwner] && g_iDeathDropsNum[s_iOwner]<29 )
{
g_iDeathDrops[s_iOwner][g_iDeathDropsNum[s_iOwner]] = iEnt; // sometimes not all the weapons have speed set right,
g_iDeathDropsNum[s_iOwner]++; // therefor we'll set their speed to again, when we'll be sure it's right
if( 0<s_iOwner<=g_iMaxPlayers ) // should we work a bit more with the weaponbox
{
if( !s_bAlive )
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] = g_fPlayerAngle[s_iOwner];
set_pev(iEnt, pev_angles, s_fAngle);
}
if( equal(iModel[9], "flashbang.mdl") ) // this weaponbox includes information about flash grenade
{
#if defined FAST_METHOD
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), m_rgiszAmmoNames[AMMO_FLASHBANG], 4);
#else
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), engfunc(EngFunc_AllocString, g_iAmmoNames[AMMO_FLASHBANG]), 4);
#endif
if( s_bAlive )
{
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), 1, 4); // not working (glitch with grenades)
if( g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG]>0 )
{
static s_iFwdMsg_AmmoPickup, s_iFwdMsg_WeapPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_Block");
s_iFwdMsg_WeapPickup = register_message(g_iMsgId_WeapPickup, "Message_Block");
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
unregister_message(g_iMsgId_WeapPickup, s_iFwdMsg_WeapPickup);
}
}
else
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG], 4); // not working (glitch with grenades)
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
}
else if( equal(iModel[9], "hegrenade.mdl") ) // this weaponbox includes information about he grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 90.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "smokegrenade.mdl") ) // this weaponbox includes information about smoke grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 45.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "knife.mdl") ) // dropped knife - lets set bullets info into it
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 180.0;
set_pev(iEnt, pev_angles, s_fAngle);
engfunc(EngFunc_SetModel, iEnt, AMMO_MODEL); // and change model to custom one of course
return FMRES_SUPERCEDE;
}
else if( get_pcvar_num(g_iCvar_ModelAngleFix) ) // lets fix angle of the weaponbox model
{
pev(iEnt, pev_angles, s_fAngle);
public Ham_Item_CanDrop_Pre(iEnt) // allow drop of various items when needed
{
if( g_bInAutoDrop )
SetHamReturnInteger(1);
else if( get_pcvar_num(g_iCvar_GrenadeDrop) )
{
static s_iOwner;
s_iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4);
if( 0<s_iOwner<=g_iMaxPlayers )
{
if( get_pdata_int(s_iOwner, m_bIsVIP, 5)&FLAG_VIP ) // yep, if somehow VIP gets a grenade, don't allow it to be dropped
return HAM_IGNORED;
public Ham_Touch_wpnbox_Pre(iEnt, iPlrId) // when weaponbox is touched
{
if( 0<iPlrId<=g_iMaxPlayers )
{
if( get_pdata_int(iPlrId, m_bIsVIP, 5)&FLAG_VIP || ~pev(iEnt, pev_flags)&FL_ONGROUND ) // weaponbox can have an effect on the player
return HAM_SUPERCEDE;
return HAM_IGNORED;
}
else // now check for actual bullets
{
static s_iTemp;
s_iTemp = get_pdata_cbase(iEnt, (m_rgpPlayerItems+3), 4);
if( s_iTemp>0 && pev_valid(s_iTemp) )
{
if( get_pdata_int(s_iTemp, m_iId, 4)==CSW_KNIFE ) // check passed - this weaponbox should include information about the bullets
{
static s_iFwdMsg_AmmoPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_AmmoPickup"); // yes, we'll have to edit hud value
g_iBulletsDropped[0][0] = g_iBulletsDropped[iPlrId][0] = 0;
for( s_iTemp=1; s_iTemp<11; s_iTemp++ )
{
if( (s_iBoxAmmo=get_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 4))>0 )
{
if( (s_iUserAmmo=clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), 5), 0, g_iMaxAmmo[s_iTemp]))>=g_iMaxAmmo[s_iTemp] )
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
else
{
if( (s_iUserAmmo+s_iBoxAmmo)<=g_iMaxAmmo[s_iTemp] )
{
g_iBulletsDropped[iPlrId][s_iTemp] = s_iBoxAmmo;
s_iUserAmmo += s_iBoxAmmo;
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 0, 4);
}
else
{
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
g_iBulletsDropped[iPlrId][s_iTemp] = (g_iMaxAmmo[s_iTemp]-s_iUserAmmo);
s_iUserAmmo = g_iMaxAmmo[s_iTemp];
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), (s_iBoxAmmo-g_iBulletsDropped[iPlrId][s_iTemp]), 4);
}
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iTemp]; // we need to save that some bullets were given
fm_give_item(iPlrId, g_iAmmoEntityNames[s_iTemp]); // we must give ammo this way, else weapon
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), s_iUserAmmo, 5); // wont be able to reload
}
}
}
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
if( g_iBulletsDropped[iPlrId][0] ) // bullets were given - emit bullet pick-up sound
emit_sound(iPlrId, CHAN_ITEM, AMMO_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
if( !g_iBulletsDropped[0][0] ) // weaponbox has no more ammo - remove it
{
set_pev(iEnt, pev_solid, SOLID_NOT);
set_pev(iEnt, pev_effects, EF_NODRAW);
dllfunc(DLLFunc_Think, iEnt);
}
if( iArmedGrenade==CSW_FLASHBANG ) // oh, ya, by dropping one flash, we disarm the other one, so we have to bypass it
{
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // just to be on the safe side, in case user had more than 2 flashes
iArmedGrenade = ham_give_item(iPlrId, "weapon_flashbang");
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // if magically user doesn't die, let him have one flash (not two)
if( iArmedGrenade>0 && pev_valid(iArmedGrenade) )
{
set_pdata_cbase(iPlrId, m_pActiveItem, iArmedGrenade, 5); // yep, lets set it to be the active item
set_pdata_float(iArmedGrenade, m_flStartThrow, 1.0, 3); // now arm the grenade, so at death it'll be dropped
set_pdata_float(iArmedGrenade, m_flTimeWeaponIdle, -0.001, 4);
}
iArmedGrenade = 0;
}
}
static s_iLoop;
g_iBulletsDropped[iPlrId][0] = 0; // this will be higher, if player has any bullets at all
for( s_iLoop=1; s_iLoop<11; s_iLoop++ ) // yep, here we get information of specific bullet types
{
g_iBulletsDropped[iPlrId][s_iLoop] = clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 5), 0, g_iMaxAmmo[s_iLoop]);
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 0, 5);
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iLoop];
}
if( g_iBulletsDropped[iPlrId][0] ) // if player has any bullets at all
{
if( ~s_iUserWeapons&(1<<CSW_KNIFE) ) // if user has no knife - give one
ham_give_item(iPlrId, "weapon_knife");
engclient_cmd(iPlrId, "drop", "weapon_knife");
ham_give_item(iPlrId, "weapon_knife"); // after dropping the knife, to be safe, lets give 1 knife back
}
g_bInAutoDrop = false; // disallow death drop of grenades and knife
ham_give_item(iPlrId, iClassName[]) // ham fowrad is useful, cause it doesn't emit no item sound
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( iEnt<=0 || !pev_valid(iEnt) )
return 0;
fm_give_item(iPlrId, iClassName[]) // fakemeta forward is useful, cause it can be used with ammo_ items
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( !pev_valid(iEnt) )
return 0;
bool:SphereToCartesian(Float:fDest[3], Float:fOrigin[3], Float:fView[3], Float:fAngle[3])
{
fView[1] *= (M_PI/180.0); // and now angle[0] and angle[1] has no effect?
fView[0] *= (M_PI/180.0); // yes, this code is eDarks, so I don't remember why I added that comment above
/**
*
* Real Weapon Drop
* by Numb
*
*
* Description:
* This plugin introduces into the game more features related to dropped weapons. Features
* such as:
* + Ability to drop weapons up and down - where you aim, in that direction weapon will be
* thrown.
* + Ability to manually drop grenades.
* + Drop all weapons at death. Including grenades and a special box of ammunition.
* + Drop all weapons on disconnect. Including grenades and a special box of ammunition.
* + Barrel of dropped weapons is always facing in the same direction as player was looking.
*
*
* Requires:
* FakeMeta
* HamSandWich
*
*
* Cvars:
*
* + "rwd_aimdrop" - Counter-Strike:Source style manual weapon drop.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_grenadedrop" - ability to manually drop grenades.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_deathdrop" - drop all weapons on death.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_disconnectdrop" - drop all weapons on disconnect.
* - "1" - enabled. [default]
* - "0" - disabled.
*
* + "rwd_modelanglefix[/U]" - barrel of the weapon angle fix.
* - "1" - enabled. [default]
* - "0" - disabled.
*
*
* Additional info:
* Tested in Counter-Strike 1.6 with amxmodx 1.8.2. Various features can be enabled and
* disabled via cvars. This plugin also has support VIP objectives and grenade trail
* plugins.
*
*
* Notes:
* Barrel of dropped weapons may be facing in wrong direction if client is using custom
* weapon models.
*
*
* WARNINGS:
* In some cases pausing this plugin may lead to glitches, therefor if when needed please
* use cvars instead. That is if paused in certain moments by other plugins. Manual pauses
* won't do much harm, except dropped flashes will fill up your flashbang slot to maximum,
* and ammunition box will be touchable only once.
*
*
* Credits:
* Special thanks to Arkshine ( http://forums.alliedmods.net/member.php?u=7779 ) for
* Counter-Strike SDK ( https://github.com/Arkshine/CSSDK/ ) and big help what he have
* provided by delivering very useful information! Also big thanks goes to eDark for
* calculation functions!
*
*
* Change-Log:
*
* + 2.3
* - Fixed: Crash at mapchange if there's too many players and other entities.
* - Changed: More reliability when saving number of dropped bullets and flash grenades.
*
* + 2.2
* - Fixed: VIPs drop all their weapons on escape.
* - Changed: Minor performance improvement.
*
* + 2.1
* - Changed: Minor performance improvement.
*
* + 2.0
* - Fixed: Grenades do not bounce insane when dropped.
* - Fixed: VIPs can't no longer pick-up ammunition.
* - Fixed: VIPs also do drop their weapons if have any.
* - Changed: Full plugin rewrite - plugin is now much more stable.
*
* + 1.4
* - Fixed: "grenade bounce for ever" by adding gravitation level manually. // had issues
*
* + 1.3
* - Fixed: Explode grenade on death if it's not armed.
* - Added: Grenade drop.
*
* + 1.2
* - Fixed: Due to bug in standard ArrayDeleteItem(Array:which, item) native I created my
* own working one.
*
* + 1.1
* - Changed: (code) Modified array clear (less cpu usage - I think).
* - Changed: (code) Entity scan (less cpu usage).
* - Changed: (code) Unneeded data getting from array - removed (less cpu usage).
*
* + 1.0
* - First release.
*
*
* Downloads:
* Amx Mod X forums: http://forums.alliedmods.net/showthread.php?p=619788#post619788
*
**/
//#define FAST_METHOD // saves AllocString value at mapstart, but isn't as reliable
new g_iBulletsDropped[33][15];
#if defined FAST_METHOD
new m_rgiszAmmoNames[15];
#endif
new g_iMaxPlayers;
new g_iConnected;
new g_iAlive;
new g_iMsgId_AmmoPickup;
new g_iMsgId_WeapPickup;
new g_iCvar_AimDrop;
new g_iCvar_GrenadeDrop;
new g_iCvar_DeathDrop;
new g_iCvar_DisconnectDrop;
new g_iCvar_ModelAngleFix;
new g_iCvar_MaxDropVel;
new g_bInAutoDrop;
new HamHook:g_iHamHook_Think;
new g_iHamHook_Active;
new g_iDeathDrops[33][29];
new g_iDeathDropsNum[33];
new Float:g_fPlayerAngle[33];
new bool:g_bVipDrop;
new bool:g_bChangingMap;
public client_connect(iPlrId)
{
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iConnected, iPlrId);
}
public client_putinserver(iPlrId)
SetPlayerBit(g_iConnected, iPlrId);
public Event_MapChangeScoreboard()
g_bChangingMap = true;
public Message_AmmoPickup(iMsgId, iMsgType, iPlrId) // modify given ammo on hud when needed
{
static s_iAmmoNum;
s_iAmmoNum = g_iBulletsDropped[iPlrId][get_msg_arg_int(1)];
if( s_iAmmoNum )
set_msg_arg_int(2, ARG_BYTE, s_iAmmoNum);
}
public Message_Block(iMsgId, iMsgType, iPlrId) // block ammo and weaponpickup hud update when needed
return PLUGIN_HANDLED;
public FM_ClientDisconnect_Pre(iPlrId)
{
ClearPlayerBit(g_iConnected, iPlrId);
ClearPlayerBit(g_iAlive, iPlrId);
ClearPlayerBit(g_iHamHook_Active, iPlrId);
if( equal(s_iClassName, "weaponbox") ) // is this a weaponbox with what we can work
{
static s_iOwner, Float:s_fVelocity[3], s_bAlive, Float:s_fAngle[3];
s_iOwner = pev(iEnt, pev_owner);
if( 0<s_iOwner<=g_iMaxPlayers )
s_bAlive = (CheckPlayerBit(g_iAlive, s_iOwner)?true:false);
else
s_bAlive = false;
if( s_bAlive && !g_bVipDrop ) // alive user dropped weapons
{
if( get_pcvar_num(g_iCvar_AimDrop) ) // should we change drop direction via player by aim
{
static Float:fMaxDropVel;
fMaxDropVel = get_pcvar_float(g_iCvar_MaxDropVel);
set_pev(iEnt, pev_velocity, s_fVelocity);
}
}
else if( is_player_connected(s_iOwner) ) // weapon is dropped due to death
{
if( get_pcvar_num(g_iCvar_DeathDrop) )
{
if( CheckPlayerBit(g_iHamHook_Active, s_iOwner) && 0<=g_iDeathDropsNum[s_iOwner] && g_iDeathDropsNum[s_iOwner]<29 )
{
g_iDeathDrops[s_iOwner][g_iDeathDropsNum[s_iOwner]] = iEnt; // sometimes not all the weapons have speed set right,
g_iDeathDropsNum[s_iOwner]++; // therefor we'll set their speed to again, when we'll be sure it's right
if( 0<s_iOwner<=g_iMaxPlayers ) // should we work a bit more with the weaponbox
{
if( !s_bAlive )
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] = g_fPlayerAngle[s_iOwner];
set_pev(iEnt, pev_angles, s_fAngle);
}
if( equal(iModel[9], "flashbang.mdl") ) // this weaponbox includes information about flash grenade
{
#if defined FAST_METHOD
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), m_rgiszAmmoNames[AMMO_FLASHBANG], 4);
#else
set_pdata_int(iEnt, (m_rgiszAmmo+AMMO_FLASHBANG), engfunc(EngFunc_AllocString, g_iAmmoNames[AMMO_FLASHBANG]), 4);
#endif
if( s_bAlive )
{
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), 1, 4); // not working (glitch with grenades)
if( g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG]>0 )
{
static s_iFwdMsg_AmmoPickup, s_iFwdMsg_WeapPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_Block");
s_iFwdMsg_WeapPickup = register_message(g_iMsgId_WeapPickup, "Message_Block");
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
unregister_message(g_iMsgId_WeapPickup, s_iFwdMsg_WeapPickup);
}
}
else
set_pdata_int(iEnt, (m_rgAmmo+AMMO_FLASHBANG), g_iBulletsDropped[s_iOwner][AMMO_FLASHBANG], 4); // not working (glitch with grenades)
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
}
else if( equal(iModel[9], "hegrenade.mdl") ) // this weaponbox includes information about he grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 90.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "smokegrenade.mdl") ) // this weaponbox includes information about smoke grenade
{
message_begin(MSG_ALL, SVC_TEMPENTITY, _, _); // yep, lets include support for grenade trail plugin
write_byte(TE_KILLBEAM);
write_short(iEnt);
message_end();
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 45.0;
set_pev(iEnt, pev_angles, s_fAngle);
}
else if( equal(iModel[9], "knife.mdl") ) // dropped knife - lets set bullets info into it
{
pev(iEnt, pev_angles, s_fAngle);
s_fAngle[1] += 180.0;
set_pev(iEnt, pev_angles, s_fAngle);
engfunc(EngFunc_SetModel, iEnt, AMMO_MODEL); // and change model to custom one of course
return FMRES_SUPERCEDE;
}
else if( get_pcvar_num(g_iCvar_ModelAngleFix) ) // lets fix angle of the weaponbox model
{
pev(iEnt, pev_angles, s_fAngle);
public Ham_Item_CanDrop_Pre(iEnt) // allow drop of various items when needed
{
if( g_bInAutoDrop )
SetHamReturnInteger(1);
else if( get_pcvar_num(g_iCvar_GrenadeDrop) )
{
static s_iOwner;
s_iOwner = get_pdata_cbase(iEnt, m_pPlayer, 4);
if( 0<s_iOwner<=g_iMaxPlayers )
{
if( get_pdata_int(s_iOwner, m_bIsVIP, 5)&FLAG_VIP ) // yep, if somehow VIP gets a grenade, don't allow it to be dropped
return HAM_IGNORED;
public Ham_Touch_wpnbox_Pre(iEnt, iPlrId) // when weaponbox is touched
{
if( 0<iPlrId<=g_iMaxPlayers )
{
if( get_pdata_int(iPlrId, m_bIsVIP, 5)&FLAG_VIP || ~pev(iEnt, pev_flags)&FL_ONGROUND ) // weaponbox can have an effect on the player
return HAM_SUPERCEDE;
return HAM_IGNORED;
}
else // now check for actual bullets
{
static s_iTemp;
s_iTemp = get_pdata_cbase(iEnt, (m_rgpPlayerItems+3), 4);
if( s_iTemp>0 && pev_valid(s_iTemp) )
{
if( get_pdata_int(s_iTemp, m_iId, 4)==CSW_KNIFE ) // check passed - this weaponbox should include information about the bullets
{
static s_iFwdMsg_AmmoPickup;
s_iFwdMsg_AmmoPickup = register_message(g_iMsgId_AmmoPickup, "Message_AmmoPickup"); // yes, we'll have to edit hud value
g_iBulletsDropped[0][0] = g_iBulletsDropped[iPlrId][0] = 0;
for( s_iTemp=1; s_iTemp<11; s_iTemp++ )
{
if( (s_iBoxAmmo=get_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 4))>0 )
{
if( (s_iUserAmmo=clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), 5), 0, g_iMaxAmmo[s_iTemp]))>=g_iMaxAmmo[s_iTemp] )
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
else
{
if( (s_iUserAmmo+s_iBoxAmmo)<=g_iMaxAmmo[s_iTemp] )
{
g_iBulletsDropped[iPlrId][s_iTemp] = s_iBoxAmmo;
s_iUserAmmo += s_iBoxAmmo;
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), 0, 4);
}
else
{
g_iBulletsDropped[0][0] = 1; // weaponbox still has ammo - don't remove the entity
g_iBulletsDropped[iPlrId][s_iTemp] = (g_iMaxAmmo[s_iTemp]-s_iUserAmmo);
s_iUserAmmo = g_iMaxAmmo[s_iTemp];
set_pdata_int(iEnt, (m_rgAmmo+s_iTemp), (s_iBoxAmmo-g_iBulletsDropped[iPlrId][s_iTemp]), 4);
}
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iTemp]; // we need to save that some bullets were given
fm_give_item(iPlrId, g_iAmmoEntityNames[s_iTemp]); // we must give ammo this way, else weapon
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iTemp), s_iUserAmmo, 5); // wont be able to reload
}
}
}
unregister_message(g_iMsgId_AmmoPickup, s_iFwdMsg_AmmoPickup);
if( g_iBulletsDropped[iPlrId][0] ) // bullets were given - emit bullet pick-up sound
emit_sound(iPlrId, CHAN_ITEM, AMMO_SOUND, VOL_NORM, ATTN_NORM, 0, PITCH_NORM);
if( !g_iBulletsDropped[0][0] ) // weaponbox has no more ammo - remove it
{
set_pev(iEnt, pev_solid, SOLID_NOT);
set_pev(iEnt, pev_effects, EF_NODRAW);
dllfunc(DLLFunc_Think, iEnt);
}
if( iArmedGrenade==CSW_FLASHBANG ) // oh, ya, by dropping one flash, we disarm the other one, so we have to bypass it
{
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // just to be on the safe side, in case user had more than 2 flashes
iArmedGrenade = ham_give_item(iPlrId, "weapon_flashbang");
set_pdata_int(iPlrId, (m_rgAmmo_player+AMMO_FLASHBANG), 1, 5); // if magically user doesn't die, let him have one flash (not two)
if( iArmedGrenade>0 && pev_valid(iArmedGrenade) )
{
set_pdata_cbase(iPlrId, m_pActiveItem, iArmedGrenade, 5); // yep, lets set it to be the active item
set_pdata_float(iArmedGrenade, m_flStartThrow, 1.0, 3); // now arm the grenade, so at death it'll be dropped
set_pdata_float(iArmedGrenade, m_flTimeWeaponIdle, -0.001, 4);
}
iArmedGrenade = 0;
}
}
static s_iLoop;
g_iBulletsDropped[iPlrId][0] = 0; // this will be higher, if player has any bullets at all
for( s_iLoop=1; s_iLoop<11; s_iLoop++ ) // yep, here we get information of specific bullet types
{
g_iBulletsDropped[iPlrId][s_iLoop] = clamp(get_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 5), 0, g_iMaxAmmo[s_iLoop]);
set_pdata_int(iPlrId, (m_rgAmmo_player+s_iLoop), 0, 5);
g_iBulletsDropped[iPlrId][0] += g_iBulletsDropped[iPlrId][s_iLoop];
}
if( g_iBulletsDropped[iPlrId][0] ) // if player has any bullets at all
{
if( ~s_iUserWeapons&(1<<CSW_KNIFE) ) // if user has no knife - give one
ham_give_item(iPlrId, "weapon_knife");
engclient_cmd(iPlrId, "drop", "weapon_knife");
ham_give_item(iPlrId, "weapon_knife"); // after dropping the knife, to be safe, lets give 1 knife back
}
g_bInAutoDrop = false; // disallow death drop of grenades and knife
ham_give_item(iPlrId, iClassName[]) // ham fowrad is useful, cause it doesn't emit no item sound
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( iEnt<=0 || !pev_valid(iEnt) )
return 0;
fm_give_item(iPlrId, iClassName[]) // fakemeta forward is useful, cause it can be used with ammo_ items
{
new iEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, iClassName));
if( !pev_valid(iEnt) )
return 0;
bool:SphereToCartesian(Float:fDest[3], Float:fOrigin[3], Float:fView[3], Float:fAngle[3])
{
fView[1] *= (M_PI/180.0); // and now angle[0] and angle[1] has no effect?
fView[0] *= (M_PI/180.0); // yes, this code is eDarks, so I don't remember why I added that comment above