aboutsummaryrefslogtreecommitdiff
path: root/sp/src/game/client/episodic/c_npc_advisor.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/game/client/episodic/c_npc_advisor.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/game/client/episodic/c_npc_advisor.cpp')
-rw-r--r--sp/src/game/client/episodic/c_npc_advisor.cpp251
1 files changed, 251 insertions, 0 deletions
diff --git a/sp/src/game/client/episodic/c_npc_advisor.cpp b/sp/src/game/client/episodic/c_npc_advisor.cpp
new file mode 100644
index 00000000..94cd047b
--- /dev/null
+++ b/sp/src/game/client/episodic/c_npc_advisor.cpp
@@ -0,0 +1,251 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Definition for client-side advisor.
+//
+//=====================================================================================//
+
+
+
+#include "cbase.h"
+// this file contains the definitions for the message ID constants (eg ADVISOR_MSG_START_BEAM etc)
+#include "npc_advisor_shared.h"
+
+#if NPC_ADVISOR_HAS_BEHAVIOR
+
+#include "particles_simple.h"
+#include "citadel_effects_shared.h"
+#include "particles_attractor.h"
+#include "clienteffectprecachesystem.h"
+#include "c_te_effect_dispatch.h"
+
+#include "c_ai_basenpc.h"
+#include "dlight.h"
+#include "iefx.h"
+
+
+//-----------------------------------------------------------------------------
+// Purpose: unpack a networked entity index into a basehandle.
+//-----------------------------------------------------------------------------
+inline C_BaseEntity *IndexToEntity( int eindex )
+{
+ return ClientEntityList().GetBaseEntityFromHandle(ClientEntityList().EntIndexToHandle(eindex));
+}
+
+
+
+#define ADVISOR_ELIGHT_CVARS 1 // enable/disable tuning advisor elight with console variables
+
+#if ADVISOR_ELIGHT_CVARS
+ConVar advisor_elight_e("advisor_elight_e","3");
+ConVar advisor_elight_rfeet("advisor_elight_rfeet","52");
+#endif
+
+
+/*! Client-side reflection of the advisor class.
+ */
+class C_NPC_Advisor : public C_AI_BaseNPC
+{
+ DECLARE_CLASS( C_NPC_Advisor, C_AI_BaseNPC );
+ DECLARE_CLIENTCLASS();
+
+public:
+ // Server to client message received
+ virtual void ReceiveMessage( int classID, bf_read &msg );
+ virtual void ClientThink( void );
+
+private:
+ /*
+ // broken into its own function so I can move it if necesasry
+ void Initialize();
+ */
+
+ // start/stop beam particle effect from me to a pelting object
+ void StartBeamFX( C_BaseEntity *pOnEntity );
+ void StopBeamFX( C_BaseEntity *pOnEntity );
+
+ void StartElight();
+ void StopElight();
+
+ int m_ElightKey; // test using an elight to make the escape sequence more visible. 0 is invalid.
+
+};
+
+IMPLEMENT_CLIENTCLASS_DT( C_NPC_Advisor, DT_NPC_Advisor, CNPC_Advisor )
+
+END_RECV_TABLE()
+
+// Server to client message received
+void C_NPC_Advisor::ReceiveMessage( int classID, bf_read &msg )
+{
+ if ( classID != GetClientClass()->m_ClassID )
+ {
+ // message is for subclass
+ BaseClass::ReceiveMessage( classID, msg );
+ return;
+ }
+
+ int messageType = msg.ReadByte();
+ switch( messageType )
+ {
+ case ADVISOR_MSG_START_BEAM:
+ {
+ int eindex = msg.ReadLong();
+ StartBeamFX(IndexToEntity(eindex));
+ }
+ break;
+
+ case ADVISOR_MSG_STOP_BEAM:
+ {
+ int eindex = msg.ReadLong();
+ StopBeamFX(IndexToEntity(eindex));
+
+ }
+ break;
+
+ case ADVISOR_MSG_STOP_ALL_BEAMS:
+ {
+ ParticleProp()->StopEmission();
+ }
+ break;
+ case ADVISOR_MSG_START_ELIGHT:
+ {
+ StartElight();
+ }
+ break;
+ case ADVISOR_MSG_STOP_ELIGHT:
+ {
+ StopElight();
+ }
+ break;
+
+ default:
+ AssertMsg1( false, "Received unknown message %d", messageType);
+ }
+}
+
+/// only use of the clientthink on the advisor is to update the elight
+void C_NPC_Advisor::ClientThink( void )
+{
+ // if the elight has gone away, bail out
+ if (m_ElightKey == 0)
+ {
+ SetNextClientThink( CLIENT_THINK_NEVER );
+ return;
+ }
+
+ // get the elight
+ dlight_t * el = effects->GetElightByKey(m_ElightKey);
+ if (!el)
+ {
+ // the elight has been invalidated. bail out.
+ m_ElightKey = 0;
+
+ SetNextClientThink( CLIENT_THINK_NEVER );
+ return;
+ }
+ else
+ {
+ el->origin = WorldSpaceCenter();
+
+#if ADVISOR_ELIGHT_CVARS
+ el->color.exponent = advisor_elight_e.GetFloat();
+ el->radius = advisor_elight_rfeet.GetFloat() * 12.0f;
+#endif
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Create a telekinetic beam effect from my head to an object
+// TODO: use a point attachment.
+//-----------------------------------------------------------------------------
+void C_NPC_Advisor::StartBeamFX( C_BaseEntity *pOnEntity )
+{
+ Assert(pOnEntity);
+ if (!pOnEntity)
+ return;
+
+ CNewParticleEffect *pEffect = ParticleProp()->Create( "Advisor_Psychic_Beam", PATTACH_ABSORIGIN_FOLLOW );
+
+ Assert(pEffect);
+ if (!pEffect) return;
+
+ ParticleProp()->AddControlPoint( pEffect, 1, pOnEntity, PATTACH_ABSORIGIN_FOLLOW );
+}
+
+
+//-----------------------------------------------------------------------------
+// terminate a telekinetic beam effect from my head to an object
+//-----------------------------------------------------------------------------
+void C_NPC_Advisor::StopBeamFX( C_BaseEntity *pOnEntity )
+{
+ Assert(pOnEntity);
+ if (!pOnEntity)
+ return;
+
+ ParticleProp()->StopParticlesInvolving( pOnEntity );
+}
+
+
+
+
+
+
+void C_NPC_Advisor::StartElight()
+{
+ AssertMsg(m_ElightKey == 0 , "Advisor trying to create new elight on top of old one!");
+ if ( m_ElightKey != 0 )
+ {
+ Warning("Advisor tried to start his elight when it was already one.\n");
+ }
+ else
+ {
+ m_ElightKey = LIGHT_INDEX_TE_DYNAMIC + this->entindex();
+ dlight_t * el = effects->CL_AllocElight( m_ElightKey );
+
+ if ( el )
+ {
+ // create an elight on top of me
+ el->origin = this->WorldSpaceCenter();
+
+ el->color.r = 235;
+ el->color.g = 255;
+ el->color.b = 255;
+ el->color.exponent = 3;
+
+ el->radius = 52*12;
+ el->decay = 0.0f;
+ el->die = gpGlobals->curtime + 2000.0f; // 1000 just means " a long time "
+
+ SetNextClientThink( CLIENT_THINK_ALWAYS );
+ }
+ else
+ { // null out the light value
+ m_ElightKey = 0;
+ }
+ }
+}
+
+void C_NPC_Advisor::StopElight()
+{
+ AssertMsg( m_ElightKey != 0, "Advisor tried to stop elight when none existed!");
+ dlight_t * el;
+ // note: the following conditional sets el if not short-circuited
+ if ( m_ElightKey == 0 || (el = effects->GetElightByKey(m_ElightKey)) == NULL )
+ {
+ Warning("Advisor tried to stop its elight when it had none.\n");
+ }
+ else
+ {
+ // kill the elight by setting the die value to now
+ el->die = gpGlobals->curtime;
+ }
+}
+
+
+#endif
+
+/******************************************************
+ * Tenser, said the Tensor. *
+ * Tenser, said the Tensor. *
+ * Tension, apprehension and dissension have begun. *
+ ******************************************************/