mirror of
https://github.com/celisej567/source-sdk-2013.git
synced 2026-09-23 20:09:45 +03:00
Added support for custom VScript procedural targets
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "npc_playercompanion.h"
|
||||
#ifdef MAPBASE
|
||||
#include "hl2_player.h"
|
||||
#include "mapbase_matchers_base.h"
|
||||
#endif
|
||||
#endif // HL2_DLL
|
||||
|
||||
@@ -78,6 +79,15 @@ public:
|
||||
|
||||
// IEntityListener
|
||||
virtual void OnEntityCreated( CBaseEntity *pEntity ) {}
|
||||
virtual void OnEntitySpawned( CBaseEntity *pEntity )
|
||||
{
|
||||
// From Alien Swarm SDK
|
||||
if ( ShouldAddEntity( pEntity ) )
|
||||
{
|
||||
RemoveEntity( pEntity );
|
||||
AddEntity( pEntity );
|
||||
}
|
||||
}
|
||||
virtual void OnEntityDeleted( CBaseEntity *pEntity )
|
||||
{
|
||||
if ( !(pEntity->GetFlags() & FL_AIMTARGET) )
|
||||
@@ -105,6 +115,10 @@ public:
|
||||
memcpy( pList, m_targetList.Base(), sizeof(CBaseEntity *) * count );
|
||||
return count;
|
||||
}
|
||||
CBaseEntity *ListElement( int iIndex ) // From Alien Swarm SDK
|
||||
{
|
||||
return m_targetList[iIndex];
|
||||
}
|
||||
|
||||
private:
|
||||
CUtlVector<CBaseEntity *> m_targetList;
|
||||
@@ -120,6 +134,10 @@ int AimTarget_ListCopy( CBaseEntity *pList[], int listMax )
|
||||
{
|
||||
return g_AimManager.ListCopy( pList, listMax );
|
||||
}
|
||||
CBaseEntity *AimTarget_ListElement( int iIndex )
|
||||
{
|
||||
return g_AimManager.ListElement( iIndex );
|
||||
}
|
||||
void AimTarget_ForceRepopulateList()
|
||||
{
|
||||
g_AimManager.ForceRepopulateList();
|
||||
@@ -293,6 +311,10 @@ CBaseEntityClassList::~CBaseEntityClassList()
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
static CUtlVector<CustomProcedural_t> g_CustomProcedurals;
|
||||
#endif
|
||||
|
||||
CGlobalEntityList::CGlobalEntityList()
|
||||
{
|
||||
m_iHighestEnt = m_iNumEnts = m_iNumEdicts = 0;
|
||||
@@ -380,6 +402,18 @@ void CGlobalEntityList::Clear( void )
|
||||
// free the memory
|
||||
g_DeleteList.Purge();
|
||||
|
||||
#ifdef _DEBUG // From Alien Swarm SDK
|
||||
for ( UtlHashHandle_t handle = g_EntsByClassname.GetFirstHandle(); g_EntsByClassname.IsValidHandle(handle); handle = g_EntsByClassname.GetNextHandle(handle) )
|
||||
{
|
||||
EntsByStringList_t &element = g_EntsByClassname[handle];
|
||||
Assert( element.pHead == NULL );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
g_CustomProcedurals.Purge();
|
||||
#endif
|
||||
|
||||
CBaseEntity::m_nDebugPlayer = -1;
|
||||
CBaseEntity::m_bInDebugSelect = false;
|
||||
m_iHighestEnt = 0;
|
||||
@@ -516,6 +550,43 @@ CBaseEntity *CGlobalEntityList::FindEntityByClassname( CBaseEntity *pStartEntity
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// From Alien Swarm SDK
|
||||
CBaseEntity *CGlobalEntityList::FindEntityByClassnameFast( CBaseEntity *pStartEntity, string_t iszClassname )
|
||||
{
|
||||
/*
|
||||
if ( pStartEntity )
|
||||
{
|
||||
return pStartEntity->m_pNextByClass;
|
||||
}
|
||||
|
||||
EntsByStringList_t key = { iszClassname };
|
||||
UtlHashHandle_t hEntry = g_EntsByClassname.Find( key );
|
||||
if ( hEntry != g_EntsByClassname.InvalidHandle() )
|
||||
{
|
||||
return g_EntsByClassname[hEntry].pHead;
|
||||
}
|
||||
*/
|
||||
|
||||
const CEntInfo *pInfo = pStartEntity ? GetEntInfoPtr( pStartEntity->GetRefEHandle() )->m_pNext : FirstEntInfo();
|
||||
|
||||
for ( ;pInfo; pInfo = pInfo->m_pNext )
|
||||
{
|
||||
CBaseEntity *pEntity = (CBaseEntity *)pInfo->m_pEntity;
|
||||
if ( !pEntity )
|
||||
{
|
||||
DevWarning( "NULL entity in global entity list!\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( pEntity->m_iClassname == iszClassname)
|
||||
{
|
||||
return pEntity;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Finds an entity given a procedural name.
|
||||
@@ -633,6 +704,93 @@ CBaseEntity *CGlobalEntityList::FindEntityProcedural( const char *szName, CBaseE
|
||||
}
|
||||
|
||||
|
||||
#ifdef MAPBASE_VSCRIPT
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Finds an entity given a custom procedural name.
|
||||
// Input : szName - The procedural name to search for, should start with '!'.
|
||||
// pSearchingEntity -
|
||||
// pActivator - The activator entity if this was called from an input
|
||||
// or Use handler.
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseEntity *CGlobalEntityList::FindEntityCustomProcedural( CBaseEntity *pStartEntity, const char *szName, CBaseEntity *pSearchingEntity, CBaseEntity *pActivator, CBaseEntity *pCaller )
|
||||
{
|
||||
const char *pName = szName;
|
||||
|
||||
//
|
||||
// Check for the name escape character.
|
||||
//
|
||||
if ( szName[0] == '!' )
|
||||
pName = szName + 1;
|
||||
|
||||
//
|
||||
// Look through the custom procedural list.
|
||||
//
|
||||
for (int i = 0; i < g_CustomProcedurals.Count(); i++)
|
||||
{
|
||||
if (Matcher_NamesMatch( g_CustomProcedurals[i].szName, pName ))
|
||||
{
|
||||
if (pStartEntity && g_CustomProcedurals[i].bCanReturnMultiple == false)
|
||||
return NULL;
|
||||
|
||||
// name, startEntity, searchingEntity, activator, caller
|
||||
ScriptVariant_t functionReturn;
|
||||
ScriptVariant_t args[] = {
|
||||
ScriptVariant_t( pName ),
|
||||
ScriptVariant_t( ToHScript( pStartEntity ) ),
|
||||
ScriptVariant_t( ToHScript( pSearchingEntity ) ),
|
||||
ScriptVariant_t( ToHScript( pActivator ) ),
|
||||
ScriptVariant_t( ToHScript( pCaller ) ),
|
||||
};
|
||||
|
||||
g_pScriptVM->ExecuteFunction( g_CustomProcedurals[i].hFunc, args, 5, &functionReturn, NULL, true );
|
||||
|
||||
return ToEnt( functionReturn.m_hScript );
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CGlobalEntityList::AddCustomProcedural( const char *pszName, HSCRIPT hFunc, bool bCanReturnMultiple )
|
||||
{
|
||||
//
|
||||
// Check for any existing custom procedurals to replace.
|
||||
//
|
||||
for (int i = 0; i < g_CustomProcedurals.Count(); i++)
|
||||
{
|
||||
if (FStrEq( pszName, g_CustomProcedurals[i].szName ))
|
||||
{
|
||||
g_CustomProcedurals.FastRemove( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Add a new custom procedural.
|
||||
//
|
||||
int i = g_CustomProcedurals.AddToTail();
|
||||
g_CustomProcedurals[i].szName = pszName;
|
||||
g_CustomProcedurals[i].hFunc = hFunc;
|
||||
g_CustomProcedurals[i].bCanReturnMultiple = bCanReturnMultiple;
|
||||
}
|
||||
|
||||
void CGlobalEntityList::RemoveCustomProcedural( const char *pszName )
|
||||
{
|
||||
//
|
||||
// Remove the specified custom procedural.
|
||||
//
|
||||
for (int i = 0; i < g_CustomProcedurals.Count(); i++)
|
||||
{
|
||||
if (FStrEq( pszName, g_CustomProcedurals[i].szName ))
|
||||
{
|
||||
g_CustomProcedurals.FastRemove( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Iterates the entities with a given name.
|
||||
// Input : pStartEntity - Last entity found, NULL to start a new iteration.
|
||||
@@ -647,6 +805,16 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con
|
||||
|
||||
if ( szName[0] == '!' )
|
||||
{
|
||||
#ifdef MAPBASE
|
||||
if (g_CustomProcedurals.Count() > 0)
|
||||
{
|
||||
// Search for a custom procedural
|
||||
CBaseEntity *ent = FindEntityCustomProcedural( pStartEntity, szName, pSearchingEntity, pActivator, pCaller );
|
||||
if (ent != NULL)
|
||||
return ent;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// Avoid an infinite loop, only find one match per procedural search!
|
||||
//
|
||||
@@ -682,6 +850,35 @@ CBaseEntity *CGlobalEntityList::FindEntityByName( CBaseEntity *pStartEntity, con
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// From Alien Swarm SDK
|
||||
CBaseEntity *CGlobalEntityList::FindEntityByNameFast( CBaseEntity *pStartEntity, string_t iszName )
|
||||
{
|
||||
if ( iszName == NULL_STRING || STRING(iszName)[0] == 0 )
|
||||
return NULL;
|
||||
|
||||
const CEntInfo *pInfo = pStartEntity ? GetEntInfoPtr( pStartEntity->GetRefEHandle() )->m_pNext : FirstEntInfo();
|
||||
|
||||
for ( ;pInfo; pInfo = pInfo->m_pNext )
|
||||
{
|
||||
CBaseEntity *ent = (CBaseEntity *)pInfo->m_pEntity;
|
||||
if ( !ent )
|
||||
{
|
||||
DevWarning( "NULL entity in global entity list!\n" );
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !ent->m_iName.Get() )
|
||||
continue;
|
||||
|
||||
if ( ent->m_iName.Get() == iszName )
|
||||
{
|
||||
return ent;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose:
|
||||
// Input : pStartEntity -
|
||||
@@ -899,6 +1096,80 @@ CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearest( const char *szName
|
||||
}
|
||||
|
||||
|
||||
// From Alien Swarm SDK
|
||||
CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearestFast( string_t iszName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
CBaseEntity *pEntity = NULL;
|
||||
|
||||
//
|
||||
// Check for matching class names within the search radius.
|
||||
//
|
||||
float flMaxDist2 = flRadius * flRadius;
|
||||
if (flMaxDist2 == 0)
|
||||
{
|
||||
flMaxDist2 = MAX_TRACE_LENGTH * MAX_TRACE_LENGTH;
|
||||
}
|
||||
|
||||
CBaseEntity *pSearch = NULL;
|
||||
while ((pSearch = gEntList.FindEntityByClassnameFast( pSearch, iszName )) != NULL)
|
||||
{
|
||||
if ( !pSearch->edict() )
|
||||
continue;
|
||||
|
||||
float flDist2 = (pSearch->GetAbsOrigin() - vecSrc).LengthSqr();
|
||||
|
||||
if (flMaxDist2 > flDist2)
|
||||
{
|
||||
pEntity = pSearch;
|
||||
flMaxDist2 = flDist2;
|
||||
}
|
||||
}
|
||||
|
||||
return pEntity;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Finds the nearest entity by class name withing given search radius.
|
||||
// From Alien Swarm SDK
|
||||
// Input : szName - Entity name to search for. Treated as a target name first,
|
||||
// then as an entity class name, ie "info_target".
|
||||
// vecSrc - Center of search radius.
|
||||
// flRadius - Search radius for classname search, 0 to search everywhere.
|
||||
// Output : Returns a pointer to the found entity, NULL if none.
|
||||
//-----------------------------------------------------------------------------
|
||||
CBaseEntity *CGlobalEntityList::FindEntityByClassnameNearest2D( const char *szName, const Vector &vecSrc, float flRadius )
|
||||
{
|
||||
CBaseEntity *pEntity = NULL;
|
||||
|
||||
//
|
||||
// Check for matching class names within the search radius.
|
||||
//
|
||||
float flMaxDist2 = flRadius * flRadius;
|
||||
if (flMaxDist2 == 0)
|
||||
{
|
||||
flMaxDist2 = MAX_TRACE_LENGTH * MAX_TRACE_LENGTH;
|
||||
}
|
||||
|
||||
CBaseEntity *pSearch = NULL;
|
||||
while ((pSearch = gEntList.FindEntityByClassname( pSearch, szName )) != NULL)
|
||||
{
|
||||
if ( !pSearch->edict() )
|
||||
continue;
|
||||
|
||||
float flDist2 = (pSearch->GetAbsOrigin().AsVector2D() - vecSrc.AsVector2D()).LengthSqr();
|
||||
|
||||
if (flMaxDist2 > flDist2)
|
||||
{
|
||||
pEntity = pSearch;
|
||||
flMaxDist2 = flDist2;
|
||||
}
|
||||
}
|
||||
|
||||
return pEntity;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Finds the first entity within radius distance by class name.
|
||||
|
||||
Reference in New Issue
Block a user