From a6f228ec2988423a26853a0524bee91073994880 Mon Sep 17 00:00:00 2001 From: JugadorXEI Date: Sat, 19 Oct 2024 20:39:26 +0200 Subject: [PATCH] Expose K_AddItemToReel and K_PushToRouletteItemList to Lua --- src/k_roulette.c | 35 +++---------- src/k_roulette.h | 36 ++++++++++++++ src/lua_baselib.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+), 28 deletions(-) diff --git a/src/k_roulette.c b/src/k_roulette.c index 10c475610..9604347e0 100644 --- a/src/k_roulette.c +++ b/src/k_roulette.c @@ -860,20 +860,11 @@ static void K_InitRoulette(itemroulette_t *const roulette) } /*-------------------------------------------------- - static void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) + void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) - Pushes a new item to the end of the item - roulette's item list. Also accepts slot machine - values instead of items. - - Input Arguments:- - roulette - The item roulette data to modify. - item - The item / slot machine index to push to the list. - - Return:- - N/A + See header file for description. --------------------------------------------------*/ -static void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) +void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) { #ifdef ITEM_LIST_SIZE if (roulette->itemList.len >= ITEM_LIST_SIZE) @@ -906,23 +897,11 @@ static void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) } /*-------------------------------------------------- - static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) + void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) - Adds an item to a player's item reel. Unlike - pushing directly with K_PushToRouletteItemList, - this function handles special behaviors (like - padding with extra Super Rings). - - Input Arguments:- - player - The player to add to the item roulette. - This is valid to be NULL. - roulette - The player's item roulette data. - item - The item to push to the list. - - Return:- - N/A + See header file for description. --------------------------------------------------*/ -static void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) +void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) { K_PushToRouletteItemList(roulette, item); @@ -1270,7 +1249,7 @@ void K_FillItemRouletteData(const player_t *player, itemroulette_t *const roulet } } - + if (ringbox == true) { // If this is being invoked by a Ring Box, it should literally never produce items. diff --git a/src/k_roulette.h b/src/k_roulette.h index 6f3054c5e..fba9ef9f6 100644 --- a/src/k_roulette.h +++ b/src/k_roulette.h @@ -76,6 +76,42 @@ boolean K_ItemSingularity(kartitems_t item); botItemPriority_e K_GetBotItemPriority(kartitems_t result); +/*-------------------------------------------------- + void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item) + + Pushes a new item to the end of the item + roulette's item list. Also accepts slot machine + values instead of items. + + Input Arguments:- + roulette - The item roulette data to modify. + item - The item / slot machine index to push to the list. + + Return:- + N/A +--------------------------------------------------*/ + +void K_PushToRouletteItemList(itemroulette_t *const roulette, INT32 item); + +/*-------------------------------------------------- + void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item) + + Adds an item to a player's item reel. Unlike + pushing directly with K_PushToRouletteItemList, + this function handles special behaviors (like + padding with extra Super Rings). + + Input Arguments:- + player - The player to add to the item roulette. + This is valid to be NULL. + roulette - The player's item roulette data. + item - The item to push to the list. + + Return:- + N/A +--------------------------------------------------*/ + +void K_AddItemToReel(const player_t *player, itemroulette_t *const roulette, kartitems_t item); /*-------------------------------------------------- INT32 K_KartGetBattleOdds(const player_t *player, itemroulette_t *const roulette, UINT8 pos, kartitems_t item); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 654542cae..b7fbbdc86 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -4081,6 +4081,128 @@ static int lib_kGetBotItemPriority(lua_State *L) return 1; } +static void getItemRouletteOrPlayerBasedOnFirstParam(lua_State *L, player_t **player, itemroulette_t **itemRoulette) +{ + /* + JugadorXEI @ 11/01/2024 (MM/DD/AAAA): + Ok, so. + I implemented luaL_testudata from Lua 5.2 because I wanted to test if an argument + was one userdata type or the other, and it worked. ...And then it didn't work, for some reason. + I was debugging this for 4 hours and couldn't figure it out. + So, raw-ass Lua funcs, here we go. THIS works. + Working with pointers gives me a headache. + */ + void *p = lua_touserdata(L, 1); + if (p != NULL) + { + if (lua_getmetatable(L, 1)) + { + lua_getfield(L, LUA_REGISTRYINDEX, META_ITEMROULETTE); + if (lua_rawequal(L, -1, -2)) + { + *itemRoulette = *(itemroulette_t **)p; + } + else + { + lua_pop(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, META_PLAYER); + if (lua_rawequal(L, -1, -2)) + { + *player = *(player_t **)p; + *itemRoulette = &(*player)->itemRoulette; + } + lua_pop(L, 2); + } + } + } +} + +static int lib_kAddItemToReel(lua_State *L) +{ + player_t *player = NULL; + itemroulette_t *itemRoulette = NULL; + + getItemRouletteOrPlayerBasedOnFirstParam(L, &player, &itemRoulette); + + NOHUD + INLEVEL + if (!player && !itemRoulette) + return LUA_ErrInvalid(L, "player_t/itemroulette_t"); + + if (lua_isnumber(L, 2)) + { + kartitems_t item = luaL_checkinteger(L, 2); + K_AddItemToReel(player, itemRoulette, item); + } + else if (lua_istable(L, 2)) + { + luaL_checktype(L, 2, LUA_TTABLE); + size_t size = luaL_getn(L, 2); + + for (size_t i = 1; i <= size; i++) + { + lua_rawgeti(L, 2, i); + if (lua_isnumber(L, -1)) + { + kartitems_t item = luaL_checkinteger(L, -1); + K_AddItemToReel(player, itemRoulette, item); + } + else // Quit early, let the scripter know they messed up. + { + lua_pop(L, 1); + return luaL_error(L, "Non-integer value in table in index %d.", i); + } + lua_pop(L, 1); + } + } + else return LUA_ErrInvalid(L, "integer/table"); + + return 0; +} + +static int lib_kPushToRouletteItemList(lua_State *L) +{ + player_t *player = NULL; + itemroulette_t *itemRoulette = NULL; + + getItemRouletteOrPlayerBasedOnFirstParam(L, &player, &itemRoulette); + + NOHUD + INLEVEL + if (!player && !itemRoulette) + return LUA_ErrInvalid(L, "player_t/itemroulette_t"); + + if (lua_isnumber(L, 2)) + { + kartitems_t item = luaL_checkinteger(L, 2); + K_PushToRouletteItemList(itemRoulette, item); + } + else if (lua_istable(L, 2)) + { + luaL_checktype(L, 2, LUA_TTABLE); + size_t size = luaL_getn(L, 2); + + for (size_t i = 1; i <= size; i++) + { + lua_rawgeti(L, 2, i); + if (lua_isnumber(L, -1)) + { + kartitems_t item = luaL_checkinteger(L, -1); + K_PushToRouletteItemList(itemRoulette, item); + } + else // Quit early, let the scripter know they messed up. + { + lua_pop(L, 1); + return luaL_error(L, "Non-integer value in table in index %d.", i); + } + lua_pop(L, 1); + } + } + else return LUA_ErrInvalid(L, "integer/table"); + + return 0; +} + static int lib_getTimeMicros(lua_State *L) { lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000)); @@ -4371,6 +4493,8 @@ static luaL_Reg lib[] = { {"K_ItemEnabled", lib_kItemEnabled}, {"K_ItemSingularity", lib_kItemSingularity}, {"K_GetBotItemPriority", lib_kGetBotItemPriority}, + {"K_AddItemToReel", lib_kAddItemToReel}, + {"K_PushToRouletteItemList", lib_kPushToRouletteItemList}, // hu_stuff technically? {"HU_DoTitlecardCEcho", lib_startTitlecardCecho},