⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listener.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-----------------------------------------------------------------------------
//
//  $Logfile:: /Quake 2 Engine/Sin/code/game/listener.cpp                     $
// $Revision:: 45                                                             $
//   $Author:: Jimdose                                                        $
//     $Date:: 11/10/98 5:48p                                                 $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//
// $Log:: /Quake 2 Engine/Sin/code/game/listener.cpp                          $
// 
// 45    11/10/98 5:48p Jimdose
// Made SortEventList sort the list manually when TEMPLATE_EXPORT is not
// defined
// 
// 44    10/26/98 4:27p Jimdose
// Sped up ValidEvent
// Added FindEvent( const char * )
// 
// 43    10/24/98 3:25a Jimdose
// added g_watch for only displaying events from a specific object
// 
// 42    10/19/98 6:30p Jimdose
// increased g_eventlimit to 1500
// 
// 41    10/19/98 12:07a Jimdose
// made all code use fast checks for inheritance (no text lookups when
// possible)
// isSubclassOf no longer requires ::_classinfo()
// 
// 40    10/18/98 8:44p Jimdose
// Made commandList a Container of str * instead of str.  Fixes problem of name
// pointer in event being invalidated when commandList is resized
// 
// 39    10/18/98 3:22a Jimdose
// Added code for timing events
// 
// 38    10/17/98 11:33p Jimdose
// Added the event name to Event to help with debugging
// 
// 37    10/17/98 12:22a Jimdose
// upped g_eventlimit to 500
// 
// 36    10/16/98 7:19p Jimdose
// Added g_eventlimit
// G_ProcessPendingEvents now breaks out if the number of events executed
// during the call exceeds g_eventlimit.
// Removed g_response and old code from ProcessEvent
// 
// 35    10/16/98 1:53a Jimdose
// Added FL_DONTSAVE to entities, so events that belong to entities with this
// flag aren't archived
// 
// 34    10/10/98 1:28a Jimdose
// PostEvent kills any events posted during a loadgame
// 
// 33    10/07/98 11:52p Jimdose
// Wrote Event archiving functions
// 
// 32    9/24/98 1:46a Jimdose
// Made Event a subclass of Class
// 
// 31    9/19/98 4:32p Jimdose
// Added ListCommands
// 
// 30    8/27/98 9:03p Jimdose
// Moved a lot of small functions to the header as inline
// 
// 29    8/26/98 6:42p Jimdose
// Added more info when g_showevents is set
// 
// 28    8/20/98 4:42p Jimdose
// (Finally) added binary search for resolving event names
// 
// 27    8/17/98 4:29p Jimdose
// added event reporting with g_showevents cvar
// 
// 26    8/06/98 5:18p Jimdose
// Fixed check for default flags in Event constructor for str objects
// 
// 25    8/01/98 7:58p Jimdose
// Fixed bug with cheats in dm
// 
// 24    7/31/98 8:09p Jimdose
// Script commands now include flags to indicate cheats and console commands
// 
// 23    7/31/98 4:19p Jimdose
// Added DepthOfEvent
// 
// 22    7/20/98 5:09p Jimdose
// Added ProcessPendingEvents
// 
// 21    7/10/98 10:00p Jimdose
// Made remove script command post remove event so that it doesn't cause
// problems during event callbacks which trigger the script
// 
// 20    7/08/98 12:54p Jimdose
// Made error for vectors not including '(' ')' a developer 2 warning
// 
// 19    6/30/98 6:05p Jimdose
// Added IsVectorAt, IsEntityAt, and IsNumericAt for doing type checking on
// args
// Changed format for storing vectors to make it easy to identify
// 
// 18    6/27/98 9:18p Jimdose
// Made lookup for event responses for faster processing
// 
// 17    6/24/98 6:48p Jimdose
// Made entity number based commands use "*" prefix consistantly
// 
// 16    6/20/98 7:41p Jimdose
// Made GetEntity return NULL if the index is out of range
// 
// 15    6/18/98 8:47p Jimdose
// Added better event error handling
// Added source info to events
// Added checks for event still in use when processing events (prevents
// deleting events twice)
// 
// 14    6/17/98 3:03p Markd
// Changed NumArgs back to previous behavior
// 
// 13    6/10/98 7:53p Markd
// Made NumArgs behave correctly like argc
// 
// 12    5/24/98 8:46p Jimdose
// Made a lot of functions more str-friendly.
// Got rid of a lot of char * based strings
// Cleaned up get spawn arg functions and sound functions
// sound functions now use consistant syntax
// 
// 11    5/24/98 4:48p Jimdose
// Made char *'s const
// 
// 10    5/24/98 1:06a Jimdose
// added const to various char *s
// 
// 9     5/08/98 2:51p Jimdose
// Moved archiving functions up to Class
// 
// 8     5/07/98 10:42p Jimdose
// Added archive and unarchive
// 
// 7     4/30/98 9:24p Jimdose
// Changed use of string to str class
// 
// 6     4/06/98 5:44p Jimdose
// Added assertion for null entities in AddEntity.  In the release version, it
// "safely" treats null ents as entnum 0
// 
// 5     4/02/98 4:48p Jimdose
// Added initCommandList to ensure that NullEvent is always initialized first
// 
// 4     3/24/98 5:02p Jimdose
// Made GetToken return the exact string instead of resolving the value of
// variables
// PostponeEvent was not updating the position of the event in the list, which
// would cause a logjam of events that were following the event.
// 
// 3     3/23/98 1:31p Jimdose
// Revamped event and command system
// 
// 2     3/04/98 1:01p Jimdose
// Created file
//
// DESCRIPTION:
// 

#include "listener.h"
#include "scriptvariable.h"
#include "worldspawn.h"
#include "scriptmaster.h"

Event EV_Remove( "immediateremove" );
Event EV_ScriptRemove( "remove" );

typedef struct eventcache_s 
	{
	Listener *obj;
	Event		*event;
	float		time;

	struct eventcache_s *next;
	struct eventcache_s *prev;
	} eventcache_t;

#define MAX_EVENTS 2000

extern "C" 
	{
	eventcache_t	Events[ MAX_EVENTS ];
	int				numEvents = 0;
	cvar_t			*g_numevents;
	};

cvar_t *g_showevents;
cvar_t *g_eventlimit;
cvar_t *g_timeevents;
cvar_t *g_watch;

eventcache_t FreeEventHead;
eventcache_t *FreeEvents = &FreeEventHead;
eventcache_t EventQueueHead;
eventcache_t *EventQueue = &EventQueueHead;

Container<str *> *Event::commandList = NULL;
Container<int> *Event::flagList = NULL;
Container<int> *Event::sortedList = NULL;
qboolean Event::dirtylist = false;

Event NullEvent;

CLASS_DECLARATION( Class, Event, NULL );

ResponseDef Event::Responses[] =
	{
		{ NULL, NULL }
	};

EXPORT_FROM_DLL int Event::NumEventCommands
	(
	void
	)

	{
	if ( commandList )
		{
		// Add 1 since container gives the inclusive number of objects
		return commandList->NumObjects() + 1;
		}

	return 0;
	}

EXPORT_FROM_DLL int Event::compareEvents
	( 
	const void *arg1, 
	const void *arg2 
	)

	{
	int ev1;
	int ev2;

	ev1 = *( int * )arg1;
	ev2 = *( int * )arg2;

	return stricmp( commandList->ObjectAt( ev1 )->c_str(), commandList->ObjectAt( ev2 )->c_str() );
	}

EXPORT_FROM_DLL void Event::SortEventList
	(
	void
	)

	{
	dirtylist = false;

	if ( sortedList && commandList )
		{
#ifndef EXPORT_TEMPLATE
      qsort( ( void * )sortedList->AddressOfObjectAt( 1 ), 
         ( size_t )sortedList->NumObjects(), 
         sizeof( int ), compareEvents );
#else
		sortedList->Sort( compareEvents );
#endif
		}
	}

inline EXPORT_FROM_DLL int Event::FindEvent
	(
	const char *name
	)

	{
	int eventnum;
   int index;
	int l;
	int r;
	int diff;

   assert( name );
   if ( !name )
      {
      return 0;
      }

	if ( !commandList )
		{
		return 0;
		}

	if ( dirtylist )
		{
		SortEventList();
		}

   l = 1;
   r = sortedList->NumObjects();
   while( r >= l )
      {
      index = ( l + r ) >> 1;
		eventnum = sortedList->ObjectAt( index );
      diff = stricmp( name, commandList->ObjectAt( eventnum )->c_str() );
      if ( diff < 0 )
         {
         r = index - 1;
         }
      else if ( diff > 0 )
         {
         l = index + 1;
         }
      else
         {
         return eventnum;
         }
      }

   return 0;
	}

EXPORT_FROM_DLL int Event::FindEvent
	(
	str &name
	)

	{
   return FindEvent( name.c_str() );
	}

EXPORT_FROM_DLL void Event::ListCommands
	(
   const char *mask
	)

	{
   str name;
   int flags;
	int eventnum;
   int num;
	int i;
	int n;
   int l;
   int p;
   int hidden;
   str text;

	if ( !commandList )
		{
      gi.printf( "No events.\n" );
		return;
		}

	if ( dirtylist )
		{
		SortEventList();
		}

   l = 0;
   if ( mask )
      {
      l = strlen( mask );
      }

   hidden = 0;
   num = 0;
   n = sortedList->NumObjects();
   for( i = 1; i <= n; i++ )
      {
		eventnum = sortedList->ObjectAt( i );
      name = commandList->ObjectAt( eventnum )->c_str();
      flags = flagList->ObjectAt( eventnum );

      if ( flags & EV_HIDE )
         {
         hidden++;
         continue;
         }

      if ( mask && Q_strncasecmp( name.c_str(), mask, l ) )
         {
         continue;
         }

      num++;

      text = "   ";
      p = 0;
      if ( flags & EV_CONSOLE )
         {
         text[ p++ ] = '*';
         }
      if ( flags & EV_CHEAT )
         {
         text[ p++ ] = 'C';
         }

      gi.printf( "%4d : %s%s\n", eventnum, text.c_str(), name.c_str() );
      }

   gi.printf( "\n* = console command.\nC = cheat command.\n\n"
      "Printed %d of %d total commands.\n", num, n - hidden );

   if ( developer->value && hidden )
      {
      gi.printf( "Suppressed %d commands.\n", hidden );
      }
	}

EXPORT_FROM_DLL void Event::initCommandList
	(
	void
	)

	{
	int flags;
   str *n;

	flags = 0;
	commandList = new Container<str *>;

   n = new str( "NULL" );
	NullEvent.eventnum = commandList->AddObject( n );
	
	flagList = new Container<int>;
	flagList->AddObject( flags );

	sortedList = new Container<int>;
	sortedList->AddObject( NullEvent.eventnum );

	dirtylist = false;

	NullEvent.data = NULL;
	NullEvent.info.inuse = 0;
	NullEvent.info.source = EV_FROM_CODE;
	NullEvent.info.flags = 0;
	NullEvent.info.linenumber = 0;
	}

Event::Event()
	{
	info.inuse = 0;
	info.source = EV_FROM_CODE;
	info.flags = 0;
	info.linenumber = 0;
	threadnum = -1;
	eventnum = 0;
	data = NULL;
   name = NULL;
	}

Event::Event
	(
	int num
	)

	{
	if ( !commandList )
		{
		initCommandList();
		}

	assert( ( num > 0 ) && num <= commandList->NumObjects() );

   if ( ( num <= 0 ) || ( num > commandList->NumObjects() ) )
      {
      num = 0;
      name = NULL;
   	info.flags = 0;
      }
   else
      {
      name = commandList->ObjectAt( num )->c_str();
	   info.flags = flagList->ObjectAt( num );
      }
	
	eventnum = num;
	data = NULL;
	info.inuse = 0;
	info.source = EV_FROM_CODE;
	info.linenumber = 0;
	threadnum = -1;
	}

Event::Event
	(
	Event &ev
	)

	{
	int num;
	int i;

	eventnum = ( int )ev;
	assert( ( eventnum > 0 ) && eventnum <= commandList->NumObjects() );
	data = NULL;
	
   name = commandList->ObjectAt( eventnum )->c_str();
	info.inuse = 0;
	info.source = ev.info.source;
	info.flags = ev.info.flags;
	info.linenumber = ev.info.linenumber;
	threadnum = ev.threadnum;

	if ( ev.data )
		{
		num = ev.data->NumObjects();

		data = new Container<str>;
		data->Resize( num );

		for( i = 1; i <= num; i++ )
			{
			data->AddObject( ev.data->ObjectAt( i ) );
			}
		}
	}

Event::Event
	(
	Event *ev
	)

	{
	int num;
	int i;

   assert( ev );
   if ( !ev )
      {
      Class::error( "Event", "NULL Event\n" );
      }

	eventnum = ( int )*ev;
	assert( ( eventnum > 0 ) && eventnum <= commandList->NumObjects() );
	data = NULL;
   name = commandList->ObjectAt( eventnum )->c_str();
	info.inuse = 0;
	info.source = ev->info.source;
	info.flags = ev->info.flags;
	info.linenumber = ev->info.linenumber;
	threadnum = ev->threadnum;
	if ( ev->data )
		{
		num = ev->data->NumObjects();

		data = new Container<str>;
		data->Resize( num );

		for( i = 1; i <= num; i++ )
			{
			data->AddObject( ev->data->ObjectAt( i ) );
			}
		}
	}

Event::Event
	(
	const char *command,
	int flags
	)

	{
	str c;
   str *t;

	if ( !commandList )
		{
		initCommandList();
		}

	c = command;
	eventnum = FindEvent( c );
	if ( !eventnum )
		{
      t = new str( c );
		eventnum = commandList->AddObject( t );
		// check for default flags
		if ( flags == -1 )
			{
			flags = 0;
			}
		flagList->AddObject( ( int )flags );
		sortedList->AddObject( eventnum );
		dirtylist = true;
		}
   
   // Use the name stored in the command list in case the string passed in 
   // is not in static memory.
   name = commandList->ObjectAt( eventnum )->c_str();

	data = NULL;
	info.inuse = 0;
	info.source = EV_FROM_CODE;
	info.linenumber = 0;
	threadnum = -1;

	// If flags have changed, let the user know.  It's probably a development bug.
	int &flagobj = flagList->ObjectAt( eventnum );

	// check for default flags
	if ( flags == -1 )
		{
		flags = flagobj;
		}

	assert( flags == flagobj );
	if ( flags != flagobj )
		{
		// Flags not equal.  Use combined value.
		flagobj |= flags;
		}

	info.flags = flagobj;
	}

Event::Event
	(
	str &command,
	int flags
	)

	{
   str *t;

	if ( !commandList )
		{
		initCommandList();
		}

	eventnum = FindEvent( command );
	if ( !eventnum )
		{
      t = new str( command );
		eventnum = commandList->AddObject( t );
		// check for default flags
		if ( flags == -1 )
			{
			flags = 0;
			}
		flagList->AddObject( flags );
		sortedList->AddObject( eventnum );
		dirtylist = true;
		}

   // Use the name stored in the command list since the string passed in 
   // is not in static memory.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -