diff --git a/src/d_player.h b/src/d_player.h index a70fd1777..faf6824e1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -352,6 +352,46 @@ typedef enum NUMKARTSTUFF } kartstufftype_t; +// Player powers. (don't edit this comment) +// What are you gonna do about it :^) - Nep +typedef enum +{ + pw_invulnerability, + pw_sneakers, + pw_flashing, + pw_shield, + pw_tailsfly, // tails flying + pw_underwater, // underwater timer + pw_spacetime, // In space, no one can hear you spin! + pw_extralife, // Extra Life timer + + pw_super, // Are you super? + pw_gravityboots, // gravity boots + + // Weapon ammunition + pw_infinityring, + pw_automaticring, + pw_bouncering, + pw_scatterring, + pw_grenadering, + pw_explosionring, + pw_railring, + + // Power Stones + pw_emeralds, // stored like global 'emeralds' variable + + // NiGHTS powerups + pw_nights_superloop, + pw_nights_helper, + pw_nights_linkfreeze, + + //for linedef exec 427 + pw_nocontrol, + pw_ingoop, // In goop + + NUMPOWERS +} powertype_t; + // QUICKLY GET RING TOTAL, INCLUDING RINGS CURRENTLY IN THE PICKUP ANIMATION #define RINGTOTAL(p) (p->rings + p->pickuprings) @@ -492,6 +532,9 @@ struct player_t UINT8 carry; UINT16 dye; + // Power ups. invinc and invis are tic counters. + UINT16 powers[NUMPOWERS]; + // SRB2kart stuff INT32 kartstuff[NUMKARTSTUFF]; INT32 karthud[NUMKARTHUD]; diff --git a/src/deh_lua.c b/src/deh_lua.c index 082a8e459..5ca784e61 100644 --- a/src/deh_lua.c +++ b/src/deh_lua.c @@ -11,6 +11,7 @@ /// \brief Lua SOC library #include "deh_lua.h" +#include "deh_tables.h" // freeslot takes a name (string only!) // and allocates it to the appropriate free slot. @@ -513,6 +514,24 @@ static int ScanConstants(lua_State *L, boolean mathlib, const char *word) if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word); return 0; } + else if (!mathlib && fastncmp("pw_",word,3)) { + p = word+3; + for (i = 0; i < NUMPOWERS; i++) + if (fasticmp(p, POWERS_LIST[i])) { + lua_pushinteger(L, i); + return 1; + } + return 0; + } + else if (mathlib && fastncmp("PW_",word,3)) { // SOCs are ALL CAPS! + p = word+3; + for (i = 0; i < NUMPOWERS; i++) + if (fastcmp(p, POWERS_LIST[i])) { + lua_pushinteger(L, i); + return 1; + } + return luaL_error(L, "powers '%s' could not be found.\n", word); + } else if (!mathlib && fastncmp("k_",word,2)) { p = word+2; for (i = 0; i < NUMKARTSTUFF; i++) diff --git a/src/deh_tables.c b/src/deh_tables.c index 0db778aa7..d23751f32 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -6182,6 +6182,41 @@ const char *COLOR_ENUMS[] = { "CSUPER5" // SKINCOLOR_CSUPER5, }; +const char *const POWERS_LIST[] = { + "INVULNERABILITY", + "SNEAKERS", + "FLASHING", + "SHIELD", + "TAILSFLY", // tails flying + "UNDERWATER", // underwater timer + "SPACETIME", // In space, no one can hear you spin! + "EXTRALIFE", // Extra Life timer + + "SUPER", // Are you super? + "GRAVITYBOOTS", // gravity boots + + // Weapon ammunition + "INFINITYRING", + "AUTOMATICRING", + "BOUNCERING", + "SCATTERRING", + "GRENADERING", + "EXPLOSIONRING", + "RAILRING", + + // Power Stones + "EMERALDS", // stored like global 'emeralds' variable + + // NiGHTS powerups + "NIGHTS_SUPERLOOP", + "NIGHTS_HELPER", + "NIGHTS_LINKFREEZE", + + //for linedef exec 427 + "NOCONTROL", + "INGOOP" // In goop +}; + const char *const KARTSTUFF_LIST[] = { "POSITION", "OLDPOSITION", diff --git a/src/lua_libs.h b/src/lua_libs.h index 070f812de..90cd514a4 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -45,6 +45,7 @@ extern lua_State *gL; #define META_PLAYER "PLAYER_T*" #define META_TICCMD "TICCMD_T*" #define META_SKIN "SKIN_T*" +#define META_POWERS "PLAYER_T*POWERS" #define META_KARTHUD "PLAYER_T*KARTHUD" #define META_KARTSTUFF "PLAYER_T*KARTSTUFF" #define META_RESPAWN "PLAYER_T*RESPAWN" diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 1d692704d..27dbdb2b9 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -216,6 +216,8 @@ static int player_get(lua_State *L) lua_pushangle(L, plr->drawangle); else if (fastcmp(field,"frameangle")) lua_pushangle(L, plr->drawangle); + else if (fastcmp(field,"powers")) + LUA_PushUserdata(L, plr->powers, META_POWERS); else if (fastcmp(field,"kartstuff")) LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF); else if (fastcmp(field,"karthud")) @@ -896,6 +898,75 @@ static int player_num(lua_State *L) return 1; } +// powers, p -> powers[p] +static int power_get(lua_State *L) +{ + UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS)); + powertype_t p = luaL_checkinteger(L, 2); + player_t *plr = (player_t*)((void*)powers - offsetof(player_t, powers)); + if (p >= NUMPOWERS) + return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p); + switch (p) + { + case pw_flashing: + lua_pushinteger(L, plr->flashing); + return 1; + case pw_nocontrol: + lua_pushinteger(L, plr->nocontrol); + return 1; + case pw_ingoop: + if (plr->mo) + lua_pushinteger(L, P_IsObjectInGoop(plr->mo)); + else + lua_pushinteger(L, 0); + return 1; + default: + lua_pushinteger(L, powers[p]); + return 1; + } + return 1; +} + +#define NOSET luaL_error(L, LUA_QL("powertype_t") " field " LUA_QS " should not be set directly.", p) +// powers, p, value -> powers[p] = value +static int power_set(lua_State *L) +{ + UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS)); + powertype_t p = luaL_checkinteger(L, 2); + player_t *plr = (player_t*)((void*)powers - offsetof(player_t, powers)); + UINT16 i = (UINT16)luaL_checkinteger(L, 3); + if (p >= NUMPOWERS) + return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p); + if (hud_running) + return luaL_error(L, "Do not alter player_t in HUD rendering code!"); + if (hook_cmd_running) + return luaL_error(L, "Do not alter player_t in BuildCMD code!"); + switch (p) + { + case pw_flashing: + plr->flashing = i; + break; + case pw_nocontrol: + plr->nocontrol = i; + break; + case pw_ingoop: + return NOSET; + default: + powers[p] = i; + break; + } + return 0; +} +#undef NOSET + +// #powers -> NUMPOWERS +static int power_len(lua_State *L) +{ + lua_pushinteger(L, NUMPOWERS); + return 1; +} + + // ???, ks -> kartstuff[ks] static int kartstuff_get(lua_State *L) { @@ -1545,6 +1616,17 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + luaL_newmetatable(L, META_POWERS); + lua_pushcfunction(L, power_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, power_set); + lua_setfield(L, -2, "__newindex"); + + lua_pushcfunction(L, power_len); + lua_setfield(L, -2, "__len"); + lua_pop(L,1); + luaL_newmetatable(L, META_KARTSTUFF); lua_pushcfunction(L, kartstuff_get); lua_setfield(L, -2, "__index");