mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Keep track of script activators
Can supply the activating object, line, line side, polyobject, and (added for SRB2) sector.
This commit is contained in:
parent
a315482aa4
commit
93cdac681b
8 changed files with 327 additions and 6 deletions
|
|
@ -155,6 +155,14 @@ ACSVM_Thread *ACSVM_AllocThread(ACSVM_Environment *env,
|
|||
return new(std::nothrow) ACSVM_Thread(env, *funcs, data);
|
||||
}
|
||||
|
||||
//
|
||||
// ACSVM_AllocThreadInfo
|
||||
//
|
||||
ACSVM_ThreadInfo *ACSVM_AllocThreadInfo(void *data)
|
||||
{
|
||||
return new(std::nothrow) ACSVM_ThreadInfo(data);
|
||||
}
|
||||
|
||||
//
|
||||
// ACSVM_ThreadFromVoid
|
||||
//
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ public:
|
|||
ACSVM_Thread *ACSVM_AllocThread(ACSVM_Environment *env,
|
||||
ACSVM_ThreadFuncs const *funcs, void *data);
|
||||
|
||||
ACSVM_ThreadInfo *ACSVM_AllocThreadInfo(void *data);
|
||||
|
||||
ACSVM_Thread *ACSVM_ThreadFromVoid(void *thread);
|
||||
|
||||
void ACSVM_Thread_Exec(ACSVM_Thread *thread);
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -60,6 +60,7 @@
|
|||
#include "k_boss.h"
|
||||
#include "k_bot.h"
|
||||
#include "doomstat.h"
|
||||
#include "k_acs.h"
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
#include "discord.h"
|
||||
|
|
@ -2877,6 +2878,8 @@ void G_DoReborn(INT32 playernum)
|
|||
if (oldmo)
|
||||
G_ChangePlayerReferences(oldmo, players[playernum].mo);
|
||||
}
|
||||
|
||||
ACS_RunPlayerEnterScript(player);
|
||||
}
|
||||
|
||||
void G_AddPlayer(INT32 playernum)
|
||||
|
|
|
|||
107
src/k_acs-func.c
107
src/k_acs-func.c
|
|
@ -30,6 +30,7 @@
|
|||
#include "p_local.h"
|
||||
#include "deh_tables.h"
|
||||
#include "fastcmp.h"
|
||||
#include "hu_stuff.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
static bool ACS_GetMobjTypeFromString(const char *word, mobjtype_t *type)
|
||||
|
|
@ -115,6 +116,34 @@ static bool ACS_CountThing(mobj_t *mobj, mobjtype_t type)
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static bool ACS_ActivatorIsLocal(ACSVM_Thread *thread)
|
||||
|
||||
Helper function for many print functions.
|
||||
Returns whenever or not the activator of the
|
||||
thread is a display player or not.
|
||||
|
||||
Input Arguments:-
|
||||
thread: The thread we're exeucting on.
|
||||
|
||||
Return:-
|
||||
true if it's for a display player,
|
||||
otherwise false.
|
||||
--------------------------------------------------*/
|
||||
static bool ACS_ActivatorIsLocal(ACSVM_Thread *thread)
|
||||
{
|
||||
acs_threadinfo_t *info = (acs_threadinfo_t *)ACSVM_Thread_GetInfo(thread);
|
||||
|
||||
if ((info != NULL)
|
||||
&& (info->mo != NULL && P_MobjWasRemoved(info->mo) == false)
|
||||
&& (info->mo->player != NULL))
|
||||
{
|
||||
return P_IsDisplayPlayer(info->mo->player);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_Random(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
|
|
@ -315,10 +344,29 @@ bool ACS_CF_ChangeCeiling(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Wo
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_LineSide(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
Pushes which side of the linedef was
|
||||
activated.
|
||||
--------------------------------------------------*/
|
||||
bool ACS_CF_LineSide(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
{
|
||||
acs_threadinfo_t *info = (acs_threadinfo_t *)ACSVM_Thread_GetInfo(thread);
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
ACSVM_Thread_DataStk_Push(thread, info->side);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
ACS wrapper for CONS_Printf.
|
||||
One of the ACS wrappers for CEcho. This
|
||||
version only prints if the activator is a
|
||||
display player.
|
||||
--------------------------------------------------*/
|
||||
bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
{
|
||||
|
|
@ -328,7 +376,13 @@ bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word ar
|
|||
(void)argC;
|
||||
|
||||
buf = ACSVM_Thread_GetPrintBuf(thread);
|
||||
CONS_Printf("%s\n", ACSVM_PrintBuf_GetData(buf));
|
||||
|
||||
if (ACS_ActivatorIsLocal(thread) == true)
|
||||
{
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(ACSVM_PrintBuf_GetData(buf));
|
||||
}
|
||||
|
||||
ACSVM_PrintBuf_Drop(buf);
|
||||
|
||||
return false;
|
||||
|
|
@ -411,3 +465,52 @@ bool ACS_CF_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
|||
ACSVM_Thread_DataStk_Push(thread, leveltime);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_EndPrintBold(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
One of the ACS wrappers for CEcho. This
|
||||
version prints for all players.
|
||||
--------------------------------------------------*/
|
||||
bool ACS_CF_EndPrintBold(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
{
|
||||
ACSVM_PrintBuf *buf = NULL;
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
buf = ACSVM_Thread_GetPrintBuf(thread);
|
||||
|
||||
HU_SetCEchoDuration(5);
|
||||
HU_DoCEcho(ACSVM_PrintBuf_GetData(buf));
|
||||
|
||||
ACSVM_PrintBuf_Drop(buf);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_EndLog(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
|
||||
One of the ACS wrappers for CONS_Printf.
|
||||
This version only prints if the activator
|
||||
is a display player.
|
||||
--------------------------------------------------*/
|
||||
bool ACS_CF_EndLog(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC)
|
||||
{
|
||||
ACSVM_PrintBuf *buf = NULL;
|
||||
|
||||
(void)argV;
|
||||
(void)argC;
|
||||
|
||||
buf = ACSVM_Thread_GetPrintBuf(thread);
|
||||
|
||||
if (ACS_ActivatorIsLocal(thread) == true)
|
||||
{
|
||||
CONS_Printf("%s\n", ACSVM_PrintBuf_GetData(buf));
|
||||
}
|
||||
|
||||
ACSVM_PrintBuf_Drop(buf);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
155
src/k_acs.c
155
src/k_acs.c
|
|
@ -23,6 +23,10 @@
|
|||
#include "r_state.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "taglist.h"
|
||||
#include "d_player.h"
|
||||
#include "g_game.h"
|
||||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
|
||||
#include "CAPI/BinaryIO.h"
|
||||
#include "CAPI/Environment.h"
|
||||
|
|
@ -227,7 +231,7 @@ static void ACS_EnvConstruct(ACSVM_Environment *env)
|
|||
ACS_AddCodeDataCallFunc(env, 67, "", 2, ACS_CF_ChangeCeiling);
|
||||
ACS_AddCodeDataCallFunc(env, 68, "WWS", 0, ACS_CF_ChangeCeiling);
|
||||
// 69 to 79: Implemented by ACSVM
|
||||
|
||||
ACS_AddCodeDataCallFunc(env, 80, "", 0, ACS_CF_LineSide);
|
||||
// 81 to 82: Implemented by ACSVM
|
||||
|
||||
// 84 to 85: Implemented by ACSVM
|
||||
|
|
@ -237,6 +241,8 @@ static void ACS_EnvConstruct(ACSVM_Environment *env)
|
|||
ACS_AddCodeDataCallFunc(env, 91, "", 0, ACS_CF_GameType);
|
||||
ACS_AddCodeDataCallFunc(env, 92, "", 0, ACS_CF_GameSpeed);
|
||||
ACS_AddCodeDataCallFunc(env, 93, "", 0, ACS_CF_Timer);
|
||||
|
||||
ACS_AddCodeDataCallFunc(env, 101, "", 0, ACS_CF_EndPrintBold);
|
||||
// 136 to 137: Implemented by ACSVM
|
||||
|
||||
// 157: Implemented by ACSVM
|
||||
|
|
@ -256,7 +262,7 @@ static void ACS_EnvConstruct(ACSVM_Environment *env)
|
|||
// 256 to 257: Implemented by ACSVM
|
||||
|
||||
// 263: Implemented by ACSVM
|
||||
ACS_AddCodeDataCallFunc(env, 270, "", 0, ACS_CF_EndPrint);
|
||||
ACS_AddCodeDataCallFunc(env, 270, "", 0, ACS_CF_EndLog);
|
||||
// 273 to 275: Implemented by ACSVM
|
||||
|
||||
// 291 to 325: Implemented by ACSVM
|
||||
|
|
@ -404,6 +410,85 @@ static bool ACS_EnvCheckTag(ACSVM_Environment const *env, ACSVM_Word type, ACSVM
|
|||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void ACS_ThrDestruct(ACSVM_Thread *thread)
|
||||
|
||||
ACSVM Thread hook. Runs as the thread
|
||||
is in the process of being destroyed.
|
||||
|
||||
Input Arguments:-
|
||||
thread - The ACS thread data to destroy.
|
||||
|
||||
Return:-
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
static void ACS_ThrDestruct(ACSVM_Thread *thread)
|
||||
{
|
||||
acs_threadinfo_t *info = ACSVM_Thread_GetInfo(thread);
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
Z_Free(info);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static void ACS_ThrStart(ACSVM_Thread *thread, void *data)
|
||||
|
||||
ACSVM Thread hook. Runs immediately after
|
||||
an ACS thread has been started.
|
||||
|
||||
Input Arguments:-
|
||||
thread - The ACS thread data.
|
||||
data - ACS thread info, as a raw pointer.
|
||||
|
||||
Return:-
|
||||
The newly created ACS thread.
|
||||
--------------------------------------------------*/
|
||||
static void ACS_ThrStart(ACSVM_Thread *thread, void *data)
|
||||
{
|
||||
acs_threadinfo_t *activator = NULL;
|
||||
|
||||
ACSVM_Thread_SetResult(thread, 1);
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
// Create an empty one, to reduce NULL checks.
|
||||
// Might not be necessary.
|
||||
activator = Z_Calloc(sizeof(acs_threadinfo_t), PU_STATIC, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
activator = (acs_threadinfo_t *)data;
|
||||
}
|
||||
|
||||
ACSVM_Thread_SetInfo(thread, activator);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static ACSVM_Thread *ACS_EnvAllocThread(ACSVM_Environment *env)
|
||||
|
||||
ACSVM Environment hook. Runs when an ACS
|
||||
thread is being created. This is where
|
||||
our own thread hooks are supposed to
|
||||
be loaded.
|
||||
|
||||
Input Arguments:-
|
||||
env - The ACS environment data.
|
||||
|
||||
Return:-
|
||||
The newly created ACS thread.
|
||||
--------------------------------------------------*/
|
||||
static ACSVM_Thread *ACS_EnvAllocThread(ACSVM_Environment *env)
|
||||
{
|
||||
ACSVM_ThreadFuncs funcs = {0};
|
||||
|
||||
funcs.dtor = ACS_ThrDestruct;
|
||||
funcs.start = ACS_ThrStart;
|
||||
|
||||
return ACSVM_AllocThread(env, &funcs, NULL);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_Init(void)
|
||||
|
||||
|
|
@ -421,6 +506,7 @@ void ACS_Init(void)
|
|||
funcs.ctor = ACS_EnvConstruct;
|
||||
funcs.loadModule = ACS_EnvLoadModule;
|
||||
funcs.checkTag = ACS_EnvCheckTag;
|
||||
funcs.allocThread = ACS_EnvAllocThread;
|
||||
|
||||
ACSenv = ACSVM_AllocEnvironment(&funcs, NULL);
|
||||
|
||||
|
|
@ -520,7 +606,7 @@ void ACS_LoadLevelScripts(size_t mapID)
|
|||
|
||||
// Start up new map scope.
|
||||
ACS_ResetMap(hub);
|
||||
map = ACSVM_HubScope_GetMapScope(hub, 0);
|
||||
map = ACSVM_HubScope_GetMapScope(hub, 0); // This is where you'd put in mapID if you add hub support.
|
||||
ACSVM_MapScope_SetActive(map, true);
|
||||
|
||||
// Allocate module list.
|
||||
|
|
@ -552,9 +638,70 @@ void ACS_LoadLevelScripts(size_t mapID)
|
|||
// Register the modules with map scope.
|
||||
ACSVM_MapScope_AddModules(map, modules, modules_len);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunPlayerEnterScript(player_t *player)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void ACS_RunPlayerEnterScript(player_t *player)
|
||||
{
|
||||
ACSVM_GlobalScope *global = NULL;
|
||||
ACSVM_HubScope *hub = NULL;
|
||||
ACSVM_MapScope *map = NULL;
|
||||
|
||||
acs_threadinfo_t *activator = NULL;
|
||||
|
||||
global = ACSVM_Environment_GetGlobalScope(ACSenv, 0);
|
||||
hub = ACSVM_GlobalScope_GetHubScope(global, 0);
|
||||
map = ACSVM_HubScope_GetMapScope(hub, 0);
|
||||
|
||||
activator = Z_Calloc(sizeof(acs_threadinfo_t), PU_STATIC, NULL);
|
||||
|
||||
P_SetTarget(&activator->mo, player->mo);
|
||||
|
||||
ACSVM_MapScope_ScriptStartTypeForced(map, ACS_ST_ENTER, NULL, 0, ACSVM_AllocThreadInfo(activator), NULL);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunLevelStartScripts(void)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void ACS_RunLevelStartScripts(void)
|
||||
{
|
||||
ACSVM_GlobalScope *global = NULL;
|
||||
ACSVM_HubScope *hub = NULL;
|
||||
ACSVM_MapScope *map = NULL;
|
||||
|
||||
UINT8 i;
|
||||
|
||||
global = ACSVM_Environment_GetGlobalScope(ACSenv, 0);
|
||||
hub = ACSVM_GlobalScope_GetHubScope(global, 0);
|
||||
map = ACSVM_HubScope_GetMapScope(hub, 0);
|
||||
|
||||
// Start OPEN scripts.
|
||||
ACSVM_MapScope_ScriptStartType(map, 1, NULL, 0, NULL, NULL);
|
||||
ACSVM_MapScope_ScriptStartType(map, ACS_ST_OPEN, NULL, 0, NULL, NULL);
|
||||
|
||||
// Start ENTER scripts.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
player_t *player = NULL;
|
||||
|
||||
if (playeringame[i] == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
player = &players[i];
|
||||
if (player->spectator == true)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ACS_RunPlayerEnterScript(player);
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
53
src/k_acs.h
53
src/k_acs.h
|
|
@ -16,6 +16,10 @@
|
|||
|
||||
#include "doomtype.h"
|
||||
#include "doomdef.h"
|
||||
#include "p_mobj.h"
|
||||
#include "r_defs.h"
|
||||
#include "p_polyobj.h"
|
||||
#include "d_player.h"
|
||||
|
||||
#include "CAPI/BinaryIO.h"
|
||||
#include "CAPI/Environment.h"
|
||||
|
|
@ -25,6 +29,9 @@
|
|||
#include "CAPI/String.h"
|
||||
#include "CAPI/Thread.h"
|
||||
|
||||
//
|
||||
// Special global script types.
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
ACS_ST_OPEN = 1, // OPEN: Runs once when the level starts.
|
||||
|
|
@ -33,12 +40,27 @@ typedef enum
|
|||
ACS_ST_ENTER = 4, // ENTER: Runs when a player enters the game; both on start of the level, and when un-spectating.
|
||||
} acs_scriptType_e;
|
||||
|
||||
//
|
||||
// Script "waiting on tag" types.
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
ACS_TAGTYPE_POLYOBJ,
|
||||
ACS_TAGTYPE_SECTOR,
|
||||
} acs_tagType_e;
|
||||
|
||||
//
|
||||
// Thread activator info
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
mobj_t *mo; // Object that activated this thread.
|
||||
line_t *line; // Linedef that activated this thread.
|
||||
UINT8 side; // Front / back side of said linedef.
|
||||
sector_t *sector; // Sector that activated this thread.
|
||||
polyobj_t *po; // Polyobject that activated this thread.
|
||||
} acs_threadinfo_t;
|
||||
|
||||
/*--------------------------------------------------
|
||||
ACSVM_Environment *ACS_GetEnvironment(void);
|
||||
|
||||
|
|
@ -96,6 +118,33 @@ void ACS_Shutdown(void);
|
|||
void ACS_LoadLevelScripts(size_t mapID);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunPlayerEnterScript(player_t *player);
|
||||
|
||||
Runs the map's special script for a player
|
||||
entering the game.
|
||||
|
||||
Input Arguments:-
|
||||
player: The player to run the script for.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void ACS_RunPlayerEnterScript(player_t *player);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_RunLevelStartScripts(void);
|
||||
|
||||
Runs the map's special scripts for opening
|
||||
the level, and for all players to enter
|
||||
the game.
|
||||
--------------------------------------------------*/
|
||||
|
||||
void ACS_RunLevelStartScripts(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void ACS_Tick(void);
|
||||
|
||||
|
|
@ -105,6 +154,7 @@ void ACS_LoadLevelScripts(size_t mapID);
|
|||
|
||||
void ACS_Tick(void);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool ACS_CF_???(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
|
||||
|
|
@ -132,11 +182,14 @@ bool ACS_CF_TagWait(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word arg
|
|||
bool ACS_CF_PolyWait(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_ChangeFloor(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_ChangeCeiling(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_LineSide(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_EndPrint(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_PlayerCount(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_GameType(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_GameSpeed(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_Timer(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_EndPrintBold(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
bool ACS_CF_EndLog(ACSVM_Thread *thread, ACSVM_Word const *argV, ACSVM_Word argC);
|
||||
|
||||
|
||||
#endif // __K_ACS__
|
||||
|
|
|
|||
|
|
@ -4333,12 +4333,17 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
if (!fromnetsave) // uglier hack
|
||||
{ // to make a newly loaded level start on the second frame.
|
||||
INT32 buf = gametic % BACKUPTICS;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
|
||||
}
|
||||
|
||||
P_PreTicker(2);
|
||||
|
||||
ACS_RunLevelStartScripts();
|
||||
|
||||
P_MapStart(); // just in case MapLoad modifies tmthing
|
||||
LUA_HookInt(gamemap, HOOK(MapLoad));
|
||||
P_MapEnd(); // just in case MapLoad modifies tmthing
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue