diff options
Diffstat (limited to 'mp/src/game/server/hl2/item_itemcrate.cpp')
| -rw-r--r-- | mp/src/game/server/hl2/item_itemcrate.cpp | 552 |
1 files changed, 276 insertions, 276 deletions
diff --git a/mp/src/game/server/hl2/item_itemcrate.cpp b/mp/src/game/server/hl2/item_itemcrate.cpp index e4229fa7..20ee2ff7 100644 --- a/mp/src/game/server/hl2/item_itemcrate.cpp +++ b/mp/src/game/server/hl2/item_itemcrate.cpp @@ -1,276 +1,276 @@ -//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: The various ammo types for HL2
-//
-//=============================================================================//
-
-#include "cbase.h"
-#include "props.h"
-#include "items.h"
-#include "item_dynamic_resupply.h"
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-const char *pszItemCrateModelName[] =
-{
- "models/items/item_item_crate.mdl",
- "models/items/item_beacon_crate.mdl",
-};
-
-//-----------------------------------------------------------------------------
-// A breakable crate that drops items
-//-----------------------------------------------------------------------------
-class CItem_ItemCrate : public CPhysicsProp
-{
-public:
- DECLARE_CLASS( CItem_ItemCrate, CPhysicsProp );
- DECLARE_DATADESC();
-
- void Precache( void );
- void Spawn( void );
-
- virtual int ObjectCaps() { return BaseClass::ObjectCaps() | FCAP_WCEDIT_POSITION; };
-
- virtual int OnTakeDamage( const CTakeDamageInfo &info );
-
- void InputKill( inputdata_t &data );
-
- virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent );
- virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason );
-
-protected:
- virtual void OnBreak( const Vector &vecVelocity, const AngularImpulse &angVel, CBaseEntity *pBreaker );
-
-private:
- // Crate types. Add more!
- enum CrateType_t
- {
- CRATE_SPECIFIC_ITEM = 0,
- CRATE_TYPE_COUNT,
- };
-
- enum CrateAppearance_t
- {
- CRATE_APPEARANCE_DEFAULT = 0,
- CRATE_APPEARANCE_RADAR_BEACON,
- };
-
-private:
- CrateType_t m_CrateType;
- string_t m_strItemClass;
- int m_nItemCount;
- string_t m_strAlternateMaster;
- CrateAppearance_t m_CrateAppearance;
-
- COutputEvent m_OnCacheInteraction;
-};
-
-
-LINK_ENTITY_TO_CLASS(item_item_crate, CItem_ItemCrate);
-
-
-//-----------------------------------------------------------------------------
-// Save/load:
-//-----------------------------------------------------------------------------
-BEGIN_DATADESC( CItem_ItemCrate )
-
- DEFINE_KEYFIELD( m_CrateType, FIELD_INTEGER, "CrateType" ),
- DEFINE_KEYFIELD( m_strItemClass, FIELD_STRING, "ItemClass" ),
- DEFINE_KEYFIELD( m_nItemCount, FIELD_INTEGER, "ItemCount" ),
- DEFINE_KEYFIELD( m_strAlternateMaster, FIELD_STRING, "SpecificResupply" ),
- DEFINE_KEYFIELD( m_CrateAppearance, FIELD_INTEGER, "CrateAppearance" ),
- DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ),
- DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ),
-
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem_ItemCrate::Precache( void )
-{
- // Set this here to quiet base prop warnings
- PrecacheModel( pszItemCrateModelName[m_CrateAppearance] );
- SetModel( pszItemCrateModelName[m_CrateAppearance] );
-
- BaseClass::Precache();
- if ( m_CrateType == CRATE_SPECIFIC_ITEM )
- {
- if ( NULL_STRING != m_strItemClass )
- {
- // Don't precache if this is a null string.
- UTIL_PrecacheOther( STRING(m_strItemClass) );
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem_ItemCrate::Spawn( void )
-{
- if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
- {
- UTIL_Remove( this );
- return;
- }
-
- DisableAutoFade();
- SetModelName( AllocPooledString( pszItemCrateModelName[m_CrateAppearance] ) );
-
- if ( NULL_STRING == m_strItemClass )
- {
- Warning( "CItem_ItemCrate(%i): CRATE_SPECIFIC_ITEM with NULL ItemClass string (deleted)!!!\n", entindex() );
- UTIL_Remove( this );
- return;
- }
-
- Precache( );
- SetModel( pszItemCrateModelName[m_CrateAppearance] );
- AddEFlags( EFL_NO_ROTORWASH_PUSH );
- BaseClass::Spawn( );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : &data -
-//-----------------------------------------------------------------------------
-void CItem_ItemCrate::InputKill( inputdata_t &data )
-{
- UTIL_Remove( this );
-}
-
-
-//-----------------------------------------------------------------------------
-// Item crates blow up immediately
-//-----------------------------------------------------------------------------
-int CItem_ItemCrate::OnTakeDamage( const CTakeDamageInfo &info )
-{
- if ( info.GetDamageType() & DMG_AIRBOAT )
- {
- CTakeDamageInfo dmgInfo = info;
- dmgInfo.ScaleDamage( 10.0 );
- return BaseClass::OnTakeDamage( dmgInfo );
- }
-
- return BaseClass::OnTakeDamage( info );
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem_ItemCrate::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent )
-{
- float flDamageScale = 1.0f;
- if ( FClassnameIs( pEvent->pEntities[!index], "prop_vehicle_airboat" ) ||
- FClassnameIs( pEvent->pEntities[!index], "prop_vehicle_jeep" ) )
- {
- flDamageScale = 100.0f;
- }
-
- m_impactEnergyScale *= flDamageScale;
- BaseClass::VPhysicsCollision( index, pEvent );
- m_impactEnergyScale /= flDamageScale;
-}
-
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse &angImpulse, CBaseEntity *pBreaker )
-{
- // FIXME: We could simply store the name of an entity to put into the crate
- // as a string entered in by worldcraft. Should we? I'd do it for sure
- // if it was easy to get a dropdown with all entity types in it.
-
- m_OnCacheInteraction.FireOutput(pBreaker,this);
-
- for ( int i = 0; i < m_nItemCount; ++i )
- {
- CBaseEntity *pSpawn = NULL;
- switch( m_CrateType )
- {
- case CRATE_SPECIFIC_ITEM:
- pSpawn = CreateEntityByName( STRING(m_strItemClass) );
- break;
-
- default:
- break;
- }
-
- if ( !pSpawn )
- return;
-
- // Give a little randomness...
- Vector vecOrigin;
- CollisionProp()->RandomPointInBounds( Vector(0.25, 0.25, 0.25), Vector( 0.75, 0.75, 0.75 ), &vecOrigin );
- pSpawn->SetAbsOrigin( vecOrigin );
-
- QAngle vecAngles;
- vecAngles.x = random->RandomFloat( -20.0f, 20.0f );
- vecAngles.y = random->RandomFloat( 0.0f, 360.0f );
- vecAngles.z = random->RandomFloat( -20.0f, 20.0f );
- pSpawn->SetAbsAngles( vecAngles );
-
- Vector vecActualVelocity;
- vecActualVelocity.Random( -10.0f, 10.0f );
-// vecActualVelocity += vecVelocity;
- pSpawn->SetAbsVelocity( vecActualVelocity );
-
- QAngle angVel;
- AngularImpulseToQAngle( angImpulse, angVel );
- pSpawn->SetLocalAngularVelocity( angVel );
-
- // If we're creating an item, it can't be picked up until it comes to rest
- // But only if it wasn't broken by a vehicle
- CItem *pItem = dynamic_cast<CItem*>(pSpawn);
- if ( pItem && !pBreaker->GetServerVehicle())
- {
- pItem->ActivateWhenAtRest();
- }
-
- pSpawn->Spawn();
-
- // Avoid missing items drops by a dynamic resupply because they don't think immediately
- if ( FClassnameIs( pSpawn, "item_dynamic_resupply" ) )
- {
- if ( m_strAlternateMaster != NULL_STRING )
- {
- DynamicResupply_InitFromAlternateMaster( pSpawn, m_strAlternateMaster );
- }
- if ( i == 0 )
- {
- pSpawn->AddSpawnFlags( SF_DYNAMICRESUPPLY_ALWAYS_SPAWN );
- }
- pSpawn->SetNextThink( gpGlobals->curtime );
- }
- }
-}
-
-void CItem_ItemCrate::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason )
-{
- BaseClass::OnPhysGunPickup( pPhysGunUser, reason );
-
- m_OnCacheInteraction.FireOutput( pPhysGunUser, this );
-
- if ( reason == PUNTED_BY_CANNON && m_CrateAppearance != CRATE_APPEARANCE_RADAR_BEACON )
- {
- Vector vForward;
- AngleVectors( pPhysGunUser->EyeAngles(), &vForward, NULL, NULL );
- Vector vForce = Pickup_PhysGunLaunchVelocity( this, vForward, PHYSGUN_FORCE_PUNTED );
- AngularImpulse angular = AngularImpulse( 0, 0, 0 );
-
- IPhysicsObject *pPhysics = VPhysicsGetObject();
-
- if ( pPhysics )
- {
- pPhysics->AddVelocity( &vForce, &angular );
- }
-
- TakeDamage( CTakeDamageInfo( pPhysGunUser, pPhysGunUser, GetHealth(), DMG_GENERIC ) );
- }
-}
+//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: The various ammo types for HL2 +// +//=============================================================================// + +#include "cbase.h" +#include "props.h" +#include "items.h" +#include "item_dynamic_resupply.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +const char *pszItemCrateModelName[] = +{ + "models/items/item_item_crate.mdl", + "models/items/item_beacon_crate.mdl", +}; + +//----------------------------------------------------------------------------- +// A breakable crate that drops items +//----------------------------------------------------------------------------- +class CItem_ItemCrate : public CPhysicsProp +{ +public: + DECLARE_CLASS( CItem_ItemCrate, CPhysicsProp ); + DECLARE_DATADESC(); + + void Precache( void ); + void Spawn( void ); + + virtual int ObjectCaps() { return BaseClass::ObjectCaps() | FCAP_WCEDIT_POSITION; }; + + virtual int OnTakeDamage( const CTakeDamageInfo &info ); + + void InputKill( inputdata_t &data ); + + virtual void VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ); + virtual void OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ); + +protected: + virtual void OnBreak( const Vector &vecVelocity, const AngularImpulse &angVel, CBaseEntity *pBreaker ); + +private: + // Crate types. Add more! + enum CrateType_t + { + CRATE_SPECIFIC_ITEM = 0, + CRATE_TYPE_COUNT, + }; + + enum CrateAppearance_t + { + CRATE_APPEARANCE_DEFAULT = 0, + CRATE_APPEARANCE_RADAR_BEACON, + }; + +private: + CrateType_t m_CrateType; + string_t m_strItemClass; + int m_nItemCount; + string_t m_strAlternateMaster; + CrateAppearance_t m_CrateAppearance; + + COutputEvent m_OnCacheInteraction; +}; + + +LINK_ENTITY_TO_CLASS(item_item_crate, CItem_ItemCrate); + + +//----------------------------------------------------------------------------- +// Save/load: +//----------------------------------------------------------------------------- +BEGIN_DATADESC( CItem_ItemCrate ) + + DEFINE_KEYFIELD( m_CrateType, FIELD_INTEGER, "CrateType" ), + DEFINE_KEYFIELD( m_strItemClass, FIELD_STRING, "ItemClass" ), + DEFINE_KEYFIELD( m_nItemCount, FIELD_INTEGER, "ItemCount" ), + DEFINE_KEYFIELD( m_strAlternateMaster, FIELD_STRING, "SpecificResupply" ), + DEFINE_KEYFIELD( m_CrateAppearance, FIELD_INTEGER, "CrateAppearance" ), + DEFINE_INPUTFUNC( FIELD_VOID, "Kill", InputKill ), + DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ), + +END_DATADESC() + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem_ItemCrate::Precache( void ) +{ + // Set this here to quiet base prop warnings + PrecacheModel( pszItemCrateModelName[m_CrateAppearance] ); + SetModel( pszItemCrateModelName[m_CrateAppearance] ); + + BaseClass::Precache(); + if ( m_CrateType == CRATE_SPECIFIC_ITEM ) + { + if ( NULL_STRING != m_strItemClass ) + { + // Don't precache if this is a null string. + UTIL_PrecacheOther( STRING(m_strItemClass) ); + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem_ItemCrate::Spawn( void ) +{ + if ( g_pGameRules->IsAllowedToSpawn( this ) == false ) + { + UTIL_Remove( this ); + return; + } + + DisableAutoFade(); + SetModelName( AllocPooledString( pszItemCrateModelName[m_CrateAppearance] ) ); + + if ( NULL_STRING == m_strItemClass ) + { + Warning( "CItem_ItemCrate(%i): CRATE_SPECIFIC_ITEM with NULL ItemClass string (deleted)!!!\n", entindex() ); + UTIL_Remove( this ); + return; + } + + Precache( ); + SetModel( pszItemCrateModelName[m_CrateAppearance] ); + AddEFlags( EFL_NO_ROTORWASH_PUSH ); + BaseClass::Spawn( ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +// Input : &data - +//----------------------------------------------------------------------------- +void CItem_ItemCrate::InputKill( inputdata_t &data ) +{ + UTIL_Remove( this ); +} + + +//----------------------------------------------------------------------------- +// Item crates blow up immediately +//----------------------------------------------------------------------------- +int CItem_ItemCrate::OnTakeDamage( const CTakeDamageInfo &info ) +{ + if ( info.GetDamageType() & DMG_AIRBOAT ) + { + CTakeDamageInfo dmgInfo = info; + dmgInfo.ScaleDamage( 10.0 ); + return BaseClass::OnTakeDamage( dmgInfo ); + } + + return BaseClass::OnTakeDamage( info ); +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem_ItemCrate::VPhysicsCollision( int index, gamevcollisionevent_t *pEvent ) +{ + float flDamageScale = 1.0f; + if ( FClassnameIs( pEvent->pEntities[!index], "prop_vehicle_airboat" ) || + FClassnameIs( pEvent->pEntities[!index], "prop_vehicle_jeep" ) ) + { + flDamageScale = 100.0f; + } + + m_impactEnergyScale *= flDamageScale; + BaseClass::VPhysicsCollision( index, pEvent ); + m_impactEnergyScale /= flDamageScale; +} + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CItem_ItemCrate::OnBreak( const Vector &vecVelocity, const AngularImpulse &angImpulse, CBaseEntity *pBreaker ) +{ + // FIXME: We could simply store the name of an entity to put into the crate + // as a string entered in by worldcraft. Should we? I'd do it for sure + // if it was easy to get a dropdown with all entity types in it. + + m_OnCacheInteraction.FireOutput(pBreaker,this); + + for ( int i = 0; i < m_nItemCount; ++i ) + { + CBaseEntity *pSpawn = NULL; + switch( m_CrateType ) + { + case CRATE_SPECIFIC_ITEM: + pSpawn = CreateEntityByName( STRING(m_strItemClass) ); + break; + + default: + break; + } + + if ( !pSpawn ) + return; + + // Give a little randomness... + Vector vecOrigin; + CollisionProp()->RandomPointInBounds( Vector(0.25, 0.25, 0.25), Vector( 0.75, 0.75, 0.75 ), &vecOrigin ); + pSpawn->SetAbsOrigin( vecOrigin ); + + QAngle vecAngles; + vecAngles.x = random->RandomFloat( -20.0f, 20.0f ); + vecAngles.y = random->RandomFloat( 0.0f, 360.0f ); + vecAngles.z = random->RandomFloat( -20.0f, 20.0f ); + pSpawn->SetAbsAngles( vecAngles ); + + Vector vecActualVelocity; + vecActualVelocity.Random( -10.0f, 10.0f ); +// vecActualVelocity += vecVelocity; + pSpawn->SetAbsVelocity( vecActualVelocity ); + + QAngle angVel; + AngularImpulseToQAngle( angImpulse, angVel ); + pSpawn->SetLocalAngularVelocity( angVel ); + + // If we're creating an item, it can't be picked up until it comes to rest + // But only if it wasn't broken by a vehicle + CItem *pItem = dynamic_cast<CItem*>(pSpawn); + if ( pItem && !pBreaker->GetServerVehicle()) + { + pItem->ActivateWhenAtRest(); + } + + pSpawn->Spawn(); + + // Avoid missing items drops by a dynamic resupply because they don't think immediately + if ( FClassnameIs( pSpawn, "item_dynamic_resupply" ) ) + { + if ( m_strAlternateMaster != NULL_STRING ) + { + DynamicResupply_InitFromAlternateMaster( pSpawn, m_strAlternateMaster ); + } + if ( i == 0 ) + { + pSpawn->AddSpawnFlags( SF_DYNAMICRESUPPLY_ALWAYS_SPAWN ); + } + pSpawn->SetNextThink( gpGlobals->curtime ); + } + } +} + +void CItem_ItemCrate::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason ) +{ + BaseClass::OnPhysGunPickup( pPhysGunUser, reason ); + + m_OnCacheInteraction.FireOutput( pPhysGunUser, this ); + + if ( reason == PUNTED_BY_CANNON && m_CrateAppearance != CRATE_APPEARANCE_RADAR_BEACON ) + { + Vector vForward; + AngleVectors( pPhysGunUser->EyeAngles(), &vForward, NULL, NULL ); + Vector vForce = Pickup_PhysGunLaunchVelocity( this, vForward, PHYSGUN_FORCE_PUNTED ); + AngularImpulse angular = AngularImpulse( 0, 0, 0 ); + + IPhysicsObject *pPhysics = VPhysicsGetObject(); + + if ( pPhysics ) + { + pPhysics->AddVelocity( &vForce, &angular ); + } + + TakeDamage( CTakeDamageInfo( pPhysGunUser, pPhysGunUser, GetHealth(), DMG_GENERIC ) ); + } +} |