Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 158 additions & 25 deletions sp/src/game/server/hl2/npc_turret_floor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ const char *GetMassEquivalent(float flMass);
//Debug visualization
ConVar g_debug_turret( "g_debug_turret", "0" );

#ifdef MAPBASE
ConVar sk_floor_turret_dmg( "sk_floor_turret_dmg", "3" );
ConVar sk_floor_turret_health( "sk_floor_turret_health", "100" );
#endif

extern ConVar physcannon_tracelength;

#if defined(MAPBASE) && defined(HL2_EPISODIC)
Expand Down Expand Up @@ -85,6 +90,12 @@ int ACT_FLOOR_TURRET_FIRE;
BEGIN_DATADESC( CNPC_FloorTurret )

DEFINE_FIELD( m_iAmmoType, FIELD_INTEGER ),
#ifdef MAPBASE
DEFINE_KEYFIELD( m_iAmmoCount, FIELD_INTEGER, "ammocount"),
DEFINE_KEYFIELD( m_bKillable, FIELD_BOOLEAN, "killable"),
DEFINE_KEYFIELD( m_bImmovable, FIELD_BOOLEAN, "immovable"),
DEFINE_KEYFIELD( m_bBehaviorOnFall, FIELD_INTEGER, "behavioronfall"),
#endif
DEFINE_FIELD( m_bAutoStart, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bActive, FIELD_BOOLEAN ),
DEFINE_FIELD( m_bBlinkState, FIELD_BOOLEAN ),
Expand Down Expand Up @@ -144,6 +155,7 @@ BEGIN_DATADESC( CNPC_FloorTurret )
#ifdef MAPBASE
DEFINE_INPUTFUNC( FIELD_VOID, "CreateSprite", InputCreateSprite ),
DEFINE_INPUTFUNC( FIELD_VOID, "DestroySprite", InputDestroySprite ),
DEFINE_INPUTFUNC( FIELD_INTEGER, "ChangeAmmoCount", InputChangeAmmoCount ),
#endif
DEFINE_INPUTFUNC( FIELD_VOID, "SelfDestruct", InputSelfDestruct ),

Expand All @@ -154,6 +166,8 @@ BEGIN_DATADESC( CNPC_FloorTurret )
DEFINE_OUTPUT( m_OnPhysGunDrop, "OnPhysGunDrop" ),
#ifdef MAPBASE
DEFINE_OUTPUT( m_OnStartTipped, "OnStartTipped" ),
DEFINE_OUTPUT( m_OnDepletedAmmo, "OnDepletedAmmo" ),
DEFINE_OUTPUT( m_OnExploded, "OnExploded" ),
#endif

DEFINE_BASENPCINTERACTABLE_DATADESC(),
Expand Down Expand Up @@ -189,6 +203,13 @@ CNPC_FloorTurret::CNPC_FloorTurret( void ) :
m_vecGoalAngles.Init();

m_vecEnemyLKP = vec3_invalid;

#ifdef MAPBASE
KeyValue("ammocount", "-1");
KeyValue("killable", "0");
KeyValue("immovable", "0");
KeyValue("behavioronfall", "0");
#endif
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -319,8 +340,22 @@ void CNPC_FloorTurret::Spawn( void )
m_HackedGunPos = Vector( 0, 0, 12.75 );
SetViewOffset( EyeOffset( ACT_IDLE ) );
m_flFieldOfView = 0.4f; // 60 degrees
#ifdef MAPBASE
if ( m_bKillable )
m_takedamage = DAMAGE_YES;
else
m_takedamage = DAMAGE_EVENTS_ONLY;

if ( m_bImmovable )
{
SetSolid( SOLID_VPHYSICS );
}

m_iHealth = sk_floor_turret_health.GetInt();
#else
m_takedamage = DAMAGE_EVENTS_ONLY;
m_iHealth = 100;
#endif
m_iMaxHealth = 100;

AddEFlags( EFL_NO_DISSOLVE );
Expand Down Expand Up @@ -367,7 +402,12 @@ void CNPC_FloorTurret::Spawn( void )
// Don't allow us to skip animation setup because our attachments are critical to us!
SetBoneCacheFlags( BCF_NO_ANIMATION_SKIP );

#ifdef MAPBASE
if ( !m_bImmovable )
CreateVPhysics();
#else
CreateVPhysics();
#endif

SetState(NPC_STATE_IDLE);
}
Expand Down Expand Up @@ -1152,34 +1192,55 @@ void CNPC_FloorTurret::Shoot( const Vector &vecSrc, const Vector &vecDirToEnemy,
{
FireBulletsInfo_t info;

if ( !bStrict && GetEnemy() != NULL )
if ( m_iAmmoCount > 0 || m_iAmmoCount == -1 )
{
Vector vecDir = GetActualShootTrajectory( vecSrc );

info.m_vecSrc = vecSrc;
info.m_vecDirShooting = vecDir;
info.m_iTracerFreq = 1;
info.m_iShots = 1;
info.m_pAttacker = this;
info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
info.m_flDistance = MAX_COORD_RANGE;
info.m_iAmmoType = m_iAmmoType;
}
else
{
info.m_vecSrc = vecSrc;
info.m_vecDirShooting = vecDirToEnemy;
info.m_iTracerFreq = 1;
info.m_iShots = 1;
info.m_pAttacker = this;
info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() );
info.m_flDistance = MAX_COORD_RANGE;
info.m_iAmmoType = m_iAmmoType;
}
if ( !bStrict && GetEnemy() != NULL )
{
Vector vecDir = GetActualShootTrajectory( vecSrc );

info.m_vecSrc = vecSrc;
info.m_vecDirShooting = vecDir;
info.m_iTracerFreq = 1;
#ifdef MAPBASE
info.m_flDamage = sk_floor_turret_dmg.GetFloat();
#endif
info.m_iShots = 1;
info.m_pAttacker = this;
info.m_vecSpread = VECTOR_CONE_PRECALCULATED;
info.m_flDistance = MAX_COORD_RANGE;
info.m_iAmmoType = m_iAmmoType;
}
else
{
info.m_vecSrc = vecSrc;
info.m_vecDirShooting = vecDirToEnemy;
info.m_iTracerFreq = 1;
#ifdef MAPBASE
info.m_flDamage = sk_floor_turret_dmg.GetFloat();
#endif
info.m_iShots = 1;
info.m_pAttacker = this;
info.m_vecSpread = GetAttackSpread( NULL, GetEnemy() );
info.m_flDistance = MAX_COORD_RANGE;
info.m_iAmmoType = m_iAmmoType;
}

FireBullets( info );
EmitSound( "NPC_FloorTurret.ShotSounds", m_ShotSounds );
DoMuzzleFlash();

FireBullets( info );
EmitSound( "NPC_FloorTurret.ShotSounds", m_ShotSounds );
DoMuzzleFlash();
#ifdef MAPBASE
if( m_iAmmoCount > 0 )
m_iAmmoCount--;

if ( m_iAmmoCount == 0 && !HasSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO ) )
{
AddSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO );
m_OnDepletedAmmo.FireOutput( this, this );
}
#endif
}
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1400,6 +1461,9 @@ void CNPC_FloorTurret::InactiveThink( void )
//-----------------------------------------------------------------------------
void CNPC_FloorTurret::ReturnToLife( void )
{
if ( m_bBehaviorOnFall == 1 )
return;

m_flThrashTime = 0;

// Enable the tip controller
Expand Down Expand Up @@ -1791,6 +1855,10 @@ void CNPC_FloorTurret::InputDisable( inputdata_t &inputdata )
void CNPC_FloorTurret::InputDepleteAmmo( inputdata_t &inputdata )
{
AddSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO );
#ifdef MAPBASE
m_iAmmoCount = 0;
m_OnDepletedAmmo.FireOutput( this, this );
#endif
}

//-----------------------------------------------------------------------------
Expand All @@ -1799,9 +1867,28 @@ void CNPC_FloorTurret::InputDepleteAmmo( inputdata_t &inputdata )
void CNPC_FloorTurret::InputRestoreAmmo( inputdata_t &inputdata )
{
RemoveSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO );
#ifdef MAPBASE
m_iAmmoCount = -1;
#endif
}

#ifdef MAPBASE
void CNPC_FloorTurret::InputChangeAmmoCount( inputdata_t &inputdata )
{
if ( inputdata.value.Int() > 0 || inputdata.value.Int() == -1 )
{
if ( HasSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO ) )
RemoveSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO );
}
else if ( inputdata.value.Int() == 0 )
{
AddSpawnFlags( SF_FLOOR_TURRET_OUT_OF_AMMO );
}

m_iAmmoCount = inputdata.value.Int();
m_OnDepletedAmmo.FireOutput( this, this );
}

//-----------------------------------------------------------------------------
// Purpose: Creates the sprite if it has been destroyed
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1886,6 +1973,45 @@ int CNPC_FloorTurret::VPhysicsTakeDamage( const CTakeDamageInfo &info )
return BaseClass::VPhysicsTakeDamage( info );
}

#ifdef MAPBASE
void CNPC_FloorTurret::Explode()
{
if ( !m_bImmovable )
CreateVPhysics();

m_flDestructStartTime = gpGlobals->curtime;
m_flPingTime = gpGlobals->curtime;
m_bSelfDestructing = true;

SetThink( &CNPC_FloorTurret::SelfDestructThink );
SetNextThink( gpGlobals->curtime + 0.1f );

// Create the dust effect in place
m_hFizzleEffect = ( CParticleSystem* ) CreateEntityByName( "info_particle_system" );
if ( m_hFizzleEffect != NULL )
{
Vector vecUp;
GetVectors( NULL, NULL, &vecUp );

// Setup our basic parameters
m_hFizzleEffect->KeyValue( "start_active", "1" );
m_hFizzleEffect->KeyValue( "effect_name", "explosion_turret_fizzle" );
m_hFizzleEffect->SetParent( this );
m_hFizzleEffect->SetAbsOrigin( WorldSpaceCenter() + ( vecUp * 12.0f ) );
DispatchSpawn( m_hFizzleEffect );
m_hFizzleEffect->Activate();
}
}

void CNPC_FloorTurret::Event_Killed( const CTakeDamageInfo& info )
{
if ( (m_bKillable && m_iHealth < 0) || m_bBehaviorOnFall == 2 )
Explode();

BaseClass::Event_Killed( info );
}
#endif

//-----------------------------------------------------------------------------
// Purpose:
// Input : &info -
Expand Down Expand Up @@ -2131,6 +2257,9 @@ void CNPC_FloorTurret::BreakThink( void )
}

// We're done!
#ifdef MAPBASE
m_OnExploded.FireOutput( this, this );
#endif
UTIL_Remove( this );
}

Expand Down Expand Up @@ -2196,6 +2325,9 @@ void CNPC_FloorTurret::SelfDestructThink( void )
//-----------------------------------------------------------------------------
void CNPC_FloorTurret::InputSelfDestruct( inputdata_t &inputdata )
{
#ifdef MAPBASE
Explode();
#else
// Ka-boom!
m_flDestructStartTime = gpGlobals->curtime;
m_flPingTime = gpGlobals->curtime;
Expand All @@ -2219,6 +2351,7 @@ void CNPC_FloorTurret::InputSelfDestruct( inputdata_t &inputdata )
DispatchSpawn( m_hFizzleEffect );
m_hFizzleEffect->Activate();
}
#endif
}

//
Expand Down
21 changes: 21 additions & 0 deletions sp/src/game/server/hl2/npc_turret_floor.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum eyeState_t
#define SF_FLOOR_TURRET_CITIZEN 0x00000200 // Citizen modified turret
#ifdef MAPBASE
#define SF_FLOOR_TURRET_NO_SPRITE 0x00000400
#define SF_FLOOR_TURRET_DIE_PERMANENTLY 0x00000800
#endif

class CTurretTipController;
Expand All @@ -70,6 +71,10 @@ class CNPC_FloorTurret : public CNPCBaseInteractive<CAI_BaseNPC>, public CDefaul
virtual void PlayerPenetratingVPhysics( void );
virtual int VPhysicsTakeDamage( const CTakeDamageInfo &info );
virtual bool CanBecomeServerRagdoll( void ) { return false; }
#ifdef MAPBASE
virtual void Event_Killed( const CTakeDamageInfo& info );
void Explode();
#endif

#ifdef HL2_EPISODIC
// We don't want to be NPCSOLID because we'll collide with NPC clips
Expand Down Expand Up @@ -214,6 +219,10 @@ class CNPC_FloorTurret : public CNPCBaseInteractive<CAI_BaseNPC>, public CDefaul
void DryFire( void );
void UpdateMuzzleMatrix();

#ifdef MAPBASE
void InputChangeAmmoCount( inputdata_t& inputdata );
#endif

protected:
matrix3x4_t m_muzzleToWorld;
int m_muzzleToWorldTick;
Expand All @@ -238,6 +247,16 @@ class CNPC_FloorTurret : public CNPCBaseInteractive<CAI_BaseNPC>, public CDefaul
#ifndef MAPBASE // Replaced with m_nSkin.
int m_iKeySkin;
#endif
#ifdef MAPBASE
int m_iAmmoCount;
bool m_bImmovable;
bool m_bKillable;

int m_bBehaviorOnFall;
// 0 - normal
// 1 - deactivate and never come back
// 2 - explode
#endif

CHandle<CBaseCombatCharacter> m_hLastNPCToKickMe; // Stores the last NPC who tried to knock me over
float m_flKnockOverFailedTime; // Time at which we should tell the NPC that he failed to knock me over
Expand Down Expand Up @@ -267,6 +286,8 @@ class CNPC_FloorTurret : public CNPCBaseInteractive<CAI_BaseNPC>, public CDefaul
COutputEvent m_OnPhysGunDrop;
#ifdef MAPBASE
COutputEvent m_OnStartTipped;
COutputEvent m_OnDepletedAmmo;
COutputEvent m_OnExploded;
#endif

bool m_bHackedByAlyx;
Expand Down
Loading