diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /game/server/portal/portal_radio.cpp | |
| download | archived-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.cpp | 618 |
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 ); + } + } +} + |