Powers->Player_t metatable

This commit is contained in:
NepDisk 2024-12-28 13:48:02 -05:00
parent 38a4544531
commit 38600f1eb6
5 changed files with 180 additions and 0 deletions

View file

@ -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];

View file

@ -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++)

View file

@ -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",

View file

@ -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"

View file

@ -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");