386 lines
8.9 KiB
C
386 lines
8.9 KiB
C
// BLANKART
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2026 by BlanKart Team.
|
|
// Copyright (C) 2014-2025 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_itemlib.c
|
|
/// \brief item structures library for Lua scripting
|
|
|
|
#include "doomdef.h"
|
|
#include "k_items.h"
|
|
|
|
#include "lua_script.h"
|
|
#include "lua_libs.h"
|
|
#include "lua_hud.h" // hud_running errors
|
|
#include "lua_hook.h" // hook_cmd_running errors
|
|
|
|
enum itemvars
|
|
{
|
|
itemvars_equipstyle,
|
|
itemvars_equipstylealt,
|
|
itemvars_flags,
|
|
itemvars_flagsalt,
|
|
//itemvars_graphics, // see K_GetItemGraphics
|
|
itemvars_altcvar,
|
|
itemvars_altenabled,
|
|
};
|
|
|
|
static const char *const itemvars_opt[] = {
|
|
"equipstyle",
|
|
"equipstylealt",
|
|
"flags",
|
|
"flagsalt",
|
|
//"graphics",
|
|
"altcvar",
|
|
"altenabled",
|
|
NULL
|
|
};
|
|
|
|
static int item_get(lua_State *L)
|
|
{
|
|
kartitem_t *item = *((kartitem_t**)luaL_checkudata(L, 1, META_KARTITEM));
|
|
enum itemvars field = luaL_checkoption(L, 2, NULL, itemvars_opt);
|
|
|
|
// items are always valid, only added, never removed
|
|
I_Assert(item != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case itemvars_equipstyle:
|
|
lua_pushinteger(L, item->equipstyle[0]);
|
|
break;
|
|
case itemvars_equipstylealt:
|
|
lua_pushinteger(L, item->equipstyle[1]);
|
|
break;
|
|
case itemvars_flags:
|
|
lua_pushinteger(L, item->flags[0]);
|
|
break;
|
|
case itemvars_flagsalt:
|
|
lua_pushinteger(L, item->flags[1]);
|
|
break;
|
|
case itemvars_altcvar:
|
|
LUA_PushUserdata(L, item->altcvar, META_CVAR);
|
|
break;
|
|
case itemvars_altenabled:
|
|
lua_pushboolean(L, item->altenabled);
|
|
break;
|
|
default:
|
|
return luaL_error(L, LUA_QL("kartitem_t") " has no field named " LUA_QS, itemvars_opt[field]);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int item_set(lua_State *L)
|
|
{
|
|
return luaL_error(L, LUA_QL("kartitem_t") " struct cannot be edited by Lua.");
|
|
}
|
|
|
|
static int item_num(lua_State *L)
|
|
{
|
|
kartitem_t *item = *((kartitem_t**)luaL_checkudata(L, 1, META_KARTITEM));
|
|
|
|
// items are always valid, only added, never removed
|
|
I_Assert(item != NULL);
|
|
|
|
lua_pushinteger(L, item - kartitems);
|
|
return 1;
|
|
}
|
|
|
|
enum resultvars
|
|
{
|
|
resultvars_type,
|
|
resultvars_amount,
|
|
resultvars_displayname,
|
|
resultvars_isalt,
|
|
resultvars_flags,
|
|
//resultvars_odds,
|
|
//resultvars_uniqueodds,
|
|
resultvars_basecooldown,
|
|
resultvars_cooldown,
|
|
};
|
|
|
|
static const char *const resultvars_opt[] = {
|
|
"type",
|
|
"amount",
|
|
"displayname",
|
|
"isalt",
|
|
"flags",
|
|
//"odds",
|
|
//"uniqueodds",
|
|
"basecooldown",
|
|
"cooldown",
|
|
NULL
|
|
};
|
|
|
|
static int result_get(lua_State *L)
|
|
{
|
|
kartresult_t *result = *((kartresult_t**)luaL_checkudata(L, 1, META_KARTRESULT));
|
|
enum resultvars field = luaL_checkoption(L, 2, NULL, resultvars_opt);
|
|
|
|
// results are always valid, only added, never removed
|
|
I_Assert(result != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case resultvars_type:
|
|
lua_pushinteger(L, result->type);
|
|
break;
|
|
case resultvars_amount:
|
|
lua_pushinteger(L, result->amount);
|
|
break;
|
|
case resultvars_displayname:
|
|
lua_pushstring(L, result->displayname);
|
|
break;
|
|
case resultvars_isalt:
|
|
lua_pushboolean(L, result->isalt);
|
|
break;
|
|
case resultvars_flags:
|
|
lua_pushinteger(L, result->flags);
|
|
break;
|
|
//case resultvars_odds:
|
|
//i don't have time for this shit
|
|
//break;
|
|
//case resultvars_uniqueodds:
|
|
//break;
|
|
case resultvars_basecooldown:
|
|
lua_pushinteger(L, result->basecooldown);
|
|
break;
|
|
case resultvars_cooldown:
|
|
lua_pushinteger(L, result->cooldown);
|
|
break;
|
|
default:
|
|
return luaL_error(L, LUA_QL("kartresult_t") " has no field named " LUA_QS, resultvars_opt[field]);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int result_set(lua_State *L)
|
|
{
|
|
kartresult_t *result = *((kartresult_t**)luaL_checkudata(L, 1, META_KARTRESULT));
|
|
enum resultvars field = luaL_checkoption(L, 2, NULL, resultvars_opt);
|
|
|
|
if (hud_running)
|
|
return luaL_error(L, "Do not alter kartresult_t in HUD rendering code!");
|
|
if (hook_cmd_running)
|
|
return luaL_error(L, "Do not alter kartresult_t in BuildCMD code!");
|
|
|
|
// results are always valid, only added, never removed
|
|
I_Assert(result != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case resultvars_type:
|
|
case resultvars_amount:
|
|
case resultvars_displayname:
|
|
case resultvars_isalt:
|
|
case resultvars_flags:
|
|
case resultvars_basecooldown:
|
|
return luaL_error(L, LUA_QL("kartresult_t") " field " LUA_QS " should not be set directly.", resultvars_opt[field]);
|
|
case resultvars_cooldown:
|
|
result->cooldown = luaL_checkinteger(L, 3);
|
|
break;
|
|
default:
|
|
return luaL_error(L, LUA_QL("kartresult_t") " has no field named " LUA_QS, resultvars_opt[field]);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int result_num(lua_State *L)
|
|
{
|
|
kartresult_t *result = *((kartresult_t**)luaL_checkudata(L, 1, META_KARTRESULT));
|
|
|
|
// results are always valid, only added, never removed
|
|
I_Assert(result != NULL);
|
|
|
|
lua_pushinteger(L, result - kartresults);
|
|
return 1;
|
|
}
|
|
|
|
static int graphics_get(lua_State *L)
|
|
{
|
|
kartitemgraphics_t *graphics = *((kartitemgraphics_t**)luaL_checkudata(L, 1, META_KARTITEMGRAPHICS));
|
|
INT32 index = luaL_checkinteger(L, 2);
|
|
|
|
if (index < 0 || index >= graphics->numpatches)
|
|
return luaL_error(L, "patch index %d out of range (0 - %d)", index, graphics->numpatches-1);
|
|
|
|
LUA_PushUserdata(L, graphics->patches[index], META_PATCH);
|
|
return 1;
|
|
}
|
|
|
|
static int graphics_set(lua_State *L)
|
|
{
|
|
return luaL_error(L, LUA_QL("kartitemgraphics_t") " struct cannot be edited by Lua.");
|
|
}
|
|
|
|
static int graphics_num(lua_State *L)
|
|
{
|
|
kartitemgraphics_t *graphics = *((kartitemgraphics_t**)luaL_checkudata(L, 1, META_KARTITEMGRAPHICS));
|
|
lua_pushinteger(L, graphics->numpatches);
|
|
return 1;
|
|
}
|
|
|
|
static int lib_iterateKartItems(lua_State *L)
|
|
{
|
|
INT32 i;
|
|
|
|
if (lua_gettop(L) < 2)
|
|
{
|
|
lua_pushcfunction(L, lib_iterateKartItems);
|
|
return 1;
|
|
}
|
|
|
|
lua_settop(L, 2);
|
|
lua_remove(L, 1); // state is unused.
|
|
|
|
if (!lua_isnil(L, 1))
|
|
i = (*(kartitem_t **)luaL_checkudata(L, 1, META_KARTITEM)) - kartitems + 1;
|
|
else
|
|
i = 1;
|
|
|
|
if (i >= 1 && i < numkartitems)
|
|
{
|
|
LUA_PushUserdata(L, &kartitems[i], META_KARTITEM);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_iterateKartResults(lua_State *L)
|
|
{
|
|
INT32 i;
|
|
|
|
if (lua_gettop(L) < 2)
|
|
{
|
|
lua_pushcfunction(L, lib_iterateKartResults);
|
|
return 1;
|
|
}
|
|
|
|
lua_settop(L, 2);
|
|
lua_remove(L, 1); // state is unused.
|
|
|
|
if (!lua_isnil(L, 1))
|
|
i = (*(kartresult_t **)luaL_checkudata(L, 1, META_KARTRESULT)) - kartresults + 1;
|
|
else
|
|
i = 0;
|
|
|
|
if (i >= 0 && i < numkartresults)
|
|
{
|
|
LUA_PushUserdata(L, &kartresults[i], META_KARTRESULT);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int lib_getKartItem(lua_State *L)
|
|
{
|
|
if (lua_type(L, 2) == LUA_TNUMBER)
|
|
{
|
|
INT32 i = luaL_checkinteger(L, 2);
|
|
if (i < 1 || i >= numkartitems)
|
|
return luaL_error(L, "kartitem index %d out of range (1 - %d)", i, numkartitems-1);
|
|
LUA_PushUserdata(L, &kartitems[i], META_KARTITEM);
|
|
return 1;
|
|
}
|
|
|
|
const char *field = luaL_checkstring(L, 2);
|
|
if (fastcmp(field, "iterate"))
|
|
{
|
|
lua_pushcfunction(L, lib_iterateKartItems);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lib_numKartItems(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, numkartitems);
|
|
return 1;
|
|
}
|
|
|
|
static int lib_getKartResult(lua_State *L)
|
|
{
|
|
if (lua_type(L, 2) == LUA_TNUMBER)
|
|
{
|
|
INT32 i = luaL_checkinteger(L, 2);
|
|
if (i < 0 || i >= numkartresults)
|
|
return luaL_error(L, "kartresult index %d out of range (0 - %d)", i, numkartresults-1);
|
|
LUA_PushUserdata(L, &kartresults[i], META_KARTRESULT);
|
|
return 1;
|
|
}
|
|
|
|
const char *field = luaL_checkstring(L, 2);
|
|
if (fastcmp(field, "iterate"))
|
|
{
|
|
lua_pushcfunction(L, lib_iterateKartResults);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lib_numKartResults(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, numkartresults);
|
|
return 1;
|
|
}
|
|
|
|
|
|
int LUA_ItemLib(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, META_KARTITEM);
|
|
lua_pushcfunction(L, item_get);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushcfunction(L, item_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
lua_pushcfunction(L, item_num);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L, 1);
|
|
|
|
luaL_newmetatable(L, META_KARTRESULT);
|
|
lua_pushcfunction(L, result_get);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushcfunction(L, result_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
lua_pushcfunction(L, result_num);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L, 1);
|
|
|
|
luaL_newmetatable(L, META_KARTITEMGRAPHICS);
|
|
lua_pushcfunction(L, graphics_get);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushcfunction(L, graphics_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
lua_pushcfunction(L, graphics_num);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L, 1);
|
|
|
|
lua_newuserdata(L, 0);
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, lib_getKartItem);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushcfunction(L, lib_numKartItems);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_setmetatable(L, -2);
|
|
lua_setglobal(L, "kartitems");
|
|
|
|
lua_newuserdata(L, 0);
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, lib_getKartResult);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pushcfunction(L, lib_numKartResults);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_setmetatable(L, -2);
|
|
lua_setglobal(L, "kartresults");
|
|
|
|
return 0;
|
|
}
|