diff --git a/sp/src/game/client/client_ez2.vpc b/sp/src/game/client/client_ez2.vpc index 819c949608..eab8cdb73f 100644 --- a/sp/src/game/client/client_ez2.vpc +++ b/sp/src/game/client/client_ez2.vpc @@ -40,6 +40,7 @@ $Project "Client (Entropy Zero 2)" $File "ez2\c_npc_base_husk.cpp" $File "$SRCDIR\game\shared\ez2\npc_husk_base_shared.h" $File "ez2\c_npc_crabsynth.cpp" + $File "ez2\c_npc_crabsynth.h" $File "ez2\c_npc_wilson.cpp" $File "ez2\c_npc_wilson.h" $File "ez2\c_weapon_pulse_pistol.cpp" diff --git a/sp/src/game/client/ez2/c_npc_crabsynth.cpp b/sp/src/game/client/ez2/c_npc_crabsynth.cpp index 7566f68007..e2e0031959 100644 --- a/sp/src/game/client/ez2/c_npc_crabsynth.cpp +++ b/sp/src/game/client/ez2/c_npc_crabsynth.cpp @@ -1,18 +1,160 @@ //=============================================================================// // -// Purpose: Clientside implementation of the Crab Synth NPC. Currently only -// used for the grenade's material proxy. +// Purpose: Clientside implementation of the Crab Synth NPC. // // Author: Blixibon // //=============================================================================// #include "cbase.h" +#include "c_npc_crabsynth.h" #include "basegrenade_shared.h" #include "particle_parse.h" #include "functionproxy.h" #include "toolframework_client.h" +IMPLEMENT_CLIENTCLASS_DT( C_NPC_CrabSynth, DT_NPC_CrabSynth, CNPC_CrabSynth ) + RecvPropBool( RECVINFO( m_bProjectedLightEnabled ) ), + RecvPropBool( RECVINFO( m_bProjectedLightShadowsEnabled ) ), + RecvPropFloat( RECVINFO( m_flProjectedLightBrightnessScale ) ), + RecvPropFloat( RECVINFO( m_flProjectedLightFOV ) ), + RecvPropFloat( RECVINFO( m_flProjectedLightHorzFOV ) ), +END_RECV_TABLE() + +LINK_ENTITY_TO_CLASS( npc_crabsynth, C_NPC_CrabSynth ) + +C_NPC_CrabSynth::C_NPC_CrabSynth() +{ +} + +C_NPC_CrabSynth::~C_NPC_CrabSynth() +{ + if (m_LightL) + { + // Turned off the flashlight; delete it. + delete m_LightL; + m_LightL = NULL; + } + if (m_LightR) + { + // Turned off the flashlight; delete it. + delete m_LightR; + m_LightR = NULL; + } +} + +void C_NPC_CrabSynth::UpdateLight( CCrabSynthLightEffect **ppLight, int nAttachment ) +{ + CCrabSynthLightEffect *pLight = *ppLight; + if ( pLight == NULL ) + { + // Turned on the headlight; create it. + *ppLight = new CCrabSynthLightEffect; + pLight = *ppLight; + + if ( pLight == NULL ) + return; + + pLight->m_bShadowsEnabled = m_bProjectedLightShadowsEnabled; + pLight->m_flBrightnessScale = m_flProjectedLightBrightnessScale; + pLight->m_flFOV = m_flProjectedLightFOV; + pLight->m_flHorzFOV = m_flProjectedLightHorzFOV; + + pLight->TurnOn(); + } + else + { + if (pLight->m_flBrightnessScale != m_flProjectedLightBrightnessScale) + pLight->m_flBrightnessScale = FLerp( pLight->m_flBrightnessScale, m_flProjectedLightBrightnessScale, 0.1f ); + + if (pLight->m_bShadowsEnabled != m_bProjectedLightShadowsEnabled) + pLight->m_bShadowsEnabled = m_bProjectedLightShadowsEnabled; + + if (pLight->m_flFOV != m_flProjectedLightFOV) + pLight->m_flFOV = m_flProjectedLightFOV; + + if (pLight->m_flHorzFOV != m_flProjectedLightHorzFOV) + pLight->m_flHorzFOV = m_flProjectedLightHorzFOV; + } + + if ( nAttachment != -1 ) + { + matrix3x4_t matAttachment; + GetAttachment( nAttachment, matAttachment ); + + Vector vVector; + Vector vecForward, vecRight, vecUp; + + MatrixGetColumn( matAttachment, 0, vecForward ); + MatrixGetColumn( matAttachment, 1, vecRight ); + MatrixGetColumn( matAttachment, 2, vecUp ); + MatrixGetColumn( matAttachment, 3, vVector ); + + // Update the flashlight + pLight->UpdateLight( vVector, vecForward, vecRight, vecUp, 40 ); + } +} + +void C_NPC_CrabSynth::Simulate( void ) +{ + // The dim light is the flashlight. + if ( m_bProjectedLightEnabled ) + { + if (m_LightL == NULL || m_LightL->m_flBrightnessScale > 0.0f) + { + if (m_nAttachmentLightL == -1) + m_nAttachmentLightL = LookupAttachment( "eye_l" ); + + UpdateLight( &m_LightL, m_nAttachmentLightL ); + } + else if (m_LightL) + { + // Turned off the flashlight; delete it. + delete m_LightL; + m_LightL = NULL; + } + + if (m_LightR == NULL || m_LightR->m_flBrightnessScale > 0.0f) + { + if (m_nAttachmentLightR == -1) + m_nAttachmentLightR = LookupAttachment( "eye_r" ); + + UpdateLight( &m_LightR, m_nAttachmentLightR ); + } + else if (m_LightR) + { + // Turned off the flashlight; delete it. + delete m_LightR; + m_LightR = NULL; + } + } + else + { + if (m_LightL) + { + // Turned off the flashlight; delete it. + delete m_LightL; + m_LightL = NULL; + } + if (m_LightR) + { + // Turned off the flashlight; delete it. + delete m_LightR; + m_LightR = NULL; + } + } + + BaseClass::Simulate(); +} + +void C_NPC_CrabSynth::OnDataChanged( DataUpdateType_t type ) +{ + BaseClass::OnDataChanged( type ); +} + +//----------------------------------------------------------------------------- +// Crab Grenade +//----------------------------------------------------------------------------- class C_CrabGrenade : public C_BaseGrenade { public: diff --git a/sp/src/game/client/ez2/c_npc_crabsynth.h b/sp/src/game/client/ez2/c_npc_crabsynth.h new file mode 100644 index 0000000000..bbf4422981 --- /dev/null +++ b/sp/src/game/client/ez2/c_npc_crabsynth.h @@ -0,0 +1,39 @@ +#ifndef C_NPC_CrabSynth_H +#define C_NPC_CrabSynth_H +#ifdef _WIN32 +#pragma once +#endif + +#include "c_ai_basenpc.h" +#include "flashlighteffect.h" + +//----------------------------------------------------------------------------- +// Crab Synth +//----------------------------------------------------------------------------- +class C_NPC_CrabSynth : public C_AI_BaseNPC +{ +public: + DECLARE_CLASS( C_NPC_CrabSynth, C_AI_BaseNPC ); + DECLARE_CLIENTCLASS(); + + C_NPC_CrabSynth(); + ~C_NPC_CrabSynth(); + + void OnDataChanged( DataUpdateType_t type ); + void UpdateLight( CCrabSynthLightEffect **ppLight, int nAttachment ); + void Simulate( void ); + + int m_nAttachmentLightL = -1; + int m_nAttachmentLightR = -1; + + bool m_bProjectedLightEnabled; + bool m_bProjectedLightShadowsEnabled; + float m_flProjectedLightBrightnessScale; + float m_flProjectedLightFOV; + float m_flProjectedLightHorzFOV; + + CCrabSynthLightEffect *m_LightL; + CCrabSynthLightEffect *m_LightR; +}; + +#endif // C_NPC_CrabSynth_H \ No newline at end of file diff --git a/sp/src/game/client/flashlighteffect.cpp b/sp/src/game/client/flashlighteffect.cpp index 51e40423e2..5cbe16c25e 100644 --- a/sp/src/game/client/flashlighteffect.cpp +++ b/sp/src/game/client/flashlighteffect.cpp @@ -739,4 +739,81 @@ void CTurretLightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir g_pClientShadowMgr->UpdateProjectedTexture( GetFlashlightHandle(), true ); } + +//----------------------------------------------------------------------------- +// Crab Synth light effect +//----------------------------------------------------------------------------- +static ConVar r_crabsynthlightbrightness( "r_crabsynthlightbrightness", "255.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlightfar( "r_crabsynthlightfar", "400", FCVAR_CHEAT ); +static ConVar r_crabsynthlightnear( "r_crabsynthlightnear", "2.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlightconstant( "r_crabsynthlightconstant", "0.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlightlinear( "r_crabsynthlightlinear", "0.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlightquadratic( "r_crabsynthlightquadratic", "100.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlightshadowatten( "r_crabsynthlightshadowatten", "1.0", FCVAR_CHEAT ); +static ConVar r_crabsynthlighttexture( "r_crabsynthlighttexture", "effects/crabsynthlight", FCVAR_CHEAT ); + +CCrabSynthLightEffect::CCrabSynthLightEffect() +{ + m_FlashlightTexture.Init( r_crabsynthlighttexture.GetString(), TEXTURE_GROUP_OTHER, true ); + m_flBrightnessScale = 1.0f; + + m_Color[0] = 1.0f; + m_Color[1] = 1.0f; + m_Color[2] = 1.0f; +} + +CCrabSynthLightEffect::~CCrabSynthLightEffect() +{ +} + +void CCrabSynthLightEffect::UpdateLight( const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance ) +{ + if ( IsOn() == false ) + return; + + FlashlightState_t state; + Vector basisX, basisY, basisZ; + basisX = vecDir; + basisY = vecRight; + basisZ = vecUp; + VectorNormalize(basisX); + VectorNormalize(basisY); + VectorNormalize(basisZ); + + BasisToQuaternion( basisX, basisY, basisZ, state.m_quatOrientation ); + + state.m_vecLightOrigin = vecPos; + + state.m_fHorizontalFOVDegrees = m_flHorzFOV; + state.m_fVerticalFOVDegrees = m_flFOV; + state.m_fQuadraticAtten = r_crabsynthlightquadratic.GetFloat(); + state.m_fLinearAtten = r_crabsynthlightlinear.GetFloat(); + state.m_fConstantAtten = r_crabsynthlightconstant.GetFloat(); + state.m_Color[0] = m_Color[0] * (m_flBrightnessScale != 1.0f ? r_crabsynthlightbrightness.GetFloat() * m_flBrightnessScale : r_crabsynthlightbrightness.GetFloat()); + state.m_Color[1] = m_Color[1] * (m_flBrightnessScale != 1.0f ? r_crabsynthlightbrightness.GetFloat() * m_flBrightnessScale : r_crabsynthlightbrightness.GetFloat()); + state.m_Color[2] = m_Color[2] * (m_flBrightnessScale != 1.0f ? r_crabsynthlightbrightness.GetFloat() * m_flBrightnessScale : r_crabsynthlightbrightness.GetFloat()); + state.m_Color[3] = r_flashlightambient.GetFloat(); + + state.m_NearZ = r_crabsynthlightnear.GetFloat(); + state.m_FarZ = r_crabsynthlightfar.GetFloat(); + + state.m_bEnableShadows = m_bShadowsEnabled; + state.m_pSpotlightTexture = m_FlashlightTexture; + state.m_nSpotlightTextureFrame = 0; + + state.m_flShadowAtten = r_crabsynthlightshadowatten.GetFloat(); + state.m_flShadowSlopeScaleDepthBias = mat_slopescaledepthbias_shadowmap.GetFloat(); + state.m_flShadowDepthBias = mat_depthbias_shadowmap.GetFloat(); + + if( GetFlashlightHandle() == CLIENTSHADOW_INVALID_HANDLE ) + { + SetFlashlightHandle( g_pClientShadowMgr->CreateFlashlight( state ) ); + } + else + { + g_pClientShadowMgr->UpdateFlashlightState( GetFlashlightHandle(), state ); + } + + g_pClientShadowMgr->UpdateProjectedTexture( GetFlashlightHandle(), true ); +} #endif diff --git a/sp/src/game/client/flashlighteffect.h b/sp/src/game/client/flashlighteffect.h index d730a565f8..20cd51162f 100644 --- a/sp/src/game/client/flashlighteffect.h +++ b/sp/src/game/client/flashlighteffect.h @@ -94,6 +94,22 @@ class CTurretLightEffect : public CFlashlightEffect float m_flFarZ; float m_flFOV; }; + +class CCrabSynthLightEffect : public CFlashlightEffect +{ +public: + + CCrabSynthLightEffect(); + ~CCrabSynthLightEffect(); + + virtual void UpdateLight( const Vector &vecPos, const Vector &vecDir, const Vector &vecRight, const Vector &vecUp, int nDistance ); + + bool m_bShadowsEnabled; + float m_flBrightnessScale; + float m_flFOV; + float m_flHorzFOV; + float m_Color[3]; +}; #endif #endif // FLASHLIGHTEFFECT_H diff --git a/sp/src/game/server/ez2/npc_crabsynth.cpp b/sp/src/game/server/ez2/npc_crabsynth.cpp index 20cc6ca3d0..ea089b9b80 100644 --- a/sp/src/game/server/ez2/npc_crabsynth.cpp +++ b/sp/src/game/server/ez2/npc_crabsynth.cpp @@ -162,6 +162,11 @@ enum SquadSlot_T CNPC_CrabSynth::CNPC_CrabSynth( void ) { m_iNumGrenades = 5; + m_bProjectedLightEnabled = false; + m_bProjectedLightShadowsEnabled = false; + m_flProjectedLightBrightnessScale = 1.0f; + m_flProjectedLightFOV = 90.0f; + m_flProjectedLightHorzFOV = 120.0f; } //----------------------------------------------------------------------------- @@ -192,6 +197,12 @@ BEGIN_DATADESC( CNPC_CrabSynth ) DEFINE_FIELD( m_bIsBleeding, FIELD_BOOLEAN ), DEFINE_FIELD( m_bLastDamageBelow, FIELD_BOOLEAN ), + DEFINE_KEYFIELD( m_bProjectedLightEnabled, FIELD_BOOLEAN, "ProjectedLightEnabled" ), + DEFINE_KEYFIELD( m_bProjectedLightShadowsEnabled, FIELD_BOOLEAN, "ProjectedLightShadowsEnabled" ), + DEFINE_KEYFIELD( m_flProjectedLightBrightnessScale, FIELD_FLOAT, "ProjectedLightBrightnessScale" ), + DEFINE_KEYFIELD( m_flProjectedLightFOV, FIELD_FLOAT, "ProjectedLightFOV" ), + DEFINE_KEYFIELD( m_flProjectedLightHorzFOV, FIELD_FLOAT, "ProjectedLightHorzFOV" ), + DEFINE_KEYFIELD( m_bDisableBoneFollowers, FIELD_BOOLEAN, "disablephysics" ), DEFINE_EMBEDDED( m_BoneFollowerManager ), @@ -202,10 +213,28 @@ BEGIN_DATADESC( CNPC_CrabSynth ) DEFINE_INPUTFUNC( FIELD_STRING, "SetChargeTarget", InputSetChargeTarget ), DEFINE_INPUTFUNC( FIELD_VOID, "ClearChargeTarget", InputClearChargeTarget ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOnProjectedLights", InputTurnOnProjectedLights ), + DEFINE_INPUTFUNC( FIELD_VOID, "TurnOffProjectedLights", InputTurnOffProjectedLights ), + DEFINE_INPUTFUNC( FIELD_BOOLEAN, "SetProjectedLightEnableShadows", InputSetProjectedLightEnableShadows ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetProjectedLightBrightnessScale", InputSetProjectedLightBrightnessScale ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetProjectedLightFOV", InputSetProjectedLightFOV ), + DEFINE_INPUTFUNC( FIELD_FLOAT, "SetProjectedLightHorzFOV", InputSetProjectedLightHorzFOV ), + DEFINE_AIGRENADE_DATADESC() END_DATADESC() +//--------------------------------------------------------- +// Custom Client entity +//--------------------------------------------------------- +IMPLEMENT_SERVERCLASS_ST( CNPC_CrabSynth, DT_NPC_CrabSynth ) + SendPropBool( SENDINFO( m_bProjectedLightEnabled ) ), + SendPropBool( SENDINFO( m_bProjectedLightShadowsEnabled ) ), + SendPropFloat( SENDINFO( m_flProjectedLightBrightnessScale ) ), + SendPropFloat( SENDINFO( m_flProjectedLightFOV ) ), + SendPropFloat( SENDINFO( m_flProjectedLightHorzFOV ) ), +END_SEND_TABLE() + //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- diff --git a/sp/src/game/server/ez2/npc_crabsynth.h b/sp/src/game/server/ez2/npc_crabsynth.h index cd8224b29a..f0dae674e5 100644 --- a/sp/src/game/server/ez2/npc_crabsynth.h +++ b/sp/src/game/server/ez2/npc_crabsynth.h @@ -32,6 +32,7 @@ class CNPC_CrabSynth : public CAI_GrenadeUser< CAI_BaseActor > public: DECLARE_CLASS( CNPC_CrabSynth, CAI_GrenadeUser< CAI_BaseActor > ); DECLARE_DATADESC(); + DECLARE_SERVERCLASS(); DEFINE_CUSTOM_AI; CNPC_CrabSynth(); @@ -134,6 +135,13 @@ class CNPC_CrabSynth : public CAI_GrenadeUser< CAI_BaseActor > void InputSetChargeTarget( inputdata_t &inputdata ); void InputClearChargeTarget( inputdata_t &inputdata ); + void InputTurnOnProjectedLights( inputdata_t &inputdata ) { m_bProjectedLightEnabled = true; } + void InputTurnOffProjectedLights( inputdata_t &inputdata ) { m_bProjectedLightEnabled = false; } + void InputSetProjectedLightEnableShadows( inputdata_t &inputdata ) { m_bProjectedLightShadowsEnabled = inputdata.value.Bool(); } + void InputSetProjectedLightBrightnessScale( inputdata_t &inputdata ) { m_flProjectedLightBrightnessScale = inputdata.value.Float(); } + void InputSetProjectedLightFOV( inputdata_t &inputdata ) { m_flProjectedLightFOV = inputdata.value.Float(); } + void InputSetProjectedLightHorzFOV( inputdata_t &inputdata ) { m_flProjectedLightHorzFOV = inputdata.value.Float(); } + private: int m_nShots; @@ -167,6 +175,13 @@ class CNPC_CrabSynth : public CAI_GrenadeUser< CAI_BaseActor > CSprite *m_pEyeGlow3; CSprite *m_pEyeGlow4; + // Controls projected texture spotlights on the client. + CNetworkVar( bool, m_bProjectedLightEnabled ); + CNetworkVar( bool, m_bProjectedLightShadowsEnabled ); + CNetworkVar( float, m_flProjectedLightBrightnessScale ); + CNetworkVar( float, m_flProjectedLightFOV ); + CNetworkVar( float, m_flProjectedLightHorzFOV ); + //----------------------------------------------------- int m_nAttachmentMuzzle;