From bc8a9b3b0f7d8af29951ef693de0f6575d2208e4 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Sun, 16 Mar 2025 23:58:58 +0100 Subject: [PATCH 01/17] Lua library for t_splash_t, t_footstep_t, t_overlay_t and terrain_t (getter, setter and num) --- src/CMakeLists.txt | 1 + src/lua_baselib.c | 4 + src/lua_libs.h | 6 + src/lua_mobjlib.c | 8 + src/lua_script.c | 1 + src/lua_terrainlib.c | 511 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 531 insertions(+) create mode 100644 src/lua_terrainlib.c diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index da820419e..59c0e81f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -118,6 +118,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 lua_thinkerlib.c lua_maplib.c lua_taglib.c + lua_terrainlib.c lua_polyobjlib.c lua_blockmaplib.c lua_hudlib.c diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 873056643..0e694e9f8 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -232,6 +232,10 @@ static const struct { {META_ACTIVATOR, "activator_t"}, {META_FOLLOWER, "follower_t"}, + {META_SPLASH, "t_splash_t"}, + {META_FOOTSTEP, "t_footstep_t"}, + {META_OVERLAY, "t_overlay_t"}, + {META_TERRAIN, "terrain_t"}, {NULL, NULL} }; diff --git a/src/lua_libs.h b/src/lua_libs.h index 73d7b4f6e..82704d728 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -104,6 +104,11 @@ extern lua_State *gL; #define META_FOLLOWER "FOLLOWER_T*" +#define META_SPLASH "T_SPLASH_T*" +#define META_FOOTSTEP "T_FOOTSTEP_T*" +#define META_OVERLAY "T_OVERLAY_T*" +#define META_TERRAIN "TERRAIN_T*" + boolean luaL_checkboolean(lua_State *L, int narg); int LUA_EnumLib(lua_State *L); @@ -123,6 +128,7 @@ int LUA_PolyObjLib(lua_State *L); int LUA_BlockmapLib(lua_State *L); int LUA_HudLib(lua_State *L); int LUA_FollowerLib(lua_State *L); +int LUA_TerrainLib(lua_State *L); #ifdef __cplusplus } // extern "C" diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 158909815..103d46c58 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -101,6 +101,7 @@ enum mobj_e { mobj_sprxoff, mobj_spryoff, mobj_sprzoff, + mobj_terrain, mobj_hitlag, mobj_waterskip, mobj_dispoffset, @@ -191,6 +192,7 @@ static const char *const mobj_opt[] = { "sprxoff", "spryoff", "sprzoff", + "terrain", "hitlag", "waterskip", "dispoffset", @@ -479,6 +481,9 @@ static int mobj_get(lua_State *L) case mobj_sprzoff: lua_pushfixed(L, mo->sprzoff); break; + case mobj_terrain: + LUA_PushUserdata(L, mo->terrain, META_TERRAIN); + break; case mobj_hitlag: lua_pushinteger(L, mo->hitlag); break; @@ -894,6 +899,9 @@ static int mobj_set(lua_State *L) case mobj_sprzoff: mo->sprzoff = luaL_checkfixed(L, 3); break; + case mobj_terrain: + mo->terrain = *((terrain_t **)luaL_checkudata(L, 3, META_TERRAIN)); + break; case mobj_hitlag: mo->hitlag = luaL_checkinteger(L, 3); break; diff --git a/src/lua_script.c b/src/lua_script.c index bfcf84bd4..08ca9a6aa 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -61,6 +61,7 @@ static lua_CFunction liblist[] = { LUA_BlockmapLib, // blockmap stuff LUA_HudLib, // HUD stuff LUA_FollowerLib, // follower_t, followers[] + LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t NULL }; diff --git a/src/lua_terrainlib.c b/src/lua_terrainlib.c new file mode 100644 index 000000000..54be0b985 --- /dev/null +++ b/src/lua_terrainlib.c @@ -0,0 +1,511 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2025 by Kart Krew. +// Copyright (C) 2020 by Sonic Team Junior. +// Copyright (C) 2016 by John "JTE" Muniz. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file lua_terrainlib.c +/// \brief terrain structure library for Lua scripting + +#include "doomdef.h" +#include "fastcmp.h" + +#include "lua_script.h" +#include "lua_libs.h" +#include "k_terrain.h" + +enum terrain { + terrain_valid = 0, + terrain_name, + terrain_hash, + terrain_splashid, + terrain_footstepid, + terrain_overlayid, + terrain_friction, + terrain_offroad, + terrain_damagetype, + terrain_trickpanel, + terrain_speedpad, + terrain_speedpadangle, + terrain_springstrength, + terrain_springstarcolor, + terrain_outrun, + terrain_floorclip, + terrain_flags +}; + +enum splash { + splash_valid = 0, + splash_name, + splash_hash, + splash_mobjtype, + splash_sfx, + splash_scale, + splash_color, + splash_pushH, + splash_pushV, + splash_spread, + splash_cone, + splash_numparticles +}; + +enum footstep { + footstep_valid = 0, + footstep_name, + footstep_hash, + footstep_mobjtype, + footstep_sfx, + footstep_scale, + footstep_color, + footstep_pushH, + footstep_pushV, + footstep_spread, + footstep_cone, + footstep_sfxfreq, + footstep_frequency, + footstep_requiredspeed +}; + +enum overlay { + overlay_valid = 0, + overlay_name, + overlay_hash, + overlay_states, + overlay_scale, + overlay_color, + overlay_speed +}; + +static const char *const terrain_opt[] = { + "valid", + "name", + "hash", + "splashid", + "footstepid", + "overlayid", + "friction", + "offroad", + "damagetype", + "trickpanel", + "speedpad", + "speedpadangle", + "springstrength", + "springstarcolor", + "outrun", + "floorclip", + "flags", + NULL +}; + +static const char *const splash_opt[] = { + "valid", + "name", + "hash", + "mobjtype", + "sfx", + "scale", + "color", + "pushh", + "pushv", + "spread", + "cone", + "numparticles", + NULL +}; + +static const char *const footstep_opt[] = { + "valid", + "name", + "hash", + "mobjtype", + "sfx", + "scale", + "color", + "pushh", + "pushv", + "spread", + "cone", + "sfxfreq", + "frequency", + "requiredspeed", + NULL +}; + +static const char *const overlay_opt[] = { + "valid", + "name", + "hash", + "states", + "scale", + "color", + "speed", + NULL +}; + +static int splash_get(lua_State *L) +{ + t_splash_t *splash = *((t_splash_t **)luaL_checkudata(L, 1, META_SPLASH)); + enum splash field = luaL_checkoption(L, 2, splash_opt[0], splash_opt); + + if (!splash) + { + switch (field) + { + case splash_valid: + lua_pushboolean(L, false); + return 1; + default: + return LUA_ErrInvalid(L, "t_splash_t"); + } + } + + switch (field) + { + case splash_valid: + lua_pushboolean(L, true); + break; + case splash_name: + lua_pushstring(L, splash->name); + break; + case splash_hash: + lua_pushnumber(L, splash->hash); + break; + case splash_mobjtype: + lua_pushnumber(L, splash->mobjType); + break; + case splash_sfx: + lua_pushnumber(L, splash->sfx); + break; + case splash_scale: + lua_pushfixed(L, splash->scale); + break; + case splash_color: + lua_pushnumber(L, splash->color); + break; + case splash_pushH: + lua_pushfixed(L, splash->pushH); + break; + case splash_pushV: + lua_pushfixed(L, splash->pushV); + break; + case splash_spread: + lua_pushfixed(L, splash->spread); + break; + case splash_cone: + lua_pushangle(L, splash->cone); + break; + case splash_numparticles: + lua_pushnumber(L, splash->numParticles); + break; + } + + return 1; +} + +static int splash_set(lua_State *L) +{ + return luaL_error(L, LUA_QL("t_splash_t") " struct cannot be edited by Lua."); +} + +static int splash_num(lua_State *L) +{ + t_splash_t *splash = *((t_splash_t **)luaL_checkudata(L, 1, META_SPLASH)); + + // This should never happen. + I_Assert(splash != NULL); + + lua_pushinteger(L, K_GetSplashHeapIndex(splash)); + return 1; +} + +static int footstep_get(lua_State *L) +{ + t_footstep_t *footstep = *((t_footstep_t **)luaL_checkudata(L, 1, META_FOOTSTEP)); + enum footstep field = luaL_checkoption(L, 2, footstep_opt[0], footstep_opt); + + if (!footstep) + { + switch (field) + { + case footstep_valid: + lua_pushboolean(L, false); + return 1; + default: + return LUA_ErrInvalid(L, "t_footstep_t"); + } + } + + switch (field) + { + case footstep_valid: + lua_pushboolean(L, true); + break; + case footstep_name: + lua_pushstring(L, footstep->name); + break; + case footstep_hash: + lua_pushnumber(L, footstep->hash); + break; + case footstep_mobjtype: + lua_pushnumber(L, footstep->mobjType); + break; + case footstep_sfx: + lua_pushnumber(L, footstep->sfx); + break; + case footstep_scale: + lua_pushfixed(L, footstep->scale); + break; + case footstep_color: + lua_pushnumber(L, footstep->color); + break; + case footstep_pushH: + lua_pushfixed(L, footstep->pushH); + break; + case footstep_pushV: + lua_pushfixed(L, footstep->pushV); + break; + case footstep_spread: + lua_pushfixed(L, footstep->spread); + break; + case footstep_cone: + lua_pushangle(L, footstep->cone); + break; + case footstep_sfxfreq: + lua_pushnumber(L, footstep->sfxFreq); + break; + case footstep_frequency: + lua_pushnumber(L, footstep->frequency); + break; + case footstep_requiredspeed: + lua_pushfixed(L, footstep->requiredSpeed); + break; + } + + return 1; +} + +static int footstep_set(lua_State *L) +{ + return luaL_error(L, LUA_QL("t_footstep_t") " struct cannot be edited by Lua."); +} + +static int footstep_num(lua_State *L) +{ + t_footstep_t *footstep = *((t_footstep_t **)luaL_checkudata(L, 1, META_FOOTSTEP)); + + // This should never happen. + I_Assert(footstep != NULL); + + lua_pushinteger(L, K_GetFootstepHeapIndex(footstep)); + return 1; +} + +static int overlay_get(lua_State *L) +{ + t_overlay_t *overlay = *((t_overlay_t **)luaL_checkudata(L, 1, META_OVERLAY)); + enum overlay field = luaL_checkoption(L, 2, overlay_opt[0], overlay_opt); + + if (!overlay) + { + switch (field) + { + case overlay_valid: + lua_pushboolean(L, false); + return 1; + default: + return LUA_ErrInvalid(L, "t_overlay_t"); + } + } + + switch (field) + { + case overlay_valid: + lua_pushboolean(L, true); + break; + case overlay_name: + lua_pushstring(L, overlay->name); + break; + case overlay_hash: + lua_pushnumber(L, overlay->hash); + break; + case overlay_states: + lua_createtable(L, TOV__MAX, 0); + for (size_t i = 0; i < TOV__MAX; i++) + { + lua_pushinteger(L, overlay->states[i]); + lua_rawseti(L, -2, 1 + i); + } + break; + case overlay_scale: + lua_pushboolean(L, overlay->scale); + break; + case overlay_color: + lua_pushnumber(L, overlay->color); + break; + case overlay_speed: + lua_pushfixed(L, overlay->speed); + break; + } + + return 1; +} + +static int overlay_set(lua_State *L) +{ + return luaL_error(L, LUA_QL("t_overlay_t") " struct cannot be edited by Lua."); +} + +static int overlay_num(lua_State *L) +{ + t_overlay_t *overlay = *((t_overlay_t **)luaL_checkudata(L, 1, META_OVERLAY)); + + // This should never happen. + I_Assert(overlay != NULL); + + lua_pushinteger(L, K_GetOverlayHeapIndex(overlay)); + return 1; +} + +static int terrain_get(lua_State *L) +{ + terrain_t *terrain = *((terrain_t **)luaL_checkudata(L, 1, META_TERRAIN)); + enum terrain field = luaL_checkoption(L, 2, terrain_opt[0], terrain_opt); + + if (!terrain) + { + switch (field) + { + case terrain_valid: + lua_pushboolean(L, false); + return 1; + default: + return LUA_ErrInvalid(L, "terrain_t"); + } + } + + switch (field) + { + case terrain_valid: + lua_pushboolean(L, true); + break; + case terrain_name: + lua_pushstring(L, terrain->name); + break; + case terrain_hash: + lua_pushnumber(L, terrain->hash); + break; + case terrain_splashid: + lua_pushnumber(L, terrain->splashID); + break; + case terrain_footstepid: + lua_pushnumber(L, terrain->footstepID); + break; + case terrain_overlayid: + lua_pushnumber(L, terrain->overlayID); + break; + case terrain_friction: + lua_pushfixed(L, terrain->friction); + break; + case terrain_offroad: + lua_pushfixed(L, terrain->offroad); + break; + case terrain_damagetype: + lua_pushnumber(L, terrain->damageType); + break; + case terrain_trickpanel: + lua_pushfixed(L, terrain->trickPanel); + break; + case terrain_speedpad: + lua_pushfixed(L, terrain->speedPad); + break; + case terrain_speedpadangle: + lua_pushangle(L, terrain->speedPadAngle); + break; + case terrain_springstrength: + lua_pushfixed(L, terrain->springStrength); + break; + case terrain_springstarcolor: + lua_pushnumber(L, terrain->springStarColor); + break; + case terrain_outrun: + lua_pushfixed(L, terrain->outrun); + break; + case terrain_floorclip: + lua_pushfixed(L, terrain->floorClip); + break; + case terrain_flags: + lua_pushnumber(L, terrain->flags); + break; + } + + return 1; +} + +static int terrain_set(lua_State *L) +{ + return luaL_error(L, LUA_QL("terrain_t") " struct cannot be edited by Lua."); +} + +static int terrain_num(lua_State *L) +{ + terrain_t *terrain = *((terrain_t **)luaL_checkudata(L, 1, META_TERRAIN)); + + // This should never happen. + I_Assert(terrain != NULL); + + lua_pushinteger(L, K_GetTerrainHeapIndex(terrain)); + return 1; +} + +int LUA_TerrainLib(lua_State *L) +{ + luaL_newmetatable(L, META_SPLASH); + lua_pushcfunction(L, splash_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, splash_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, splash_num); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + + luaL_newmetatable(L, META_FOOTSTEP); + lua_pushcfunction(L, footstep_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, footstep_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, footstep_num); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + + luaL_newmetatable(L, META_OVERLAY); + lua_pushcfunction(L, overlay_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, overlay_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, overlay_num); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + + luaL_newmetatable(L, META_TERRAIN); + lua_pushcfunction(L, terrain_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, terrain_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, terrain_num); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + + return 0; +} \ No newline at end of file -- GitLab From ad8d035bf9efed61a3d3a7c3f1e1219be1aeed52 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Mon, 17 Mar 2025 00:23:36 +0100 Subject: [PATCH 02/17] Expose outrun and stairjank player properties to lua (get, set) --- src/lua_playerlib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index ee56da06f..f8bb9859a 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -282,6 +282,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->ringboxaward); else if (fastcmp(field,"itemflags")) lua_pushinteger(L, plr->itemflags); + else if (fastcmp(field,"outrun")) + lua_pushinteger(L, plr->outrun); else if (fastcmp(field,"drift")) lua_pushinteger(L, plr->drift); else if (fastcmp(field,"driftcharge")) @@ -682,6 +684,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->griefStrikes); else if (fastcmp(field,"griefwarned")) lua_pushinteger(L, plr->griefWarned); + else if (fastcmp(field,"stairjank")) + lua_pushinteger(L, plr->stairjank); else if (fastcmp(field,"splitscreenindex")) lua_pushinteger(L, plr->splitscreenindex); else if (fastcmp(field,"whip")) @@ -848,6 +852,8 @@ static int player_set(lua_State *L) plr->ringboxaward = luaL_checkinteger(L, 3); else if (fastcmp(field,"itemflags")) plr->itemflags = luaL_checkinteger(L, 3); + else if (fastcmp(field,"outrun")) + plr->outrun = luaL_checkinteger(L, 3); else if (fastcmp(field,"drift")) plr->drift = luaL_checkinteger(L, 3); else if (fastcmp(field,"driftcharge")) @@ -1241,6 +1247,8 @@ static int player_set(lua_State *L) plr->griefStrikes = (UINT8)luaL_checkinteger(L, 3); else if (fastcmp(field,"griefwarned")) plr->griefWarned = luaL_checkinteger(L, 3); + else if (fastcmp(field,"stairjank")) + plr->stairjank = luaL_checkinteger(L, 3); else if (fastcmp(field,"splitscreenindex")) return NOSET; else if (fastcmp(field,"whip")) -- GitLab From 08d213de77b064022c34aa907aaf8413b95122b5 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Mon, 17 Mar 2025 17:17:36 +0100 Subject: [PATCH 03/17] Expose terrains[], terrains.iterate and #terrains to Lua --- src/lua_terrainlib.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/lua_terrainlib.c b/src/lua_terrainlib.c index 54be0b985..6abd46e38 100644 --- a/src/lua_terrainlib.c +++ b/src/lua_terrainlib.c @@ -461,6 +461,75 @@ static int terrain_num(lua_State *L) return 1; } +static int lib_iterateTerrains(lua_State *L) +{ + size_t i; + + if (lua_gettop(L) < 2) + { + lua_pushcfunction(L, lib_iterateTerrains); + return 1; + } + + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + + if (!lua_isnil(L, 1)) + i = K_GetTerrainHeapIndex(*(terrain_t **)luaL_checkudata(L, 1, META_TERRAIN)) + 1; + else + i = 0; + + // terrains are always valid, only added, never removed + if (i < K_GetNumTerrainDefs()) + { + LUA_PushUserdata(L, K_GetTerrainByIndex(i), META_TERRAIN); + return 1; + } + + return 0; +} + +static int lib_getTerrain(lua_State *L) +{ + const char *field; + size_t i; + + // find terrain by number + if (lua_type(L, 2) == LUA_TNUMBER) + { + i = luaL_checkinteger(L, 2); + if (i >= K_GetNumTerrainDefs()) + return luaL_error(L, "terrains[] index %d out of range (0 - %d)", i, K_GetNumTerrainDefs()-1); + LUA_PushUserdata(L, K_GetTerrainByIndex(i), META_TERRAIN); + return 1; + } + + field = luaL_checkstring(L, 2); + + // special function iterate + if (fastcmp(field,"iterate")) + { + lua_pushcfunction(L, lib_iterateTerrains); + return 1; + } + + // find terrain by name + terrain_t *byname = K_GetTerrainByName(field); + if (byname != NULL) + { + LUA_PushUserdata(L, byname, META_TERRAIN); + return 1; + } + + return 0; +} + +static int lib_numTerrains(lua_State *L) +{ + lua_pushinteger(L, K_GetNumTerrainDefs()); + return 1; +} + int LUA_TerrainLib(lua_State *L) { luaL_newmetatable(L, META_SPLASH); @@ -506,6 +575,16 @@ int LUA_TerrainLib(lua_State *L) lua_pushcfunction(L, terrain_num); lua_setfield(L, -2, "__len"); lua_pop(L,1); + + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getTerrain); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numTerrains); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "terrains"); return 0; } \ No newline at end of file -- GitLab From b2f17afbb24c09510637ee7e6aa570d4144e68dd Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Mon, 17 Mar 2025 17:32:04 +0100 Subject: [PATCH 04/17] Expose overlays[], overlays.iterate and #overlays to Lua --- src/lua_terrainlib.c | 83 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/lua_terrainlib.c b/src/lua_terrainlib.c index 6abd46e38..7588992d8 100644 --- a/src/lua_terrainlib.c +++ b/src/lua_terrainlib.c @@ -370,6 +370,79 @@ static int overlay_num(lua_State *L) return 1; } +static int lib_iterateOverlays(lua_State *L) +{ + size_t i; + + if (lua_gettop(L) < 2) + { + lua_pushcfunction(L, lib_iterateOverlays); + return 1; + } + + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + + if (!lua_isnil(L, 1)) + i = K_GetOverlayHeapIndex(*(t_overlay_t **)luaL_checkudata(L, 1, META_OVERLAY)) + 1; + else + i = 0; + + // overlays are always valid, only added, never removed + if (i < K_GetNumOverlayDefs()) + { + LUA_PushUserdata(L, K_GetOverlayByIndex(i), META_OVERLAY); + return 1; + } + + return 0; +} + +static int lib_getOverlay(lua_State *L) +{ + const char *field; + size_t i; + + // find overlay by number + if (lua_type(L, 2) == LUA_TNUMBER) + { + // Making a special condition for this as the game contains no overlays by default. + if (K_GetNumOverlayDefs() == 0) + return luaL_error(L, "no overlays available in overlays[]"); + + i = luaL_checkinteger(L, 2); + if (i >= K_GetNumOverlayDefs()) + return luaL_error(L, "overlays[] index %d out of range (0 - %d)", i, K_GetNumOverlayDefs()-1); + LUA_PushUserdata(L, K_GetOverlayByIndex(i), META_OVERLAY); + return 1; + } + + field = luaL_checkstring(L, 2); + + // special function iterate + if (fastcmp(field,"iterate")) + { + lua_pushcfunction(L, lib_iterateOverlays); + return 1; + } + + // find overlay by name + t_overlay_t *byname = K_GetOverlayByName(field); + if (byname != NULL) + { + LUA_PushUserdata(L, byname, META_OVERLAY); + return 1; + } + + return 0; +} + +static int lib_numOverlays(lua_State *L) +{ + lua_pushinteger(L, K_GetNumOverlayDefs()); + return 1; +} + static int terrain_get(lua_State *L) { terrain_t *terrain = *((terrain_t **)luaL_checkudata(L, 1, META_TERRAIN)); @@ -564,6 +637,16 @@ int LUA_TerrainLib(lua_State *L) lua_pushcfunction(L, overlay_num); lua_setfield(L, -2, "__len"); lua_pop(L,1); + + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getOverlay); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numOverlays); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "overlays"); luaL_newmetatable(L, META_TERRAIN); lua_pushcfunction(L, terrain_get); -- GitLab From 012dbd0c0c2cfe9b0feacb7dbb328ce94ff921e8 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Mon, 17 Mar 2025 19:38:57 +0100 Subject: [PATCH 05/17] Expose footsteps[], footsteps.iterate and #footsteps to Lua --- src/lua_terrainlib.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/lua_terrainlib.c b/src/lua_terrainlib.c index 7588992d8..25aaaf706 100644 --- a/src/lua_terrainlib.c +++ b/src/lua_terrainlib.c @@ -304,6 +304,75 @@ static int footstep_num(lua_State *L) return 1; } +static int lib_iterateFootsteps(lua_State *L) +{ + size_t i; + + if (lua_gettop(L) < 2) + { + lua_pushcfunction(L, lib_iterateFootsteps); + return 1; + } + + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + + if (!lua_isnil(L, 1)) + i = K_GetFootstepHeapIndex(*(t_footstep_t **)luaL_checkudata(L, 1, META_FOOTSTEP)) + 1; + else + i = 0; + + // footsteps are always valid, only added, never removed + if (i < K_GetNumFootstepDefs()) + { + LUA_PushUserdata(L, K_GetFootstepByIndex(i), META_FOOTSTEP); + return 1; + } + + return 0; +} + +static int lib_getFootstep(lua_State *L) +{ + const char *field; + size_t i; + + // find footstep by number + if (lua_type(L, 2) == LUA_TNUMBER) + { + i = luaL_checkinteger(L, 2); + if (i >= K_GetNumFootstepDefs()) + return luaL_error(L, "footsteps[] index %d out of range (0 - %d)", i, K_GetNumFootstepDefs()-1); + LUA_PushUserdata(L, K_GetFootstepByIndex(i), META_FOOTSTEP); + return 1; + } + + field = luaL_checkstring(L, 2); + + // special function iterate + if (fastcmp(field,"iterate")) + { + lua_pushcfunction(L, lib_iterateFootsteps); + return 1; + } + + // find footstep by name + t_footstep_t *byname = K_GetFootstepByName(field); + if (byname != NULL) + { + LUA_PushUserdata(L, byname, META_FOOTSTEP); + return 1; + } + + return 0; +} + +static int lib_numFootsteps(lua_State *L) +{ + lua_pushinteger(L, K_GetNumFootstepDefs()); + return 1; +} + static int overlay_get(lua_State *L) { t_overlay_t *overlay = *((t_overlay_t **)luaL_checkudata(L, 1, META_OVERLAY)); @@ -626,6 +695,16 @@ int LUA_TerrainLib(lua_State *L) lua_pushcfunction(L, footstep_num); lua_setfield(L, -2, "__len"); lua_pop(L,1); + + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getFootstep); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numFootsteps); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "footsteps"); luaL_newmetatable(L, META_OVERLAY); lua_pushcfunction(L, overlay_get); -- GitLab From 39f3eb039aeaa59615a037e2da107dc6702bb7c6 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Mon, 17 Mar 2025 20:49:04 +0100 Subject: [PATCH 06/17] Expose splashes[], splashes.iterate and #splashes to Lua --- src/lua_terrainlib.c | 79 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/lua_terrainlib.c b/src/lua_terrainlib.c index 25aaaf706..3ffe504dc 100644 --- a/src/lua_terrainlib.c +++ b/src/lua_terrainlib.c @@ -222,6 +222,75 @@ static int splash_num(lua_State *L) return 1; } +static int lib_iterateSplashes(lua_State *L) +{ + size_t i; + + if (lua_gettop(L) < 2) + { + lua_pushcfunction(L, lib_iterateSplashes); + return 1; + } + + lua_settop(L, 2); + lua_remove(L, 1); // state is unused. + + if (!lua_isnil(L, 1)) + i = K_GetSplashHeapIndex(*(t_splash_t **)luaL_checkudata(L, 1, META_SPLASH)) + 1; + else + i = 0; + + // terrains are always valid, only added, never removed + if (i < K_GetNumSplashDefs()) + { + LUA_PushUserdata(L, K_GetSplashByIndex(i), META_SPLASH); + return 1; + } + + return 0; +} + +static int lib_getSplash(lua_State *L) +{ + const char *field; + size_t i; + + // find terrain by number + if (lua_type(L, 2) == LUA_TNUMBER) + { + i = luaL_checkinteger(L, 2); + if (i >= K_GetNumSplashDefs()) + return luaL_error(L, "splashes[] index %d out of range (0 - %d)", i, K_GetNumSplashDefs()-1); + LUA_PushUserdata(L, K_GetSplashByIndex(i), META_SPLASH); + return 1; + } + + field = luaL_checkstring(L, 2); + + // special function iterate + if (fastcmp(field,"iterate")) + { + lua_pushcfunction(L, lib_iterateSplashes); + return 1; + } + + // find terrain by name + t_splash_t *byname = K_GetSplashByName(field); + if (byname != NULL) + { + LUA_PushUserdata(L, byname, META_SPLASH); + return 1; + } + + return 0; +} + +static int lib_numSplashes(lua_State *L) +{ + lua_pushinteger(L, K_GetNumSplashDefs()); + return 1; +} + static int footstep_get(lua_State *L) { t_footstep_t *footstep = *((t_footstep_t **)luaL_checkudata(L, 1, META_FOOTSTEP)); @@ -685,6 +754,16 @@ int LUA_TerrainLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + lua_newuserdata(L, 0); + lua_createtable(L, 0, 2); + lua_pushcfunction(L, lib_getSplash); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, lib_numSplashes); + lua_setfield(L, -2, "__len"); + lua_setmetatable(L, -2); + lua_setglobal(L, "splashes"); + luaL_newmetatable(L, META_FOOTSTEP); lua_pushcfunction(L, footstep_get); lua_setfield(L, -2, "__index"); -- GitLab From ab9d44bfa6ac4588f1d2e48b683d6bb4453cf961 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 12:57:07 +0100 Subject: [PATCH 07/17] Expose K_GetDefaultTerrain to Lua --- src/lua_baselib.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 0e694e9f8..a97bda0ee 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -40,6 +40,7 @@ #include "k_powerup.h" #include "k_hitlag.h" #include "music.h" // music functions necessary for lua integration +#include "k_terrain.h" #include "lua_script.h" #include "lua_libs.h" @@ -4078,6 +4079,12 @@ static int lib_startTitlecardCecho(lua_State *L) return 1; } +static int lib_kGetDefaultTerrain(lua_State *L) +{ + LUA_PushUserdata(L, K_GetDefaultTerrain(), META_TERRAIN); + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4369,6 +4376,9 @@ static luaL_Reg lib[] = { {"Music_UnPauseAll", lib_mMusicUnPauseAll}, {"Music_Loop", lib_mMusicLoop}, {"Music_BatchExempt", lib_mMusicBatchExempt}, + + // k_terrain + {"K_GetDefaultTerrain", lib_kGetDefaultTerrain}, {NULL, NULL} }; -- GitLab From f70176d3239b9fb7b34f16ded50e657e8e18fb91 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:03:50 +0100 Subject: [PATCH 08/17] Expose K_GetTerrainForTextureName to Lua --- src/lua_baselib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index a97bda0ee..617dfc660 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4085,6 +4085,13 @@ static int lib_kGetDefaultTerrain(lua_State *L) return 1; } +static int lib_kGetTerrainForTextureName(lua_State *L) +{ + const char *str = luaL_checkstring(L, 1); + LUA_PushUserdata(L, K_GetTerrainForTextureName(str), META_TERRAIN); + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4379,6 +4386,7 @@ static luaL_Reg lib[] = { // k_terrain {"K_GetDefaultTerrain", lib_kGetDefaultTerrain}, + {"K_GetTerrainForTextureName", lib_kGetTerrainForTextureName}, {NULL, NULL} }; -- GitLab From e16d7f8046a60fb90fde6e598c8be1b4e3ee6fbd Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:14:54 +0100 Subject: [PATCH 09/17] Expose K_GetTerrainForTextureNum to Lua --- src/lua_baselib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 617dfc660..e8b01a94c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4092,6 +4092,13 @@ static int lib_kGetTerrainForTextureName(lua_State *L) return 1; } +static int lib_kGetTerrainForTextureNum(lua_State *L) +{ + INT32 id = luaL_checkinteger(L, 1); + LUA_PushUserdata(L, K_GetTerrainForTextureNum(id), META_TERRAIN); + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4387,6 +4394,7 @@ static luaL_Reg lib[] = { // k_terrain {"K_GetDefaultTerrain", lib_kGetDefaultTerrain}, {"K_GetTerrainForTextureName", lib_kGetTerrainForTextureName}, + {"K_GetTerrainForTextureNum", lib_kGetTerrainForTextureNum}, {NULL, NULL} }; -- GitLab From d33f8f9d7bf38db7c9c5a377d4abbd2b915b793c Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 14:46:34 +0100 Subject: [PATCH 10/17] Expose K_ProcessTerrainEffect to Lua --- src/lua_baselib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e8b01a94c..2a703f0b4 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4099,6 +4099,20 @@ static int lib_kGetTerrainForTextureNum(lua_State *L) return 1; } +static int lib_kProcessTerrainEffect(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + + NOHUD + INLEVEL + + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + + K_ProcessTerrainEffect(mo); + return 0; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4395,6 +4409,7 @@ static luaL_Reg lib[] = { {"K_GetDefaultTerrain", lib_kGetDefaultTerrain}, {"K_GetTerrainForTextureName", lib_kGetTerrainForTextureName}, {"K_GetTerrainForTextureNum", lib_kGetTerrainForTextureNum}, + {"K_ProcessTerrainEffect", lib_kProcessTerrainEffect}, {NULL, NULL} }; -- GitLab From a229e716e1e611eb4b2977bc41e353d2416bbadf Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:37:43 +0100 Subject: [PATCH 11/17] Expose K_SetDefaultFriction to Lua --- src/lua_baselib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2a703f0b4..0c173a7f0 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4113,6 +4113,20 @@ static int lib_kProcessTerrainEffect(lua_State *L) return 0; } +static int lib_kSetDefaultFriction(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + + NOHUD + INLEVEL + + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + + K_SetDefaultFriction(mo); + return 0; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4410,6 +4424,7 @@ static luaL_Reg lib[] = { {"K_GetTerrainForTextureName", lib_kGetTerrainForTextureName}, {"K_GetTerrainForTextureNum", lib_kGetTerrainForTextureNum}, {"K_ProcessTerrainEffect", lib_kProcessTerrainEffect}, + {"K_SetDefaultFriction", lib_kSetDefaultFriction}, {NULL, NULL} }; -- GitLab From e5bc0ee3b347386e7b865dfe437a3f8099e67498 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:41:10 +0100 Subject: [PATCH 12/17] Expose K_SpawnSplashForMobj to Lua --- src/lua_baselib.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 0c173a7f0..7b4305c49 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4127,6 +4127,21 @@ static int lib_kSetDefaultFriction(lua_State *L) return 0; } +static int lib_kSpawnSplashForMobj(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + fixed_t impact = luaL_optinteger(L, 2, FRACUNIT); + + NOHUD + INLEVEL + + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + + K_SpawnSplashForMobj(mo, impact); + return 0; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4425,6 +4440,7 @@ static luaL_Reg lib[] = { {"K_GetTerrainForTextureNum", lib_kGetTerrainForTextureNum}, {"K_ProcessTerrainEffect", lib_kProcessTerrainEffect}, {"K_SetDefaultFriction", lib_kSetDefaultFriction}, + {"K_SpawnSplashForMobj", lib_kSpawnSplashForMobj}, {NULL, NULL} }; -- GitLab From a9fa415e9e736f8187f4c74e662329019cdeb335 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:44:21 +0100 Subject: [PATCH 13/17] Expose K_HandleFootstepParticles to Lua --- src/lua_baselib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7b4305c49..d876bc906 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4142,6 +4142,20 @@ static int lib_kSpawnSplashForMobj(lua_State *L) return 0; } +static int lib_kHandleFootstepParticles(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + + NOHUD + INLEVEL + + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + + K_HandleFootstepParticles(mo); + return 0; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4441,6 +4455,7 @@ static luaL_Reg lib[] = { {"K_ProcessTerrainEffect", lib_kProcessTerrainEffect}, {"K_SetDefaultFriction", lib_kSetDefaultFriction}, {"K_SpawnSplashForMobj", lib_kSpawnSplashForMobj}, + {"K_HandleFootstepParticles", lib_kHandleFootstepParticles}, {NULL, NULL} }; -- GitLab From e5678964d4bcd82f9f87ffb222b8ca7690ee6e02 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:45:49 +0100 Subject: [PATCH 14/17] Expose K_UpdateTerrainOverlay to Lua --- src/lua_baselib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index d876bc906..49d89967f 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4156,6 +4156,20 @@ static int lib_kHandleFootstepParticles(lua_State *L) return 0; } +static int lib_kUpdateTerrainOverlay(lua_State *L) +{ + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + + NOHUD + INLEVEL + + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + + K_UpdateTerrainOverlay(mo); + return 0; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4456,6 +4470,7 @@ static luaL_Reg lib[] = { {"K_SetDefaultFriction", lib_kSetDefaultFriction}, {"K_SpawnSplashForMobj", lib_kSpawnSplashForMobj}, {"K_HandleFootstepParticles", lib_kHandleFootstepParticles}, + {"K_UpdateTerrainOverlay", lib_kUpdateTerrainOverlay}, {NULL, NULL} }; -- GitLab From 473b5f812c95a73c1b4b49205b7180cfadcc97f0 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 13:50:10 +0100 Subject: [PATCH 15/17] Expose K_TerrainHasAffect to Lua --- src/lua_baselib.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 49d89967f..86a328012 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4170,6 +4170,21 @@ static int lib_kUpdateTerrainOverlay(lua_State *L) return 0; } +static int lib_kTerrainHasAffect(lua_State *L) +{ + terrain_t *terrain = *((terrain_t **)luaL_checkudata(L, 1, META_TERRAIN)); + boolean badonly = lua_optboolean(L, 2); + + NOHUD + INLEVEL + + if (!terrain) + return LUA_ErrInvalid(L, "terrain_t"); + + lua_pushboolean(L, K_TerrainHasAffect(terrain, badonly)); + return 1; +} + static luaL_Reg lib[] = { {"print", lib_print}, {"chatprint", lib_chatprint}, @@ -4471,6 +4486,7 @@ static luaL_Reg lib[] = { {"K_SpawnSplashForMobj", lib_kSpawnSplashForMobj}, {"K_HandleFootstepParticles", lib_kHandleFootstepParticles}, {"K_UpdateTerrainOverlay", lib_kUpdateTerrainOverlay}, + {"K_TerrainHasAffect", lib_kTerrainHasAffect}, {NULL, NULL} }; -- GitLab From 891d1f2188fff9c151d6293dbed59010791e48f2 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Wed, 19 Mar 2025 15:11:42 +0100 Subject: [PATCH 16/17] Expose t_overlay_action_t enum and terrain_flags_t flags to Lua --- src/deh_tables.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index 6a5255e8e..dcb18a33e 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -5206,7 +5206,20 @@ struct int_const_s const INT_CONST[] = { {"TN_NIGHTCOREABLE",TN_NIGHTCOREABLE}, {"TN_CHANGEPITCH",TN_CHANGEPITCH}, {"TN_LOOPING",TN_LOOPING}, - + + // t_overlay_action_t + {"TOV_UNDEFINED",TOV_UNDEFINED}, + {"TOV_STILL",TOV_STILL}, + {"TOV_MOVING",TOV_MOVING}, + {"TOV__MAX",TOV__MAX}, + + // terrain_flags_t + {"TRF_LIQUID",TRF_LIQUID}, + {"TRF_SNEAKERPANEL",TRF_SNEAKERPANEL}, + {"TRF_STAIRJANK",TRF_STAIRJANK}, + {"TRF_TRIPWIRE",TRF_TRIPWIRE}, + {"TRF_REMAP",TRF_REMAP}, + {NULL,0} }; -- GitLab From 929ff7d28f27ef025921ef4d0c78471087835567 Mon Sep 17 00:00:00 2001 From: JugadorXEI <eugeniom9@gmail.com> Date: Thu, 1 May 2025 01:27:54 +0200 Subject: [PATCH 17/17] Check gameplay-altering flags only when onlybad is false in K_TerrainHasAffect --- src/k_terrain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index bc41bbc31..fa6f9742d 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -1630,7 +1630,7 @@ boolean K_TerrainHasAffect(terrain_t *terrain, boolean badonly) || terrain->trickPanel != 0 || terrain->speedPad != 0 || terrain->springStrength != 0 - || terrain->flags != 0); + || (terrain->flags & (TRF_LIQUID|TRF_SNEAKERPANEL|TRF_TRIPWIRE))); } /*-------------------------------------------------- -- GitLab