Paranoia2_original/dlls/items.cpp

507 lines
11 KiB
C++
Raw Permalink Blame History

/***
*
* 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 <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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: <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
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 );