Add JingleStatus hook for carrying custom jingle tunes

The extra argument is the music name, as passed into
P_PlayJingleMusic(player, musname), to run the hook for, optional.
Arguments are (player, musname) - the latter to allow global hooks
that still differentiate between different tracks.
This commit is contained in:
fickleheart 2020-02-23 17:20:44 -06:00
parent c5f3868819
commit f2c968dea8
5 changed files with 57 additions and 5 deletions

View File

@ -58,6 +58,7 @@ enum hook {
hook_ViewpointSwitch, hook_ViewpointSwitch,
hook_SeenPlayer, hook_SeenPlayer,
hook_PlayerThink, hook_PlayerThink,
hook_JingleStatus,
hook_MAX // last hook hook_MAX // last hook
}; };
@ -110,5 +111,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
#endif #endif
#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
boolean LUAh_JingleStatus(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
#endif #endif

View File

@ -69,6 +69,7 @@ const char *const hookNames[hook_MAX+1] = {
"ViewpointSwitch", "ViewpointSwitch",
"SeenPlayer", "SeenPlayer",
"PlayerThink", "PlayerThink",
"JingleStatus",
NULL NULL
}; };
@ -80,7 +81,7 @@ struct hook_s
UINT16 id; UINT16 id;
union { union {
mobjtype_t mt; mobjtype_t mt;
char *skinname; char *skinname; // also used as musname for JingleStatus... I'm lazy
char *funcname; char *funcname;
} s; } s;
boolean error; boolean error;
@ -148,6 +149,7 @@ static int lib_addHook(lua_State *L)
luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t"); luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t");
break; break;
case hook_BotAI: case hook_BotAI:
case hook_JingleStatus:
hook.s.skinname = NULL; hook.s.skinname = NULL;
if (lua_isstring(L, 2)) if (lua_isstring(L, 2))
{ // lowercase copy { // lowercase copy
@ -1632,4 +1634,49 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
} }
#endif // SEENAMES #endif // SEENAMES
boolean LUAh_JingleStatus(player_t *player, const char *musname)
{
hook_p hookp;
boolean keepplaying = false;
if (!gL || !(hooksAvailable[hook_JingleStatus/8] & (1<<(hook_JingleStatus%8))))
return true;
lua_settop(gL, 0);
hud_running = true; // local hook
for (hookp = roothook; hookp; hookp = hookp->next)
{
if (hookp->type == hook_JingleStatus) CONS_Printf("jingle status hook for %s vs %s\n", hookp->s.skinname, musname);
if (hookp->type != hook_JingleStatus
|| (hookp->s.skinname && strcmp(hookp->s.skinname, musname)))
continue;
if (lua_gettop(gL) == 0)
{
LUA_PushUserdata(gL, player, META_PLAYER);
lua_pushstring(gL, musname);
}
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -3);
lua_pushvalue(gL, -3);
if (lua_pcall(gL, 2, 1, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
continue;
}
if (!lua_isnil(gL, -1) && lua_toboolean(gL, -1))
keepplaying = true; // Keep playing this boolean
lua_pop(gL, 1);
}
lua_settop(gL, 0);
hud_running = false;
return keepplaying;
}
#endif #endif

View File

@ -250,7 +250,7 @@ extern jingle_t jingleinfo[NUMJINGLES];
#define JINGLEPOSTFADE 1000 #define JINGLEPOSTFADE 1000
void P_PlayJingle(player_t *player, jingletype_t jingletype); void P_PlayJingle(player_t *player, jingletype_t jingletype);
boolean P_EvaluateMusicStatus(UINT16 status); boolean P_EvaluateMusicStatus(UINT16 status, const char *musname);
void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status); void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status);
// //

View File

@ -1541,7 +1541,7 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
S_ChangeMusicInternal(musname, looping); S_ChangeMusicInternal(musname, looping);
} }
boolean P_EvaluateMusicStatus(UINT16 status) boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
{ {
// \todo lua hook // \todo lua hook
int i; int i;
@ -1598,8 +1598,11 @@ boolean P_EvaluateMusicStatus(UINT16 status)
result = (players[i].nightstime && players[i].nightstime <= 10*TICRATE); result = (players[i].nightstime && players[i].nightstime <= 10*TICRATE);
break; break;
case JT_NONE: // Null state
case JT_OTHER: // Other state case JT_OTHER: // Other state
result = LUAh_JingleStatus(&players[i], musname);
break;
case JT_NONE: // Null state
case JT_MASTER: // Main level music case JT_MASTER: // Main level music
default: default:
result = true; result = true;

View File

@ -2045,7 +2045,7 @@ static musicstack_t *S_GetMusicStackEntry(UINT16 status, boolean fromfirst, INT1
if (!status || mst->status == status) if (!status || mst->status == status)
{ {
if (P_EvaluateMusicStatus(mst->status)) if (P_EvaluateMusicStatus(mst->status, mst->musname))
{ {
if (!S_MusicExists(mst->musname, !midi_disabled, !digital_disabled)) // paranoia if (!S_MusicExists(mst->musname, !midi_disabled, !digital_disabled)) // paranoia
S_RemoveMusicStackEntry(mst); // then continue S_RemoveMusicStackEntry(mst); // then continue