Может быть кому-нибудь пригодится:
Код: //********************************************************* // 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; }
|