Merge branch 'master' into m-for-mini

This commit is contained in:
Sally Coolatta 2022-09-11 18:39:53 -04:00
commit 92f9fc266d
37 changed files with 1432 additions and 2363 deletions

View file

@ -890,6 +890,9 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
UINT8 *p; UINT8 *p;
size_t mirror_length; size_t mirror_length;
const char *httpurl = cv_httpsource.string; const char *httpurl = cv_httpsource.string;
UINT8 prefgametype = (cv_kartgametypepreference.value == -1)
? gametype
: cv_kartgametypepreference.value;
netbuffer->packettype = PT_SERVERINFO; netbuffer->packettype = PT_SERVERINFO;
netbuffer->u.serverinfo._255 = 255; netbuffer->u.serverinfo._255 = 255;
@ -914,7 +917,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
else else
netbuffer->u.serverinfo.refusereason = 0; netbuffer->u.serverinfo.refusereason = 0;
strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[prefgametype],
sizeof netbuffer->u.serverinfo.gametypename); sizeof netbuffer->u.serverinfo.gametypename);
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
@ -2426,14 +2429,14 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason)
K_CalculateBattleWanted(); K_CalculateBattleWanted();
LUAh_PlayerQuit(&players[playernum], reason); // Lua hook for player quitting LUA_HookPlayerQuit(&players[playernum], reason); // Lua hook for player quitting
// don't look through someone's view who isn't there // don't look through someone's view who isn't there
if (playernum == displayplayers[0] && !demo.playback) if (playernum == displayplayers[0] && !demo.playback)
{ {
// Call ViewpointSwitch hooks here. // Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed. // The viewpoint was forcibly changed.
LUAh_ViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true); LUA_HookViewpointSwitch(&players[consoleplayer], &players[consoleplayer], true);
displayplayers[0] = consoleplayer; displayplayers[0] = consoleplayer;
} }
@ -2937,7 +2940,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
if (playernode[pnum] == playernode[consoleplayer]) if (playernode[pnum] == playernode[consoleplayer])
{ {
LUAh_GameQuit(false); LUA_HookBool(false, HOOK(GameQuit));
#ifdef DUMPCONSISTENCY #ifdef DUMPCONSISTENCY
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
#endif #endif
@ -3455,7 +3458,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (server && multiplayer && motd[0] != '\0') if (server && multiplayer && motd[0] != '\0')
COM_BufAddText(va("sayto %d %s\n", newplayernum, motd)); COM_BufAddText(va("sayto %d %s\n", newplayernum, motd));
LUAh_PlayerJoin(newplayernum); LUA_HookInt(newplayernum, HOOK(PlayerJoin));
#ifdef HAVE_DISCORDRPC #ifdef HAVE_DISCORDRPC
DRPC_UpdatePresence(); DRPC_UpdatePresence();
@ -3537,7 +3540,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
HU_AddChatText(va("\x82*Bot %d has been added to the game", newplayernum+1), false); HU_AddChatText(va("\x82*Bot %d has been added to the game", newplayernum+1), false);
} }
LUAh_PlayerJoin(newplayernum); LUA_HookInt(newplayernum, HOOK(PlayerJoin));
} }
static boolean SV_AddWaitingPlayers(SINT8 node, const char *name, const char *name2, const char *name3, const char *name4) static boolean SV_AddWaitingPlayers(SINT8 node, const char *name, const char *name2, const char *name3, const char *name4)
@ -3883,7 +3886,7 @@ static void HandleConnect(SINT8 node)
static void HandleShutdown(SINT8 node) static void HandleShutdown(SINT8 node)
{ {
(void)node; (void)node;
LUAh_GameQuit(false); LUA_HookBool(false, HOOK(GameQuit));
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
@ -3898,7 +3901,7 @@ static void HandleShutdown(SINT8 node)
static void HandleTimeout(SINT8 node) static void HandleTimeout(SINT8 node)
{ {
(void)node; (void)node;
LUAh_GameQuit(false); LUA_HookBool(false, HOOK(GameQuit));
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();

View file

@ -406,6 +406,8 @@ static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "
consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange); consvar_t cv_kartencore = CVAR_INIT ("kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange);
static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}}; static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}};
consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL); consvar_t cv_kartvoterulechanges = CVAR_INIT ("kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL);
static CV_PossibleValue_t kartgametypepreference_cons_t[] = {{-1, "None"}, {GT_RACE, "Race"}, {GT_BATTLE, "Battle"}, {0, NULL}};
consvar_t cv_kartgametypepreference = CVAR_INIT ("kartgametypepreference", "None", CV_NETVAR, kartgametypepreference_cons_t, NULL);
static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}};
consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display consvar_t cv_kartspeedometer = CVAR_INIT ("kartdisplayspeed", "Percentage", CV_SAVE, kartspeedometer_cons_t, NULL); // use tics in display
static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}}; static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, {2, "Meme"}, {0, NULL}};
@ -2476,27 +2478,28 @@ void D_SetupVote(void)
UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes UINT8 buf[5*2]; // four UINT16 maps (at twice the width of a UINT8), and two gametypes
UINT8 *p = buf; UINT8 *p = buf;
INT32 i; INT32 i;
UINT8 secondgt = G_SometimesGetDifferentGametype(); UINT8 gt = (cv_kartgametypepreference.value == -1) ? gametype : cv_kartgametypepreference.value;
UINT8 secondgt = G_SometimesGetDifferentGametype(gt);
INT16 votebuffer[4] = {-1,-1,-1,0}; INT16 votebuffer[4] = {-1,-1,-1,0};
if ((cv_kartencore.value == 1) && (gametyperules & GTR_CIRCUIT)) if ((cv_kartencore.value == 1) && (gametypedefaultrules[gt] & GTR_CIRCUIT))
WRITEUINT8(p, (gametype|0x80)); WRITEUINT8(p, (gt|VOTEMODIFIER_ENCORE));
else else
WRITEUINT8(p, gametype); WRITEUINT8(p, gt);
WRITEUINT8(p, secondgt); WRITEUINT8(p, secondgt);
secondgt &= ~0x80; secondgt &= ~VOTEMODIFIER_ENCORE;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
UINT16 m; UINT16 m;
if (i == 2) // sometimes a different gametype if (i == 2) // sometimes a different gametype
m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer); m = G_RandMap(G_TOLFlag(secondgt), prevmap, ((secondgt != gametype) ? 2 : 0), 0, true, votebuffer);
else if (i >= 3) // unknown-random and force-unknown MAP HELL else if (i >= 3) // unknown-random and formerly force-unknown MAP HELL
m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, (i-2), (i < 4), votebuffer); m = G_RandMap(G_TOLFlag(gt), prevmap, 0, (i-2), (i < 4), votebuffer);
else else
m = G_RandMap(G_TOLFlag(gametype), prevmap, 0, 0, true, votebuffer); m = G_RandMap(G_TOLFlag(gt), prevmap, 0, 0, true, votebuffer);
if (i < 3) if (i < 3)
votebuffer[i] = m; // min() is a dumb workaround for gcc 4.4 array-bounds error votebuffer[i] = m;
WRITEUINT16(p, m); WRITEUINT16(p, m);
} }
@ -3435,7 +3438,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
} }
// Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh // Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh
if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled)) if (!LUA_HookTeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled))
return; return;
//Make sure that the right team number is sent. Keep in mind that normal clients cannot change to certain teams in certain gametypes. //Make sure that the right team number is sent. Keep in mind that normal clients cannot change to certain teams in certain gametypes.
@ -3531,7 +3534,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
{ {
if (localplayertable[i] == playernum) if (localplayertable[i] == playernum)
{ {
LUAh_ViewpointSwitch(players+playernum, players+playernum, true); LUA_HookViewpointSwitch(players+playernum, players+playernum, true);
displayplayers[i] = playernum; displayplayers[i] = playernum;
break; break;
} }
@ -4451,7 +4454,7 @@ static void Command_Playintro_f(void)
*/ */
FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void) FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
{ {
LUAh_GameQuit(true); LUA_HookBool(true, HOOK(GameQuit));
I_Quit(); I_Quit();
} }
@ -4914,6 +4917,13 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
gt = (UINT8)READUINT8(*cp); gt = (UINT8)READUINT8(*cp);
secondgt = (UINT8)READUINT8(*cp); secondgt = (UINT8)READUINT8(*cp);
// Strip illegal Encore flag.
if ((gt & VOTEMODIFIER_ENCORE)
&& !(gametypedefaultrules[(gt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
{
gt &= ~VOTEMODIFIER_ENCORE;
}
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++)
{ {
votelevels[i][0] = (UINT16)READUINT16(*cp); votelevels[i][0] = (UINT16)READUINT16(*cp);
@ -4922,6 +4932,19 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
P_AllocMapHeader(votelevels[i][0]); P_AllocMapHeader(votelevels[i][0]);
} }
// If third entry has an illelegal Encore flag... (illelegal!?)
if ((secondgt & VOTEMODIFIER_ENCORE)
&& !(gametypedefaultrules[(secondgt & ~VOTEMODIFIER_ENCORE)] & GTR_CIRCUIT))
{
secondgt &= ~VOTEMODIFIER_ENCORE;
// Apply it to the second entry instead, gametype permitting!
if (gametypedefaultrules[gt] & GTR_CIRCUIT)
{
votelevels[1][1] |= VOTEMODIFIER_ENCORE;
}
}
// Finally, set third entry's gametype/Encore status.
votelevels[2][1] = secondgt; votelevels[2][1] = secondgt;
G_SetGamestate(GS_VOTING); G_SetGamestate(GS_VOTING);
@ -5016,7 +5039,7 @@ void Command_ExitGame_f(void)
{ {
INT32 i; INT32 i;
LUAh_GameQuit(false); LUA_HookBool(false, HOOK(GameQuit));
D_QuitNetGame(); D_QuitNetGame();
CL_Reset(); CL_Reset();

View file

@ -90,6 +90,7 @@ extern consvar_t cv_kartfrantic;
extern consvar_t cv_kartcomeback; extern consvar_t cv_kartcomeback;
extern consvar_t cv_kartencore; extern consvar_t cv_kartencore;
extern consvar_t cv_kartvoterulechanges; extern consvar_t cv_kartvoterulechanges;
extern consvar_t cv_kartgametypepreference;
extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartspeedometer;
extern consvar_t cv_kartvoices; extern consvar_t cv_kartvoices;
extern consvar_t cv_kartbot; extern consvar_t cv_kartbot;

View file

@ -4506,6 +4506,7 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi
// because sadly no one remembers this place while searching for full state names. // because sadly no one remembers this place while searching for full state names.
const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later. const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity testing later.
"MT_NULL", "MT_NULL",
"MT_RAY",
"MT_UNKNOWN", "MT_UNKNOWN",
"MT_THOK", // Thok! mobj "MT_THOK", // Thok! mobj

View file

@ -368,6 +368,8 @@ typedef UINT32 tic_t;
#define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24) #define UINT2RGBA(a) (UINT32)((a&0xff)<<24)|((a&0xff00)<<8)|((a&0xff0000)>>8)|(((UINT32)a&0xff000000)>>24)
#endif #endif
#define TOSTR(x) #x
/* preprocessor dumb and needs second macro to expand input */ /* preprocessor dumb and needs second macro to expand input */
#define WSTRING2(s) L ## s #define WSTRING2(s) L ## s
#define WSTRING(s) WSTRING2 (s) #define WSTRING(s) WSTRING2 (s)

View file

@ -40,6 +40,7 @@
#include "fastcmp.h" #include "fastcmp.h"
#include "lua_hud.h" #include "lua_hud.h"
#include "lua_hook.h"
// SRB2Kart // SRB2Kart
#include "k_menu.h" #include "k_menu.h"
@ -2105,7 +2106,7 @@ luahook:
if (renderisnewtic) if (renderisnewtic)
{ {
LUA_HUD_ClearDrawList(luahuddrawlist_title); LUA_HUD_ClearDrawList(luahuddrawlist_title);
LUAh_TitleHUD(luahuddrawlist_title); LUA_HookHUD(luahuddrawlist_title, HUD_HOOK(title));
} }
LUA_HUD_DrawList(luahuddrawlist_title); LUA_HUD_DrawList(luahuddrawlist_title);
} }

View file

@ -1174,7 +1174,7 @@ aftercmdinput:
*/ */
if (addedtogame && gamestate == GS_LEVEL) if (addedtogame && gamestate == GS_LEVEL)
{ {
LUAh_PlayerCmd(player, cmd); LUA_HookTiccmd(player, cmd, HOOK(PlayerCmd));
// Send leveltime when this tic was generated to the server for control lag calculations. // Send leveltime when this tic was generated to the server for control lag calculations.
// Only do this when in a level. Also do this after the hook, so that it can't overwrite this. // Only do this when in a level. Also do this after the hook, so that it can't overwrite this.
@ -1204,7 +1204,7 @@ aftercmdinput:
{ {
// Call ViewpointSwitch hooks here. // Call ViewpointSwitch hooks here.
// The viewpoint was forcibly changed. // The viewpoint was forcibly changed.
LUAh_ViewpointSwitch(player, &players[consoleplayer], true); LUA_HookViewpointSwitch(player, &players[consoleplayer], true);
displayplayers[0] = consoleplayer; displayplayers[0] = consoleplayer;
} }
} }
@ -2476,7 +2476,7 @@ void G_SpawnPlayer(INT32 playernum)
P_SpawnPlayer(playernum); P_SpawnPlayer(playernum);
G_MovePlayerToSpawnOrStarpost(playernum); G_MovePlayerToSpawnOrStarpost(playernum);
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :) LUA_HookPlayer(&players[playernum], HOOK(PlayerSpawn)); // Lua hook for player spawning :)
} }
void G_MovePlayerToSpawnOrStarpost(INT32 playernum) void G_MovePlayerToSpawnOrStarpost(INT32 playernum)
@ -3203,51 +3203,53 @@ boolean G_GametypeHasSpectators(void)
// //
// Oh, yeah, and we sometimes flip encore mode on here too. // Oh, yeah, and we sometimes flip encore mode on here too.
// //
INT16 G_SometimesGetDifferentGametype(void) INT16 G_SometimesGetDifferentGametype(UINT8 prefgametype)
{ {
boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1) && (gametyperules & GTR_CIRCUIT)); // Most of the gametype references in this condition are intentionally not prefgametype.
// This is so a server CAN continue playing a gametype if they like the taste of it.
// The encore check needs prefgametype so can't use G_RaceGametype...
boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1)
&& ((gametyperules|gametypedefaultrules[prefgametype]) & GTR_CIRCUIT));
UINT8 encoremodifier = 0;
if (!cv_kartvoterulechanges.value // never if (encorepossible)
&& encorescramble != 1) // destroying the code for this one instance
return gametype;
if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3))
{ {
randmapbuffer[NUMMAPS]--; if (encorescramble != -1)
if (encorepossible)
{ {
if (encorescramble != -1) encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission
encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission
else
{
switch (cv_kartvoterulechanges.value)
{
case 3: // always
randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set
break;
case 2: // frequent
encorepossible = M_RandomChance(FRACUNIT>>1);
break;
case 1: // sometimes
default:
encorepossible = M_RandomChance(FRACUNIT>>2);
break;
}
}
if (encorepossible != (cv_kartencore.value == 1))
return (gametype|0x80);
} }
return gametype; else
{
switch (cv_kartvoterulechanges.value)
{
case 3: // always
encorepossible = true;
break;
case 2: // frequent
encorepossible = M_RandomChance(FRACUNIT>>1);
break;
case 1: // sometimes
encorepossible = M_RandomChance(FRACUNIT>>2);
break;
default:
break;
}
}
if (encorepossible != (cv_kartencore.value == 1))
encoremodifier = VOTEMODIFIER_ENCORE;
} }
if (!cv_kartvoterulechanges.value) // never (again) if (!cv_kartvoterulechanges.value) // never
return gametype; return (gametype|encoremodifier);
if (randmapbuffer[NUMMAPS] > 0 && (cv_kartvoterulechanges.value != 3))
{
randmapbuffer[NUMMAPS]--;
return (gametype|encoremodifier);
}
switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv? switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv?
{ {
case 3: // always
randmapbuffer[NUMMAPS] = 1; // every other vote (or always if !encorepossible)
break;
case 1: // sometimes case 1: // sometimes
randmapbuffer[NUMMAPS] = 5; // per "cup" randmapbuffer[NUMMAPS] = 5; // per "cup"
break; break;
@ -3258,9 +3260,17 @@ INT16 G_SometimesGetDifferentGametype(void)
break; break;
} }
if (gametype == GT_BATTLE) // Only this response is prefgametype-based.
return GT_RACE; // todo custom gametypes
return GT_BATTLE; if (prefgametype == GT_BATTLE)
{
// Intentionally does not use encoremodifier!
if (cv_kartencore.value == 1)
return (GT_RACE|VOTEMODIFIER_ENCORE);
return (GT_RACE);
}
// This might appear wrong HERE, but the game will display the Encore possibility on the second voting choice instead.
return (GT_BATTLE|encoremodifier);
} }
// //
@ -4597,7 +4607,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer); F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer);
else else
{ {
LUAh_MapChange(gamemap); LUA_HookInt(gamemap, HOOK(MapChange));
G_DoLoadLevel(resetplayer); G_DoLoadLevel(resetplayer);
} }

View file

@ -181,7 +181,8 @@ boolean G_IsSpecialStage(INT32 mapnum);
boolean G_GametypeUsesLives(void); boolean G_GametypeUsesLives(void);
boolean G_GametypeHasTeams(void); boolean G_GametypeHasTeams(void);
boolean G_GametypeHasSpectators(void); boolean G_GametypeHasSpectators(void);
INT16 G_SometimesGetDifferentGametype(void); #define VOTEMODIFIER_ENCORE 0x80
INT16 G_SometimesGetDifferentGametype(UINT8 prefgametype);
UINT8 G_GetGametypeColor(INT16 gt); UINT8 G_GetGametypeColor(INT16 gt);
void G_ExitLevel(void); void G_ExitLevel(void);
void G_NextLevel(void); void G_NextLevel(void);

View file

@ -712,7 +712,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// run the lua hook even if we were supposed to eat the msg, netgame consistency goes first. // run the lua hook even if we were supposed to eat the msg, netgame consistency goes first.
if (LUAh_PlayerMsg(playernum, target, flags, msg, spam_eatmsg)) if (LUA_HookPlayerMsg(playernum, target, flags, msg, spam_eatmsg))
return; return;
if (spam_eatmsg) if (spam_eatmsg)
@ -2151,7 +2151,7 @@ void HU_Drawer(void)
if (renderisnewtic) if (renderisnewtic)
{ {
LUA_HUD_ClearDrawList(luahuddrawlist_scores); LUA_HUD_ClearDrawList(luahuddrawlist_scores);
LUAh_ScoresHUD(luahuddrawlist_scores); LUA_HookHUD(luahuddrawlist_scores, HUD_HOOK(scores));
} }
LUA_HUD_DrawList(luahuddrawlist_scores); LUA_HUD_DrawList(luahuddrawlist_scores);
} }

View file

@ -5120,6 +5120,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_RAY
-1, // doomednum
S_NULL, // spawnstate
0, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
0, // radius
0, // height
0, // display offset
0, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_UNKNOWN { // MT_UNKNOWN
-1, // doomednum -1, // doomednum
S_UNKNOWN, // spawnstate S_UNKNOWN, // spawnstate

View file

@ -5532,6 +5532,7 @@ extern playersprite_t free_spr2;
typedef enum mobj_type typedef enum mobj_type
{ {
MT_NULL, MT_NULL,
MT_RAY, // General purpose mobj
MT_UNKNOWN, MT_UNKNOWN,
MT_THOK, // Thok! mobj MT_THOK, // Thok! mobj

View file

@ -1224,7 +1224,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
} }
// Complete override of all ticcmd functionality // Complete override of all ticcmd functionality
if (LUAh_BotTiccmd(player, cmd) == true) if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)) == true)
{ {
return; return;
} }

View file

@ -75,7 +75,7 @@ static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkN
{ {
brightmapStorage_t *bms = &brightmapStorage[i]; brightmapStorage_t *bms = &brightmapStorage[i];
if (checkHash == bms->textureHash) if (checkHash == bms->textureHash && !strncmp(checkName, bms->textureName, 8))
{ {
// Name matches. // Name matches.
return bms; return bms;
@ -119,8 +119,8 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size)
if (bms == NULL) if (bms == NULL)
{ {
bms = K_NewBrightmap(); bms = K_NewBrightmap();
strncpy(bms->textureName, tkn, 9); strncpy(bms->textureName, tkn, 8);
bms->textureHash = quickncasehash(bms->textureName, 8); bms->textureHash = quickncasehash(tkn, 8);
} }
Z_Free(tkn); Z_Free(tkn);
@ -129,8 +129,8 @@ static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size)
if (tkn && pos < size) if (tkn && pos < size)
{ {
strncpy(bms->brightmapName, tkn, 9); strncpy(bms->brightmapName, tkn, 8);
bms->brightmapHash = quickncasehash(bms->brightmapName, 8); bms->brightmapHash = quickncasehash(tkn, 8);
} }
else else
{ {

View file

@ -23,11 +23,11 @@ typedef struct brightmapStorage_s
// Stores data for brightmap definitions, // Stores data for brightmap definitions,
// before putting them into texturebrightmaps. // before putting them into texturebrightmaps.
char textureName[9]; // The texture's name. char textureName[8]; // The texture's name.
UINT32 textureHash; // The texture name's hash. UINT32 textureHash; // The texture name's hash.
char brightmapName[9]; // The brightmap's name. char brightmapName[8]; // The brightmap's name.
UINT32 brightmapHash; // The brightmap name's hash. UINT32 brightmapHash; // The brightmap name's hash.
} brightmapStorage_t; } brightmapStorage_t;
/*-------------------------------------------------- /*--------------------------------------------------

View file

@ -248,6 +248,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartcomeback); CV_RegisterVar(&cv_kartcomeback);
CV_RegisterVar(&cv_kartencore); CV_RegisterVar(&cv_kartencore);
CV_RegisterVar(&cv_kartvoterulechanges); CV_RegisterVar(&cv_kartvoterulechanges);
CV_RegisterVar(&cv_kartgametypepreference);
CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_kartspeedometer);
CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_kartvoices);
CV_RegisterVar(&cv_kartbot); CV_RegisterVar(&cv_kartbot);

View file

@ -91,6 +91,7 @@ t_splash_t *K_GetSplashByIndex(size_t checkIndex)
--------------------------------------------------*/ --------------------------------------------------*/
t_splash_t *K_GetSplashByName(const char *checkName) t_splash_t *K_GetSplashByName(const char *checkName)
{ {
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
size_t i; size_t i;
if (numSplashDefs == 0) if (numSplashDefs == 0)
@ -102,7 +103,7 @@ t_splash_t *K_GetSplashByName(const char *checkName)
{ {
t_splash_t *s = &splashDefs[i]; t_splash_t *s = &splashDefs[i];
if (stricmp(checkName, s->name) == 0) if (checkHash == s->hash && !strncmp(checkName, s->name, TERRAIN_NAME_LEN))
{ {
// Name matches. // Name matches.
return s; return s;
@ -159,6 +160,7 @@ t_footstep_t *K_GetFootstepByIndex(size_t checkIndex)
--------------------------------------------------*/ --------------------------------------------------*/
t_footstep_t *K_GetFootstepByName(const char *checkName) t_footstep_t *K_GetFootstepByName(const char *checkName)
{ {
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
size_t i; size_t i;
if (numFootstepDefs == 0) if (numFootstepDefs == 0)
@ -170,7 +172,7 @@ t_footstep_t *K_GetFootstepByName(const char *checkName)
{ {
t_footstep_t *fs = &footstepDefs[i]; t_footstep_t *fs = &footstepDefs[i];
if (stricmp(checkName, fs->name) == 0) if (checkHash == fs->hash && !strncmp(checkName, fs->name, TERRAIN_NAME_LEN))
{ {
// Name matches. // Name matches.
return fs; return fs;
@ -227,21 +229,20 @@ terrain_t *K_GetTerrainByIndex(size_t checkIndex)
--------------------------------------------------*/ --------------------------------------------------*/
terrain_t *K_GetTerrainByName(const char *checkName) terrain_t *K_GetTerrainByName(const char *checkName)
{ {
UINT32 checkHash = quickncasehash(checkName, TERRAIN_NAME_LEN);
size_t i; size_t i;
if (numTerrainDefs == 0) if (numTerrainDefs > 0)
{ {
return NULL; for (i = 0; i < numTerrainDefs; i++)
}
for (i = 0; i < numTerrainDefs; i++)
{
terrain_t *t = &terrainDefs[i];
if (stricmp(checkName, t->name) == 0)
{ {
// Name matches. terrain_t *t = &terrainDefs[i];
return t;
if (checkHash == t->hash && !strncmp(checkName, t->name, TERRAIN_NAME_LEN))
{
// Name matches.
return t;
}
} }
} }
@ -265,20 +266,19 @@ terrain_t *K_GetDefaultTerrain(void)
--------------------------------------------------*/ --------------------------------------------------*/
terrain_t *K_GetTerrainForTextureName(const char *checkName) terrain_t *K_GetTerrainForTextureName(const char *checkName)
{ {
UINT32 checkHash = quickncasehash(checkName, 8);
size_t i; size_t i;
if (numTerrainFloorDefs == 0) if (numTerrainFloorDefs > 0)
{ {
return NULL; for (i = 0; i < numTerrainFloorDefs; i++)
}
for (i = 0; i < numTerrainFloorDefs; i++)
{
t_floor_t *f = &terrainFloorDefs[i];
if (strncasecmp(checkName, f->textureName, 8) == 0)
{ {
return K_GetTerrainByIndex(f->terrainID); t_floor_t *f = &terrainFloorDefs[i];
if (checkHash == f->textureHash && !strncmp(checkName, f->textureName, 8))
{
return K_GetTerrainByIndex(f->terrainID);
}
} }
} }
@ -294,15 +294,15 @@ terrain_t *K_GetTerrainForTextureName(const char *checkName)
--------------------------------------------------*/ --------------------------------------------------*/
terrain_t *K_GetTerrainForTextureNum(INT32 textureNum) terrain_t *K_GetTerrainForTextureNum(INT32 textureNum)
{ {
texture_t *tex = NULL; if (textureNum >= 0 && textureNum < numtextures)
if (textureNum < 0 || textureNum >= numtextures)
{ {
return NULL; texture_t *tex = textures[textureNum];
return K_GetTerrainForTextureName(tex->name);
} }
tex = textures[textureNum]; // This texture doesn't have a terrain directly applied to it,
return K_GetTerrainForTextureName(tex->name); // so we fallback to the default terrain.
return K_GetDefaultTerrain();
} }
/*-------------------------------------------------- /*--------------------------------------------------
@ -1187,6 +1187,7 @@ static boolean K_DoTERRAINLumpParse(size_t num, void (*parser)(size_t, char *, c
static boolean K_TERRAINLumpParser(UINT8 *data, size_t size) static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
char *tkn = M_GetToken((char *)data); char *tkn = M_GetToken((char *)data);
UINT32 tknHash = 0;
size_t pos = 0; size_t pos = 0;
size_t i; size_t i;
@ -1211,11 +1212,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
t_splash_t *s = NULL; t_splash_t *s = NULL;
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
for (i = 0; i < numSplashDefs; i++) for (i = 0; i < numSplashDefs; i++)
{ {
s = &splashDefs[i]; s = &splashDefs[i];
if (stricmp(tkn, s->name) == 0) if (tknHash == s->hash && !strncmp(tkn, s->name, TERRAIN_NAME_LEN))
{ {
break; break;
} }
@ -1227,6 +1230,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
s = &splashDefs[i]; s = &splashDefs[i];
strncpy(s->name, tkn, TERRAIN_NAME_LEN); strncpy(s->name, tkn, TERRAIN_NAME_LEN);
s->hash = tknHash;
CONS_Printf("Created new Splash type '%s'\n", s->name); CONS_Printf("Created new Splash type '%s'\n", s->name);
} }
@ -1248,11 +1253,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
t_footstep_t *fs = NULL; t_footstep_t *fs = NULL;
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
for (i = 0; i < numFootstepDefs; i++) for (i = 0; i < numFootstepDefs; i++)
{ {
fs = &footstepDefs[i]; fs = &footstepDefs[i];
if (stricmp(tkn, fs->name) == 0) if (tknHash == fs->hash && !strncmp(tkn, fs->name, TERRAIN_NAME_LEN))
{ {
break; break;
} }
@ -1264,6 +1271,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
fs = &footstepDefs[i]; fs = &footstepDefs[i];
strncpy(fs->name, tkn, TERRAIN_NAME_LEN); strncpy(fs->name, tkn, TERRAIN_NAME_LEN);
fs->hash = tknHash;
CONS_Printf("Created new Footstep type '%s'\n", fs->name); CONS_Printf("Created new Footstep type '%s'\n", fs->name);
} }
@ -1285,11 +1294,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
terrain_t *t = NULL; terrain_t *t = NULL;
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
for (i = 0; i < numTerrainDefs; i++) for (i = 0; i < numTerrainDefs; i++)
{ {
t = &terrainDefs[i]; t = &terrainDefs[i];
if (stricmp(tkn, t->name) == 0) if (tknHash == t->hash && !strncmp(tkn, t->name, TERRAIN_NAME_LEN))
{ {
break; break;
} }
@ -1301,6 +1312,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
t = &terrainDefs[i]; t = &terrainDefs[i];
strncpy(t->name, tkn, TERRAIN_NAME_LEN); strncpy(t->name, tkn, TERRAIN_NAME_LEN);
t->hash = tknHash;
CONS_Printf("Created new Terrain type '%s'\n", t->name); CONS_Printf("Created new Terrain type '%s'\n", t->name);
} }
@ -1333,11 +1346,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
t_floor_t *f = NULL; t_floor_t *f = NULL;
tknHash = quickncasehash(tkn, 8);
for (i = 0; i < numTerrainFloorDefs; i++) for (i = 0; i < numTerrainFloorDefs; i++)
{ {
f = &terrainFloorDefs[i]; f = &terrainFloorDefs[i];
if (stricmp(tkn, f->textureName) == 0) if (f->textureHash == tknHash && !strncmp(tkn, f->textureName, 8))
{ {
break; break;
} }
@ -1348,7 +1363,8 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
K_NewTerrainFloorDefs(); K_NewTerrainFloorDefs();
f = &terrainFloorDefs[i]; f = &terrainFloorDefs[i];
strncpy(f->textureName, tkn, 9); strncpy(f->textureName, tkn, 8);
f->textureHash = tknHash;
} }
Z_Free(tkn); Z_Free(tkn);
@ -1398,11 +1414,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
terrain_t *t = NULL; terrain_t *t = NULL;
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
for (i = 0; i < numTerrainDefs; i++) for (i = 0; i < numTerrainDefs; i++)
{ {
t = &terrainDefs[i]; t = &terrainDefs[i];
if (stricmp(tkn, t->name) == 0) if (tknHash == t->hash && !strncmp(tkn, t->name, TERRAIN_NAME_LEN))
{ {
break; break;
} }
@ -1435,11 +1453,13 @@ static boolean K_TERRAINLumpParser(UINT8 *data, size_t size)
{ {
t_footstep_t *fs = NULL; t_footstep_t *fs = NULL;
tknHash = quickncasehash(tkn, TERRAIN_NAME_LEN);
for (i = 0; i < numFootstepDefs; i++) for (i = 0; i < numFootstepDefs; i++)
{ {
fs = &footstepDefs[i]; fs = &footstepDefs[i];
if (stricmp(tkn, fs->name) == 0) if (tknHash == fs->hash && !strncmp(tkn, fs->name, TERRAIN_NAME_LEN))
{ {
break; break;
} }

View file

@ -28,6 +28,7 @@ typedef struct t_splash_s
// These are particles spawned when hitting the floor. // These are particles spawned when hitting the floor.
char name[TERRAIN_NAME_LEN]; // Lookup name. char name[TERRAIN_NAME_LEN]; // Lookup name.
UINT32 hash; // Lookup name's hash.
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything. UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
UINT16 sfx; // Sound to play. UINT16 sfx; // Sound to play.
@ -48,6 +49,7 @@ typedef struct t_footstep_s
// These are particles spawned when moving fast enough on a floor. // These are particles spawned when moving fast enough on a floor.
char name[TERRAIN_NAME_LEN]; // Lookup name. char name[TERRAIN_NAME_LEN]; // Lookup name.
UINT32 hash; // Lookup name's hash.
UINT16 mobjType; // Thing type. MT_NULL to not spawn anything. UINT16 mobjType; // Thing type. MT_NULL to not spawn anything.
UINT16 sfx; // Sound to play. UINT16 sfx; // Sound to play.
@ -79,6 +81,7 @@ typedef struct terrain_s
// These are all of the properties that the floor gets. // These are all of the properties that the floor gets.
char name[TERRAIN_NAME_LEN]; // Lookup name. char name[TERRAIN_NAME_LEN]; // Lookup name.
UINT32 hash; // Lookup name's hash.
size_t splashID; // Splash defintion ID. size_t splashID; // Splash defintion ID.
size_t footstepID; // Footstep defintion ID. size_t footstepID; // Footstep defintion ID.
@ -93,16 +96,14 @@ typedef struct terrain_s
typedef struct t_floor_s typedef struct t_floor_s
{ {
// Terrain floor definition. // Terrain floor definition.
// Ties texture names to a . // Ties a texture name to a terrain definition.
// (Could be optimized by using texture IDs instead of names, char textureName[8]; // Floor texture name.
// but was concerned because I recall sooomething about those not being netsafe? UINT32 textureHash; // Floor texture hash.
// Someone confirm if I just hallucinated that. :V)
char textureName[9]; // Floor texture name.
size_t terrainID; // Terrain definition ID. size_t terrainID; // Terrain definition ID.
} t_floor_t; } t_floor_t;
/*-------------------------------------------------- /*--------------------------------------------------
size_t K_GetSplashHeapIndex(t_splash_t *splash); size_t K_GetSplashHeapIndex(t_splash_t *splash);
@ -285,6 +286,7 @@ terrain_t *K_GetTerrainByIndex(size_t checkIndex);
terrain_t *K_GetTerrainByName(const char *checkName); terrain_t *K_GetTerrainByName(const char *checkName);
/*-------------------------------------------------- /*--------------------------------------------------
terrain_t *K_GetDefaultTerrain(void); terrain_t *K_GetDefaultTerrain(void);

View file

@ -1,7 +1,7 @@
// SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (C) 2012-2016 by John "JTE" Muniz. // Copyright (C) 2012-2016 by John "JTE" Muniz.
// Copyright (C) 2012-2020 by Sonic Team Junior. // Copyright (C) 2012-2022 by Sonic Team Junior.
// //
// This program is free software distributed under the // This program is free software distributed under the
// terms of the GNU General Public License, version 2. // terms of the GNU General Public License, version 2.
@ -12,115 +12,134 @@
#include "r_defs.h" #include "r_defs.h"
#include "d_player.h" #include "d_player.h"
#include "s_sound.h"
#include "d_event.h"
#include "lua_hudlib_drawlist.h" #include "lua_hudlib_drawlist.h"
enum hook { /*
hook_NetVars=0, Do you know what an 'X Macro' is? Such a macro is called over each element of
hook_MapChange, a list and expands the input. I use it for the hook lists because both an enum
hook_MapLoad, and array of hook names need to be kept in order. The X Macro handles this
hook_PlayerJoin, automatically.
hook_PreThinkFrame, */
hook_ThinkFrame,
hook_PostThinkFrame,
hook_MobjSpawn,
hook_MobjCollide,
hook_MobjLineCollide,
hook_MobjMoveCollide,
hook_TouchSpecial,
hook_MobjFuse,
hook_MobjThinker,
hook_BossThinker,
hook_ShouldDamage,
hook_MobjDamage,
hook_MobjDeath,
hook_BossDeath,
hook_MobjRemoved,
hook_JumpSpecial,
hook_AbilitySpecial,
hook_SpinSpecial,
hook_JumpSpinSpecial,
hook_BotTiccmd,
hook_BotAI,
hook_BotRespawn,
hook_LinedefExecute,
hook_PlayerMsg,
hook_HurtMsg,
hook_PlayerSpawn,
hook_ShieldSpawn,
hook_ShieldSpecial,
hook_MobjMoveBlocked,
hook_MapThingSpawn,
hook_FollowMobj,
hook_PlayerCanDamage,
hook_PlayerQuit,
hook_MusicChange,
hook_TeamSwitch,
hook_ViewpointSwitch,
hook_PlayerThink,
hook_ShouldJingleContinue,
hook_GameQuit,
hook_PlayerCmd,
// SRB2Kart #define MOBJ_HOOK_LIST(X) \
hook_IntermissionThinker, X (MobjSpawn),/* P_SpawnMobj */\
hook_VoteThinker, X (MobjCollide),/* PIT_CheckThing */\
X (MobjLineCollide),/* ditto */\
X (MobjMoveCollide),/* tritto */\
X (TouchSpecial),/* P_TouchSpecialThing */\
X (MobjFuse),/* when mobj->fuse runs out */\
X (MobjThinker),/* P_MobjThinker, P_SceneryThinker */\
X (BossThinker),/* P_GenericBossThinker */\
X (ShouldDamage),/* P_DamageMobj (Should mobj take damage?) */\
X (MobjDamage),/* P_DamageMobj (Mobj actually takes damage!) */\
X (MobjDeath),/* P_KillMobj */\
X (BossDeath),/* A_BossDeath */\
X (MobjRemoved),/* P_RemoveMobj */\
X (BotRespawn),/* B_CheckRespawn */\
X (MobjMoveBlocked),/* P_XYMovement (when movement is blocked) */\
X (MapThingSpawn),/* P_SpawnMapThing */\
X (FollowMobj),/* P_PlayerAfterThink Smiles mobj-following */\
hook_MAX // last hook #define HOOK_LIST(X) \
}; X (NetVars),/* add to archive table (netsave) */\
extern const char *const hookNames[]; X (MapChange),/* (before map load) */\
X (MapLoad),\
X (PlayerJoin),/* Got_AddPlayer */\
X (PreThinkFrame)/* frame (before mobj and player thinkers) */,\
X (ThinkFrame),/* frame (after mobj and player thinkers) */\
X (PostThinkFrame),/* frame (at end of tick, ie after overlays, precipitation, specials) */\
X (JumpSpecial),/* P_DoJumpStuff (Any-jumping) */\
X (AbilitySpecial),/* P_DoJumpStuff (Double-jumping) */\
X (SpinSpecial),/* P_DoSpinAbility (Spin button effect) */\
X (JumpSpinSpecial),/* P_DoJumpStuff (Spin button effect (mid-air)) */\
X (BotTiccmd),/* B_BuildTiccmd */\
X (PlayerMsg),/* chat messages */\
X (HurtMsg),/* imhurttin */\
X (PlayerSpawn),/* G_SpawnPlayer */\
X (ShieldSpawn),/* P_SpawnShieldOrb */\
X (ShieldSpecial),/* shield abilities */\
X (PlayerCanDamage),/* P_PlayerCanDamage */\
X (PlayerQuit),\
X (IntermissionThinker),/* Y_Ticker */\
X (TeamSwitch),/* team switching in... uh... *what* speak, spit it the fuck out */\
X (ViewpointSwitch),/* spy mode (no trickstabs) */\
X (SeenPlayer),/* MT_NAMECHECK */\
X (PlayerThink),/* P_PlayerThink */\
X (GameQuit),\
X (PlayerCmd),/* building the player's ticcmd struct */\
X (MusicChange),\
X (VoteThinker),/* Y_VoteTicker */\
#define STRING_HOOK_LIST(X) \
X (LinedefExecute),\
X (ShouldJingleContinue),/* should jingle of the given music continue playing */\
#define HUD_HOOK_LIST(X) \
X (game),\
X (scores),/* emblems/multiplayer list */\
X (title),/* titlescreen */\
X (titlecard),\
X (intermission),\
/*
I chose to access the hook enums through a macro as well. This could provide
a hint to lookup the macro's definition instead of the enum's definition.
(Since each enumeration is not defined in the source code, but by the list
macros above, it is not greppable.) The name passed to the macro can also be
grepped and found in the lists above.
*/
#define MOBJ_HOOK(name) mobjhook_ ## name
#define HOOK(name) hook_ ## name
#define HUD_HOOK(name) hudhook_ ## name
#define STRING_HOOK(name) stringhook_ ## name
#define ENUM(X) enum { X ## _LIST (X) X(MAX) }
ENUM (MOBJ_HOOK);
ENUM (HOOK);
ENUM (HUD_HOOK);
ENUM (STRING_HOOK);
#undef ENUM
/* dead simple, LUA_HOOK(GameQuit) */
#define LUA_HOOK(type) LUA_HookVoid(HOOK(type))
//#define LUA_HUDHOOK(type) LUA_HookHUD(HUD_HOOK(type))
extern boolean hook_cmd_running; extern boolean hook_cmd_running;
extern int hook_defrosting; extern int hook_defrosting;
void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUA_HookVoid(int hook);
void LUAh_MapLoad(void); // Hook for map load void LUA_HookHUD(huddrawlist_h, int hook);
void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer
void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers)
void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers)
void LUAh_PostThinkFrame(void); // Hook for frame (at end of tick, ie after overlays, precipitation, specials)
boolean LUAh_MobjHook(mobj_t *mo, enum hook which);
boolean LUAh_PlayerHook(player_t *plr, enum hook which);
#define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type
UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which);
UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which);
#define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type
#define LUAh_MobjLineCollide(thing, line) LUAh_MobjLineCollideHook(thing, line, hook_MobjLineCollide) // Hook for PIT_CheckThing by (thing) mobj type
#define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type
boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type
#define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type
boolean LUAh_MobjThinker(mobj_t *mo); // Hook for P_MobjThinker or P_SceneryThinker by mobj type
#define LUAh_BossThinker(mo) LUAh_MobjHook(mo, hook_BossThinker) // Hook for P_GenericBossThinker by mobj type
UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Should mobj take damage?)
boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype); // Hook for P_DamageMobj by mobj type (Mobj actually takes damage!)
boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for P_KillMobj by mobj type
#define LUAh_BossDeath(mo) LUAh_MobjHook(mo, hook_BossDeath) // Hook for A_BossDeath by mobj type
#define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type
#define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping)
#define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping)
#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect)
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name
boolean LUAh_BotRespawn(mobj_t *sonic, mobj_t *tails); // Hook for B_CheckRespawn
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute); // Hook for chat messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source, UINT8 damagetype); // Hook for hurt messages
#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer
void LUAh_PlayerQuit(player_t *plr, kickreason_t reason); // Hook for player quitting
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping,
UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them. int LUA_HookMobj(mobj_t *, int hook);
int LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);
void LUA_HookInt(INT32 integer, int hook);
void LUA_HookBool(boolean value, int hook);
int LUA_HookPlayer(player_t *, int hook);
int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUA_HookThinkFrame(void);
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker int LUA_HookMobjLineCollide(mobj_t *, line_t *);
int LUA_HookTouchSpecial(mobj_t *special, mobj_t *toucher);
#define LUAh_MobjMoveBlocked(mo) LUAh_MobjHook(mo, hook_MobjMoveBlocked) // Hook for P_XYMovement (when movement is blocked) int LUA_HookShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
boolean LUAh_MapThingSpawn(mobj_t *mo, mapthing_t *mthing); // Hook for P_SpawnMapThing by mobj type int LUA_HookMobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype);
boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAfterThink Smiles mobj-following int LUA_HookMobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage int LUA_HookMobjMoveBlocked(mobj_t *, mobj_t *, line_t *);
boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... void LUA_HookLinedefExecute(line_t *, mobj_t *, sector_t *);
UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode int LUA_HookPlayerMsg(int source, int target, int flags, char *msg, int mute);
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink int LUA_HookHurtMsg(player_t *, mobj_t *inflictor, mobj_t *source, UINT8 damagetype);
boolean LUAh_ShouldJingleContinue(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing int LUA_HookMapThingSpawn(mobj_t *, mapthing_t *);
void LUAh_GameQuit(boolean quitting); // Hook for game quitting int LUA_HookFollowMobj(player_t *, mobj_t *);
int LUA_HookPlayerCanDamage(player_t *, mobj_t *);
void LUA_HookPlayerQuit(player_t *, kickreason_t);
int LUA_HookTeamSwitch(player_t *, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble);
int LUA_HookViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced);
int LUA_HookSeenPlayer(player_t *player, player_t *seenfriend);
int LUA_HookShouldJingleContinue(player_t *, const char *musname);
int LUA_HookMusicChange(const char *oldname, struct MusicChange *);

File diff suppressed because it is too large Load diff

View file

@ -47,10 +47,6 @@ extern boolean hud_running;
boolean LUA_HudEnabled(enum hud option); boolean LUA_HudEnabled(enum hud option);
void LUAh_GameHUD(player_t *stplyr, huddrawlist_h list); void LUA_SetHudHook(int hook, huddrawlist_h list);
void LUAh_ScoresHUD(huddrawlist_h list);
void LUAh_TitleHUD(huddrawlist_h list);
void LUAh_TitleCardHUD(player_t *stplayr, huddrawlist_h list);
void LUAh_IntermissionHUD(huddrawlist_h list);
#endif // __LUA_HUD_H__ #endif // __LUA_HUD_H__

View file

@ -29,14 +29,13 @@
#include "lua_script.h" #include "lua_script.h"
#include "lua_libs.h" #include "lua_libs.h"
#include "lua_hud.h" #include "lua_hud.h"
#include "lua_hook.h"
#define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!"); #define HUDONLY if (!hud_running) return luaL_error(L, "HUD rendering code should not be called outside of rendering hooks!");
boolean hud_running = false; boolean hud_running = false;
static UINT8 hud_enabled[(hud_MAX/8)+1]; static UINT8 hud_enabled[(hud_MAX/8)+1];
static UINT8 hudAvailable; // hud hooks field
static UINT8 camnum = 1; static UINT8 camnum = 1;
// must match enum hud in lua_hud.h // must match enum hud in lua_hud.h
@ -79,21 +78,6 @@ static const char *const patch_opt[] = {
"topoffset", "topoffset",
NULL}; NULL};
enum hudhook {
hudhook_game = 0,
hudhook_scores,
hudhook_intermission,
hudhook_title,
hudhook_titlecard
};
static const char *const hudhook_opt[] = {
"game",
"scores",
"intermission",
"title",
"titlecard",
NULL};
// alignment types for v.drawString // alignment types for v.drawString
enum align { enum align {
align_left = 0, align_left = 0,
@ -1249,6 +1233,8 @@ static luaL_Reg lib_draw[] = {
{NULL, NULL} {NULL, NULL}
}; };
static int lib_draw_ref;
// //
// lib_hud // lib_hud
// //
@ -1282,28 +1268,7 @@ static int lib_hudenabled(lua_State *L)
} }
// add a HUD element for rendering // add a HUD element for rendering
static int lib_hudadd(lua_State *L) extern int lib_hudadd(lua_State *L);
{
enum hudhook field;
luaL_checktype(L, 1, LUA_TFUNCTION);
field = luaL_checkoption(L, 2, "game", hudhook_opt);
if (!lua_lumploading)
return luaL_error(L, "This function cannot be called from within a hook or coroutine!");
lua_getfield(L, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(L, -1));
lua_rawgeti(L, -1, field+2); // HUD[2+]
I_Assert(lua_istable(L, -1));
lua_remove(L, -2);
lua_pushvalue(L, 1);
lua_rawseti(L, -2, (int)(lua_objlen(L, -2) + 1));
hudAvailable |= 1<<field;
return 0;
}
static luaL_Reg lib_hud[] = { static luaL_Reg lib_hud[] = {
{"enable", lib_hudenable}, {"enable", lib_hudenable},
@ -1321,26 +1286,9 @@ int LUA_HudLib(lua_State *L)
{ {
memset(hud_enabled, 0xff, (hud_MAX/8)+1); memset(hud_enabled, 0xff, (hud_MAX/8)+1);
lua_newtable(L); // HUD registry table lua_newtable(L);
lua_newtable(L); luaL_register(L, NULL, lib_draw);
luaL_register(L, NULL, lib_draw); lib_draw_ref = luaL_ref(L, LUA_REGISTRYINDEX);
lua_rawseti(L, -2, 1); // HUD[1] = lib_draw
lua_newtable(L);
lua_rawseti(L, -2, 2); // HUD[2] = game rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 3); // HUD[3] = scores rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 4); // HUD[4] = intermission rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 5); // HUD[5] = title rendering functions array
lua_newtable(L);
lua_rawseti(L, -2, 6); // HUD[6] = title card rendering functions array
lua_setfield(L, LUA_REGISTRYINDEX, "HUD");
luaL_newmetatable(L, META_COLORMAP); luaL_newmetatable(L, META_COLORMAP);
lua_pushcfunction(L, colormap_get); lua_pushcfunction(L, colormap_get);
@ -1371,170 +1319,28 @@ boolean LUA_HudEnabled(enum hud option)
return false; return false;
} }
// Hook for HUD rendering void LUA_SetHudHook(int hook, huddrawlist_h list)
void LUAh_GameHUD(player_t *stplayr, huddrawlist_h list)
{ {
if (!gL || !(hudAvailable & (1<<hudhook_game))) lua_getref(gL, lib_draw_ref);
return;
lua_pushlightuserdata(gL, list); lua_pushlightuserdata(gL, list);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST"); lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
hud_running = true; switch (hook)
lua_settop(gL, 0); {
case HUD_HOOK(game):
camnum = R_GetViewNumber();
lua_pushcfunction(gL, LUA_GetErrorMessage); LUA_PushUserdata(gL, stplyr, META_PLAYER);
LUA_PushUserdata(gL, &camera[camnum], META_CAMERA);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD"); camnum++; // for compatibility
I_Assert(lua_istable(gL, -1)); break;
lua_rawgeti(gL, -1, 2+hudhook_game); // HUD[2] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw case HUD_HOOK(titlecard):
I_Assert(lua_istable(gL, -1)); LUA_PushUserdata(gL, stplyr, META_PLAYER);
lua_remove(gL, -3); // pop HUD lua_pushinteger(gL, lt_ticker);
LUA_PushUserdata(gL, stplayr, META_PLAYER); lua_pushinteger(gL, (lt_endtime + TICRATE));
break;
camnum = R_GetViewNumber();
LUA_PushUserdata(gL, &camera[camnum], META_CAMERA);
camnum++; // for compatibility
lua_pushnil(gL);
while (lua_next(gL, -5) != 0) {
lua_pushvalue(gL, -5); // graphics library (HUD[1])
lua_pushvalue(gL, -5); // stplayr
lua_pushvalue(gL, -5); // camera
LUA_Call(gL, 3, 0, 1);
} }
lua_settop(gL, 0);
hud_running = false;
}
void LUAh_ScoresHUD(huddrawlist_h list)
{
if (!gL || !(hudAvailable & (1<<hudhook_scores)))
return;
lua_pushlightuserdata(gL, list);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
hud_running = true;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 2+hudhook_scores); // HUD[3] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // graphics library (HUD[1])
LUA_Call(gL, 1, 0, 1);
}
lua_settop(gL, 0);
hud_running = false;
}
void LUAh_TitleHUD(huddrawlist_h list)
{
if (!gL || !(hudAvailable & (1<<hudhook_title)))
return;
lua_pushlightuserdata(gL, list);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
hud_running = true;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 2+hudhook_title); // HUD[5] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // graphics library (HUD[1])
LUA_Call(gL, 1, 0, 1);
}
lua_settop(gL, 0);
hud_running = false;
}
void LUAh_TitleCardHUD(player_t *stplayr, huddrawlist_h list)
{
if (!gL || !(hudAvailable & (1<<hudhook_titlecard)))
return;
lua_pushlightuserdata(gL, list);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
hud_running = true;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 2+hudhook_titlecard); // HUD[6] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
LUA_PushUserdata(gL, stplayr, META_PLAYER);
lua_pushinteger(gL, lt_ticker);
lua_pushinteger(gL, (lt_endtime + TICRATE));
lua_pushnil(gL);
while (lua_next(gL, -6) != 0) {
lua_pushvalue(gL, -6); // graphics library (HUD[1])
lua_pushvalue(gL, -6); // stplayr
lua_pushvalue(gL, -6); // lt_ticker
lua_pushvalue(gL, -6); // lt_endtime
LUA_Call(gL, 4, 0, 1);
}
lua_settop(gL, 0);
hud_running = false;
}
void LUAh_IntermissionHUD(huddrawlist_h list)
{
if (!gL || !(hudAvailable & (1<<hudhook_intermission)))
return;
lua_pushlightuserdata(gL, list);
lua_setfield(gL, LUA_REGISTRYINDEX, "HUD_DRAW_LIST");
hud_running = true;
lua_settop(gL, 0);
lua_pushcfunction(gL, LUA_GetErrorMessage);
lua_getfield(gL, LUA_REGISTRYINDEX, "HUD");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, 2+hudhook_intermission); // HUD[4] = rendering funcs
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -2, 1); // HUD[1] = lib_draw
I_Assert(lua_istable(gL, -1));
lua_remove(gL, -3); // pop HUD
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // graphics library (HUD[1])
LUA_Call(gL, 1, 0, 1);
}
lua_settop(gL, 0);
hud_running = false;
} }

View file

@ -1687,7 +1687,7 @@ void LUA_Archive(UINT8 **p)
WRITEUINT32(*p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. WRITEUINT32(*p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode LUA_HookNetArchive(NetArchive); // call the NetArchive hook in archive mode
} }
ArchiveTables(p); ArchiveTables(p);
@ -1726,7 +1726,7 @@ void LUA_UnArchive(UINT8 **p)
} }
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. } while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode LUA_HookNetArchive(NetUnArchive); // call the NetArchive hook in unarchive mode
} }
UnArchiveTables(p); UnArchiveTables(p);

View file

@ -63,7 +63,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
void LUA_CVarChanged(void *cvar); // lua_consolelib.c void LUA_CVarChanged(void *cvar); // lua_consolelib.c
int Lua_optoption(lua_State *L, int narg, int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]); const char *def, const char *const lst[]);
void LUAh_NetArchiveHook(lua_CFunction archFunc); void LUA_HookNetArchive(lua_CFunction archFunc);
void LUA_PushTaggableObjectArray void LUA_PushTaggableObjectArray
( lua_State *L, ( lua_State *L,

View file

@ -2474,7 +2474,7 @@ void A_LobShot(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
INT32 locvar2 = var2 >> 16; INT32 locvar2 = var2 >> 16;
mobj_t *shot, *hitspot; mobj_t *shot;
angle_t an; angle_t an;
fixed_t z; fixed_t z;
fixed_t dist; fixed_t dist;
@ -2502,11 +2502,6 @@ void A_LobShot(mobj_t *actor)
shot->destscale = actor->scale; shot->destscale = actor->scale;
P_SetScale(shot, actor->scale); P_SetScale(shot, actor->scale);
// Keep track of where it's going to land
hitspot = P_SpawnMobj(actor->target->x&(64*FRACUNIT-1), actor->target->y&(64*FRACUNIT-1), actor->target->subsector->sector->floorheight, MT_NULL);
hitspot->tics = airtime;
P_SetTarget(&shot->tracer, hitspot);
P_SetTarget(&shot->target, actor); // where it came from P_SetTarget(&shot->target, actor); // where it came from
P_InitAngle(shot, actor->angle); P_InitAngle(shot, actor->angle);
@ -3142,20 +3137,18 @@ void A_SkullAttack(mobj_t *actor)
actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90; actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90;
else if (locvar1 == 3) else if (locvar1 == 3)
{ {
statenum_t oldspawnstate = mobjinfo[MT_NULL].spawnstate; statenum_t oldspawnstate = mobjinfo[MT_RAY].spawnstate;
UINT32 oldflags = mobjinfo[MT_NULL].flags; UINT32 oldflags = mobjinfo[MT_RAY].flags;
fixed_t oldradius = mobjinfo[MT_NULL].radius; fixed_t oldradius = mobjinfo[MT_RAY].radius;
fixed_t oldheight = mobjinfo[MT_NULL].height; fixed_t oldheight = mobjinfo[MT_RAY].height;
mobj_t *check;
INT32 i, j; INT32 i, j;
static INT32 k;/* static for (at least) GCC 9.1 weirdness */ static INT32 k;/* static for (at least) GCC 9.1 weirdness */
boolean allow;
angle_t testang = 0; angle_t testang = 0;
mobjinfo[MT_NULL].spawnstate = S_INVISIBLE; mobjinfo[MT_RAY].spawnstate = S_INVISIBLE;
mobjinfo[MT_NULL].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP; mobjinfo[MT_RAY].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP;
mobjinfo[MT_NULL].radius = mobjinfo[actor->type].radius; mobjinfo[MT_RAY].radius = mobjinfo[actor->type].radius;
mobjinfo[MT_NULL].height = mobjinfo[actor->type].height; mobjinfo[MT_RAY].height = mobjinfo[actor->type].height;
if (P_RandomChance(FRACUNIT/2)) // port priority 1? if (P_RandomChance(FRACUNIT/2)) // port priority 1?
{ {
@ -3168,15 +3161,12 @@ void A_SkullAttack(mobj_t *actor)
j = 9; j = 9;
} }
#define dostuff(q) check = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_NULL);\ #define dostuff(q) \
testang = actor->angle + ((i+(q))*ANG10);\ testang = actor->angle + ((i+(q))*ANG10);\
allow = (P_TryMove(check,\ if (P_CheckMove(actor,\
P_ReturnThrustX(check, testang, dist + 2*actor->radius),\ P_ReturnThrustX(actor, testang, dist + 2*actor->radius),\
P_ReturnThrustY(check, testang, dist + 2*actor->radius),\ P_ReturnThrustY(actor, testang, dist + 2*actor->radius),\
true));\ true)) break;
P_RemoveMobj(check);\
if (allow)\
break;
if (P_RandomChance(FRACUNIT/2)) // port priority 2? if (P_RandomChance(FRACUNIT/2)) // port priority 2?
{ {
@ -3202,10 +3192,10 @@ void A_SkullAttack(mobj_t *actor)
#undef dostuff #undef dostuff
mobjinfo[MT_NULL].spawnstate = oldspawnstate; mobjinfo[MT_RAY].spawnstate = oldspawnstate;
mobjinfo[MT_NULL].flags = oldflags; mobjinfo[MT_RAY].flags = oldflags;
mobjinfo[MT_NULL].radius = oldradius; mobjinfo[MT_RAY].radius = oldradius;
mobjinfo[MT_NULL].height = oldheight; mobjinfo[MT_RAY].height = oldheight;
} }
an = actor->angle >> ANGLETOFINESHIFT; an = actor->angle >> ANGLETOFINESHIFT;
@ -3495,7 +3485,7 @@ void A_BossDeath(mobj_t *mo)
} }
bossjustdie: bossjustdie:
if (LUAh_BossDeath(mo)) if (LUA_HookMobj(mo, MOBJ_HOOK(BossDeath)))
return; return;
else if (P_MobjWasRemoved(mo)) else if (P_MobjWasRemoved(mo))
return; return;

View file

@ -219,7 +219,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET) if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET)
return; return;
if (LUAh_TouchSpecial(special, toucher) || P_MobjWasRemoved(special)) if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special))
return; return;
if ((special->flags & (MF_ENEMY|MF_BOSS)) && !(special->flags & MF_MISSILE)) if ((special->flags & (MF_ENEMY|MF_BOSS)) && !(special->flags & MF_MISSILE))
@ -973,7 +973,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->shadowscale = 0; target->shadowscale = 0;
} }
if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) if (LUA_HookMobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target))
return; return;
//K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true); //K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true);
@ -1861,7 +1861,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
// Everything above here can't be forced. // Everything above here can't be forced.
if (!metalrecording) if (!metalrecording)
{ {
UINT8 shouldForce = LUAh_ShouldDamage(target, inflictor, source, damage, damagetype); UINT8 shouldForce = LUA_HookShouldDamage(target, inflictor, source, damage, damagetype);
if (P_MobjWasRemoved(target)) if (P_MobjWasRemoved(target))
return (shouldForce == 1); // mobj was removed return (shouldForce == 1); // mobj was removed
if (shouldForce == 1) if (shouldForce == 1)
@ -1887,7 +1887,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit if (!force && target->flags2 & MF2_FRET) // Currently flashing from being hit
return false; return false;
if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target)) if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype) || P_MobjWasRemoved(target))
return true; return true;
if (target->health > 1) if (target->health > 1)
@ -1917,7 +1917,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (!P_KillPlayer(player, inflictor, source, damagetype)) if (!P_KillPlayer(player, inflictor, source, damagetype))
return false; return false;
} }
else if (LUAh_MobjDamage(target, inflictor, source, damage, damagetype)) else if (LUA_HookMobjDamage(target, inflictor, source, damage, damagetype))
{ {
return true; return true;
} }

View file

@ -410,6 +410,7 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing);
boolean P_IsLineTripWire(const line_t *ld); boolean P_IsLineTripWire(const line_t *ld);
boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y); boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y);
boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam);
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);
fixed_t P_BaseStepUp(void); fixed_t P_BaseStepUp(void);
fixed_t P_GetThingStepUp(mobj_t *thing); fixed_t P_GetThingStepUp(mobj_t *thing);
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff);

View file

@ -656,7 +656,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
} }
{ {
UINT8 shouldCollide = LUAh_MobjCollide(thing, tmthing); // checks hook for thing's type UINT8 shouldCollide = LUA_Hook2Mobj(thing, tmthing, MOBJ_HOOK(MobjCollide)); // checks hook for thing's type
if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE; // one of them was removed??? return BMIT_CONTINUE; // one of them was removed???
if (shouldCollide == 1) if (shouldCollide == 1)
@ -664,7 +664,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
else if (shouldCollide == 2) else if (shouldCollide == 2)
return BMIT_CONTINUE; // force no collide return BMIT_CONTINUE; // force no collide
shouldCollide = LUAh_MobjMoveCollide(tmthing, thing); // checks hook for tmthing's type shouldCollide = LUA_Hook2Mobj(tmthing, thing, MOBJ_HOOK(MobjMoveCollide)); // checks hook for tmthing's type
if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(tmthing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE; // one of them was removed??? return BMIT_CONTINUE; // one of them was removed???
if (shouldCollide == 1) if (shouldCollide == 1)
@ -1640,7 +1640,7 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld)
blockingline = ld; blockingline = ld;
{ {
UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, blockingline); // checks hook for thing's type UINT8 shouldCollide = LUA_HookMobjLineCollide(tmthing, blockingline); // checks hook for thing's type
if (P_MobjWasRemoved(tmthing)) if (P_MobjWasRemoved(tmthing))
return BMIT_CONTINUE; // one of them was removed??? return BMIT_CONTINUE; // one of them was removed???
if (shouldCollide == 1) if (shouldCollide == 1)
@ -2483,21 +2483,19 @@ fixed_t P_GetThingStepUp(mobj_t *thing)
return maxstep; return maxstep;
} }
// static boolean
// P_TryMove increment_move
// Attempt to move to a new position. ( mobj_t * thing,
// fixed_t x,
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t y,
boolean allowdropoff,
fixed_t * return_stairjank)
{ {
fixed_t tryx = thing->x; fixed_t tryx = thing->x;
fixed_t tryy = thing->y; fixed_t tryy = thing->y;
fixed_t oldx = tryx;
fixed_t oldy = tryy;
fixed_t radius = thing->radius; fixed_t radius = thing->radius;
fixed_t thingtop; fixed_t thingtop;
fixed_t startingonground = P_IsObjectOnGround(thing);
fixed_t stairjank = 0; fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
floatok = false; floatok = false;
// reset this to 0 at the start of each trymove call as it's only used here // reset this to 0 at the start of each trymove call as it's only used here
@ -2643,7 +2641,45 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
} }
} while (tryx != x || tryy != y); } while (tryx != x || tryy != y);
if (return_stairjank)
*return_stairjank = stairjank;
return true;
}
//
// P_CheckMove
// Check if a P_TryMove would be successful.
//
boolean P_CheckMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
boolean moveok;
mobj_t *hack = P_SpawnMobjFromMobj(thing, 0, 0, 0, MT_RAY);
hack->radius = thing->radius;
hack->height = thing->height;
moveok = increment_move(hack, x, y, allowdropoff, NULL);
P_RemoveMobj(hack);
return moveok;
}
//
// P_TryMove
// Attempt to move to a new position.
//
boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
fixed_t oldx = thing->x;
fixed_t oldy = thing->y;
fixed_t startingonground = P_IsObjectOnGround(thing);
fixed_t stairjank = 0;
pslope_t *oldslope = thing->standingslope;
// The move is ok! // The move is ok!
if (!increment_move(thing, x, y, allowdropoff, &stairjank))
return false;
// If it's a pushable object, check if anything is // If it's a pushable object, check if anything is
// standing on top and move it, too. // standing on top and move it, too.

View file

@ -1574,7 +1574,7 @@ void P_XYMovement(mobj_t *mo)
// blocked move // blocked move
moved = false; moved = false;
if (LUAh_MobjMoveBlocked(mo)) if (LUA_HookMobjMoveBlocked(mo, tmhitthing, blockingline))
{ {
if (P_MobjWasRemoved(mo)) if (P_MobjWasRemoved(mo))
return; return;
@ -3976,7 +3976,7 @@ static void P_RingThinker(mobj_t *mobj)
if (!mobj->fuse) if (!mobj->fuse)
{ {
if (!LUAh_MobjFuse(mobj)) if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)))
{ {
mobj->renderflags &= ~RF_DONTDRAW; mobj->renderflags &= ~RF_DONTDRAW;
spark = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SIGNSPARKLE); // Spawn a fancy sparkle spark = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SIGNSPARKLE); // Spawn a fancy sparkle
@ -5356,7 +5356,7 @@ static boolean P_ParticleGenSceneryThink(mobj_t *mobj)
static void P_MobjSceneryThink(mobj_t *mobj) static void P_MobjSceneryThink(mobj_t *mobj)
{ {
if (LUAh_MobjThinker(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)))
return; return;
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return; return;
@ -6218,7 +6218,7 @@ static void P_MobjSceneryThink(mobj_t *mobj)
mobj->fuse--; mobj->fuse--;
if (!mobj->fuse) if (!mobj->fuse)
{ {
if (!LUAh_MobjFuse(mobj)) if (!LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)))
P_RemoveMobj(mobj); P_RemoveMobj(mobj);
return; return;
} }
@ -6238,7 +6238,7 @@ static boolean P_MobjPushableThink(mobj_t *mobj)
static boolean P_MobjBossThink(mobj_t *mobj) static boolean P_MobjBossThink(mobj_t *mobj)
{ {
if (LUAh_BossThinker(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(BossThinker)))
{ {
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return false; return false;
@ -9164,7 +9164,7 @@ static boolean P_FuseThink(mobj_t *mobj)
if (mobj->fuse) if (mobj->fuse)
return true; return true;
if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjFuse)) || P_MobjWasRemoved(mobj))
; ;
else if (mobj->info->flags & MF_MONITOR) else if (mobj->info->flags & MF_MONITOR)
{ {
@ -9396,13 +9396,13 @@ void P_MobjThinker(mobj_t *mobj)
// Check for a Lua thinker first // Check for a Lua thinker first
if (!mobj->player) if (!mobj->player)
{ {
if (LUAh_MobjThinker(mobj) || P_MobjWasRemoved(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker)) || P_MobjWasRemoved(mobj))
return; return;
} }
else if (!mobj->player->spectator) else if (!mobj->player->spectator)
{ {
// You cannot short-circuit the player thinker like you can other thinkers. // You cannot short-circuit the player thinker like you can other thinkers.
LUAh_MobjThinker(mobj); LUA_HookMobj(mobj, MOBJ_HOOK(MobjThinker));
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return; return;
} }
@ -9893,7 +9893,24 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
const mobjinfo_t *info = &mobjinfo[type]; const mobjinfo_t *info = &mobjinfo[type];
SINT8 sc = -1; SINT8 sc = -1;
state_t *st; state_t *st;
mobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); mobj_t *mobj;
if (type == MT_NULL)
{
#if 0
#ifdef PARANOIA
I_Error("Tried to spawn MT_NULL\n");
#endif
return NULL;
#endif
// Hack: Some code assumes that P_SpawnMobj can never return NULL
// So replace MT_NULL with MT_RAY in the meantime
// Remove when dealt properly
CONS_Debug(DBG_GAMELOGIC, "Tried to spawn MT_NULL, using MT_RAY\n");
type = MT_RAY;
}
mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL);
// this is officially a mobj, declared as soon as possible. // this is officially a mobj, declared as soon as possible.
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker;
@ -9994,7 +10011,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
// DANGER! This can cause P_SpawnMobj to return NULL! // DANGER! This can cause P_SpawnMobj to return NULL!
// Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks!
if (LUAh_MobjSpawn(mobj)) if (LUA_HookMobj(mobj, MOBJ_HOOK(MobjSpawn)))
{ {
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return NULL; return NULL;
@ -10594,7 +10611,7 @@ void P_RemoveMobj(mobj_t *mobj)
return; // something already removing this mobj. return; // something already removing this mobj.
mobj->thinker.function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; // shh. no recursing. mobj->thinker.function.acp1 = (actionf_p1)P_RemoveThinkerDelayed; // shh. no recursing.
LUAh_MobjRemoved(mobj); LUA_HookMobj(mobj, MOBJ_HOOK(MobjRemoved));
mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; // needed for P_UnsetThingPosition, etc. to work. mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; // needed for P_UnsetThingPosition, etc. to work.
// Rings only, please! // Rings only, please!
@ -12191,7 +12208,7 @@ static void P_SnapToFinishLine(mobj_t *mobj)
static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle)
{ {
boolean override = LUAh_MapThingSpawn(mobj, mthing); boolean override = LUA_HookMapThingSpawn(mobj, mthing);
if (P_MobjWasRemoved(mobj)) if (P_MobjWasRemoved(mobj))
return false; return false;

View file

@ -66,7 +66,7 @@
#include "md5.h" // map MD5 #include "md5.h" // map MD5
// for LUAh_MapLoad // for MapLoad hook
#include "lua_script.h" #include "lua_script.h"
#include "lua_hook.h" #include "lua_hook.h"
@ -4486,7 +4486,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
} }
P_PreTicker(2); P_PreTicker(2);
P_MapStart(); // just in case MapLoad modifies tmthing P_MapStart(); // just in case MapLoad modifies tmthing
LUAh_MapLoad(); LUA_HookInt(gamemap, HOOK(MapLoad));
P_MapEnd(); // just in case MapLoad modifies tmthing P_MapEnd(); // just in case MapLoad modifies tmthing
} }

View file

@ -36,7 +36,7 @@
#include "v_video.h" // V_ALLOWLOWERCASE #include "v_video.h" // V_ALLOWLOWERCASE
#include "m_misc.h" #include "m_misc.h"
#include "m_cond.h" //unlock triggers #include "m_cond.h" //unlock triggers
#include "lua_hook.h" // LUAh_LinedefExecute #include "lua_hook.h" // LUA_HookLinedefExecute
#include "f_finale.h" // control text prompt #include "f_finale.h" // control text prompt
#include "r_skins.h" // skins #include "r_skins.h" // skins
@ -3028,7 +3028,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 443: // Calls a named Lua function case 443: // Calls a named Lua function
if (line->stringargs[0]) if (line->stringargs[0])
LUAh_LinedefExecute(line, mo, callsec); LUA_HookLinedefExecute(line, mo, callsec);
else else
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in arg0str)\n", sizeu1(line-lines)); CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in arg0str)\n", sizeu1(line-lines));
break; break;

View file

@ -581,7 +581,7 @@ void P_Ticker(boolean run)
ps_lua_mobjhooks = 0; ps_lua_mobjhooks = 0;
ps_checkposition_calls = 0; ps_checkposition_calls = 0;
LUAh_PreThinkFrame(); LUA_HOOK(PreThinkFrame);
ps_playerthink_time = I_GetPreciseTime(); ps_playerthink_time = I_GetPreciseTime();
@ -654,7 +654,7 @@ void P_Ticker(boolean run)
} }
ps_lua_thinkframe_time = I_GetPreciseTime(); ps_lua_thinkframe_time = I_GetPreciseTime();
LUAh_ThinkFrame(); LUA_HOOK(ThinkFrame);
ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time; ps_lua_thinkframe_time = I_GetPreciseTime() - ps_lua_thinkframe_time;
} }
@ -748,7 +748,7 @@ void P_Ticker(boolean run)
// Always move the camera. // Always move the camera.
P_RunChaseCameras(); P_RunChaseCameras();
LUAh_PostThinkFrame(); LUA_HOOK(PostThinkFrame);
if (run) if (run)
{ {
@ -802,7 +802,7 @@ void P_PreTicker(INT32 frames)
K_KartUpdatePosition(&players[i]); K_KartUpdatePosition(&players[i]);
// OK! Now that we got all of that sorted, players can think! // OK! Now that we got all of that sorted, players can think!
LUAh_PreThinkFrame(); LUA_HOOK(PreThinkFrame);
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
@ -825,7 +825,7 @@ void P_PreTicker(INT32 frames)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
P_PlayerAfterThink(&players[i]); P_PlayerAfterThink(&players[i]);
LUAh_ThinkFrame(); LUA_HOOK(ThinkFrame);
// Run shield positioning // Run shield positioning
P_RunOverlays(); P_RunOverlays();
@ -833,7 +833,7 @@ void P_PreTicker(INT32 frames)
P_UpdateSpecials(); P_UpdateSpecials();
P_RespawnSpecials(); P_RespawnSpecials();
LUAh_PostThinkFrame(); LUA_HOOK(PostThinkFrame);
R_UpdateLevelInterpolators(); R_UpdateLevelInterpolators();
R_UpdateViewInterpolation(); R_UpdateViewInterpolation();

View file

@ -665,7 +665,7 @@ boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
break; break;
case JT_OTHER: // Other state case JT_OTHER: // Other state
result = LUAh_ShouldJingleContinue(&players[i], musname); result = LUA_HookShouldJingleContinue(&players[i], musname);
break; break;
case JT_NONE: // Null state case JT_NONE: // Null state
@ -3684,7 +3684,7 @@ boolean P_SpectatorJoinGame(player_t *player)
else else
changeto = (P_RandomFixed() & 1) + 1; changeto = (P_RandomFixed() & 1) + 1;
if (!LUAh_TeamSwitch(player, changeto, true, false, false)) if (!LUA_HookTeamSwitch(player, changeto, true, false, false))
return false; return false;
} }
@ -3710,7 +3710,7 @@ boolean P_SpectatorJoinGame(player_t *player)
{ {
if (localplayertable[i] == (player-players)) if (localplayertable[i] == (player-players))
{ {
LUAh_ViewpointSwitch(player, player, true); LUA_HookViewpointSwitch(player, player, true);
displayplayers[i] = (player-players); displayplayers[i] = (player-players);
break; break;
} }
@ -4220,7 +4220,7 @@ void P_PlayerThink(player_t *player)
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
LUAh_PlayerThink(player); LUA_HookPlayer(player, HOOK(PlayerThink));
return; return;
} }
} }
@ -4269,7 +4269,7 @@ void P_PlayerThink(player_t *player)
else else
player->mo->renderflags &= ~RF_GHOSTLYMASK; player->mo->renderflags &= ~RF_GHOSTLYMASK;
P_DeathThink(player); P_DeathThink(player);
LUAh_PlayerThink(player); LUA_HookPlayer(player, HOOK(PlayerThink));
return; return;
} }
@ -4474,7 +4474,7 @@ void P_PlayerThink(player_t *player)
if (player->carry == CR_SLIDING) if (player->carry == CR_SLIDING)
player->carry = CR_NONE; player->carry = CR_NONE;
LUAh_PlayerThink(player); LUA_HookPlayer(player, HOOK(PlayerThink));
} }
// //
@ -4581,7 +4581,7 @@ void P_PlayerAfterThink(player_t *player)
if (player->followmobj) if (player->followmobj)
{ {
if (LUAh_FollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj)) if (LUA_HookFollowMobj(player, player->followmobj) || P_MobjWasRemoved(player->followmobj))
{;} {;}
else else
{ {

View file

@ -2121,6 +2121,15 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
{ {
char newmusic[7]; char newmusic[7];
struct MusicChange hook_param = {
newmusic,
&mflags,
&looping,
&position,
&prefadems,
&fadeinms
};
if (S_MusicDisabled() if (S_MusicDisabled()
|| demo.rewinding // Don't mess with music while rewinding! || demo.rewinding // Don't mess with music while rewinding!
|| demo.title) // SRB2Kart: Demos don't interrupt title screen music || demo.title) // SRB2Kart: Demos don't interrupt title screen music
@ -2128,7 +2137,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
strncpy(newmusic, mmusic, 7); strncpy(newmusic, mmusic, 7);
if (LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms)) if (LUA_HookMusicChange(music_name, &hook_param))
return; return;
newmusic[6] = 0; newmusic[6] = 0;

View file

@ -243,6 +243,16 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst);
// Music Playback // Music Playback
// //
/* this is for the sake of the hook */
struct MusicChange {
char * newname;
UINT16 * mflags;
boolean * looping;
UINT32 * position;
UINT32 * prefadems;
UINT32 * fadeinms;
};
enum enum
{ {
MUS_SPECIAL = 1,/* powerups--invincibility, grow */ MUS_SPECIAL = 1,/* powerups--invincibility, grow */

View file

@ -1041,7 +1041,7 @@ void I_GetEvent(void)
#endif #endif
break; break;
case SDL_QUIT: case SDL_QUIT:
LUAh_GameQuit(true); LUA_HookBool(true, HOOK(GameQuit));
I_Quit(); I_Quit();
break; break;
} }

View file

@ -47,6 +47,7 @@
#include "lua_hudlib_drawlist.h" #include "lua_hudlib_drawlist.h"
#include "lua_hud.h" #include "lua_hud.h"
#include "lua_hook.h"
// SRB2Kart // SRB2Kart
#include "k_hud.h" // SRB2kart #include "k_hud.h" // SRB2kart
@ -965,7 +966,7 @@ luahook:
if (renderisnewtic) if (renderisnewtic)
{ {
LUA_HUD_ClearDrawList(luahuddrawlist_titlecard); LUA_HUD_ClearDrawList(luahuddrawlist_titlecard);
LUAh_TitleCardHUD(stplyr, luahuddrawlist_titlecard); LUA_HookHUD(luahuddrawlist_titlecard, HUD_HOOK(titlecard));
} }
LUA_HUD_DrawList(luahuddrawlist_titlecard); LUA_HUD_DrawList(luahuddrawlist_titlecard);
} }
@ -1012,7 +1013,7 @@ static void ST_overlayDrawer(void)
if (renderisnewtic) if (renderisnewtic)
{ {
LUA_HUD_ClearDrawList(luahuddrawlist_game); LUA_HUD_ClearDrawList(luahuddrawlist_game);
LUAh_GameHUD(stplyr, luahuddrawlist_game); LUA_HookHUD(luahuddrawlist_game, HUD_HOOK(game));
} }
LUA_HUD_DrawList(luahuddrawlist_game); LUA_HUD_DrawList(luahuddrawlist_game);
} }

View file

@ -348,7 +348,7 @@ void Y_IntermissionDrawer(void)
if (renderisnewtic) if (renderisnewtic)
{ {
LUA_HUD_ClearDrawList(luahuddrawlist_intermission); LUA_HUD_ClearDrawList(luahuddrawlist_intermission);
LUAh_IntermissionHUD(luahuddrawlist_intermission); LUA_HookHUD(luahuddrawlist_intermission, HUD_HOOK(intermission));
} }
LUA_HUD_DrawList(luahuddrawlist_intermission); LUA_HUD_DrawList(luahuddrawlist_intermission);
@ -644,7 +644,7 @@ void Y_Ticker(void)
if (paused || P_AutoPause()) if (paused || P_AutoPause())
return; return;
LUAh_IntermissionThinker(); LUA_HOOK(IntermissionThinker);
intertic++; intertic++;
@ -1234,7 +1234,7 @@ void Y_VoteTicker(void)
if (paused || P_AutoPause() || !voteclient.loaded) if (paused || P_AutoPause() || !voteclient.loaded)
return; return;
LUAh_VoteThinker(); LUA_HOOK(VoteThinker);
votetic++; votetic++;
@ -1450,6 +1450,7 @@ void Y_VoteTicker(void)
void Y_StartVote(void) void Y_StartVote(void)
{ {
INT32 i = 0; INT32 i = 0;
boolean battlemode = ((votelevels[0][1] & ~VOTEMODIFIER_ENCORE) == GT_BATTLE); // todo gametyperules
votetic = -1; votetic = -1;
@ -1458,8 +1459,8 @@ void Y_StartVote(void)
I_Error("voteendtic is dirty"); I_Error("voteendtic is dirty");
#endif #endif
widebgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCW" : "INTERSCW"), PU_STATIC); widebgpatch = W_CachePatchName((battlemode ? "BATTLSCW" : "INTERSCW"), PU_STATIC);
bgpatch = W_CachePatchName(((gametype == GT_BATTLE) ? "BATTLSCR" : "INTERSCR"), PU_STATIC); bgpatch = W_CachePatchName((battlemode ? "BATTLSCR" : "INTERSCR"), PU_STATIC);
cursor = W_CachePatchName("M_CURSOR", PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC);
cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC); cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC);
cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC); cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC);
@ -1493,8 +1494,8 @@ void Y_StartVote(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
// set up the encore // set up the encore
levelinfo[i].encore = (votelevels[i][1] & 0x80); levelinfo[i].encore = (votelevels[i][1] & VOTEMODIFIER_ENCORE);
votelevels[i][1] &= ~0x80; votelevels[i][1] &= ~VOTEMODIFIER_ENCORE;
// set up the levelstring // set up the levelstring
if (mapheaderinfo[votelevels[i][0]]->levelflags & LF_NOZONE || !mapheaderinfo[votelevels[i][0]]->zonttl[0]) if (mapheaderinfo[votelevels[i][0]]->levelflags & LF_NOZONE || !mapheaderinfo[votelevels[i][0]]->zonttl[0])