upload "kind" alien swarm

This commit is contained in:
nillerusr
2023-10-03 17:23:56 +03:00
parent b7bd94c52e
commit 7d3c0d8b5a
4229 changed files with 462903 additions and 495158 deletions

View File

@@ -1,4 +1,4 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: The system for handling director's commentary style production info in-game.
//
@@ -11,9 +11,9 @@
#include "tier0/icommandline.h"
#include "igamesystem.h"
#include "filesystem.h"
#include <KeyValues.h>
#include <keyvalues.h>
#include "in_buttons.h"
#include "engine/IEngineSound.h"
#include "engine/ienginesound.h"
#include "soundenvelope.h"
#include "utldict.h"
#include "isaverestore.h"
@@ -21,7 +21,9 @@
#include "saverestore_utlvector.h"
#include "gamestats.h"
#include "ai_basenpc.h"
#include "Sprite.h"
#include "sprite.h"
#include "point_template.h"
#include "mapentities.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
@@ -33,6 +35,7 @@ static const char *s_pCommentaryUpdateViewThink = "CommentaryUpdateViewThink";
extern ConVar commentary;
ConVar commentary_available("commentary_available", "0", FCVAR_NONE, "Automatically set by the game when a commentary file is available for the current map." );
extern ConVar rr_remarkables_enabled;
enum teleport_stages_t
{
@@ -59,6 +62,10 @@ bool IsInCommentaryMode( void )
return g_bInCommentaryMode;
}
PRECACHE_REGISTER_BEGIN( GLOBAL, PrecachePointCommentaryNode )
PRECACHE( MODEL, "models/extras/info_speech.mdl" )
PRECACHE_REGISTER_END()
//-----------------------------------------------------------------------------
// Purpose: An entity that marks a spot for a piece of commentary
//-----------------------------------------------------------------------------
@@ -255,6 +262,7 @@ public:
CCommentarySystem() : CAutoGameSystemPerFrame( "CCommentarySystem" )
{
m_iCommentaryNodeCount = 0;
m_pkvSavedModifications = NULL;
}
virtual void LevelInitPreEntity()
@@ -283,6 +291,7 @@ public:
{
g_bInCommentaryMode = true;
}
}
else
{
@@ -341,7 +350,10 @@ public:
virtual void LevelInitPostEntity( void )
{
if ( !IsInCommentaryMode() )
// Previously, we would bail out immediately. However if info_remarkables are enabled,
// there is the possiblity that they are defined in the commentary file, because it was a
// more convenient markup tool for the writers than Hammer. Therefore we must load it.
if ( !IsInCommentaryMode() && !rr_remarkables_enabled.GetBool() )
return;
// Don't spawn commentary entities when loading a savegame
@@ -351,8 +363,11 @@ public:
m_bCommentaryEnabledMidGame = false;
InitCommentary();
IGameEvent *event = gameeventmanager->CreateEvent( "playing_commentary" );
gameeventmanager->FireEventClientSide( event );
if ( IsInCommentaryMode() )
{
IGameEvent *event = gameeventmanager->CreateEvent( "playing_commentary" );
gameeventmanager->FireEventClientSide( event );
}
}
CPointCommentaryNode *GetNodeUnderCrosshair()
@@ -591,11 +606,19 @@ public:
return;
// Spawn the commentary semaphore entity
CBaseEntity *pSemaphore = CreateEntityByName( "info_target" );
pSemaphore->SetName( MAKE_STRING(COMMENTARY_SPAWNED_SEMAPHORE) );
static CGameString infoTargetStr( "info_target" );
static CGameString commentarySpawnedSemaphoreName( COMMENTARY_SPAWNED_SEMAPHORE );
CBaseEntity *pSemaphore = CreateEntityByName( infoTargetStr );
pSemaphore->SetName( commentarySpawnedSemaphoreName );
bool oldLock = engine->LockNetworkStringTables( false );
if ( m_pkvSavedModifications != NULL )
{
m_pkvSavedModifications->deleteThis();
m_pkvSavedModifications = NULL;
}
// Find the commentary file
char szFullName[512];
Q_snprintf(szFullName,sizeof(szFullName), "maps/%s_commentary.txt", STRING( gpGlobals->mapname ));
@@ -604,6 +627,20 @@ public:
{
Msg( "Commentary: Loading commentary data from %s. \n", szFullName );
unsigned int iFileSize = filesystem->Size( szFullName, "MOD" );
Assert( iFileSize > 0 );
CPointTemplate *PointTemplates[MAX_EDICTS];
int iPointTemplateCount = 0;
HierarchicalSpawnMapData_t SpawnData[MAX_EDICTS]; //for point templates
//to avoid rewriting a bunch of code, I'm leaving the keyvalue parsing as is. But to get point_templates to work, I need the keyvalues as strings. So we go file->KeyValues->String.
char *pKVToStringBuffer = (char *)stackalloc( sizeof(char *) * iFileSize );
char TempKeyBuffer[20 * 1024];
CUtlBuffer SpawnKeyValuesBackToString( TempKeyBuffer, 20 * 1024 );
int iKVStringBufferIndex = 0;
// Load each commentary block, and spawn the entities
KeyValues *pkvNode = pkvFile->GetFirstSubKey();
while ( pkvNode )
@@ -625,16 +662,71 @@ public:
pNodeName = pClassname->GetString();
}
if ( rr_remarkables_enabled.GetBool() )
{
bool bModifyBlock = !Q_strcmp( pkvNode->GetName(), "modify_entity" );
// in L4D, we hijack the commentary system to create
// info_remarkable nodes. If we are here with commentary
// disabled, load only those nodes.
// We also hijack it for map updates (exploits/etc.) on 360
KeyValues *pUpdateFlag = pkvNode->FindKey( "mapupdate", false );
if ( !IsInCommentaryMode() &&
( Q_strncmp( pNodeName, "info_remarkable", sizeof("info_remarkable")) != 0 ) &&
!pUpdateFlag && !bModifyBlock )
{
// Move to next entity
pkvNode = pkvNode->GetNextKey();
continue;
}
if ( bModifyBlock )
{
if ( m_pkvSavedModifications == NULL )
{
m_pkvSavedModifications = new KeyValues("Entities");
}
m_pkvSavedModifications->AddSubKey( pkvNode->MakeCopy() );
}
}
// Spawn the commentary entity
CBaseEntity *pNode = CreateEntityByName( pNodeName );
if ( pNode )
{
ParseEntKVBlock( pNode, pkvNode );
DispatchSpawn( pNode );
EHANDLE hHandle;
hHandle = pNode;
m_hSpawnedEntities.AddToTail( hHandle );
int iAddIndex = m_hSpawnedEntities.AddToTail( hHandle );
SpawnKeyValuesBackToString.SeekPut( CUtlBuffer::SEEK_HEAD, 0 );
pkvNode->RecursiveSaveToFile( SpawnKeyValuesBackToString, 0 );
int iLength = SpawnKeyValuesBackToString.TellPut() - 1;
//trim off the start and end that we don't care about
while( TempKeyBuffer[iLength] != '}' )
{
--iLength;
}
--iLength;
char *pStart = TempKeyBuffer;
while( *pStart != '{' )
{
++pStart;
}
pStart += 2; //RecursiveSaveToFile saves "name"\n{\n. We're skipping past that final \n
iLength -= (pStart - TempKeyBuffer);
//don't need to null terminate or space at all
memcpy( &pKVToStringBuffer[iKVStringBufferIndex], pStart, iLength );
SpawnData[iAddIndex].m_pMapData = &pKVToStringBuffer[iKVStringBufferIndex];
SpawnData[iAddIndex].m_iMapDataLength = iLength;
iKVStringBufferIndex += iLength;
CPointCommentaryNode *pCommNode = dynamic_cast<CPointCommentaryNode*>(pNode);
if ( pCommNode )
@@ -642,6 +734,13 @@ public:
m_iCommentaryNodeCount++;
pCommNode->SetNodeNumber( m_iCommentaryNodeCount );
}
CPointTemplate *pPointTemplate = dynamic_cast<CPointTemplate*>(pNode);
if ( pPointTemplate )
{
PointTemplates[iPointTemplateCount] = pPointTemplate;
++iPointTemplateCount;
}
}
else
{
@@ -652,6 +751,39 @@ public:
pkvNode = pkvNode->GetNextKey();
}
ApplyCommentaryModifications();
if( iPointTemplateCount != 0 )
{
CBaseEntity **pSpawnedEntities = NULL;
int iSpawnedEntityCount = m_hSpawnedEntities.Count();
if( iSpawnedEntityCount != 0 )
{
pSpawnedEntities = (CBaseEntity **)stackalloc( sizeof(CBaseEntity *) * m_hSpawnedEntities.Count() );
for( int i = 0; i != iSpawnedEntityCount; ++i )
{
pSpawnedEntities[i] = m_hSpawnedEntities[i].Get();
}
}
MapEntity_ParseAllEntites_SpawnTemplates( PointTemplates, iPointTemplateCount, pSpawnedEntities, SpawnData, iSpawnedEntityCount );
for( int i = iSpawnedEntityCount; --i >= 0; )
{
//remove any entities that were nullified in the point template parsing process
if( pSpawnedEntities[i] == NULL )
m_hSpawnedEntities.Remove(i);
}
}
for( int i = 0; i != m_hSpawnedEntities.Count(); ++i )
{
DispatchSpawn( m_hSpawnedEntities[i] );
}
PrecachePointTemplates();
// Then activate all the entities
for ( int i = 0; i < m_hSpawnedEntities.Count(); i++ )
{
@@ -666,6 +798,56 @@ public:
engine->LockNetworkStringTables( oldLock );
}
void ApplyCommentaryModifications()
{
KeyValues *pkvNode = m_pkvSavedModifications ? m_pkvSavedModifications->GetFirstSubKey() : NULL;
while ( pkvNode )
{
KeyValues *pModifyBlock = pkvNode->FindKey( "modify" );
if ( pModifyBlock )
{
// find entities with model name
KeyValues *pFindByModelname = pkvNode->FindKey( "find_by_modelname" );
if ( pFindByModelname )
{
CBaseEntity *pEnt = gEntList.FindEntityByModel( NULL, pFindByModelname->GetString() );
while ( pEnt )
{
KeyValues *pKey = pModifyBlock->GetFirstSubKey();
while( pKey )
{
pEnt->KeyValue( pKey->GetName(), pKey->GetString() );
pKey = pKey->GetNextKey();
}
pEnt = gEntList.FindEntityByModel( pEnt, pFindByModelname->GetString() );
}
}
KeyValues *pFindByTargetname = pkvNode->FindKey( "find_by_targetname" );
if ( pFindByTargetname )
{
CBaseEntity *pTarget = gEntList.FindEntityByTarget( NULL, pFindByTargetname->GetString() );
while ( pTarget )
{
KeyValues *pKey = pModifyBlock->GetFirstSubKey();
while( pKey )
{
pTarget->KeyValue( pKey->GetName(), pKey->GetString() );
pKey = pKey->GetNextKey();
}
pTarget = gEntList.FindEntityByTarget( pTarget, pFindByTargetname->GetString() );
}
}
}
// Move to next entity
pkvNode = pkvNode->GetNextKey();
}
}
void ShutDownCommentary( void )
{
if ( GetActiveNode() )
@@ -705,6 +887,12 @@ public:
}
m_ModifiedConvars.Purge();
if ( m_pkvSavedModifications )
{
m_pkvSavedModifications->deleteThis();
}
m_pkvSavedModifications = NULL;
m_hCurrentNode = NULL;
m_hActiveCommentaryNode = NULL;
m_hLastCommentaryNode = NULL;
@@ -790,15 +978,48 @@ private:
float m_flNextTeleportTime;
int m_iTeleportStage;
KeyValues *m_pkvSavedModifications;
CUtlVector< modifiedconvars_t > m_ModifiedConvars;
CUtlVector<EHANDLE> m_hSpawnedEntities;
CHandle<CPointCommentaryNode> m_hCurrentNode;
CHandle<CPointCommentaryNode> m_hActiveCommentaryNode;
CHandle<CPointCommentaryNode> m_hLastCommentaryNode;
friend bool Commentary_IsCommentaryEntity( CBaseEntity *pEntity );
};
CCommentarySystem g_CommentarySystem;
void ApplyCommentaryModifications()
{
g_CommentarySystem.ApplyCommentaryModifications();
}
bool Commentary_IsCommentaryEntity( CBaseEntity *pEntity )
{
for( int i = 0; i != g_CommentarySystem.m_hSpawnedEntities.Count(); ++i )
{
if( pEntity == g_CommentarySystem.m_hSpawnedEntities[i].Get() )
return true;
}
if( pEntity->GetEntityName() == MAKE_STRING( COMMENTARY_SPAWNED_SEMAPHORE ) )
{
return true;
}
return false;
}
void Commentary_AbortCurrentNode( void )
{
if ( g_CommentarySystem.GetActiveNode() )
{
g_CommentarySystem.GetActiveNode()->AbortPlaying();
}
}
void CommentarySystem_PePlayerRunCommand( CBasePlayer *player, CUserCmd *ucmd )
{
g_CommentarySystem.PrePlayerRunCommand( player, ucmd );
@@ -1244,7 +1465,7 @@ void CPointCommentaryNode::UpdateViewThink( void )
// Blend to the target position over time.
float flCurTime = (gpGlobals->curtime - m_flStartTime);
float flBlendPerc = clamp( flCurTime * 0.5f, 0.f, 1.f );
float flBlendPerc = clamp( flCurTime / 2.0, 0, 1 );
// Figure out the current view position
Vector vecCurEye;
@@ -1269,7 +1490,7 @@ void CPointCommentaryNode::UpdateViewPostThink( void )
// Blend back to the player's position over time.
float flCurTime = (gpGlobals->curtime - m_flFinishedTime);
float flTimeToBlend = MIN( 2.0, m_flFinishedTime - m_flStartTime );
float flBlendPerc = 1.0f - clamp( flCurTime / flTimeToBlend, 0.f, 1.f );
float flBlendPerc = 1.0 - clamp( flCurTime / flTimeToBlend, 0, 1 );
//Msg("OUT: CurTime %.2f, BlendTime: %.2f, Blend: %.3f\n", flCurTime, flTimeToBlend, flBlendPerc );