Skip to content

Commit

Permalink
sentry animations
Browse files Browse the repository at this point in the history
  • Loading branch information
BenLubar committed Nov 2, 2023
1 parent e2f1e06 commit 7ac3498
Show file tree
Hide file tree
Showing 19 changed files with 300 additions and 215 deletions.
99 changes: 85 additions & 14 deletions src/game/client/swarm/c_asw_sentry_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ IMPLEMENT_CLIENTCLASS_DT( C_ASW_Sentry_Base, DT_ASW_Sentry_Base, CASW_Sentry_Bas
RecvPropInt( RECVINFO( m_nGunType ) ),
RecvPropEHandle( RECVINFO( m_hOriginalOwnerPlayer ) ),
RecvPropIntWithMinusOneFlag( RECVINFO( m_iInventoryEquipSlot ) ),
RecvPropEHandle( RECVINFO( m_hLastDisassembler ) ),
END_RECV_TABLE()

BEGIN_PREDICTION_DATA( C_ASW_Sentry_Base )
Expand All @@ -41,6 +42,17 @@ END_PREDICTION_DATA()

CUtlVector<C_ASW_Sentry_Base*> g_SentryGuns;

static const char *const s_szSentryTopBuildModels[] =
{
"models/sentry_gun/machinegun_top.mdl",
"models/sentry_gun/grenade_top.mdl",
"models/sentry_gun/flame_top.mdl",
"models/sentry_gun/freeze_top.mdl",
#ifdef RD_7A_WEAPONS
"models/sentry_gun/railgun_top.mdl",
#endif
};

vgui::HFont C_ASW_Sentry_Base::s_hAmmoFont = vgui::INVALID_FONT;

C_ASW_Sentry_Base::C_ASW_Sentry_Base()
Expand All @@ -53,24 +65,80 @@ C_ASW_Sentry_Base::C_ASW_Sentry_Base()
m_nUseIconTextureID = -1;
m_hOriginalOwnerPlayer = NULL;
m_iInventoryEquipSlot = -1;
m_hLastDisassembler = NULL;
}


C_ASW_Sentry_Base::~C_ASW_Sentry_Base()
{
if ( m_hBuildTop.Get() )
{
UTIL_Remove( m_hBuildTop.Get() );
m_hBuildTop = NULL;
}

g_SentryGuns.FindAndRemove( this );
}

bool C_ASW_Sentry_Base::ShouldDraw()
void C_ASW_Sentry_Base::OnDataChanged( DataUpdateType_t updateType )
{
return true;
BaseClass::OnDataChanged( updateType );

if ( updateType == DATA_UPDATE_CREATED )
{
SetNextClientThink( CLIENT_THINK_ALWAYS );
}
}

int C_ASW_Sentry_Base::DrawModel( int flags, const RenderableInstance_t &instance )
void C_ASW_Sentry_Base::ClientThink()
{
int d = BaseClass::DrawModel(flags, instance);
BaseClass::ClientThink();

if ( m_bAssembled )
{
if ( m_hBuildTop.Get() )
{
UTIL_Remove( m_hBuildTop.Get() );
m_hBuildTop = NULL;
}

SetNextClientThink( CLIENT_THINK_NEVER );

return d;
return;
}

if ( !m_hBuildTop.Get() )
{
C_BaseAnimating *pBuildTop = new C_BaseAnimating;
Assert( pBuildTop );
if ( !pBuildTop )
{
return;
}

if ( !pBuildTop->InitializeAsClientEntity( s_szSentryTopBuildModels[m_nGunType], false ) )
{
Assert( !"sentry top build model failed to spawn" );
UTIL_Remove( pBuildTop );
SetNextClientThink( CLIENT_THINK_NEVER );
return;
}

pBuildTop->SetOwnerEntity( this );
pBuildTop->SetParent( this );
pBuildTop->SetLocalOrigin( vec3_origin );
pBuildTop->SetLocalAngles( vec3_angle );
pBuildTop->SetSolid( SOLID_NONE );
pBuildTop->SetPoseParameter( "aim_pitch", -30.0f ); // should match the spawn value for m_fAimPitch on both client and server
pBuildTop->SetSequence( pBuildTop->SelectWeightedSequence( ACT_OBJ_ASSEMBLING ) );
pBuildTop->SetPlaybackRate( 0.0f );

m_hBuildTop = pBuildTop;
}

if ( m_hBuildTop )
{
m_hBuildTop->SetCycle( m_fAssembleProgress );
}
}

int C_ASW_Sentry_Base::GetSentryIconTextureID()
Expand Down Expand Up @@ -123,7 +191,7 @@ bool C_ASW_Sentry_Base::GetUseAction(ASWUseAction &action, C_ASW_Inhabitable_NPC
action.bShowHoldButtonUseKey = true;
action.bShowUseKey = true;
}
action.iUseIconTexture = GetSentryIconTextureID();
action.iUseIconTexture = GetSentryIconTextureID();
action.UseTarget = this;
}
else
Expand All @@ -139,7 +207,7 @@ bool C_ASW_Sentry_Base::GetUseAction(ASWUseAction &action, C_ASW_Inhabitable_NPC
TryLocalize( "#asw_assemble_sentry", action.wszText, sizeof( action.wszText ) );
action.bShowUseKey = true;
}
action.iUseIconTexture = GetSentryIconTextureID();
action.iUseIconTexture = GetSentryIconTextureID();
action.UseTarget = this;
action.fProgress = GetAssembleProgress();
}
Expand Down Expand Up @@ -184,14 +252,17 @@ void C_ASW_Sentry_Base::CustomPaint( int ix, int iy, int alpha, vgui::Panel *pUs
}
}

const char* C_ASW_Sentry_Base::GetWeaponClass()
const char *C_ASW_Sentry_Base::GetWeaponClass()
{
switch( m_nGunType.Get() )
switch ( m_nGunType.Get() )
{
case 0: return "asw_weapon_sentry";
case 1: return "asw_weapon_sentry_cannon";
case 2: return "asw_weapon_sentry_flamer";
case 3: return "asw_weapon_sentry_freeze";
case 0: return "asw_weapon_sentry";
case 1: return "asw_weapon_sentry_cannon";
case 2: return "asw_weapon_sentry_flamer";
case 3: return "asw_weapon_sentry_freeze";
#ifdef RD_7A_WEAPONS
case 4: return "asw_weapon_sentry_railgun";
#endif
}
return "asw_weapon_sentry";
}
Expand Down
10 changes: 7 additions & 3 deletions src/game/client/swarm/c_asw_sentry_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ class C_ASW_Sentry_Base : public C_BaseAnimating, public IASW_Client_Usable_Enti
C_ASW_Sentry_Base();
virtual ~C_ASW_Sentry_Base();

bool ShouldDraw();

virtual int DrawModel( int flags, const RenderableInstance_t &instance );
void OnDataChanged( DataUpdateType_t updateType ) override;
void ClientThink() override;

bool IsAssembled() const { return m_bAssembled; }
bool IsInUse() const { return m_bIsInUse; }
Expand All @@ -44,9 +43,14 @@ class C_ASW_Sentry_Base : public C_BaseAnimating, public IASW_Client_Usable_Enti
CNetworkVar( int, m_iInventoryEquipSlot );
bool IsInventoryEquipSlotValid() const { return !!m_hOriginalOwnerPlayer && m_iInventoryEquipSlot != -1; }

CNetworkHandle( C_ASW_Inhabitable_NPC, m_hLastDisassembler );

// class of the weapon that created us
const char* GetWeaponClass();

// fake sentry top for building animation
CHandle<C_BaseAnimating> m_hBuildTop;

// IASW_Client_Usable_Entity
virtual C_BaseEntity* GetEntity() { return this; }
virtual bool IsUsable(C_BaseEntity *pUser);
Expand Down
29 changes: 19 additions & 10 deletions src/game/client/swarm/c_asw_sentry_top.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ IMPLEMENT_CLIENTCLASS_DT( C_ASW_Sentry_Top, DT_ASW_Sentry_Top, CASW_Sentry_Top )
RecvPropInt( RECVINFO( m_iSentryAngle ) ),
RecvPropFloat( RECVINFO( m_fDeployYaw ) ),
RecvPropFloat( RECVINFO( m_fCenterAimYaw ) ),
RecvPropFloat( RECVINFO( m_fGoalPitch ) ),
RecvPropFloat( RECVINFO( m_fGoalYaw ) ),
RecvPropBool( RECVINFO( m_bLowAmmo ) ),
END_RECV_TABLE()

Expand All @@ -26,11 +28,21 @@ BEGIN_PREDICTION_DATA( C_ASW_Sentry_Top )
END_PREDICTION_DATA()

C_ASW_Sentry_Top::C_ASW_Sentry_Top() :
m_iv_fCenterAimYaw( "C_ASW_Sentry_Top::m_iv_fCenterAimYaw" )
m_iv_fCenterAimYaw( "C_ASW_Sentry_Top::m_iv_fCenterAimYaw" ),
m_iv_fGoalYaw( "C_ASW_Sentry_Top::m_iv_fGoalYaw" ),
m_iv_fGoalPitch( "C_ASW_Sentry_Top::m_iv_fGoalPitch" )
{
UseClientSideAnimation();

AddVar( &m_fCenterAimYaw, &m_iv_fCenterAimYaw, LATCH_SIMULATION_VAR );
AddVar( &m_fGoalYaw, &m_iv_fGoalYaw, LATCH_SIMULATION_VAR );
AddVar( &m_fGoalPitch, &m_iv_fGoalPitch, LATCH_SIMULATION_VAR );

m_bSpawnedDisplayEffects = false;

m_iPoseParamPitch = -2;
m_iPoseParamYaw = -2;
m_iPoseParamFireRate = -2;
}

C_ASW_Sentry_Top::~C_ASW_Sentry_Top()
Expand Down Expand Up @@ -85,7 +97,10 @@ void C_ASW_Sentry_Top::OnDataChanged( DataUpdateType_t updateType )
C_RD_Weapon_Accessory::CreateWeaponAccessories( this, pBase->m_hOriginalOwnerPlayer->m_EquippedItemDataDynamic[pBase->m_iInventoryEquipSlot], m_hWeaponAccessory, s_pKVAccessoryPosition[pBase->m_nGunType], s_szAccessoryPositionFiles[pBase->m_nGunType] );
}

SetNextClientThink( gpGlobals->curtime );
m_fAimPitch = -30.0f; // should match the angle that the build animation uses
m_fCameraYaw = 0.0f;

SetNextClientThink( CLIENT_THINK_ALWAYS );
}

if ( m_bLowAmmo && !m_hWarningLight )
Expand Down Expand Up @@ -136,9 +151,8 @@ void C_ASW_Sentry_Top::ClientThink()
{
BaseClass::ClientThink();

UpdatePose();
Scan();

SetNextClientThink( gpGlobals->curtime + 0.05f );
}

int C_ASW_Sentry_Top::GetMuzzleAttachment( void )
Expand Down Expand Up @@ -209,11 +223,6 @@ C_ASW_Sentry_Base *C_ASW_Sentry_Top::GetSentryBase()
return m_hSentryBase.Get();
}

int C_ASW_Sentry_Top::GetSentryAngle( void )
{
return m_iSentryAngle;
}

void C_ASW_Sentry_Top::Scan()
{
C_ASW_Sentry_Base *RESTRICT pBase = GetSentryBase();
Expand Down Expand Up @@ -311,7 +320,7 @@ void C_ASW_Sentry_Top::Scan()
AdjustRadiusBeamEdges( vecEye, forward, 3 );

scanAngle = baseAngle;
scanAngle.y += GetSentryAngle() * sin( gpGlobals->curtime * 3.0f );
scanAngle.y += GetScanAngle();

Vector vecBase = pBase->GetAbsOrigin() + Vector( 0, 0, 2 );// + m_vecLightOffset;
AngleVectors( scanAngle, &forward, NULL, NULL );
Expand Down
12 changes: 12 additions & 0 deletions src/game/client/swarm/c_asw_sentry_top.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class C_ASW_Sentry_Top : public C_BaseCombatCharacter
virtual bool HasPilotLight() { return false; }

int GetSentryAngle( void );
float GetScanAngle();
void UpdatePose();
void Scan( void );
void CreateRadiusBeamEdges( const Vector &vecStart, const Vector &vecDir, int iControlPoint );

Expand All @@ -44,10 +46,20 @@ class C_ASW_Sentry_Top : public C_BaseCombatCharacter
CNetworkVar( int, m_iSentryAngle );
CNetworkVar( float, m_fDeployYaw );
CNetworkVar( float, m_fCenterAimYaw );
float m_fAimPitch;
float m_fCameraYaw;
CNetworkVar( float, m_fGoalPitch );
CNetworkVar( float, m_fGoalYaw );
CNetworkVar( bool, m_bLowAmmo );
float GetDeployYaw();

CInterpolatedVar<float> m_iv_fCenterAimYaw;
CInterpolatedVar<float> m_iv_fGoalYaw;
CInterpolatedVar<float> m_iv_fGoalPitch;

int m_iPoseParamPitch;
int m_iPoseParamYaw;
int m_iPoseParamFireRate;

bool m_bSpawnedDisplayEffects;
CUtlReference<CNewParticleEffect> m_hRadiusDisplay;
Expand Down
93 changes: 1 addition & 92 deletions src/game/client/swarm/c_asw_sentry_top_flamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@ void C_ASW_Sentry_Top_Flamer::OnDataChanged( DataUpdateType_t updateType )

if ( updateType == DATA_UPDATE_CREATED )
{
//CreateObsoleteEmitters();

SetNextClientThink(gpGlobals->curtime);
// We might want to think every frame.
// SetNextClientThink( CLIENT_THINK_ALWAYS );

m_bFiringShadow = m_bFiring;

if ( HasPilotLight() && !m_hPilotLight )
Expand Down Expand Up @@ -83,91 +77,6 @@ void C_ASW_Sentry_Top_Flamer::OnDataChanged( DataUpdateType_t updateType )
}
}

void C_ASW_Sentry_Top_Flamer::ClientThink( void )
{
BaseClass::ClientThink();
/*
// walk emitters and turn them on or off as appropriate, then call their thinks.
if ( m_OldStyleEmitters.Count() > 0 )
{
// a turret with old school emitters must think every frame.
// we need to forcibly reset this because the base class sets a longer
// think interval.
SetNextClientThink( CLIENT_THINK_ALWAYS );
bool bWantEmitters = ShouldEmittersBeOn();
Vector vecMuzzle = GetAbsOrigin()+Vector(0,0,30);
QAngle angMuzzle;
GetAttachment( GetMuzzleAttachment(), vecMuzzle, angMuzzle );
Vector vForward; AngleVectors(angMuzzle, &vForward);
angMuzzle.x = m_flPitchHack;
vecMuzzle += vForward * 36;
for ( int i = 0 ; i < m_OldStyleEmitters.Count() ; ++i )
{
CSmartPtr<CASWGenericEmitter> &hEmitter = m_OldStyleEmitters[i];
Assert( hEmitter.IsValid() );
if ( hEmitter.IsValid() )
{
if ( hEmitter->GetActive() != bWantEmitters )
{
hEmitter->SetActive( bWantEmitters );
}
// now think them so they have the correct orientation
hEmitter->Think(gpGlobals->frametime, vecMuzzle, angMuzzle);
}
}
}
*/
}

/*
void C_ASW_Sentry_Top_Flamer::CreateObsoleteEmitters( void )
{
AssertMsg( m_OldStyleEmitters.Count() == 0, "Flame turret tried to create emitters when it already had some!" );
// create two emitter handles (use default constructor to pull them to NULL to begin with)
m_OldStyleEmitters.EnsureCount(2);
CSmartPtr<CASWGenericEmitter> &m_hFlameEmitter = m_OldStyleEmitters[0];
CSmartPtr<CASWGenericEmitter> &m_hFlameStreamEmitter = m_OldStyleEmitters[1];
m_hFlameEmitter = CASWGenericEmitter::Create( "asw_emitter" );
if ( m_hFlameEmitter.IsValid() )
{
m_hFlameEmitter->UseTemplate("flamer5");
m_hFlameEmitter->SetActive(false);
m_hFlameEmitter->m_hCollisionIgnoreEntity = this;
m_hFlameEmitter->SetCustomCollisionGroup(ASW_COLLISION_GROUP_IGNORE_NPCS);
//m_hFlameEmitter->SetGlowMaterial("swarm/sprites/aswredglow2");
}
else
{
AssertMsg( false, "m_hFlameEmitter.IsValid()" );
Warning("Failed to create a turret's flame emitter\n");
}
m_hFlameStreamEmitter = CASWGenericEmitter::Create( "asw_emitter" );
if ( m_hFlameStreamEmitter.IsValid() )
{
m_hFlameStreamEmitter->UseTemplate("flamerstream1");
m_hFlameStreamEmitter->SetActive(false);
m_hFlameStreamEmitter->m_hCollisionIgnoreEntity = this;
m_hFlameStreamEmitter->SetCustomCollisionGroup(ASW_COLLISION_GROUP_IGNORE_NPCS);
//m_hFlameEmitter->SetGlowMaterial("swarm/sprites/aswredglow2");
}
else
{
AssertMsg( false, "m_hFlameStreamEmitter.IsValid()" );
Warning("Failed to create a turret's flame stream emitter\n");
}
}
*/

void C_ASW_Sentry_Top_Flamer::OnStartFiring()
{
if ( m_szBeginFireSoundScriptName )
Expand Down Expand Up @@ -221,4 +130,4 @@ void C_ASW_Sentry_Top_Flamer::UpdateOnRemove()
OnStopFiring();

BaseClass::UpdateOnRemove();
}
}
Loading

0 comments on commit 7ac3498

Please sign in to comment.