/*** * * Copyright (c) 1996-2002, Valve LLC. All rights reserved. * * This product contains software technology licensed from Id * Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc. * All Rights Reserved. * * Use, distribution, and modification of this source code and/or resulting * object code is restricted to non-commercial enhancements to products from * Valve LLC. All other use, distribution, or modification is prohibited * without written permission from Valve LLC. * ****/ /* ===== items.cpp ======================================================== functions governing the selection/use of weapons for players */ #include "extdll.h" #include "util.h" #include "cbase.h" #include "weapons.h" #include "player.h" #include "skill.h" #include "items.h" #include "gamerules.h" extern int gmsgItemPickup; class CWorldItem : public CBaseEntity { public: void KeyValue(KeyValueData *pkvd ); void Spawn( void ); int m_iType; }; LINK_ENTITY_TO_CLASS(world_items, CWorldItem); void CWorldItem::KeyValue(KeyValueData *pkvd) { if (FStrEq(pkvd->szKeyName, "type")) { m_iType = atoi(pkvd->szValue); pkvd->fHandled = TRUE; } else CBaseEntity::KeyValue( pkvd ); } void CWorldItem::Spawn( void ) { CBaseEntity *pEntity = NULL; switch (m_iType) { case 44: // ITEM_BATTERY: pEntity = CBaseEntity::Create( "item_battery", pev->origin, pev->angles ); break; case 42: // ITEM_ANTIDOTE: pEntity = CBaseEntity::Create( "item_antidote", pev->origin, pev->angles ); break; case 43: // ITEM_SECURITY: pEntity = CBaseEntity::Create( "item_security", pev->origin, pev->angles ); break; case 45: // ITEM_SUIT: pEntity = CBaseEntity::Create( "item_suit", pev->origin, pev->angles ); break; } if (!pEntity) { ALERT( at_debug, "unable to create world_item %d\n", m_iType ); } else { pEntity->pev->target = pev->target; pEntity->pev->targetname = pev->targetname; pEntity->pev->spawnflags = pev->spawnflags; } REMOVE_ENTITY(edict()); } // Wargon: SaveData для юзабельных итемов. TYPEDESCRIPTION CItem::m_SaveData[] = { DEFINE_FIELD( CItem, m_iCurrCaps, FIELD_INTEGER ), }; IMPLEMENT_SAVERESTORE( CItem, CBaseEntity ); void CItem::Spawn( void ) { pev->movetype = MOVETYPE_TOSS; pev->solid = SOLID_TRIGGER; UTIL_SetOrigin( this, pev->origin ); UTIL_SetSize(pev, Vector(-16, -16, 0), Vector(16, 16, 16)); if( !FBitSet( ObjectCaps(), FCAP_USE_ONLY ) || FBitSet( pev->spawnflags, SF_NORESPAWN )) SetTouch(&CItem::ItemTouch); // Wargon: Итем юзабельный. SetUse( &CItem::ItemUse ); m_iCurrCaps = CBaseEntity::ObjectCaps() | FCAP_IMPULSE_USE; DROP_TO_FLOOR(ENT(pev)); } extern int gEvilImpulse101; void CItem::ItemTouch( CBaseEntity *pOther ) { // if it's not a player, ignore if ( !pOther->IsPlayer() ) { return; } CBasePlayer *pPlayer = (CBasePlayer *)pOther; // ok, a player is touching this item, but can he have it? if ( !g_pGameRules->CanHaveItem( pPlayer, this ) ) { // no? Ignore the touch. return; } if (MyTouch( pPlayer )) { SUB_UseTargets( pOther, USE_TOGGLE, 0 ); SetTouch( NULL ); // Wargon: Итем неюзабельный. SetUse( NULL ); m_iCurrCaps = CBaseEntity::ObjectCaps(); // player grabbed the item. g_pGameRules->PlayerGotItem( pPlayer, this ); if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES ) { Respawn(); } else { UTIL_Remove( this ); } } else if (gEvilImpulse101) { UTIL_Remove( this ); } } CBaseEntity* CItem::Respawn( void ) { // Wargon: Итем юзабельный. SetUse( NULL ); m_iCurrCaps = CBaseEntity::ObjectCaps(); SetTouch( NULL ); pev->effects |= EF_NODRAW; UTIL_SetOrigin( this, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn. SetThink(&CItem:: Materialize ); AbsoluteNextThink( g_pGameRules->FlItemRespawnTime( this ) ); return this; } void CItem::Materialize( void ) { if ( pev->effects & EF_NODRAW ) { // changing from invisible state to visible. EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", 1, ATTN_NORM, 0, 150 ); pev->effects &= ~EF_NODRAW; pev->effects |= EF_MUZZLEFLASH; } if( !FBitSet( ObjectCaps(), FCAP_USE_ONLY )) SetTouch(&CItem:: ItemTouch ); // Wargon: Итем юзабельный. SetUse( &CItem::ItemUse ); m_iCurrCaps = CBaseEntity::ObjectCaps() | FCAP_IMPULSE_USE; } #define SF_SUIT_SHORTLOGON 0x0001 #define SF_SUIT_WITHHEADSHIELD 0x0002 #define SF_SUIT_WITHARMOR 0x0004 class CItemSuit : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_suit.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_suit.mdl"); } BOOL MyTouch( CBasePlayer *pPlayer ) { if ( pPlayer->pev->deadflag != DEAD_NO ) { return FALSE; } if( FBitSet( pPlayer->m_iHideHUD, ITEM_SUIT )) return FALSE; if ( pev->spawnflags & SF_SUIT_WITHHEADSHIELD ) { if ( FBitSet( pPlayer->m_iHideHUD, ITEM_HEADSHIELD )) return FALSE; SetBits( pPlayer->m_iHideHUD, ITEM_HEADSHIELD ); } if ( pev->spawnflags & SF_SUIT_WITHARMOR ) { pPlayer->pev->armorvalue = MAX_NORMAL_BATTERY; } SetBits( pPlayer->m_iHideHUD, ITEM_SUIT ); return TRUE; } }; LINK_ENTITY_TO_CLASS(item_suit, CItemSuit); class CItemBattery : public CItem { void Spawn( void ) { Precache( ); if (pev->model) SET_MODEL(ENT(pev), STRING(pev->model)); //LRC else SET_MODEL(ENT(pev), "models/w_battery.mdl"); CItem::Spawn( ); } void Precache( void ) { if (pev->model) PRECACHE_MODEL((char*)STRING(pev->model)); //LRC else PRECACHE_MODEL ("models/w_battery.mdl"); if (pev->noise) PRECACHE_SOUND( (char*)STRING(pev->noise) ); //LRC else PRECACHE_SOUND( "items/gunpickup2.wav" ); } BOOL MyTouch( CBasePlayer *pPlayer ) { if ( pPlayer->pev->deadflag != DEAD_NO ) { return FALSE; } if ((pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY) && FBitSet( pPlayer->m_iHideHUD, ITEM_SUIT )) { int pct; char szcharge[64]; if (pev->armorvalue) pPlayer->pev->armorvalue += pev->armorvalue; else pPlayer->pev->armorvalue += gSkillData.batteryCapacity; pPlayer->pev->armorvalue = min(pPlayer->pev->armorvalue, MAX_NORMAL_BATTERY); if (pev->noise) EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, STRING(pev->noise), 1, ATTN_NORM ); //LRC else EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); WRITE_STRING( STRING(pev->classname) ); MESSAGE_END(); // Suit reports new power level // For some reason this wasn't working in release build -- round it. pct = (int)( (float)(pPlayer->pev->armorvalue * 100.0) * (1.0/MAX_NORMAL_BATTERY) + 0.5); pct = (pct / 5); if (pct > 0) pct--; sprintf( szcharge,"!HEV_%1dP", pct ); //EMIT_SOUND_SUIT(ENT(pev), szcharge); pPlayer->SetSuitUpdate(szcharge, FALSE, SUIT_NEXT_IN_30SEC); return TRUE; } return FALSE; } }; LINK_ENTITY_TO_CLASS(item_battery, CItemBattery); // buz: big battery, 100% class CItemArmour : public CItem { void Spawn( void ) { Precache( ); if (pev->model) SET_MODEL(ENT(pev), STRING(pev->model)); //LRC else SET_MODEL(ENT(pev), "models/w_armour.mdl"); CItem::Spawn( ); } void Precache( void ) { if (pev->model) PRECACHE_MODEL((char*)STRING(pev->model)); //LRC else PRECACHE_MODEL ("models/w_armour.mdl"); PRECACHE_SOUND( "items/armour.wav" ); } BOOL MyTouch( CBasePlayer *pPlayer ) { if ( pPlayer->pev->deadflag != DEAD_NO ) { return FALSE; } if (pPlayer->pev->armorvalue < MAX_NORMAL_BATTERY) { pPlayer->pev->armorvalue = MAX_NORMAL_BATTERY; EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/armour.wav", 1, ATTN_NORM ); MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); WRITE_STRING( STRING(pev->classname) ); MESSAGE_END(); return TRUE; } return FALSE; } }; LINK_ENTITY_TO_CLASS(item_armour, CItemArmour); class CItemAntidote : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_antidote.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_antidote.mdl"); } BOOL MyTouch( CBasePlayer *pPlayer ) { pPlayer->SetSuitUpdate("!HEV_DET4", FALSE, SUIT_NEXT_IN_1MIN); pPlayer->m_rgItems[ITEM_ANTIDOTE] += 1; return TRUE; } }; LINK_ENTITY_TO_CLASS(item_antidote, CItemAntidote); class CItemSecurity : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_security.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_security.mdl"); } BOOL MyTouch( CBasePlayer *pPlayer ) { pPlayer->m_rgItems[ITEM_SECURITY] += 1; return TRUE; } }; LINK_ENTITY_TO_CLASS(item_security, CItemSecurity); class CItemLongJump : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_longjump.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_longjump.mdl"); } BOOL MyTouch( CBasePlayer *pPlayer ) { if ( pPlayer->m_fLongJump ) { return FALSE; } if ( FBitSet( pPlayer->m_iHideHUD, ITEM_SUIT )) { pPlayer->m_fLongJump = TRUE;// player now has longjump module g_engfuncs.pfnSetPhysicsKeyValue( pPlayer->edict(), "slj", "1" ); MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); WRITE_STRING( STRING(pev->classname) ); MESSAGE_END(); // buz EMIT_SOUND_SUIT( pPlayer->edict(), "!HEV_A1" ); // Play the longjump sound UNDONE: Kelly? correct sound? return TRUE; } return FALSE; } }; LINK_ENTITY_TO_CLASS( item_longjump, CItemLongJump ); // buz: gasmask class CItemGasMask : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_gasmask.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_gasmask.mdl"); PRECACHE_SOUND( "items/gunpickup2.wav" ); } BOOL MyTouch( CBasePlayer *pPlayer ) { if( FBitSet( pPlayer->m_iHideHUD, ITEM_GASMASK )) return FALSE; SetBits( pPlayer->m_iHideHUD, ITEM_GASMASK ); MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); WRITE_STRING( STRING(pev->classname) ); MESSAGE_END(); EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); return TRUE; } }; LINK_ENTITY_TO_CLASS( item_gasmask, CItemGasMask ); // buz: head shield class CItemHeadShield : public CItem { void Spawn( void ) { Precache( ); SET_MODEL(ENT(pev), "models/w_headshield.mdl"); CItem::Spawn( ); } void Precache( void ) { PRECACHE_MODEL ("models/w_headshield.mdl"); PRECACHE_SOUND( "items/gunpickup2.wav" ); } BOOL MyTouch( CBasePlayer *pPlayer ) { if ( FBitSet( pPlayer->m_iHideHUD, ITEM_HEADSHIELD) ) { return FALSE; } SetBits( pPlayer->m_iHideHUD, ITEM_HEADSHIELD ); MESSAGE_BEGIN( MSG_ONE, gmsgItemPickup, NULL, pPlayer->pev ); WRITE_STRING( STRING(pev->classname) ); MESSAGE_END(); EMIT_SOUND( pPlayer->edict(), CHAN_ITEM, "items/gunpickup2.wav", 1, ATTN_NORM ); return TRUE; } }; LINK_ENTITY_TO_CLASS( item_headshield, CItemHeadShield );