|
|
//========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#include "cbase.h"
#include "eventlist.h"
#include "stringregistry.h"
// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"
// NOTE: If CStringRegistry allowed storing arbitrary data, we could just use that.
// in this case we have the "isPrivate" member and the replacement rules
// (eventIndex can be reused by private activities), so a custom table is necessary
struct eventlist_t { int eventIndex; int iType; unsigned short stringKey; short isPrivate; };
CUtlVector<eventlist_t> g_EventList;
// This stores the actual event names. Also, the string ID in the registry is simply an index
// into the g_EventList array.
CStringRegistry g_EventStrings;
// this is just here to accelerate adds
static int g_HighestEvent = 0;
int g_nEventListVersion = 1;
void EventList_Init( void ) { g_HighestEvent = 0; }
void EventList_Free( void ) { g_EventStrings.ClearStrings(); g_EventList.Purge();
// So studiohdrs can reindex event indices
++g_nEventListVersion; }
// add a new event to the database
eventlist_t *EventList_AddEventEntry( const char *pName, int iEventIndex, bool isPrivate, int iType ) { MEM_ALLOC_CREDIT(); int index = g_EventList.AddToTail(); eventlist_t *pList = &g_EventList[index]; pList->eventIndex = iEventIndex; pList->stringKey = g_EventStrings.AddString( pName, index ); pList->isPrivate = isPrivate; pList->iType = iType;
// UNDONE: This implies that ALL shared activities are added before ANY custom activities
// UNDONE: Segment these instead? It's a 32-bit int, how many activities do we need?
if ( iEventIndex > g_HighestEvent ) { g_HighestEvent = iEventIndex; }
return pList; }
// get the database entry from a string
static eventlist_t *ListFromString( const char *pString ) { // just use the string registry to do this search/map
int stringID = g_EventStrings.GetStringID( pString ); if ( stringID < 0 ) return NULL;
return &g_EventList[stringID]; }
// Get the database entry for an index
static eventlist_t *ListFromEvent( int eventIndex ) { // ugly linear search
for ( int i = 0; i < g_EventList.Count(); i++ ) { if ( g_EventList[i].eventIndex == eventIndex ) { return &g_EventList[i]; } }
return NULL; }
int EventList_GetEventType( int eventIndex ) { eventlist_t *pEvent = ListFromEvent( eventIndex );
if ( pEvent ) { return pEvent->iType; }
return -1; }
bool EventList_RegisterSharedEvent( const char *pszEventName, int iEventIndex, int iType ) { // UNDONE: Do we want to do these checks when not in developer mode? or maybe DEBUG only?
// They really only matter when you change the list of code controlled activities. IDs
// for content controlled activities never collide because they are generated.
// first, check to make sure the slot we're asking for is free. It must be for
// a shared event.
eventlist_t *pList = ListFromString( pszEventName ); if ( !pList ) { pList = ListFromEvent( iEventIndex ); }
//Already in list.
if ( pList ) { return false; } // ----------------------------------------------------------------
EventList_AddEventEntry( pszEventName, iEventIndex, false, iType ); return true; }
Animevent EventList_RegisterPrivateEvent( const char *pszEventName ) { eventlist_t *pList = ListFromString( pszEventName ); if ( pList ) { // this activity is already in the list. If the activity we collided with is also private,
// then the collision is OK. Otherwise, it's a bug.
if ( pList->isPrivate ) { return (Animevent)pList->eventIndex; } else { // this private activity collides with a shared activity. That is not allowed.
Warning( "***\nShared<->Private Event collision!\n***\n" ); Assert(0); return AE_INVALID; } }
int iType = AE_TYPE_SERVER;
#ifdef CLIENT_DLL
iType = AE_TYPE_CLIENT; #endif
pList = EventList_AddEventEntry( pszEventName, g_HighestEvent+1, true, iType ); return (Animevent)pList->eventIndex; }
// Get the index for a given Event name
// Done at load time for all models
int EventList_IndexForName( const char *pszEventName ) { // this is a fast O(lgn) search (actually does 2 O(lgn) searches)
eventlist_t *pList = ListFromString( pszEventName );
if ( pList ) { return pList->eventIndex; }
return -1; }
// Get the name for a given index
// This should only be used in debug code, it does a linear search
// But at least it only compares integers
const char *EventList_NameForIndex( int eventIndex ) { eventlist_t *pList = ListFromEvent( eventIndex ); if ( pList ) { return g_EventStrings.GetStringForKey( pList->stringKey ); } return NULL; }
void EventList_RegisterSharedEvents( void ) { REGISTER_SHARED_ANIMEVENT( AE_EMPTY, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_LEFTFOOT, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_RIGHTFOOT, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_BODYDROP_LIGHT, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_BODYDROP_HEAVY, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_SWISHSOUND, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_180TURN, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_ITEM_PICKUP, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_WEAPON_DROP, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_WEAPON_SET_SEQUENCE_NAME, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_WEAPON_SET_SEQUENCE_NUMBER, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_WEAPON_SET_ACTIVITY, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_HOLSTER, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_DRAW, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_WEAPON_FIRE, AE_TYPE_SERVER | AE_TYPE_WEAPON );
REGISTER_SHARED_ANIMEVENT( AE_CL_PLAYSOUND, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_SV_PLAYSOUND, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_STOPSOUND, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_START_SCRIPTED_EFFECT, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_STOP_SCRIPTED_EFFECT, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CLIENT_EFFECT_ATTACH, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_MUZZLEFLASH, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_NPC_MUZZLEFLASH, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_THUMPER_THUMP, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_AMMOCRATE_PICKUP_AMMO, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_NPC_RAGDOLL, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_NPC_ADDGESTURE, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_RESTARTGESTURE, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_NPC_ATTACK_BROADCAST, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_NPC_HURT_INTERACTION_PARTNER, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_NPC_SET_INTERACTION_CANTDIE, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_SV_DUSTTRAIL, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CL_CREATE_PARTICLE_EFFECT, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_STOP_PARTICLE_EFFECT, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_ADD_PARTICLE_EFFECT_CP, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_CREATE_PARTICLE_BRASS, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_RAGDOLL, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CL_ENABLE_BODYGROUP, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_DISABLE_BODYGROUP, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_BODYGROUP_SET_VALUE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_BODYGROUP_SET_VALUE_CMODEL_WPN, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_CL_BODYGROUP_SET_TO_CLIP, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_BODYGROUP_SET_TO_NEXTCLIP, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CL_EJECT_MAG, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_EJECT_MAG_UNHIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CL_SHOW_SILENCER, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_ATTACH_SILENCER_COMPLETE, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_HIDE_SILENCER, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_CL_DETACH_SILENCER_COMPLETE, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_WPN_PRIMARYATTACK, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_INCREMENTAMMO, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_WPN_HIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_UNHIDE, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_ASW_FOOTSTEP, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_MARINE_FOOTSTEP, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_MARINE_RELOAD_SOUND_A, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_MARINE_RELOAD_SOUND_B, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_MARINE_RELOAD_SOUND_C, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_REMOVE_CLIENT_AIM, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_WPN_PLAYWPNSOUND, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_COMPLETE_RELOAD, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_MELEE_DAMAGE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_MELEE_START_COLLISION_DAMAGE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_MELEE_STOP_COLLISION_DAMAGE, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_SCREEN_SHAKE, AE_TYPE_CLIENT ); REGISTER_SHARED_ANIMEVENT( AE_START_DETECTING_COMBO, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_STOP_DETECTING_COMBO, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_COMBO_TRANSITION, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_ALLOW_MOVEMENT, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_SKILL_EVENT, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_TUG_INCAP, AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_BEGIN_TAUNT_LOOP, AE_TYPE_CLIENT | AE_TYPE_SERVER );
REGISTER_SHARED_ANIMEVENT( AE_CLIENT_EJECT_BRASS, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_CL_SET_STATTRAK_GLOW, AE_TYPE_CLIENT );
REGISTER_SHARED_ANIMEVENT( AE_WPN_CZ_DUMP_CURRENT_MAG, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_CZ_UPDATE_BODYGROUP, AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_CLIP_TO_POSEPARAM, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_NEXTCLIP_TO_POSEPARAM, AE_TYPE_CLIENT | AE_TYPE_SERVER ); REGISTER_SHARED_ANIMEVENT( AE_WPN_EMPTYSHOTS_TO_POSEPARAM, AE_TYPE_CLIENT | AE_TYPE_SERVER );
}
|