summaryrefslogtreecommitdiff
path: root/game/server/portal/portal_radio.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/portal/portal_radio.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'game/server/portal/portal_radio.cpp')
-rw-r--r--game/server/portal/portal_radio.cpp618
1 files changed, 618 insertions, 0 deletions
diff --git a/game/server/portal/portal_radio.cpp b/game/server/portal/portal_radio.cpp
new file mode 100644
index 0000000..184aa54
--- /dev/null
+++ b/game/server/portal/portal_radio.cpp
@@ -0,0 +1,618 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+//
+//=====================================================================================//
+
+#include "cbase.h" // for pch
+#include "props.h"
+#include "filters.h"
+#include "achievementmgr.h"
+
+extern CAchievementMgr g_AchievementMgrPortal;
+
+#define RADIO_MODEL_NAME "models/props/radio_reference.mdl"
+//#define RADIO_DEBUG_SERVER
+
+class CDinosaurSignal : public CBaseEntity
+{
+public:
+ DECLARE_DATADESC();
+ DECLARE_SERVERCLASS();
+ DECLARE_CLASS( CDinosaurSignal, CBaseEntity );
+ void Spawn();
+ int UpdateTransmitState();
+#if RADIO_DEBUG_SERVER
+ int DrawDebugTextOverlays( void );
+#endif
+
+ CNetworkString( m_szSoundName, 128 );
+ CNetworkVar( float, m_flInnerRadius );
+ CNetworkVar( float, m_flOuterRadius );
+ CNetworkVar( int, m_nSignalID );
+};
+
+LINK_ENTITY_TO_CLASS( updateitem1, CDinosaurSignal );
+
+BEGIN_DATADESC( CDinosaurSignal )
+ DEFINE_AUTO_ARRAY( m_szSoundName, FIELD_CHARACTER ),
+ DEFINE_FIELD( m_flOuterRadius, FIELD_FLOAT ),
+ DEFINE_FIELD( m_flInnerRadius, FIELD_FLOAT ),
+ DEFINE_FIELD( m_nSignalID, FIELD_INTEGER ),
+END_DATADESC()
+
+IMPLEMENT_SERVERCLASS_ST( CDinosaurSignal, DT_DinosaurSignal )
+ SendPropString( SENDINFO(m_szSoundName) ),
+ SendPropFloat( SENDINFO(m_flOuterRadius) ),
+ SendPropFloat( SENDINFO(m_flInnerRadius) ),
+ SendPropInt( SENDINFO(m_nSignalID) ),
+END_SEND_TABLE()
+
+void CDinosaurSignal::Spawn()
+{
+ PrecacheScriptSound( m_szSoundName.Get() );
+ BaseClass::Spawn();
+ SetTransmitState( FL_EDICT_ALWAYS );
+}
+
+int CDinosaurSignal::UpdateTransmitState()
+{
+ // ALWAYS transmit to all clients.
+ return SetTransmitState( FL_EDICT_ALWAYS );
+}
+
+#if RADIO_DEBUG_SERVER
+int CDinosaurSignal::DrawDebugTextOverlays( void )
+{
+ int text_offset = BaseClass::DrawDebugTextOverlays();
+ if (m_debugOverlays & OVERLAY_TEXT_BIT)
+ {
+ NDebugOverlay::Sphere( GetAbsOrigin(), GetAbsAngles(), m_flInnerRadius, 255, 0, 0, 64, false, 0.1f );
+ NDebugOverlay::Sphere( GetAbsOrigin(), GetAbsAngles(), m_flOuterRadius, 0, 255, 0, 64, false, 0.1f );
+ }
+ return text_offset;
+}
+#endif
+
+
+class CPortal_Dinosaur : public CPhysicsProp
+{
+public:
+ DECLARE_CLASS( CPortal_Dinosaur, CPhysicsProp );
+ DECLARE_DATADESC();
+ DECLARE_SERVERCLASS();
+
+ virtual void Spawn();
+ virtual void Precache();
+ virtual QAngle PreferredCarryAngles( void ) { return QAngle( 0, 180, 0 ); }
+ virtual bool HasPreferredCarryAnglesForPlayer( CBasePlayer *pPlayer ) { return true; }
+ virtual void Activate();
+
+
+ CNetworkHandle( CDinosaurSignal, m_hDinosaur_Signal );
+ CNetworkVar( bool, m_bAlreadyDiscovered );
+};
+
+LINK_ENTITY_TO_CLASS( updateitem2, CPortal_Dinosaur );
+
+BEGIN_DATADESC( CPortal_Dinosaur )
+ DEFINE_FIELD( m_hDinosaur_Signal, FIELD_EHANDLE ),
+ DEFINE_FIELD( m_bAlreadyDiscovered, FIELD_BOOLEAN ),
+END_DATADESC()
+
+IMPLEMENT_SERVERCLASS_ST( CPortal_Dinosaur, DT_PropDinosaur )
+ SendPropEHandle( SENDINFO( m_hDinosaur_Signal ) ),
+ SendPropBool( SENDINFO( m_bAlreadyDiscovered ) ),
+END_SEND_TABLE()
+
+void CPortal_Dinosaur::Precache()
+{
+ PrecacheModel( RADIO_MODEL_NAME );
+
+ PrecacheScriptSound( "Portal.room1_radio" );
+ PrecacheScriptSound( "UpdateItem.Static" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur01" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur02" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur03" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur04" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur05" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur06" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur07" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur08" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur09" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur10" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur11" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur12" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur13" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur14" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur15" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur16" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur17" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur18" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur19" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur20" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur21" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur22" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur23" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur24" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur25" );
+ PrecacheScriptSound( "UpdateItem.Dinosaur26" );
+
+ PrecacheScriptSound( "UpdateItem.Fizzle" );
+}
+
+
+void CPortal_Dinosaur::Spawn()
+{
+ Precache();
+ KeyValue( "model", RADIO_MODEL_NAME );
+ m_spawnflags |= SF_PHYSPROP_START_ASLEEP;
+ BaseClass::Spawn();
+}
+
+void CPortal_Dinosaur::Activate( void )
+{
+ // Find the current completion status of the dinosaurs
+ uint64 fStateFlags = 0;
+ CBaseAchievement *pTransmissionRecvd = dynamic_cast<CBaseAchievement *>(g_AchievementMgrPortal.GetAchievementByName("PORTAL_TRANSMISSION_RECEIVED"));
+ if ( pTransmissionRecvd )
+ {
+ fStateFlags = pTransmissionRecvd->GetComponentBits();
+ }
+
+ if ( m_hDinosaur_Signal != NULL )
+ {
+ uint64 nId = m_hDinosaur_Signal.Get()->m_nSignalID;
+ // See if we're already tripped
+ if ( fStateFlags & ((uint64)1<<nId) )
+ {
+ m_bAlreadyDiscovered = true;
+ }
+ }
+
+ BaseClass::Activate();
+}
+
+struct radiolocs
+{
+ const char *mapname;
+ const char *soundname;
+ int id;
+ float radiopos[3];
+ float radioang[3];
+ float soundpos[3];
+ float soundouterrad;
+ float soundinnerrad;
+};
+static const radiolocs s_radiolocs[] =
+{
+ {
+ "testchmb_a_00",
+ "UpdateItem.Dinosaur01",
+ 0,
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { -506, -924, 161 },
+ 200,
+ 64
+ },
+ {
+ "testchmb_a_00",
+ "UpdateItem.Dinosaur02",
+ 1,
+ { -960, -634, 783 },
+ { 0, 90, 0 },
+ { -926.435, -256.323, 583 },
+ 200,
+ 64,
+ },
+ {
+ "testchmb_a_01",
+ "UpdateItem.Dinosaur03",
+ 2,
+ { 233, 393, 130 },
+ { 0, 225, 0 },
+ { 96, 160, -108 },
+ 224,
+ 128,
+ },
+ {
+ "testchmb_a_01",
+ "UpdateItem.Dinosaur04",
+ 3,
+ { -1439.89, 1076.04, 779.102 },
+ { 0, 270, 0 },
+ { -731, 735, 888 },
+ 400,
+ 64,
+ },
+ {
+ // new entry
+ "testchmb_a_02",
+ "UpdateItem.Dinosaur05",
+ 4,
+ { 2, 65, 390 },
+ { 0, 270, 0 },
+ { -864, 192, 64},
+ 192,
+ 96,
+ },
+ {
+ "testchmb_a_02",
+ "UpdateItem.Dinosaur06",
+ 21,
+ { 111, 832, 577 },
+ { 0, 0, 0 },
+ { 918, 831, 512},
+ 192,
+ 96,
+ },
+ {
+ "testchmb_a_03",
+ "UpdateItem.Dinosaur07",
+ 5,
+ { -53.2337, 78.181, 236 },
+ { 0, 225, 0 },
+ { 304, 0, -96 },
+ 256,
+ 128
+ },
+ // new entry
+ {
+ "testchmb_a_03",
+ "UpdateItem.Dinosaur08",
+ 6,
+ { 428.112, 0.22326, 1201 },
+ { 0, 180, 0 },
+ { -581.096, 193.694, 1351 },
+ 165,
+ 128
+ },
+ {
+ "testchmb_a_04",
+ "UpdateItem.Dinosaur09",
+ 7,
+ { 118, -56.6, -38.8 },
+ { 0, 180, 0 },
+ { -640, 256, 8 },
+ 512,
+ 128
+ },
+ // new entry
+ {
+ "testchmb_a_05",
+ "UpdateItem.Dinosaur10",
+ 8,
+ { 64, 144, 160 },
+ { 0, 270, 0 },
+ { 64, 740, 7 },
+ 350,
+ 128
+ },
+ {
+ "testchmb_a_06",
+ "UpdateItem.Dinosaur11",
+ 9,
+ { 529, 315, 320 },
+ { 0, 270, 0 },
+ { 608, 128, -184 },
+ 384,
+ 160
+ },
+ {
+ "testchmb_a_07",
+ "UpdateItem.Dinosaur12",
+ 10,
+ { 192, -1546, 1425 },
+ { 0, 113, 0 },
+ { 272, -496, 1328 },
+ 432,
+ 88
+ },
+ // new entry
+ {
+ "testchmb_a_07",
+ "UpdateItem.Dinosaur13",
+ 11,
+ { -144, -768, 256 },
+ { 0, 90, 0 },
+ { -192, -384, 176 },
+ 256,
+ 128
+ },
+ {
+ "testchmb_a_08",
+ "UpdateItem.Dinosaur14",
+ 12,
+ { 267, -378, 256 },
+ { 0, 90, 0 },
+ { -560, 96, 320 },
+ 288,
+ 128,
+ },
+ {
+ "testchmb_a_09",
+ "UpdateItem.Dinosaur15",
+ 13,
+ { 634, 1308, 256 },
+ { 0, 180, 0 },
+ { 386.699, 1792.43, 7},
+ 548,
+ 64
+ },
+ {
+ "testchmb_a_10",
+ "UpdateItem.Dinosaur16",
+ 14,
+ { -1420, -2752, 76 },
+ { 0, 0, 0 },
+ { -1968, -2880, -334 },
+ 448,
+ 196,
+ },
+ // new entry
+ {
+ "testchmb_a_10",
+ "UpdateItem.Dinosaur17",
+ 15,
+ { 112, 1392, -63 },
+ { 0, 260, 0 },
+ { -189, 1220, 65 },
+ 192,
+ 128,
+ },
+ {
+ "testchmb_a_11",
+ "UpdateItem.Dinosaur18",
+ 16,
+ {0,0,0},
+ {0,0,0},
+ {-512,644,64},
+ 192,
+ 96,
+ },
+ {
+ "testchmb_a_13",
+ "UpdateItem.Dinosaur19",
+ 17,
+ {955,931,-267},
+ {-90,0,0},
+ {1472,-191,-12},
+ 256,
+ 128,
+ },
+ {
+ "testchmb_a_14",
+ "UpdateItem.Dinosaur20",
+ 18,
+ {0,0,0},
+ {0,0,0},
+ {144,192,1288},
+ 807,
+ 128,
+ },
+ {
+ "testchmb_a_14",
+ "UpdateItem.Dinosaur21",
+ 22,
+ {1285, 1344, 1412},
+ {0,0,0},
+ {2712, 894, 1011},
+ 200,
+ 120,
+ },
+ {
+ "testchmb_a_14",
+ "UpdateItem.Dinosaur22",
+ 23,
+ {-952, 336, -256},
+ {0,0,0},
+ {-1144, -249, 3336},
+ 400,
+ 128,
+ },
+ {
+ "testchmb_a_15",
+ "UpdateItem.Dinosaur23",
+ 19,
+ {-1529,293,-283},
+ {0,90,0},
+ {761,443,810},
+ 256,
+ 128,
+ },
+ {
+ "escape_00",
+ "UpdateItem.Dinosaur24",
+ 24,
+ {192, -1344, -832},
+ {0, 135, 0},
+ {891, 322, -184},
+ 285,
+ 150,
+ },
+ {
+ "escape_01",
+ "UpdateItem.Dinosaur25",
+ 20,
+ {0,0,0},
+ {0,0,0},
+ {-624, 1440, -464},
+ 512,
+ 128,
+ },
+ {
+ "escape_02",
+ "UpdateItem.Dinosaur26",
+ 25,
+ {5504, 131, -1422},
+ {0, 90, 0},
+ {4218, 674, 8},
+ 300,
+ 100,
+ },
+};
+
+class CSpawnDinosaurHack : CAutoGameSystem
+{
+public:
+ virtual void LevelInitPreEntity();
+ virtual void LevelInitPostEntity();
+
+ CPortal_Dinosaur *SpawnDinosaur( radiolocs& loc );
+ CDinosaurSignal *SpawnSignal( radiolocs& loc );
+
+ void ApplyMapSpecificHacks();
+};
+
+static CSpawnDinosaurHack g_SpawnRadioHack;
+
+void CSpawnDinosaurHack::LevelInitPreEntity()
+{
+ UTIL_PrecacheOther( "updateitem2", RADIO_MODEL_NAME );
+
+ ApplyMapSpecificHacks();
+}
+
+// Spawn all the Dinosaurs and sstv images
+void CSpawnDinosaurHack::LevelInitPostEntity()
+{
+ if ( gpGlobals->eLoadType == MapLoad_LoadGame )
+ {
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "Not spawning any Dinosaurs: Detected a map load\n" );
+#endif
+
+ return;
+ }
+
+ IAchievement *pHeartbreaker = g_AchievementMgrPortal.GetAchievementByName("PORTAL_BEAT_GAME");
+ if ( pHeartbreaker == NULL || pHeartbreaker->IsAchieved() == false )
+ {
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "Not spawning any Dinosaurs: Player has not beat the game, or failed to get heartbreaker achievement from mgr\n" );
+#endif
+
+ return;
+ }
+
+ for ( int i = 0; i < ARRAYSIZE( s_radiolocs ); ++i )
+ {
+ radiolocs loc = s_radiolocs[i];
+ if ( V_strcmp( STRING(gpGlobals->mapname), loc.mapname ) == 0 )
+ {
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "Found Dinosaur and signal info for %s, spawning.\n", loc.mapname );
+ Msg( "Dinosaur pos: %f %f %f, ang: %f %f %f\n", loc.radiopos[0], loc.radiopos[1], loc.radiopos[2], loc.radioang[0], loc.radioang[1], loc.radioang[2] );
+ Msg( "Signal pos: %f %f %f, inner rad: %f, outter rad: %f\n", loc.soundpos[0], loc.soundpos[1], loc.soundpos[2], loc.soundinnerrad, loc.soundouterrad );
+#endif
+
+ CPortal_Dinosaur *pDinosaur = SpawnDinosaur( loc );
+ CDinosaurSignal *pSignal = SpawnSignal( loc );
+
+ Assert ( pDinosaur && pSignal );
+ if ( pDinosaur && pSignal )
+ {
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "SUCCESS: Spawned Dinosaur and signal and linked them.\n" );
+#endif
+ // OK, so these really could have been the same class... not worth changing it now though.
+ pDinosaur->m_hDinosaur_Signal.Set( pSignal );
+ pDinosaur->Activate();
+ }
+ }
+ }
+}
+
+CPortal_Dinosaur *CSpawnDinosaurHack::SpawnDinosaur( radiolocs& loc )
+{
+ Vector vSpawnPos ( loc.radiopos[0], loc.radiopos[1], loc.radiopos[2] );
+ QAngle vSpawnAng ( loc.radioang[0], loc.radioang[1], loc.radioang[2] );
+
+ // origin and angles of zero means skip this Dinosaur creation and look for an existing radio
+ if ( loc.radiopos[0] == 0 &&
+ loc.radiopos[1] == 0 &&
+ loc.radiopos[2] == 0 &&
+ loc.radioang[0] == 0 &&
+ loc.radioang[1] == 0 &&
+ loc.radioang[2] == 0 )
+ {
+
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "Dinosaur found with zero angles and origin. Replacing existing radio.\n" );
+#endif
+ // Find existing Dinosaur, kill it and spawn at its position
+ CPhysicsProp *pOldDinosaur = (CPhysicsProp*)gEntList.FindEntityByClassname( NULL, "prop_physics" );
+ while ( pOldDinosaur )
+ {
+ if ( V_strcmp( STRING( pOldDinosaur->GetModelName() ), RADIO_MODEL_NAME ) == 0 )
+ {
+ vSpawnPos = pOldDinosaur->GetAbsOrigin();
+ vSpawnAng = pOldDinosaur->GetAbsAngles();
+
+ UTIL_Remove( pOldDinosaur );
+
+#if defined ( RADIO_DEBUG_SERVER )
+ Msg( "Found Dinosaur exiting in level, replacing with %f, %f %f and %f %f %f.\n", XYZ(vSpawnPos), XYZ(vSpawnAng) );
+#endif
+ break;
+ }
+
+ pOldDinosaur = (CPhysicsProp*)gEntList.FindEntityByClassname( pOldDinosaur, "prop_physics" );
+ }
+ }
+
+ Assert( vSpawnPos != vec3_origin );
+
+ CPortal_Dinosaur *pDinosaur = (CPortal_Dinosaur*)CreateEntityByName( "updateitem2" );
+ Assert ( pDinosaur );
+ if ( pDinosaur )
+ {
+ pDinosaur->SetAbsOrigin( vSpawnPos );
+ pDinosaur->SetAbsAngles( vSpawnAng );
+ DispatchSpawn( pDinosaur );
+ }
+
+ return pDinosaur;
+}
+
+CDinosaurSignal *CSpawnDinosaurHack::SpawnSignal( radiolocs& loc )
+{
+ CDinosaurSignal *pSignal = (CDinosaurSignal*)CreateEntityByName( "updateitem1" );
+ Assert ( pSignal );
+ if ( pSignal )
+ {
+#if defined ( RADIO_DEBUG_SERVER )
+ if ( loc.soundinnerrad > loc.soundouterrad )
+ {
+ Assert( 0 );
+ Warning( "Dinosaur BUG: Inner radius is greater than outer radius. Will swap them.\n" );
+ swap( loc.soundinnerrad, loc.soundouterrad );
+ }
+#endif
+ pSignal->SetAbsOrigin( Vector( loc.soundpos[0], loc.soundpos[1], loc.soundpos[2] ) );
+ pSignal->m_flInnerRadius = loc.soundinnerrad;
+ pSignal->m_flOuterRadius = loc.soundouterrad;
+ V_strncpy( pSignal->m_szSoundName.GetForModify(), loc.soundname, 128 );
+ pSignal->m_nSignalID = loc.id;
+ DispatchSpawn( pSignal );
+ }
+
+ return pSignal;
+}
+
+
+void CSpawnDinosaurHack::ApplyMapSpecificHacks()
+{
+ if ( V_strcmp( STRING(gpGlobals->mapname), "testchmb_a_02" ) == 0 )
+ {
+ CBaseEntity *pFilter = CreateEntityByName( "filter_activator_name" );
+ Assert( pFilter );
+ if ( pFilter )
+ {
+ pFilter->KeyValue( "filtername", "box_2" );
+ pFilter->KeyValue( "targetname", "filter_weight_box" );
+ DispatchSpawn( pFilter );
+ }
+ }
+}
+