Weapon Respawn Fix
Introduction
When weapons are not placed correctly by level designers (i.e. when their bounding boxes intersect other entities or world geometry), they will respawn at an incorrect place on the map after being picked up by players. In most cases, the weapon will instead respawn at 0 0 0
on the map, and will continue on in a perpetual loop of falling, waiting, respawning and falling again. Fortunately, the fix for this extremely common bug is very simple.
Requirements
- Using the latest multiplayer OB SDK code
Solution
Open game/shared/hl2mp/weapon_hl2mpbase.h
and change this block:
#ifdef GAME_DLL
DECLARE_DATADESC();
void Materialize( void );
virtual int ObjectCaps( void );
#endif
such that it becomes:
#ifdef GAME_DLL
DECLARE_DATADESC();
void Materialize( void );
virtual int ObjectCaps( void );
virtual void FallThink( void ); // make the weapon fall to the ground after spawning
#endif
Now, edit game/shared/hl2mp/weapon_hl2mpbase.cpp
and in CWeaponHL2MPBase::FallInit( void )
, change:
SetThink(&CBaseCombatWeapon::FallThink);
to:
SetThink(&CWeaponHL2MPBase::FallThink);
Add the following block below CWeaponHL2MPBase::FallInit( void )
:
#ifdef GAME_DLL
void CWeaponHL2MPBase::FallThink(void)
{
// Prevent the common HL2DM weapon respawn bug from happening
// When a weapon is spawned, the following chain of events occurs:
// - Spawn() is called (duh), which then calls FallInit()
// - FallInit() is called, and prepares the weapon's 'Think' function (CBaseCombatWeapon::FallThink())
// - FallThink() is called, and performs several checks before deciding whether the weapon should Materialize()
// - Materialize() is called (the HL2DM version above), which sets the weapon's respawn location.
// The problem occurs when a weapon isn't placed properly by a level designer.
// If the weapon is unable to move from its location (e.g. if its bounding box is halfway inside a wall), Materialize() never gets called.
// Since Materialize() never gets called, the weapon's respawn location is never set, so if a person picks it up, it respawns forever at
// 0 0 0 on the map (infinite loop of fall, wait, respawn, not nice at all for performance and bandwidth!)
if ( HasSpawnFlags( SF_NORESPAWN ) == false )
{
if ( GetOriginalSpawnOrigin() == vec3_origin )
{
m_vOriginalSpawnOrigin = GetAbsOrigin();
m_vOriginalSpawnAngles = GetAbsAngles();
}
}
return BaseClass::FallThink();
}
#endif // GAME_DLL
And that's really all there is to it - incorrectly placed weapons should now respawn at their correct locations, instead of some awkward location on the map.