Может быть кому-нибудь пригодится:
Код:
//*********************************************************
// weaponbox code:
//*********************************************************
#include <engine>
#include <fakemeta>
#include <hamsandwich>
#define MAX_ITEM_TYPES 6 // hud item selection slots
#define MAX_AMMO_SLOTS 32 // not really slots
// CBasePlayerItem offsets
const m_pPlayer = 28
const m_pNext = 29;
const m_iId = 30;
// CWeaponBox offsets
new const m_rgpPlayerItems[MAX_ITEM_TYPES] = {21, 22, 23, 24, 25, 26}// one slot for each
const m_rgiszAmmo_slot0 = 28;// ammo names
const m_rgAmmo_slot0 = 60;// ammo quantities
// WeaponBox extraoffset
const XTRA_OFS_WEAPONBOX = 4
//=========================================================
// WeaponBox - Spawn
//=========================================================
stock WeaponBox_Spawn()
{
new pWeaponBox = create_entity("weaponbox");
if (!pev_valid(pWeaponBox))
return FM_NULLENT;
set_pev(pWeaponBox, pev_movetype, MOVETYPE_TOSS);
set_pev(pWeaponBox, pev_solid, SOLID_TRIGGER);
engfunc(EngFunc_SetSize, pWeaponBox, Float:{0.0, 0.0, 0.0} , Float:{0.0, 0.0, 0.0});
engfunc(EngFunc_SetModel, pWeaponBox, "models/w_weaponbox.mdl");
ExecuteHamB(Ham_Spawn, pWeaponBox)
return pWeaponBox;
}
//=========================================================
// WeaponBox_Kill - the function that removes the
// box from the world.
//=========================================================
stock WeaponBox_Kill(const pWeaponBox)
{
new pWeapon, i;
// destroy the weapons
for (i = 0 ; i < MAX_ITEM_TYPES ; i++)
{
pWeapon = get_pdata_cbase(pWeaponBox, m_rgpPlayerItems[i], XTRA_OFS_WEAPONBOX)
while (pev_valid(pWeapon))
{
set_pev(pWeapon, pev_flags, FL_KILLME)
pWeapon = get_pdata_cbase(pWeapon, m_pNext, XTRA_OFS_WEAPONBOX)
}
}
// remove the box
set_pev(pWeaponBox, pev_flags, FL_KILLME);
}
//=========================================================
// PackWeapon: Add this weapon to the box
//=========================================================
stock WeaponBox_PackWeapon(const pWeaponBox, const pWeapon)
{
// is one of these weapons already packed in this box?
if (WeaponBox_HasWeapon(pWeaponBox, pWeapon))
{
return 0;// box can only hold one of each weapon type
}
new pPlayer = get_pdata_cbase(pWeapon, m_pPlayer, XTRA_OFS_WEAPONBOX);
new iWeaponSlot = ExecuteHamB(Ham_Item_ItemSlot, pWeapon);
new rgpPlayerItem = get_pdata_cbase(pWeaponBox, m_rgpPlayerItems[iWeaponSlot], XTRA_OFS_WEAPONBOX);
if (pev_valid(pPlayer))
{
if (!ExecuteHamB(Ham_RemovePlayerItem, pPlayer, pWeapon))
{
// failed to unhook the weapon from the player!
return 0;
}
}
if (pev_valid(rgpPlayerItem))
{
// there's already one weapon in this slot, so link this into the slot's column
set_pdata_cbase(pWeapon, m_pNext, rgpPlayerItem, XTRA_OFS_WEAPONBOX);
set_pdata_cbase(pWeaponBox, m_rgpPlayerItems[iWeaponSlot], pWeapon, XTRA_OFS_WEAPONBOX);
}
else
{
// first weapon we have for this slot
set_pdata_cbase(pWeaponBox, m_rgpPlayerItems[iWeaponSlot], pWeapon, XTRA_OFS_WEAPONBOX);
set_pdata_cbase(pWeapon, m_pNext, FM_NULLENT, XTRA_OFS_WEAPONBOX);
}
set_pev(pWeapon, pev_spawnflags, pev(pWeapon, pev_spawnflags) | SF_NORESPAWN);// never respawn
set_pev(pWeapon, pev_movetype, MOVETYPE_NONE);
set_pev(pWeapon, pev_solid, SOLID_NOT);
set_pev(pWeapon, pev_effects, EF_NODRAW);
set_pev(pWeapon, pev_modelindex, 0);
set_pev(pWeapon, pev_model, 0);
set_pev(pWeapon, pev_owner, pWeaponBox);
set_pdata_cbase(pWeapon, m_pPlayer, FM_NULLENT, XTRA_OFS_WEAPONBOX);
return 1;
}
//=========================================================
// WeaponBox - GiveAmmo
//=========================================================
stock WeaponBox_GiveAmmo(const pWeaponBox, const iCount, const szName[], const iMax)
{
new i
for (new m_rgiszAmmo, szAmmo[24], i = 0; i < MAX_AMMO_SLOTS && (m_rgiszAmmo = get_pdata_int(pWeaponBox, m_rgiszAmmo_slot0 + i, XTRA_OFS_WEAPONBOX)); i++)
{
global_get(glb_pStringBase, m_rgiszAmmo, szAmmo, charsmax(szAmmo))
if (strcmp(szName, szAmmo) == 0)
{
new m_rgAmmo = get_pdata_int(pWeaponBox, m_rgAmmo_slot0 + i, XTRA_OFS_WEAPONBOX)
new iAdd = min(iCount, iMax - m_rgAmmo)
if (iCount == 0 || iAdd > 0)
{
set_pdata_int(pWeaponBox, m_rgAmmo_slot0 + i, m_rgAmmo + iAdd, XTRA_OFS_WEAPONBOX)
return i;
}
return -1;
}
}
if (i < MAX_AMMO_SLOTS)
{
set_pdata_int(pWeaponBox, m_rgiszAmmo_slot0 + i, engfunc(EngFunc_AllocString, szName), XTRA_OFS_WEAPONBOX)
set_pdata_int(pWeaponBox, m_rgAmmo_slot0 + i, iCount, XTRA_OFS_WEAPONBOX)
return i;
}
// out of named ammo slots
return i;
}
//=========================================================
// HasWeapon - is a weapon of this type already
// packed in this box?
//=========================================================
stock WeaponBox_HasWeapon(const pWeaponBox, const pCheckItem)
{
new pItem = get_pdata_cbase(pWeaponBox, m_rgpPlayerItems[ExecuteHamB(Ham_Item_ItemSlot, pCheckItem)], XTRA_OFS_WEAPONBOX)
while (pev_valid(pItem))
{
if (get_pdata_int(pItem, m_iId, XTRA_OFS_WEAPONBOX) == get_pdata_int(pCheckItem, m_iId, XTRA_OFS_WEAPONBOX))
{
return 1;
}
pItem = get_pdata_cbase(pItem, m_pNext, XTRA_OFS_WEAPONBOX)
}
return 0;
}
//=========================================================
// WeaponBox_IsEmpty - is there anything in this box?
//=========================================================
stock bool: WeaponBox_IsEmpty(const pWeaponBox)
{
new i;
for (i = 0 ; i < MAX_ITEM_TYPES ; i++)
{
if (pev_valid(get_pdata_cbase(pWeaponBox, m_rgpPlayerItems[i], XTRA_OFS_WEAPONBOX)))
{
return false;
}
}
for (i = 0 ; i < MAX_AMMO_SLOTS ; i++)
{
if (get_pdata_int(pWeaponBox, m_rgiszAmmo_slot0 + i, XTRA_OFS_WEAPONBOX))
{
// still have a bit of this type of ammo
return false;
}
}
return true;
}