2016-03-27 11:49:47 +02:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Copyright ( C ) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code .
OpenMoHAA source code is free software ; you can redistribute it
and / or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation ; either version 2 of the License ,
or ( at your option ) any later version .
OpenMoHAA source code is distributed in the hope that it will be
useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
// scriptmaster.cpp : Spawns at the beginning of the maps, parse scripts.
# include "glb_local.h"
# include "scriptmaster.h"
2023-01-29 22:57:04 +01:00
# include "scriptthread.h"
2023-01-30 18:20:50 +01:00
# include "scriptclass.h"
2016-03-27 11:49:47 +02:00
# include "gamescript.h"
# include "game.h"
# include "g_spawn.h"
# include "object.h"
2023-01-30 18:20:50 +01:00
# include "world.h"
# include "scriptcompiler.h"
2023-04-29 21:56:38 +02:00
# include "scriptexception.h"
2016-03-27 11:49:47 +02:00
# ifdef WIN32
# include <direct.h>
# else
# include <sys/stat.h>
# include <unistd.h>
# endif
# if defined ( CGAME_DLL )
# include <hud.h>
# define SCRIPT_Printf cgi.Printf
# define SCRIPT_DPrintf cgi.DPrintf
# elif defined ( GAME_DLL )
2023-06-17 01:24:20 +02:00
# include "hud.h"
# include "dm_team.h"
# include "player.h"
# include "entity.h"
# include "huddraw.h"
# include "weaputils.h"
# include "camera.h"
# include "consoleevent.h"
2016-03-27 11:49:47 +02:00
# define SCRIPT_Printf gi.Printf
# define SCRIPT_DPrintf gi.DPrintf
# endif
con_set < str , ScriptThreadLabel > m_scriptCmds ;
str vision_current ;
qboolean disable_team_change ;
qboolean disable_team_spectate ;
ScriptMaster Director ;
ScriptEvent scriptedEvents [ SE_MAX ] ;
CLASS_DECLARATION ( Class , ScriptEvent , NULL )
{
{ NULL , NULL }
} ;
2023-01-29 22:57:04 +01:00
//
// world stuff
//
Event EV_RegisterAlias
2016-03-27 11:49:47 +02:00
(
2023-01-29 22:57:04 +01:00
" alias " ,
2016-03-27 11:49:47 +02:00
EV_DEFAULT ,
2023-01-29 22:57:04 +01:00
" ssSSSS " ,
" alias_name real_name arg1 arg2 arg3 arg4 " ,
" Sets up an alias. "
2016-03-27 11:49:47 +02:00
) ;
2023-01-29 22:57:04 +01:00
Event EV_RegisterAliasAndCache
2016-03-27 11:49:47 +02:00
(
2023-01-29 22:57:04 +01:00
" aliascache " ,
2016-03-27 11:49:47 +02:00
EV_DEFAULT ,
2023-01-29 22:57:04 +01:00
" ssSSSS " ,
" alias_name real_name arg1 arg2 arg3 arg4 " ,
" Sets up an alias and caches the resourse. "
2016-03-27 11:49:47 +02:00
) ;
2023-01-29 22:57:04 +01:00
Event EV_Cache
2016-03-27 11:49:47 +02:00
(
2023-01-29 22:57:04 +01:00
" cache " ,
EV_CACHE ,
" s " ,
" resourceName " ,
" pre-cache the given resource. "
2016-03-27 11:49:47 +02:00
) ;
2023-01-29 22:57:04 +01:00
CLASS_DECLARATION ( Listener , ScriptMaster , NULL )
{
{ & EV_RegisterAlias , & ScriptMaster : : RegisterAlias } ,
{ & EV_RegisterAliasAndCache , & ScriptMaster : : RegisterAliasAndCache } ,
{ & EV_Cache , & ScriptMaster : : Cache } ,
{ NULL , NULL }
} ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
void ScriptMaster : : Archive ( Archiver & arc )
{
ScriptClass * scr ;
ScriptVM * m_current ;
ScriptThread * m_thread ;
int num ;
int i , j ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( arc . Saving ( ) )
{
2023-02-01 00:28:40 +01:00
num = ( int ) ScriptClass_allocator . Count ( ) ;
2023-01-29 22:57:04 +01:00
arc . ArchiveInteger ( & num ) ;
2016-03-27 11:49:47 +02:00
2023-01-30 17:11:44 +01:00
MEM_BlockAlloc_enum < ScriptClass > en = ScriptClass_allocator ;
2023-01-29 22:57:04 +01:00
for ( scr = en . NextElement ( ) ; scr ! = NULL ; scr = en . NextElement ( ) )
{
scr - > ArchiveInternal ( arc ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
num = 0 ;
for ( m_current = scr - > m_Threads ; m_current ! = NULL ; m_current = m_current - > next )
num + + ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
arc . ArchiveInteger ( & num ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( m_current = scr - > m_Threads ; m_current ! = NULL ; m_current = m_current - > next )
m_current - > m_Thread - > ArchiveInternal ( arc ) ;
}
}
else
{
arc . ArchiveInteger ( & num ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( i = 0 ; i < num ; i + + )
{
scr = new ScriptClass ( ) ;
scr - > ArchiveInternal ( arc ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
arc . ArchiveInteger ( & num ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( j = 0 ; j < num ; j + + )
{
m_thread = new ScriptThread ( scr , NULL ) ;
m_thread - > ArchiveInternal ( arc ) ;
}
}
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
timerList . Archive ( arc ) ;
m_menus . Archive ( arc ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ArchiveString ( Archiver & arc , const_str & s )
{
str s2 ;
byte b ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( arc . Loading ( ) )
{
arc . ArchiveByte ( & b ) ;
if ( b )
{
arc . ArchiveString ( & s2 ) ;
s = AddString ( s2 ) ;
}
else
{
s = 0 ;
}
}
else
{
if ( s )
{
b = 1 ;
arc . ArchiveByte ( & b ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
s2 = Director . GetString ( s ) ;
arc . ArchiveString ( & s2 ) ;
}
else
{
b = 0 ;
arc . ArchiveByte ( & b ) ;
}
}
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
const char * ScriptMaster : : ConstStrings [ ] =
{
" " ,
" touch " , " block " , " trigger " , " use " ,
" damage " , " location " ,
" say " , " fail " , " bump " ,
" default " , " all " ,
" move_action " , " resume " , " open " , " close " , " pickup " , " reach " , " start " , " teleport " ,
" move " , " move_end " , " moveto " , " walkto " , " runto " , " crouchto " , " crawlto " , " stop " ,
" reset " , " prespawn " , " spawn " , " playerspawn " , " skip " , " roudstart " ,
" visible " , " not_visible " ,
" done " , " animdone " , " upperanimdone " , " saydone " , " flaggedanimdone " ,
" idle " , " walk " , " shuffle " , " anim/crouch.scr " ,
" forgot " ,
" jog_hunch " , " jog_hunch_rifle " ,
" killed " , " alarm " , " scriptclass " , " ai/utils/fact_script_factory.scr " , " death " , " death_fall_to_knees " ,
" enemy " , " dead " , " mood " , " patrol " , " runner " , " follow " , " action " ,
" move_begin " , " action_begin " , " action_end " , " success " ,
" entry " , " exit " , " path " , " node " , " ask_count " , " attacker " , " usecover " , " waitcover " ,
" void " , " end " , " attack " , " near " ,
" papers " , " check_papers " ,
" timeout " ,
" hostile " , " leader " ,
" gamemap " ,
" bored " , " nervous " , " curious " , " alert " , " greet " , " depend " ,
" anim " , " anim_scripted " , " anim_curious " , " animloop " , " undefined " , " notset " ,
" increment " , " decrement " , " toggle " ,
" normal " , " suspend " , " mystery " , " surprise " ,
" anim/crouch_run.scr " , " anim/aim.scr " , " anim/shoot.scr " , " anim/mg42_shoot.scr " , " anim/mg42_idle.scr " , " anim_mg42_reload.scr " ,
" drive " ,
" global/weapon.scr " , " global/moveto.scr " ,
" global/anim.scr " , " global/anim_scripted.scr " , " global/anim_noclip.scr " ,
" global/walkto.scr " , " global/runto.scr " ,
" aimat " ,
" global/disabled_ai.scr " ,
" global/crouchto.scr " , " global/crawlto.scr " , " global/killed.scr " , " global/pain.scr " ,
" pain " , " track " , " hasenemy " ,
" anim/cower.scr " , " anim/stand.scr " , " anim/idle.scr " , " anim/surprise.scr " , " anim/standshock.scr " , " anim/standidentify " , " anim/standflinch.scr " ,
" anim/dog_idle.scr " , " anim/dog_attack.scr " , " anim/dog_curious.scr " , " anim/dog_chase.scr " ,
" cannon " , " grenade " , " heavy " ,
" item " , " items " , " item1 " , " item2 " , " item3 " , " item4 " ,
" stand " , " mg " , " pistol " , " rifle " , " smg " ,
" turnto " , " standing " , " crouching " , " prone " , " offground " , " walking " , " running " , " falling " ,
" anim_nothing " , " anim_direct " , " anim_path " , " anim_waypoint " , " anim_direct_nogravity " ,
" emotion_none " , " emotion_neutral " ,
" emotion_worry " , " emotion_panic " , " emotion_fear " ,
" emotion_disgust " , " emotion_anger " ,
" emotion_aiming " , " emotion_determined " ,
" emotion_dead " ,
" emotion_curious " ,
" anim/emotion.scr " ,
" forceanim " , " forceanim_scripted " ,
" turret " , " cover " ,
" anim/pain.scr " , " anim/killed.scr " , " anim/attack.scr " , " anim/sniper.scr " ,
" knees " , " crawl " , " floor " ,
" anim/patrol.scr " , " anim/run.scr " ,
" crouch " , " crouchwalk " , " crouchrun " ,
" anim/crouch_walk.scr " , " anim/walk.scr " , " anim/prone.scr " ,
" anim/runawayfiring.scr " , " anim/run_shoot.scr " ,
" anim/runto_alarm.scr " , " anim/runto_casual.scr " , " anim/runto_cover.scr " , " anim/runto_danger.scr " , " anim/runto_dive.scr " , " anim/runto_flee.scr " , " anim/runto_inopen.scr " ,
" anim/disguise_salute.scr " , " anim/disguise_wait.scr " , " anim/disguise_papers.scr " , " anim/disguise_enemy.scr " , " anim/disguise_halt.scr " , " anim/disguise_accept.scr " , " anim/disguise_deny.scr " ,
" anim/cornerleft.scr " , " anim/cornerright.scr " , " anim/overattack.scr " , " anim/continue_last_anim.scr " ,
" flagged " ,
" anim/fullbody.scr " ,
" internal " ,
" salute " , " sentry " , " officier " , " rover " ,
" none " , " machinegunner " ,
" disguise " ,
" dog_idle " , " dog_attack " , " dog_curious " , " dog_grenade " ,
" anim/grenadeturn.scr " , " anim/grenadekick.scr " , " anim/grenadethrow.scr " , " anim/grenadetoss.scr " , " anim/grenademartyr.scr " ,
" movedone " ,
" aim " , " ontarget " ,
" unarmed " ,
" balcony_idle " , " balcony_curious " , " balcony_attack " , " balcony_disguise " , " balcony_grenade " , " balcony_pain " , " balcony_killed " ,
" weaponless " ,
" death_balcony_intro " , " death_balcony_loop " , " death_balcony_outtro " ,
" sounddone " ,
" noclip " ,
" german " , " american " , " spectator " , " freeforall " , " allies " , " axis " ,
" draw " , " kills " , " allieswin " , " axiswin " ,
" anim/say_curious_sight.scr " , " anim/say_curious_sound.scr " , " anim/say_grenade_sighted.scr " , " anim/say_kill.scr " , " anim/say_mandown.scr " , " anim/say_sighted.scr " ,
" vehicleanimdone " ,
" postthink " ,
" turndone " ,
" anim/no_anim_killed.scr " ,
" mg42 " , " mp40 " ,
" remove " , " delete " ,
" respawn " ,
" none "
} ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
ScriptMaster : : ~ ScriptMaster ( )
{
Reset ( false ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
void ScriptMaster : : InitConstStrings ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
EventDef * eventDef ;
const_str name ;
unsigned int eventnum ;
con_map_enum < Event * , EventDef > en ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( int i = 0 ; i < sizeof ( ConstStrings ) / sizeof ( ConstStrings [ 0 ] ) ; i + + )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
AddString ( ConstStrings [ i ] ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
Event : : normalCommandList . clear ( ) ;
Event : : returnCommandList . clear ( ) ;
Event : : getterCommandList . clear ( ) ;
Event : : setterCommandList . clear ( ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
en = Event : : eventDefList ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( en . NextValue ( ) ; en . CurrentValue ( ) ! = NULL ; en . NextValue ( ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
eventDef = en . CurrentValue ( ) ;
eventnum = ( * en . CurrentKey ( ) ) - > eventnum ;
str command = eventDef - > command . c_str ( ) ;
command . tolower ( ) ;
name = AddString ( command ) ;
if ( eventDef - > type = = EV_NORMAL )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Event : : normalCommandList [ name ] = eventnum ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
else if ( eventDef - > type = = EV_RETURN )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Event : : returnCommandList [ name ] = eventnum ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
else if ( eventDef - > type = = EV_GETTER )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Event : : getterCommandList [ name ] = eventnum ;
}
else if ( eventDef - > type = = EV_SETTER )
{
Event : : setterCommandList [ name ] = eventnum ;
2016-03-27 11:49:47 +02:00
}
}
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : CloseGameScript ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
con_map_enum < const_str , GameScript * > en ( m_GameScripts ) ;
GameScript * * g ;
Container < GameScript * > gameScripts ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( g = en . NextValue ( ) ; g ! = NULL ; g = en . NextValue ( ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
gameScripts . AddObject ( * g ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
for ( int i = gameScripts . NumObjects ( ) ; i > 0 ; i - - )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
delete gameScripts . ObjectAt ( i ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
m_GameScripts . clear ( ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : Reset ( qboolean samemap )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
ScriptClass_allocator . FreeAll ( ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
stackCount = 0 ;
cmdCount = 0 ;
cmdTime = 0 ;
maxTime = MAX_EXECUTION_TIME ;
//pTop = &avar_Stack[ 0 ];
iPaused = 0 ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
# if defined ( GAME_DLL )
for ( int i = 1 ; i < = m_menus . NumObjects ( ) ; i + + )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Hidemenu ( m_menus . ObjectAt ( i ) , true ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
m_menus . ClearObjectList ( ) ;
# endif
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! samemap )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
for ( int i = 0 ; i < SE_MAX ; i + + )
{
scriptedEvents [ i ] = ScriptEvent ( ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
CloseGameScript ( ) ;
StringDict . clear ( ) ;
InitConstStrings ( ) ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
const_str ScriptMaster : : AddString ( const char * s )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return StringDict . addKeyIndex ( s ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
const_str ScriptMaster : : AddString ( str & s )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return StringDict . addKeyIndex ( s ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
const_str ScriptMaster : : GetString ( const char * s )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
const_str cs = StringDict . findKeyIndex ( s ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return cs ? cs : STRING_EMPTY ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
const_str ScriptMaster : : GetString ( str s )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return GetString ( s . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
str & ScriptMaster : : GetString ( const_str s )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return StringDict [ s ] ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : AddTiming ( ScriptThread * thread , float time )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
timerList . AddElement ( thread , level . inttime + ( int ) ( time * 1000.0f + 0.5f ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : RemoveTiming ( ScriptThread * thread )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
timerList . RemoveElement ( thread ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateScriptThread ( GameScript * scr , Listener * self , str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return CreateScriptThread ( scr , self , Director . AddString ( label ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateScriptThread ( GameScript * scr , Listener * self , const_str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
ScriptClass * scriptClass = new ScriptClass ( scr , self ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return CreateScriptThread ( scriptClass , label ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateScriptThread ( ScriptClass * scriptClass , const_str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
unsigned char * m_pCodePos = scriptClass - > FindLabel ( label ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! m_pCodePos )
{
2023-01-30 00:50:21 +01:00
throw ScriptException ( " ScriptMaster::CreateScriptThread: label '%s' does not exist in '%s'. " , Director . GetString ( label ) . c_str ( ) , scriptClass - > Filename ( ) . c_str ( ) ) ;
2023-01-29 22:57:04 +01:00
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return CreateScriptThread ( scriptClass , m_pCodePos ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateScriptThread ( ScriptClass * scriptClass , str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
if ( label . length ( ) & & * label )
{
return CreateScriptThread ( scriptClass , Director . AddString ( label ) ) ;
}
else
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return CreateScriptThread ( scriptClass , STRING_EMPTY ) ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateScriptThread ( ScriptClass * scriptClass , unsigned char * m_pCodePos )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return new ScriptThread ( scriptClass , m_pCodePos ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateThread ( GameScript * scr , str label , Listener * self )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
try
{
return CreateScriptThread ( scr , self , label ) ;
}
catch ( ScriptException & exc )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
gi . DPrintf ( " ScriptMaster::CreateThread: %s \n " , exc . string . c_str ( ) ) ;
2023-01-29 22:57:04 +01:00
return NULL ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CreateThread ( str filename , str label , Listener * self )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
GameScript * scr = GetScript ( filename ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! scr )
{
return NULL ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return CreateThread ( scr , label , self ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptClass * ScriptMaster : : CurrentScriptClass ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return CurrentThread ( ) - > GetScriptClass ( ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : CurrentThread ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
assert ( m_CurrentThread ) ;
if ( ! m_CurrentThread )
{
2023-01-30 00:50:21 +01:00
throw ScriptException ( " current thread is NULL " ) ;
2023-01-29 22:57:04 +01:00
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return m_CurrentThread ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ScriptThread * ScriptMaster : : PreviousThread ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return m_PreviousThread ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ExecuteThread ( GameScript * scr , str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
ScriptThread * thread = CreateThread ( scr , label ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
try
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
if ( thread ) {
thread - > Execute ( ) ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
catch ( ScriptException & exc )
{
2023-01-30 00:50:21 +01:00
gi . DPrintf ( " ScriptMaster::ExecuteThread: %s \n " , exc . string . c_str ( ) ) ;
2023-01-29 22:57:04 +01:00
}
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ExecuteThread ( str filename , str label )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
GameScript * scr = GetScript ( filename ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! scr )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
ExecuteThread ( scr , label ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ExecuteThread ( GameScript * scr , str label , Event & parms )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
ScriptThread * thread = CreateThread ( scr , label ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
try
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
thread - > Execute ( parms ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
catch ( ScriptException & exc )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
gi . DPrintf ( " ScriptMaster::ExecuteThread: %s \n " , exc . string . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ExecuteThread ( str filename , str label , Event & parms )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
GameScript * scr = GetScript ( filename ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! scr )
2016-03-27 11:49:47 +02:00
{
return ;
}
2023-01-29 22:57:04 +01:00
ExecuteThread ( scr , label , parms ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetTempScript ( const char * data )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
GameScript * scr = new GameScript ;
scr - > Load ( ( void * ) data , strlen ( data ) ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! scr - > successCompile )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return NULL ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
return scr ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetGameScript ( str filename , qboolean recompile )
{
const_str s = StringDict . findKeyIndex ( filename ) ;
GameScript * scr = m_GameScripts [ s ] ;
int i ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( scr ! = NULL & & ! recompile )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
if ( ! scr - > successCompile )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
throw ScriptException ( " Script '%s' was not properly loaded \n " , filename . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
return scr ;
}
else
{
if ( scr & & recompile )
{
Container < ScriptClass * > list ;
2023-01-30 17:11:44 +01:00
MEM_BlockAlloc_enum < ScriptClass > en = ScriptClass_allocator ;
2023-01-29 22:57:04 +01:00
ScriptClass * scriptClass ;
m_GameScripts [ s ] = NULL ;
for ( scriptClass = en . NextElement ( ) ; scriptClass ! = NULL ; scriptClass = en . NextElement ( ) )
{
if ( scriptClass - > GetScript ( ) = = scr )
{
list . AddObject ( scriptClass ) ;
}
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( i = 1 ; i < = list . NumObjects ( ) ; i + + )
{
delete list . ObjectAt ( i ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
delete scr ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
return GetGameScriptInternal ( filename ) ;
2016-03-27 11:49:47 +02:00
}
}
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetGameScript ( const_str filename , qboolean recompile )
{
return GetGameScript ( Director . GetString ( filename ) , recompile ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetGameScriptInternal ( str & filename )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
void * sourceBuffer = NULL ;
int sourceLength ;
char filepath [ MAX_QPATH ] ;
GameScript * scr ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( filename . length ( ) > = MAX_QPATH )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
gi . Error ( ERR_DROP , " Script filename '%s' exceeds maximum length of %d \n " , filename . c_str ( ) , MAX_QPATH ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
scr = m_GameScripts [ StringDict . findKeyIndex ( filename ) ] ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( scr ! = NULL )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
return scr ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
strcpy ( filepath , filename . c_str ( ) ) ;
2023-01-30 00:50:21 +01:00
gi . FS_CanonicalFilename ( filepath ) ;
2023-01-29 22:57:04 +01:00
filename = filepath ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
scr = new GameScript ( filename ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
m_GameScripts [ StringDict . addKeyIndex ( filename ) ] = scr ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( GetCompiledScript ( scr ) )
{
scr - > m_Filename = Director . AddString ( filename ) ;
return scr ;
2016-03-27 11:49:47 +02:00
}
2023-01-30 00:50:21 +01:00
sourceLength = gi . FS_ReadFile ( filename . c_str ( ) , & sourceBuffer , true ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( sourceLength < 0 )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
throw ScriptException ( " Can't find '%s' \n " , filename . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
scr - > Load ( sourceBuffer , sourceLength ) ;
2016-03-27 11:49:47 +02:00
2023-01-30 00:50:21 +01:00
gi . FS_FreeFile ( sourceBuffer ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! scr - > successCompile )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
throw ScriptException ( " Script '%s' was not properly loaded " , filename . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
return scr ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetScript ( str filename , qboolean recompile )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
try
{
return GetGameScript ( filename , recompile ) ;
}
catch ( ScriptException & exc )
{
2023-01-30 00:50:21 +01:00
gi . DPrintf ( " ScriptMaster::GetScript: %s \n " , exc . string . c_str ( ) ) ;
2023-01-29 22:57:04 +01:00
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return NULL ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
GameScript * ScriptMaster : : GetScript ( const_str filename , qboolean recompile )
2016-03-27 11:49:47 +02:00
{
try
{
2023-01-29 22:57:04 +01:00
return GetGameScript ( filename , recompile ) ;
2016-03-27 11:49:47 +02:00
}
catch ( ScriptException & exc )
{
2023-01-30 00:50:21 +01:00
gi . DPrintf ( " ScriptMaster::GetScript: %s \n " , exc . string . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
return NULL ;
}
2018-08-19 08:26:59 +02:00
2023-01-29 22:57:04 +01:00
void ScriptMaster : : ExecuteRunning ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
int i ;
int startTime ;
if ( stackCount )
{
return ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( timerList . IsDirty ( ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
cmdTime = 0 ;
cmdCount = 0 ;
startTime = level . svsTime ;
while ( ( m_CurrentThread = ( ScriptThread * ) timerList . GetNextElement ( i ) ) )
{
level . setTime ( level . svsStartTime + i ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
m_CurrentThread - > m_ScriptVM - > m_ThreadState = THREAD_RUNNING ;
m_CurrentThread - > m_ScriptVM - > Execute ( ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
level . setTime ( startTime ) ;
level . m_LoopProtection = true ;
2016-03-27 11:49:47 +02:00
}
2023-01-30 00:50:21 +01:00
startTime = gi . Milliseconds ( ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : SetTime ( int time )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
timerList . SetTime ( time ) ;
timerList . SetDirty ( ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : PrintStatus ( void )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
str status ;
int iThreadNum = 0 ;
int iThreadRunning = 0 ;
int iThreadWaiting = 0 ;
int iThreadSuspended = 0 ;
2023-01-30 17:11:44 +01:00
MEM_BlockAlloc_enum < ScriptClass > en = ScriptClass_allocator ;
2023-01-29 22:57:04 +01:00
ScriptClass * scriptClass ;
char szBuffer [ MAX_STRING_TOKENS ] ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
status = " num state label script \n " ;
status + = " ------- ---------- --------------- --------------- \n " ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( scriptClass = en . NextElement ( ) ; scriptClass ! = NULL ; scriptClass = en . NextElement ( ) )
{
ScriptVM * vm ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( vm = scriptClass - > m_Threads ; vm ! = NULL ; vm = vm - > next )
{
sprintf ( szBuffer , " %.7d " , iThreadNum ) ;
status + = szBuffer + str ( " " ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
switch ( vm - > ThreadState ( ) )
{
case THREAD_CONTEXT_SWITCH :
case THREAD_RUNNING :
sprintf ( szBuffer , " %8s " , " running " ) ;
iThreadRunning + + ;
break ;
case THREAD_WAITING :
sprintf ( szBuffer , " %8s " , " waiting " ) ;
iThreadWaiting + + ;
break ;
case THREAD_SUSPENDED :
sprintf ( szBuffer , " %8s " , " suspended " ) ;
iThreadSuspended + + ;
break ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
status + = szBuffer ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
sprintf ( szBuffer , " %15s " , vm - > Label ( ) . c_str ( ) ) ;
status + = szBuffer + str ( " " ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
sprintf ( szBuffer , " %15s " , vm - > Filename ( ) . c_str ( ) ) ;
status + = szBuffer ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
status + = " \n " ;
iThreadNum + + ;
}
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
status + = " ------- ---------- --------------- --------------- \n " ;
status + = str ( m_GameScripts . size ( ) ) + " total scripts compiled \n " ;
status + = str ( iThreadNum ) + " total threads ( " + str ( iThreadRunning ) + " running thread(s), " + str ( iThreadWaiting ) + " waiting thread(s), " + str ( iThreadSuspended ) + " suspended thread(s) ) \n " ;
2016-03-27 11:49:47 +02:00
2023-01-30 00:50:21 +01:00
gi . Printf ( status . c_str ( ) ) ;
2023-01-29 22:57:04 +01:00
}
void ScriptMaster : : PrintThread ( int iThreadNum )
{
int iThread = 0 ;
ScriptVM * vm ;
bool bFoundThread = false ;
str status ;
2023-01-30 17:11:44 +01:00
MEM_BlockAlloc_enum < ScriptClass > en = ScriptClass_allocator ;
2023-01-29 22:57:04 +01:00
ScriptClass * scriptClass ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( scriptClass = en . NextElement ( ) ; scriptClass ! = NULL ; scriptClass = en . NextElement ( ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
for ( vm = scriptClass - > m_Threads ; vm ! = NULL ; vm = vm - > next )
{
if ( iThread = = iThreadNum )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
bFoundThread = true ;
break ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
iThread + + ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
if ( bFoundThread )
{
break ;
2016-03-27 11:49:47 +02:00
}
}
2019-06-29 23:43:30 +02:00
2023-01-29 22:57:04 +01:00
if ( ! bFoundThread )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
gi . Printf ( " Can't find thread id %i. \n " , iThreadNum ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
status = " ------------------------- \n " ;
status + = " num: " + str ( iThreadNum ) + " \n " ;
switch ( vm - > ThreadState ( ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
case THREAD_CONTEXT_SWITCH :
status + = " state: running (context switch) \n " ;
break ;
case THREAD_RUNNING :
status + = " state: running \n " ;
break ;
case THREAD_WAITING :
status + = " state: waiting \n " ;
break ;
case THREAD_SUSPENDED :
status + = " state: suspended \n " ;
break ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
status + = " script: ' " + vm - > Filename ( ) + " ' \n " ;
status + = " label: ' " + vm - > Label ( ) + " ' \n " ;
status + = " waittill: " ;
2018-08-19 08:26:59 +02:00
2023-01-29 22:57:04 +01:00
if ( ! vm - > m_Thread - > m_WaitForList )
2019-06-29 23:43:30 +02:00
{
2023-01-29 22:57:04 +01:00
status + = " (none) \n " ;
2019-06-29 23:43:30 +02:00
}
2023-01-29 22:57:04 +01:00
else
{
con_set_enum < const_str , ConList > en = * vm - > m_Thread - > m_WaitForList ;
Entry < const_str , ConList > * entry ;
int i = 0 ;
2019-06-29 23:43:30 +02:00
2023-01-29 22:57:04 +01:00
for ( entry = en . NextElement ( ) ; entry ! = NULL ; entry = en . NextElement ( ) )
{
str & name = Director . GetString ( entry - > key ) ;
2018-08-19 08:26:59 +02:00
2023-01-29 22:57:04 +01:00
if ( i > 0 )
{
status + = " , " ;
}
2018-08-19 08:26:59 +02:00
2023-01-29 22:57:04 +01:00
status + = " ' " + name + " ' " ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( int j = 1 ; j < = entry - > value . NumObjects ( ) ; j + + )
{
Listener * l = entry - > value . ObjectAt ( j ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( j > 1 )
{
status + = " , " ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( l )
{
status + = " on " + str ( l - > getClassname ( ) ) ;
}
else
{
status + = " on (null) " ;
}
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
i + + ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
status + = " \n " ;
2016-03-27 11:49:47 +02:00
}
2023-01-30 00:50:21 +01:00
gi . Printf ( status . c_str ( ) ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
static int bLoadForMap ( char * psMapsBuffer , const char * name )
2016-03-27 11:49:47 +02:00
{
2023-01-30 00:50:21 +01:00
cvar_t * mapname = gi . Cvar_Get ( " mapname " , " " , 0 ) ;
2023-01-29 22:57:04 +01:00
const char * token ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
if ( ! strncmp ( " test " , mapname - > string , sizeof ( " test " ) ) ) {
return true ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
token = COM_Parse ( & psMapsBuffer ) ;
if ( ! token | | ! * token )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Com_Printf ( " ERROR bLoadForMap: %s alias with empty maps specification. \n " , name ) ;
return false ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
while ( token & & * token )
{
if ( ! Q_stricmpn ( token , mapname - > string , strlen ( token ) ) ) {
return true ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
token = COM_Parse ( & psMapsBuffer ) ;
}
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
return false ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : RegisterAliasInternal
(
Event * ev ,
bool bCache
)
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
# ifdef GAME_DLL
int i ;
char parameters [ MAX_STRING_CHARS ] ;
char * psMapsBuffer ;
int subtitle ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
// Get the parameters for this alias command
parameters [ 0 ] = 0 ;
subtitle = 0 ;
psMapsBuffer = NULL ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
for ( i = 3 ; i < = ev - > NumArgs ( ) ; i + + )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
str s ;
// MOHAA doesn't check that
if ( ev - > IsListenerAt ( i ) )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
Listener * l = ev - > GetListener ( i ) ;
if ( l & & l = = Director . CurrentThread ( ) )
{
s = " local " ;
}
else
{
s = ev - > GetString ( i ) ;
}
2016-03-27 11:49:47 +02:00
}
else
{
2023-01-29 22:57:04 +01:00
s = ev - > GetString ( i ) ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
if ( subtitle )
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
strcat ( parameters , " \" " ) ;
strcat ( parameters , s ) ;
strcat ( parameters , " \" " ) ;
2016-03-27 11:49:47 +02:00
2023-01-29 22:57:04 +01:00
subtitle = 0 ;
2016-03-27 11:49:47 +02:00
}
2023-01-29 22:57:04 +01:00
else if ( ! s . icmp ( " maps " ) )
{
i + + ;
psMapsBuffer = ( char * ) ev - > GetToken ( i ) . c_str ( ) ;
}
else
2016-03-27 11:49:47 +02:00
{
2023-01-29 22:57:04 +01:00
subtitle = s . icmp ( " subtitle " ) = = 0 ;
strcat ( parameters , s ) ;
strcat ( parameters , " " ) ;
2016-03-27 11:49:47 +02:00
}
}
2017-06-08 11:46:08 +02:00
2023-01-29 22:57:04 +01:00
if ( bLoadForMap ( psMapsBuffer , ev - > GetString ( 1 ) ) )
2017-06-08 11:46:08 +02:00
{
2023-01-30 00:50:21 +01:00
gi . GlobalAlias_Add ( ev - > GetString ( 1 ) , ev - > GetString ( 2 ) , parameters ) ;
2017-06-08 11:46:08 +02:00
2023-01-29 22:57:04 +01:00
if ( bCache )
CacheResource ( ev - > GetString ( 2 ) ) ;
2017-06-08 11:46:08 +02:00
}
2023-01-29 22:57:04 +01:00
# endif
2017-06-08 11:46:08 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : RegisterAlias
(
Event * ev
)
2017-06-08 11:46:08 +02:00
{
2023-01-29 22:57:04 +01:00
RegisterAliasInternal ( ev ) ;
2017-06-08 11:46:08 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : RegisterAliasAndCache
(
Event * ev
)
2017-06-08 11:46:08 +02:00
{
2023-01-29 22:57:04 +01:00
RegisterAliasInternal ( ev , true ) ;
2017-06-08 11:46:08 +02:00
}
2023-01-29 22:57:04 +01:00
void ScriptMaster : : Cache
(
Event * ev
)
2017-06-08 11:46:08 +02:00
{
2023-01-29 22:57:04 +01:00
# ifdef GAME_DLL
if ( ! precache - > integer )
2017-06-08 11:46:08 +02:00
return ;
2023-01-29 22:57:04 +01:00
CacheResource ( ev - > GetString ( 1 ) ) ;
2016-03-27 11:49:47 +02:00
# endif
2023-01-29 22:57:04 +01:00
}