aboutsummaryrefslogtreecommitdiff
path: root/mp/src/game/server/item_world.cpp
diff options
context:
space:
mode:
authorJørgen P. Tjernø <[email protected]>2013-12-02 19:31:46 -0800
committerJørgen P. Tjernø <[email protected]>2013-12-02 19:46:31 -0800
commitf56bb35301836e56582a575a75864392a0177875 (patch)
treede61ddd39de3e7df52759711950b4c288592f0dc /mp/src/game/server/item_world.cpp
parentMark some more files as text. (diff)
downloadsource-sdk-2013-f56bb35301836e56582a575a75864392a0177875.tar.xz
source-sdk-2013-f56bb35301836e56582a575a75864392a0177875.zip
Fix line endings. WHAMMY.
Diffstat (limited to 'mp/src/game/server/item_world.cpp')
-rw-r--r--mp/src/game/server/item_world.cpp1094
1 files changed, 547 insertions, 547 deletions
diff --git a/mp/src/game/server/item_world.cpp b/mp/src/game/server/item_world.cpp
index 9b832c8e..e4233172 100644
--- a/mp/src/game/server/item_world.cpp
+++ b/mp/src/game/server/item_world.cpp
@@ -1,547 +1,547 @@
-//========= Copyright Valve Corporation, All rights reserved. ============//
-//
-// Purpose: Handling for the base world item. Most of this was moved from items.cpp.
-//
-// $NoKeywords: $
-//===========================================================================//
-
-#include "cbase.h"
-#include "player.h"
-#include "items.h"
-#include "gamerules.h"
-#include "engine/IEngineSound.h"
-#include "iservervehicle.h"
-#include "physics_saverestore.h"
-#include "world.h"
-
-#ifdef HL2MP
-#include "hl2mp_gamerules.h"
-#endif
-
-// memdbgon must be the last include file in a .cpp file!!!
-#include "tier0/memdbgon.h"
-
-#define ITEM_PICKUP_BOX_BLOAT 24
-
-class CWorldItem : public CBaseAnimating
-{
- DECLARE_DATADESC();
-public:
- DECLARE_CLASS( CWorldItem, CBaseAnimating );
-
- bool KeyValue( const char *szKeyName, const char *szValue );
- void Spawn( void );
-
- int m_iType;
-};
-
-LINK_ENTITY_TO_CLASS(world_items, CWorldItem);
-
-BEGIN_DATADESC( CWorldItem )
-
-DEFINE_FIELD( m_iType, FIELD_INTEGER ),
-
-END_DATADESC()
-
-
-bool CWorldItem::KeyValue( const char *szKeyName, const char *szValue )
-{
- if (FStrEq(szKeyName, "type"))
- {
- m_iType = atoi(szValue);
- }
- else
- return BaseClass::KeyValue( szKeyName, szValue );
-
- return true;
-}
-
-void CWorldItem::Spawn( void )
-{
- CBaseEntity *pEntity = NULL;
-
- switch (m_iType)
- {
- case 44: // ITEM_BATTERY:
- pEntity = CBaseEntity::Create( "item_battery", GetLocalOrigin(), GetLocalAngles() );
- break;
- case 45: // ITEM_SUIT:
- pEntity = CBaseEntity::Create( "item_suit", GetLocalOrigin(), GetLocalAngles() );
- break;
- }
-
- if (!pEntity)
- {
- Warning("unable to create world_item %d\n", m_iType );
- }
- else
- {
- pEntity->m_target = m_target;
- pEntity->SetName( GetEntityName() );
- pEntity->ClearSpawnFlags();
- pEntity->AddSpawnFlags( m_spawnflags );
- }
-
- UTIL_RemoveImmediate( this );
-}
-
-
-BEGIN_DATADESC( CItem )
-
- DEFINE_FIELD( m_bActivateWhenAtRest, FIELD_BOOLEAN ),
- DEFINE_FIELD( m_vOriginalSpawnOrigin, FIELD_POSITION_VECTOR ),
- DEFINE_FIELD( m_vOriginalSpawnAngles, FIELD_VECTOR ),
- DEFINE_PHYSPTR( m_pConstraint ),
-
- // Function Pointers
- DEFINE_ENTITYFUNC( ItemTouch ),
- DEFINE_THINKFUNC( Materialize ),
- DEFINE_THINKFUNC( ComeToRest ),
-
-#if defined( HL2MP ) || defined( TF_DLL )
- DEFINE_FIELD( m_flNextResetCheckTime, FIELD_TIME ),
- DEFINE_THINKFUNC( FallThink ),
-#endif
-
- // Outputs
- DEFINE_OUTPUT( m_OnPlayerTouch, "OnPlayerTouch" ),
- DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ),
-
-END_DATADESC()
-
-
-//-----------------------------------------------------------------------------
-// Constructor
-//-----------------------------------------------------------------------------
-CItem::CItem()
-{
- m_bActivateWhenAtRest = false;
-}
-
-bool CItem::CreateItemVPhysicsObject( void )
-{
- // Create the object in the physics system
- int nSolidFlags = GetSolidFlags() | FSOLID_NOT_STANDABLE;
- if ( !m_bActivateWhenAtRest )
- {
- nSolidFlags |= FSOLID_TRIGGER;
- }
-
- if ( VPhysicsInitNormal( SOLID_VPHYSICS, nSolidFlags, false ) == NULL )
- {
- SetSolid( SOLID_BBOX );
- AddSolidFlags( nSolidFlags );
-
- // If it's not physical, drop it to the floor
- if (UTIL_DropToFloor(this, MASK_SOLID) == 0)
- {
- Warning( "Item %s fell out of level at %f,%f,%f\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z);
- UTIL_Remove( this );
- return false;
- }
- }
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem::Spawn( void )
-{
- if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
- {
- UTIL_Remove( this );
- return;
- }
-
- SetMoveType( MOVETYPE_FLYGRAVITY );
- SetSolid( SOLID_BBOX );
- SetBlocksLOS( false );
- AddEFlags( EFL_NO_ROTORWASH_PUSH );
-
- if( IsX360() )
- {
- AddEffects( EF_ITEM_BLINK );
- }
-
- // This will make them not collide with the player, but will collide
- // against other items + weapons
- SetCollisionGroup( COLLISION_GROUP_WEAPON );
- CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT );
- SetTouch(&CItem::ItemTouch);
-
- if ( CreateItemVPhysicsObject() == false )
- return;
-
- m_takedamage = DAMAGE_EVENTS_ONLY;
-
-#if !defined( CLIENT_DLL )
- // Constrained start?
- if ( HasSpawnFlags( SF_ITEM_START_CONSTRAINED ) )
- {
- //Constrain the weapon in place
- IPhysicsObject *pReferenceObject, *pAttachedObject;
-
- pReferenceObject = g_PhysWorldObject;
- pAttachedObject = VPhysicsGetObject();
-
- if ( pReferenceObject && pAttachedObject )
- {
- constraint_fixedparams_t fixed;
- fixed.Defaults();
- fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );
-
- fixed.constraint.forceLimit = lbs2kg( 10000 );
- fixed.constraint.torqueLimit = lbs2kg( 10000 );
-
- m_pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );
-
- m_pConstraint->SetGameData( (void *) this );
- }
- }
-#endif //CLIENT_DLL
-
-#if defined( HL2MP ) || defined( TF_DLL )
- SetThink( &CItem::FallThink );
- SetNextThink( gpGlobals->curtime + 0.1f );
-#endif
-}
-
-unsigned int CItem::PhysicsSolidMaskForEntity( void ) const
-{
- return BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_PLAYERCLIP;
-}
-
-void CItem::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
-{
- CBasePlayer *pPlayer = ToBasePlayer( pActivator );
-
- if ( pPlayer )
- {
- pPlayer->PickupObject( this );
- }
-}
-
-extern int gEvilImpulse101;
-
-
-//-----------------------------------------------------------------------------
-// Activate when at rest, but don't allow pickup until then
-//-----------------------------------------------------------------------------
-void CItem::ActivateWhenAtRest( float flTime /* = 0.5f */ )
-{
- RemoveSolidFlags( FSOLID_TRIGGER );
- m_bActivateWhenAtRest = true;
- SetThink( &CItem::ComeToRest );
- SetNextThink( gpGlobals->curtime + flTime );
-}
-
-
-//-----------------------------------------------------------------------------
-// Become touchable when we are at rest
-//-----------------------------------------------------------------------------
-void CItem::OnEntityEvent( EntityEvent_t event, void *pEventData )
-{
- BaseClass::OnEntityEvent( event, pEventData );
-
- switch( event )
- {
- case ENTITY_EVENT_WATER_TOUCH:
- {
- // Delay rest for a sec, to avoid changing collision
- // properties inside a collision callback.
- SetThink( &CItem::ComeToRest );
- SetNextThink( gpGlobals->curtime + 0.1f );
- }
- break;
- }
-}
-
-
-//-----------------------------------------------------------------------------
-// Become touchable when we are at rest
-//-----------------------------------------------------------------------------
-void CItem::ComeToRest( void )
-{
- if ( m_bActivateWhenAtRest )
- {
- m_bActivateWhenAtRest = false;
- AddSolidFlags( FSOLID_TRIGGER );
- SetThink( NULL );
- }
-}
-
-#if defined( HL2MP ) || defined( TF_DLL )
-
-//-----------------------------------------------------------------------------
-// Purpose: Items that have just spawned run this think to catch them when
-// they hit the ground. Once we're sure that the object is grounded,
-// we change its solid type to trigger and set it in a large box that
-// helps the player get it.
-//-----------------------------------------------------------------------------
-void CItem::FallThink ( void )
-{
- SetNextThink( gpGlobals->curtime + 0.1f );
-
-#if defined( HL2MP )
- bool shouldMaterialize = false;
- IPhysicsObject *pPhysics = VPhysicsGetObject();
- if ( pPhysics )
- {
- shouldMaterialize = pPhysics->IsAsleep();
- }
- else
- {
- shouldMaterialize = (GetFlags() & FL_ONGROUND) ? true : false;
- }
-
- if ( shouldMaterialize )
- {
- SetThink ( NULL );
-
- m_vOriginalSpawnOrigin = GetAbsOrigin();
- m_vOriginalSpawnAngles = GetAbsAngles();
-
- HL2MPRules()->AddLevelDesignerPlacedObject( this );
- }
-#endif // HL2MP
-
-#if defined( TF_DLL )
- // We only come here if ActivateWhenAtRest() is never called,
- // which is the case when creating currencypacks in MvM
- if ( !( GetFlags() & FL_ONGROUND ) )
- {
- if ( !GetAbsVelocity().Length() && GetMoveType() == MOVETYPE_FLYGRAVITY )
- {
- // Mr. Game, meet Mr. Hammer. Mr. Hammer, meet the uncooperative Mr. Physics.
- // Mr. Physics really doesn't want to give our friend the FL_ONGROUND flag.
- // This means our wonderfully helpful radius currency collection code will be sad.
- // So in the name of justice, we ask that this flag be delivered unto him.
-
- SetMoveType( MOVETYPE_NONE );
- SetGroundEntity( GetWorldEntity() );
- }
- }
- else
- {
- SetThink( &CItem::ComeToRest );
- }
-#endif // TF
-}
-
-#endif // HL2MP, TF
-
-//-----------------------------------------------------------------------------
-// Purpose: Used to tell whether an item may be picked up by the player. This
-// accounts for solid obstructions being in the way.
-// Input : *pItem - item in question
-// *pPlayer - player attempting the pickup
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool UTIL_ItemCanBeTouchedByPlayer( CBaseEntity *pItem, CBasePlayer *pPlayer )
-{
- if ( pItem == NULL || pPlayer == NULL )
- return false;
-
- // For now, always allow a vehicle riding player to pick up things they're driving over
- if ( pPlayer->IsInAVehicle() )
- return true;
-
- // Get our test positions
- Vector vecStartPos;
- IPhysicsObject *pPhysObj = pItem->VPhysicsGetObject();
- if ( pPhysObj != NULL )
- {
- // Use the physics hull's center
- QAngle vecAngles;
- pPhysObj->GetPosition( &vecStartPos, &vecAngles );
- }
- else
- {
- // Use the generic bbox center
- vecStartPos = pItem->CollisionProp()->WorldSpaceCenter();
- }
-
- Vector vecEndPos = pPlayer->EyePosition();
-
- // FIXME: This is the simple first try solution towards the problem. We need to take edges and shape more into account
- // for this to be fully robust.
-
- // Trace between to see if we're occluded
- trace_t tr;
- CTraceFilterSkipTwoEntities filter( pPlayer, pItem, COLLISION_GROUP_PLAYER_MOVEMENT );
- UTIL_TraceLine( vecStartPos, vecEndPos, MASK_SOLID, &filter, &tr );
-
- // Occluded
- // FIXME: For now, we exclude starting in solid because there are cases where this doesn't matter
- if ( tr.fraction < 1.0f )
- return false;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// Purpose: Whether or not the item can be touched and picked up by the player, taking
-// into account obstructions and other hinderances
-// Output : Returns true on success, false on failure.
-//-----------------------------------------------------------------------------
-bool CItem::ItemCanBeTouchedByPlayer( CBasePlayer *pPlayer )
-{
- return UTIL_ItemCanBeTouchedByPlayer( this, pPlayer );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : pOther -
-//-----------------------------------------------------------------------------
-void CItem::ItemTouch( CBaseEntity *pOther )
-{
- // Vehicles can touch items + pick them up
- if ( pOther->GetServerVehicle() )
- {
- pOther = pOther->GetServerVehicle()->GetPassenger();
- if ( !pOther )
- return;
- }
-
- // if it's not a player, ignore
- if ( !pOther->IsPlayer() )
- return;
-
- CBasePlayer *pPlayer = (CBasePlayer *)pOther;
-
- // Must be a valid pickup scenario (no blocking). Though this is a more expensive
- // check than some that follow, this has to be first Obecause it's the only one
- // that inhibits firing the output OnCacheInteraction.
- if ( ItemCanBeTouchedByPlayer( pPlayer ) == false )
- return;
-
- m_OnCacheInteraction.FireOutput(pOther, this);
-
- // Can I even pick stuff up?
- if ( !pPlayer->IsAllowedToPickupWeapons() )
- return;
-
- // 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 ) )
- {
- m_OnPlayerTouch.FireOutput(pOther, this);
-
- SetTouch( NULL );
- SetThink( NULL );
-
- // player grabbed the item.
- g_pGameRules->PlayerGotItem( pPlayer, this );
- if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES )
- {
- Respawn();
- }
- else
- {
- UTIL_Remove( this );
-
-#ifdef HL2MP
- HL2MPRules()->RemoveLevelDesignerPlacedObject( this );
-#endif
- }
- }
- else if (gEvilImpulse101)
- {
- UTIL_Remove( this );
- }
-}
-
-CBaseEntity* CItem::Respawn( void )
-{
- SetTouch( NULL );
- AddEffects( EF_NODRAW );
-
- VPhysicsDestroyObject();
-
- SetMoveType( MOVETYPE_NONE );
- SetSolid( SOLID_BBOX );
- AddSolidFlags( FSOLID_TRIGGER );
-
- UTIL_SetOrigin( this, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn.
- SetAbsAngles( g_pGameRules->VecItemRespawnAngles( this ) );// set the angles.
-
-#if !defined( TF_DLL )
- UTIL_DropToFloor( this, MASK_SOLID );
-#endif
-
- RemoveAllDecals(); //remove any decals
-
- SetThink ( &CItem::Materialize );
- SetNextThink( gpGlobals->curtime + g_pGameRules->FlItemRespawnTime( this ) );
- return this;
-}
-
-void CItem::Materialize( void )
-{
- CreateItemVPhysicsObject();
-
- if ( IsEffectActive( EF_NODRAW ) )
- {
- // changing from invisible state to visible.
-
-#ifdef HL2MP
- EmitSound( "AlyxEmp.Charge" );
-#else
- EmitSound( "Item.Materialize" );
-#endif
- RemoveEffects( EF_NODRAW );
- DoMuzzleFlash();
- }
-
- SetTouch( &CItem::ItemTouch );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-//-----------------------------------------------------------------------------
-void CItem::Precache()
-{
- BaseClass::Precache();
-
- PrecacheScriptSound( "Item.Materialize" );
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pPhysGunUser -
-// PICKED_UP_BY_CANNON -
-//-----------------------------------------------------------------------------
-void CItem::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason )
-{
- m_OnCacheInteraction.FireOutput(pPhysGunUser, this);
-
- if ( reason == PICKED_UP_BY_CANNON )
- {
- // Expand the pickup box
- CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT * 2 );
-
- if( m_pConstraint != NULL )
- {
- physenv->DestroyConstraint( m_pConstraint );
- m_pConstraint = NULL;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// Purpose:
-// Input : *pPhysGunUser -
-// reason -
-//-----------------------------------------------------------------------------
-void CItem::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason )
-{
- // Restore the pickup box to the original
- CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT );
-}
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Handling for the base world item. Most of this was moved from items.cpp.
+//
+// $NoKeywords: $
+//===========================================================================//
+
+#include "cbase.h"
+#include "player.h"
+#include "items.h"
+#include "gamerules.h"
+#include "engine/IEngineSound.h"
+#include "iservervehicle.h"
+#include "physics_saverestore.h"
+#include "world.h"
+
+#ifdef HL2MP
+#include "hl2mp_gamerules.h"
+#endif
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+#define ITEM_PICKUP_BOX_BLOAT 24
+
+class CWorldItem : public CBaseAnimating
+{
+ DECLARE_DATADESC();
+public:
+ DECLARE_CLASS( CWorldItem, CBaseAnimating );
+
+ bool KeyValue( const char *szKeyName, const char *szValue );
+ void Spawn( void );
+
+ int m_iType;
+};
+
+LINK_ENTITY_TO_CLASS(world_items, CWorldItem);
+
+BEGIN_DATADESC( CWorldItem )
+
+DEFINE_FIELD( m_iType, FIELD_INTEGER ),
+
+END_DATADESC()
+
+
+bool CWorldItem::KeyValue( const char *szKeyName, const char *szValue )
+{
+ if (FStrEq(szKeyName, "type"))
+ {
+ m_iType = atoi(szValue);
+ }
+ else
+ return BaseClass::KeyValue( szKeyName, szValue );
+
+ return true;
+}
+
+void CWorldItem::Spawn( void )
+{
+ CBaseEntity *pEntity = NULL;
+
+ switch (m_iType)
+ {
+ case 44: // ITEM_BATTERY:
+ pEntity = CBaseEntity::Create( "item_battery", GetLocalOrigin(), GetLocalAngles() );
+ break;
+ case 45: // ITEM_SUIT:
+ pEntity = CBaseEntity::Create( "item_suit", GetLocalOrigin(), GetLocalAngles() );
+ break;
+ }
+
+ if (!pEntity)
+ {
+ Warning("unable to create world_item %d\n", m_iType );
+ }
+ else
+ {
+ pEntity->m_target = m_target;
+ pEntity->SetName( GetEntityName() );
+ pEntity->ClearSpawnFlags();
+ pEntity->AddSpawnFlags( m_spawnflags );
+ }
+
+ UTIL_RemoveImmediate( this );
+}
+
+
+BEGIN_DATADESC( CItem )
+
+ DEFINE_FIELD( m_bActivateWhenAtRest, FIELD_BOOLEAN ),
+ DEFINE_FIELD( m_vOriginalSpawnOrigin, FIELD_POSITION_VECTOR ),
+ DEFINE_FIELD( m_vOriginalSpawnAngles, FIELD_VECTOR ),
+ DEFINE_PHYSPTR( m_pConstraint ),
+
+ // Function Pointers
+ DEFINE_ENTITYFUNC( ItemTouch ),
+ DEFINE_THINKFUNC( Materialize ),
+ DEFINE_THINKFUNC( ComeToRest ),
+
+#if defined( HL2MP ) || defined( TF_DLL )
+ DEFINE_FIELD( m_flNextResetCheckTime, FIELD_TIME ),
+ DEFINE_THINKFUNC( FallThink ),
+#endif
+
+ // Outputs
+ DEFINE_OUTPUT( m_OnPlayerTouch, "OnPlayerTouch" ),
+ DEFINE_OUTPUT( m_OnCacheInteraction, "OnCacheInteraction" ),
+
+END_DATADESC()
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+CItem::CItem()
+{
+ m_bActivateWhenAtRest = false;
+}
+
+bool CItem::CreateItemVPhysicsObject( void )
+{
+ // Create the object in the physics system
+ int nSolidFlags = GetSolidFlags() | FSOLID_NOT_STANDABLE;
+ if ( !m_bActivateWhenAtRest )
+ {
+ nSolidFlags |= FSOLID_TRIGGER;
+ }
+
+ if ( VPhysicsInitNormal( SOLID_VPHYSICS, nSolidFlags, false ) == NULL )
+ {
+ SetSolid( SOLID_BBOX );
+ AddSolidFlags( nSolidFlags );
+
+ // If it's not physical, drop it to the floor
+ if (UTIL_DropToFloor(this, MASK_SOLID) == 0)
+ {
+ Warning( "Item %s fell out of level at %f,%f,%f\n", GetClassname(), GetAbsOrigin().x, GetAbsOrigin().y, GetAbsOrigin().z);
+ UTIL_Remove( this );
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItem::Spawn( void )
+{
+ if ( g_pGameRules->IsAllowedToSpawn( this ) == false )
+ {
+ UTIL_Remove( this );
+ return;
+ }
+
+ SetMoveType( MOVETYPE_FLYGRAVITY );
+ SetSolid( SOLID_BBOX );
+ SetBlocksLOS( false );
+ AddEFlags( EFL_NO_ROTORWASH_PUSH );
+
+ if( IsX360() )
+ {
+ AddEffects( EF_ITEM_BLINK );
+ }
+
+ // This will make them not collide with the player, but will collide
+ // against other items + weapons
+ SetCollisionGroup( COLLISION_GROUP_WEAPON );
+ CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT );
+ SetTouch(&CItem::ItemTouch);
+
+ if ( CreateItemVPhysicsObject() == false )
+ return;
+
+ m_takedamage = DAMAGE_EVENTS_ONLY;
+
+#if !defined( CLIENT_DLL )
+ // Constrained start?
+ if ( HasSpawnFlags( SF_ITEM_START_CONSTRAINED ) )
+ {
+ //Constrain the weapon in place
+ IPhysicsObject *pReferenceObject, *pAttachedObject;
+
+ pReferenceObject = g_PhysWorldObject;
+ pAttachedObject = VPhysicsGetObject();
+
+ if ( pReferenceObject && pAttachedObject )
+ {
+ constraint_fixedparams_t fixed;
+ fixed.Defaults();
+ fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject );
+
+ fixed.constraint.forceLimit = lbs2kg( 10000 );
+ fixed.constraint.torqueLimit = lbs2kg( 10000 );
+
+ m_pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed );
+
+ m_pConstraint->SetGameData( (void *) this );
+ }
+ }
+#endif //CLIENT_DLL
+
+#if defined( HL2MP ) || defined( TF_DLL )
+ SetThink( &CItem::FallThink );
+ SetNextThink( gpGlobals->curtime + 0.1f );
+#endif
+}
+
+unsigned int CItem::PhysicsSolidMaskForEntity( void ) const
+{
+ return BaseClass::PhysicsSolidMaskForEntity() | CONTENTS_PLAYERCLIP;
+}
+
+void CItem::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value )
+{
+ CBasePlayer *pPlayer = ToBasePlayer( pActivator );
+
+ if ( pPlayer )
+ {
+ pPlayer->PickupObject( this );
+ }
+}
+
+extern int gEvilImpulse101;
+
+
+//-----------------------------------------------------------------------------
+// Activate when at rest, but don't allow pickup until then
+//-----------------------------------------------------------------------------
+void CItem::ActivateWhenAtRest( float flTime /* = 0.5f */ )
+{
+ RemoveSolidFlags( FSOLID_TRIGGER );
+ m_bActivateWhenAtRest = true;
+ SetThink( &CItem::ComeToRest );
+ SetNextThink( gpGlobals->curtime + flTime );
+}
+
+
+//-----------------------------------------------------------------------------
+// Become touchable when we are at rest
+//-----------------------------------------------------------------------------
+void CItem::OnEntityEvent( EntityEvent_t event, void *pEventData )
+{
+ BaseClass::OnEntityEvent( event, pEventData );
+
+ switch( event )
+ {
+ case ENTITY_EVENT_WATER_TOUCH:
+ {
+ // Delay rest for a sec, to avoid changing collision
+ // properties inside a collision callback.
+ SetThink( &CItem::ComeToRest );
+ SetNextThink( gpGlobals->curtime + 0.1f );
+ }
+ break;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Become touchable when we are at rest
+//-----------------------------------------------------------------------------
+void CItem::ComeToRest( void )
+{
+ if ( m_bActivateWhenAtRest )
+ {
+ m_bActivateWhenAtRest = false;
+ AddSolidFlags( FSOLID_TRIGGER );
+ SetThink( NULL );
+ }
+}
+
+#if defined( HL2MP ) || defined( TF_DLL )
+
+//-----------------------------------------------------------------------------
+// Purpose: Items that have just spawned run this think to catch them when
+// they hit the ground. Once we're sure that the object is grounded,
+// we change its solid type to trigger and set it in a large box that
+// helps the player get it.
+//-----------------------------------------------------------------------------
+void CItem::FallThink ( void )
+{
+ SetNextThink( gpGlobals->curtime + 0.1f );
+
+#if defined( HL2MP )
+ bool shouldMaterialize = false;
+ IPhysicsObject *pPhysics = VPhysicsGetObject();
+ if ( pPhysics )
+ {
+ shouldMaterialize = pPhysics->IsAsleep();
+ }
+ else
+ {
+ shouldMaterialize = (GetFlags() & FL_ONGROUND) ? true : false;
+ }
+
+ if ( shouldMaterialize )
+ {
+ SetThink ( NULL );
+
+ m_vOriginalSpawnOrigin = GetAbsOrigin();
+ m_vOriginalSpawnAngles = GetAbsAngles();
+
+ HL2MPRules()->AddLevelDesignerPlacedObject( this );
+ }
+#endif // HL2MP
+
+#if defined( TF_DLL )
+ // We only come here if ActivateWhenAtRest() is never called,
+ // which is the case when creating currencypacks in MvM
+ if ( !( GetFlags() & FL_ONGROUND ) )
+ {
+ if ( !GetAbsVelocity().Length() && GetMoveType() == MOVETYPE_FLYGRAVITY )
+ {
+ // Mr. Game, meet Mr. Hammer. Mr. Hammer, meet the uncooperative Mr. Physics.
+ // Mr. Physics really doesn't want to give our friend the FL_ONGROUND flag.
+ // This means our wonderfully helpful radius currency collection code will be sad.
+ // So in the name of justice, we ask that this flag be delivered unto him.
+
+ SetMoveType( MOVETYPE_NONE );
+ SetGroundEntity( GetWorldEntity() );
+ }
+ }
+ else
+ {
+ SetThink( &CItem::ComeToRest );
+ }
+#endif // TF
+}
+
+#endif // HL2MP, TF
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to tell whether an item may be picked up by the player. This
+// accounts for solid obstructions being in the way.
+// Input : *pItem - item in question
+// *pPlayer - player attempting the pickup
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool UTIL_ItemCanBeTouchedByPlayer( CBaseEntity *pItem, CBasePlayer *pPlayer )
+{
+ if ( pItem == NULL || pPlayer == NULL )
+ return false;
+
+ // For now, always allow a vehicle riding player to pick up things they're driving over
+ if ( pPlayer->IsInAVehicle() )
+ return true;
+
+ // Get our test positions
+ Vector vecStartPos;
+ IPhysicsObject *pPhysObj = pItem->VPhysicsGetObject();
+ if ( pPhysObj != NULL )
+ {
+ // Use the physics hull's center
+ QAngle vecAngles;
+ pPhysObj->GetPosition( &vecStartPos, &vecAngles );
+ }
+ else
+ {
+ // Use the generic bbox center
+ vecStartPos = pItem->CollisionProp()->WorldSpaceCenter();
+ }
+
+ Vector vecEndPos = pPlayer->EyePosition();
+
+ // FIXME: This is the simple first try solution towards the problem. We need to take edges and shape more into account
+ // for this to be fully robust.
+
+ // Trace between to see if we're occluded
+ trace_t tr;
+ CTraceFilterSkipTwoEntities filter( pPlayer, pItem, COLLISION_GROUP_PLAYER_MOVEMENT );
+ UTIL_TraceLine( vecStartPos, vecEndPos, MASK_SOLID, &filter, &tr );
+
+ // Occluded
+ // FIXME: For now, we exclude starting in solid because there are cases where this doesn't matter
+ if ( tr.fraction < 1.0f )
+ return false;
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Whether or not the item can be touched and picked up by the player, taking
+// into account obstructions and other hinderances
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CItem::ItemCanBeTouchedByPlayer( CBasePlayer *pPlayer )
+{
+ return UTIL_ItemCanBeTouchedByPlayer( this, pPlayer );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : pOther -
+//-----------------------------------------------------------------------------
+void CItem::ItemTouch( CBaseEntity *pOther )
+{
+ // Vehicles can touch items + pick them up
+ if ( pOther->GetServerVehicle() )
+ {
+ pOther = pOther->GetServerVehicle()->GetPassenger();
+ if ( !pOther )
+ return;
+ }
+
+ // if it's not a player, ignore
+ if ( !pOther->IsPlayer() )
+ return;
+
+ CBasePlayer *pPlayer = (CBasePlayer *)pOther;
+
+ // Must be a valid pickup scenario (no blocking). Though this is a more expensive
+ // check than some that follow, this has to be first Obecause it's the only one
+ // that inhibits firing the output OnCacheInteraction.
+ if ( ItemCanBeTouchedByPlayer( pPlayer ) == false )
+ return;
+
+ m_OnCacheInteraction.FireOutput(pOther, this);
+
+ // Can I even pick stuff up?
+ if ( !pPlayer->IsAllowedToPickupWeapons() )
+ return;
+
+ // 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 ) )
+ {
+ m_OnPlayerTouch.FireOutput(pOther, this);
+
+ SetTouch( NULL );
+ SetThink( NULL );
+
+ // player grabbed the item.
+ g_pGameRules->PlayerGotItem( pPlayer, this );
+ if ( g_pGameRules->ItemShouldRespawn( this ) == GR_ITEM_RESPAWN_YES )
+ {
+ Respawn();
+ }
+ else
+ {
+ UTIL_Remove( this );
+
+#ifdef HL2MP
+ HL2MPRules()->RemoveLevelDesignerPlacedObject( this );
+#endif
+ }
+ }
+ else if (gEvilImpulse101)
+ {
+ UTIL_Remove( this );
+ }
+}
+
+CBaseEntity* CItem::Respawn( void )
+{
+ SetTouch( NULL );
+ AddEffects( EF_NODRAW );
+
+ VPhysicsDestroyObject();
+
+ SetMoveType( MOVETYPE_NONE );
+ SetSolid( SOLID_BBOX );
+ AddSolidFlags( FSOLID_TRIGGER );
+
+ UTIL_SetOrigin( this, g_pGameRules->VecItemRespawnSpot( this ) );// blip to whereever you should respawn.
+ SetAbsAngles( g_pGameRules->VecItemRespawnAngles( this ) );// set the angles.
+
+#if !defined( TF_DLL )
+ UTIL_DropToFloor( this, MASK_SOLID );
+#endif
+
+ RemoveAllDecals(); //remove any decals
+
+ SetThink ( &CItem::Materialize );
+ SetNextThink( gpGlobals->curtime + g_pGameRules->FlItemRespawnTime( this ) );
+ return this;
+}
+
+void CItem::Materialize( void )
+{
+ CreateItemVPhysicsObject();
+
+ if ( IsEffectActive( EF_NODRAW ) )
+ {
+ // changing from invisible state to visible.
+
+#ifdef HL2MP
+ EmitSound( "AlyxEmp.Charge" );
+#else
+ EmitSound( "Item.Materialize" );
+#endif
+ RemoveEffects( EF_NODRAW );
+ DoMuzzleFlash();
+ }
+
+ SetTouch( &CItem::ItemTouch );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CItem::Precache()
+{
+ BaseClass::Precache();
+
+ PrecacheScriptSound( "Item.Materialize" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pPhysGunUser -
+// PICKED_UP_BY_CANNON -
+//-----------------------------------------------------------------------------
+void CItem::OnPhysGunPickup( CBasePlayer *pPhysGunUser, PhysGunPickup_t reason )
+{
+ m_OnCacheInteraction.FireOutput(pPhysGunUser, this);
+
+ if ( reason == PICKED_UP_BY_CANNON )
+ {
+ // Expand the pickup box
+ CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT * 2 );
+
+ if( m_pConstraint != NULL )
+ {
+ physenv->DestroyConstraint( m_pConstraint );
+ m_pConstraint = NULL;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pPhysGunUser -
+// reason -
+//-----------------------------------------------------------------------------
+void CItem::OnPhysGunDrop( CBasePlayer *pPhysGunUser, PhysGunDrop_t reason )
+{
+ // Restore the pickup box to the original
+ CollisionProp()->UseTriggerBounds( true, ITEM_PICKUP_BOX_BLOAT );
+}