diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index dcaad1416..1d15b3b14 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -566,27 +566,59 @@ static luaL_Reg lib[] = { {NULL, NULL} }; +enum cvar_e +{ + cvar_name, + cvar_defaultvalue, + cvar_flags, + cvar_value, + cvar_string, + cvar_changed, +}; + +static const char *const cvar_opt[] = { + "name", + "defaultvalue", + "flags", + "value", + "string", + "changed", + NULL, +}; + +static int cvar_fields_ref = LUA_NOREF; + static int cvar_get(lua_State *L) { consvar_t *cvar = *(consvar_t **)luaL_checkudata(L, 1, META_CVAR); - const char *field = luaL_checkstring(L, 2); + enum cvar_e field = Lua_optoption(L, 2, -1, cvar_fields_ref); - if(fastcmp(field,"name")) + switch (field) + { + case cvar_name: lua_pushstring(L, cvar->name); - else if(fastcmp(field,"defaultvalue")) + break; + case cvar_defaultvalue: lua_pushstring(L, cvar->defaultvalue); - else if(fastcmp(field,"flags")) + break; + case cvar_flags: lua_pushinteger(L, cvar->flags); - else if(fastcmp(field,"value")) + break; + case cvar_value: lua_pushinteger(L, cvar->value); - else if(fastcmp(field,"string")) + break; + case cvar_string: lua_pushstring(L, cvar->string); - else if(fastcmp(field,"changed")) + break; + case cvar_changed: lua_pushboolean(L, cvar->changed); - else if (devparm) - return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field); - else - return 0; + break; + default: + if (devparm) + return luaL_error(L, LUA_QL("consvar_t") " has no field named " LUA_QS, field); + else + return 0; + } return 1; } @@ -598,6 +630,8 @@ int LUA_ConsoleLib(lua_State *L) lua_setfield(L, -2, "__index"); lua_pop(L,1); + cvar_fields_ref = Lua_CreateFieldTable(L, cvar_opt); + // Set empty registry tables lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "COM_Command"); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 1a0599757..c7f67e93a 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -95,6 +95,8 @@ static const char *const patch_opt[] = { "topoffset", NULL}; +static int patch_fields_ref = LUA_NOREF; + // alignment types for v.drawString enum align { align_left = 0, @@ -196,6 +198,8 @@ static const char *const camera_opt[] = { "momz", NULL}; +static int camera_fields_ref = LUA_NOREF; + static int lib_getHudInfo(lua_State *L) { UINT32 i; @@ -276,7 +280,7 @@ static int colormap_get(lua_State *L) static int patch_get(lua_State *L) { patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); - enum patch field = luaL_checkoption(L, 2, NULL, patch_opt); + enum patch field = Lua_optoption(L, 2, -1, patch_fields_ref); // patches are invalidated when switching renderers if (!patch) { @@ -316,7 +320,7 @@ static int patch_set(lua_State *L) static int camera_get(lua_State *L) { camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); - enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt); + enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref); // cameras should always be valid unless I'm a nutter I_Assert(cam != NULL); @@ -372,7 +376,7 @@ static int camera_get(lua_State *L) static int camera_set(lua_State *L) { camera_t *cam = *((camera_t **)luaL_checkudata(L, 1, META_CAMERA)); - enum cameraf field = luaL_checkoption(L, 2, NULL, camera_opt); + enum cameraf field = Lua_optoption(L, 2, -1, camera_fields_ref); I_Assert(cam != NULL); @@ -1444,6 +1448,8 @@ int LUA_HudLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + patch_fields_ref = Lua_CreateFieldTable(L, patch_opt); + luaL_newmetatable(L, META_CAMERA); lua_pushcfunction(L, camera_get); lua_setfield(L, -2, "__index"); @@ -1452,6 +1458,8 @@ int LUA_HudLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + camera_fields_ref = Lua_CreateFieldTable(L, camera_opt); + luaL_register(L, "hud", lib_hud); return 0; } diff --git a/src/lua_infolib.c b/src/lua_infolib.c index 7388632d3..fb07ccebb 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1106,75 +1106,161 @@ static int lib_mobjinfolen(lua_State *L) return 1; } +enum mobjinfo_e +{ + mobjinfo_doomednum, + mobjinfo_spawnstate, + mobjinfo_spawnhealth, + mobjinfo_seestate, + mobjinfo_seesound, + mobjinfo_reactiontime, + mobjinfo_attacksound, + mobjinfo_painstate, + mobjinfo_painchance, + mobjinfo_painsound, + mobjinfo_meleestate, + mobjinfo_missilestate, + mobjinfo_deathstate, + mobjinfo_xdeathstate, + mobjinfo_deathsound, + mobjinfo_speed, + mobjinfo_radius, + mobjinfo_height, + mobjinfo_dispoffset, + mobjinfo_mass, + mobjinfo_damage, + mobjinfo_activesound, + mobjinfo_flags, + mobjinfo_raisestate, +}; + +const char *const mobjinfo_opt[] = { + "doomednum", + "spawnstate", + "spawnhealth", + "seestate", + "seesound", + "reactiontime", + "attacksound", + "painstate", + "painchance", + "painsound", + "meleestate", + "missilestate", + "deathstate", + "xdeathstate", + "deathsound", + "speed", + "radius", + "height", + "dispoffset", + "mass", + "damage", + "activesound", + "flags", + "raisestate", + NULL, +}; + +static int mobjinfo_fields_ref = LUA_NOREF; + // mobjinfo_t *, field -> number static int mobjinfo_get(lua_State *L) { mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO)); - const char *field = luaL_checkstring(L, 2); + enum mobjinfo_e field = luaL_checkoption(L, 2, mobjinfo_opt[0], mobjinfo_opt); I_Assert(info != NULL); I_Assert(info >= mobjinfo); - if (fastcmp(field,"doomednum")) + switch (field) + { + case mobjinfo_doomednum: lua_pushinteger(L, info->doomednum); - else if (fastcmp(field,"spawnstate")) + break; + case mobjinfo_spawnstate: lua_pushinteger(L, info->spawnstate); - else if (fastcmp(field,"spawnhealth")) + break; + case mobjinfo_spawnhealth: lua_pushinteger(L, info->spawnhealth); - else if (fastcmp(field,"seestate")) + break; + case mobjinfo_seestate: lua_pushinteger(L, info->seestate); - else if (fastcmp(field,"seesound")) + break; + case mobjinfo_seesound: lua_pushinteger(L, info->seesound); - else if (fastcmp(field,"reactiontime")) + break; + case mobjinfo_reactiontime: lua_pushinteger(L, info->reactiontime); - else if (fastcmp(field,"attacksound")) + break; + case mobjinfo_attacksound: lua_pushinteger(L, info->attacksound); - else if (fastcmp(field,"painstate")) + break; + case mobjinfo_painstate: lua_pushinteger(L, info->painstate); - else if (fastcmp(field,"painchance")) + break; + case mobjinfo_painchance: lua_pushinteger(L, info->painchance); - else if (fastcmp(field,"painsound")) + break; + case mobjinfo_painsound: lua_pushinteger(L, info->painsound); - else if (fastcmp(field,"meleestate")) + break; + case mobjinfo_meleestate: lua_pushinteger(L, info->meleestate); - else if (fastcmp(field,"missilestate")) + break; + case mobjinfo_missilestate: lua_pushinteger(L, info->missilestate); - else if (fastcmp(field,"deathstate")) + break; + case mobjinfo_deathstate: lua_pushinteger(L, info->deathstate); - else if (fastcmp(field,"xdeathstate")) + break; + case mobjinfo_xdeathstate: lua_pushinteger(L, info->xdeathstate); - else if (fastcmp(field,"deathsound")) + break; + case mobjinfo_deathsound: lua_pushinteger(L, info->deathsound); - else if (fastcmp(field,"speed")) + break; + case mobjinfo_speed: lua_pushinteger(L, info->speed); // sometimes it's fixed_t, sometimes it's not... - else if (fastcmp(field,"radius")) + break; + case mobjinfo_radius: lua_pushfixed(L, info->radius); - else if (fastcmp(field,"height")) + break; + case mobjinfo_height: lua_pushfixed(L, info->height); - else if (fastcmp(field,"dispoffset")) + break; + case mobjinfo_dispoffset: lua_pushinteger(L, info->dispoffset); - else if (fastcmp(field,"mass")) + break; + case mobjinfo_mass: lua_pushinteger(L, info->mass); - else if (fastcmp(field,"damage")) + break; + case mobjinfo_damage: lua_pushinteger(L, info->damage); - else if (fastcmp(field,"activesound")) + break; + case mobjinfo_activesound: lua_pushinteger(L, info->activesound); - else if (fastcmp(field,"flags")) + break; + case mobjinfo_flags: lua_pushinteger(L, info->flags); - else if (fastcmp(field,"raisestate")) + break; + case mobjinfo_raisestate: lua_pushinteger(L, info->raisestate); - else { + break; + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, info); lua_rawget(L, -2); if (!lua_istable(L, -1)) { // no extra values table - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2)); return 0; } - lua_getfield(L, -1, field); + lua_pushvalue(L, 2); // field name + lua_gettable(L, -2); if (lua_isnil(L, -1)) // no value for this field - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "mobjinfo_t", lua_tostring(L, 2)); + break; } return 1; } @@ -1183,7 +1269,7 @@ static int mobjinfo_get(lua_State *L) static int mobjinfo_set(lua_State *L) { mobjinfo_t *info = *((mobjinfo_t **)luaL_checkudata(L, 1, META_MOBJINFO)); - const char *field = luaL_checkstring(L, 2); + enum mobjinfo_e field = Lua_optoption(L, 2, -1, mobjinfo_fields_ref); if (hud_running) return luaL_error(L, "Do not alter mobjinfo in HUD rendering code!"); @@ -1193,55 +1279,81 @@ static int mobjinfo_set(lua_State *L) I_Assert(info != NULL); I_Assert(info >= mobjinfo); - if (fastcmp(field,"doomednum")) + switch (field) + { + case mobjinfo_doomednum: info->doomednum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"spawnstate")) + break; + case mobjinfo_spawnstate: info->spawnstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"spawnhealth")) + break; + case mobjinfo_spawnhealth: info->spawnhealth = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"seestate")) + break; + case mobjinfo_seestate: info->seestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"seesound")) + break; + case mobjinfo_seesound: info->seesound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"reactiontime")) + break; + case mobjinfo_reactiontime: info->reactiontime = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"attacksound")) + break; + case mobjinfo_attacksound: info->attacksound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"painstate")) + break; + case mobjinfo_painstate: info->painstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"painchance")) + break; + case mobjinfo_painchance: info->painchance = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"painsound")) + break; + case mobjinfo_painsound: info->painsound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"meleestate")) + break; + case mobjinfo_meleestate: info->meleestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"missilestate")) + break; + case mobjinfo_missilestate: info->missilestate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"deathstate")) + break; + case mobjinfo_deathstate: info->deathstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"xdeathstate")) + break; + case mobjinfo_xdeathstate: info->xdeathstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"deathsound")) + break; + case mobjinfo_deathsound: info->deathsound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"speed")) + break; + case mobjinfo_speed: info->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"radius")) + break; + case mobjinfo_radius: info->radius = luaL_checkfixed(L, 3); - else if (fastcmp(field,"height")) + break; + case mobjinfo_height: info->height = luaL_checkfixed(L, 3); - else if (fastcmp(field,"dispoffset")) + break; + case mobjinfo_dispoffset: info->dispoffset = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"mass")) + break; + case mobjinfo_mass: info->mass = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"damage")) + break; + case mobjinfo_damage: info->damage = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"activesound")) + break; + case mobjinfo_activesound: info->activesound = luaL_checkinteger(L, 3); - else if (fastcmp(field,"flags")) + break; + case mobjinfo_flags: info->flags = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"raisestate")) + break; + case mobjinfo_raisestate: info->raisestate = luaL_checkinteger(L, 3); - else { + break; + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, info); @@ -1249,18 +1361,17 @@ static int mobjinfo_set(lua_State *L) if (lua_isnil(L, -1)) { // This index doesn't have a table for extra values yet, let's make one. lua_pop(L, 1); - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "mobjinfo_t", lua_tostring(L, 2)); lua_newtable(L); lua_pushlightuserdata(L, info); lua_pushvalue(L, -2); // ext value table lua_rawset(L, -4); // LREG_EXTVARS table } + lua_pushvalue(L, 2); // key lua_pushvalue(L, 3); // value to store - lua_setfield(L, -2, field); + lua_settable(L, -3); lua_pop(L, 2); } - //else - //return luaL_error(L, LUA_QL("mobjinfo_t") " has no field named " LUA_QS, field); return 0; } @@ -1788,6 +1899,8 @@ int LUA_InfoLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + mobjinfo_fields_ref = Lua_CreateFieldTable(L, mobjinfo_opt); + luaL_newmetatable(L, META_SKINCOLOR); lua_pushcfunction(L, skincolor_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 898651520..dc477c81f 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -88,6 +88,8 @@ static const char *const sector_opt[] = { "gravity", NULL}; +static int sector_fields_ref = LUA_NOREF; + enum subsector_e { subsector_valid = 0, subsector_sector, @@ -104,6 +106,8 @@ static const char *const subsector_opt[] = { "polyList", NULL}; +static int subsector_fields_ref = LUA_NOREF; + enum line_e { line_valid = 0, line_v1, @@ -156,6 +160,8 @@ static const char *const line_opt[] = { "callcount", NULL}; +static int line_fields_ref = LUA_NOREF; + enum side_e { side_valid = 0, side_textureoffset, @@ -184,6 +190,8 @@ static const char *const side_opt[] = { "text", NULL}; +static int side_fields_ref = LUA_NOREF; + enum vertex_e { vertex_valid = 0, vertex_x, @@ -204,6 +212,8 @@ static const char *const vertex_opt[] = { "ceilingzset", NULL}; +static int vertex_fields_ref = LUA_NOREF; + enum ffloor_e { ffloor_valid = 0, ffloor_topheight, @@ -256,6 +266,8 @@ static const char *const ffloor_opt[] = { "bouncestrength", NULL}; +static int ffloor_fields_ref = LUA_NOREF; + #ifdef HAVE_LUA_SEGS enum seg_e { seg_valid = 0, @@ -285,6 +297,8 @@ static const char *const seg_opt[] = { "polyseg", NULL}; +static int seg_fields_ref = LUA_NOREF; + enum node_e { node_valid = 0, node_x, @@ -305,6 +319,8 @@ static const char *const node_opt[] = { "children", NULL}; +static int node_fields_ref = LUA_NOREF; + enum nodechild_e { nodechild_valid = 0, nodechild_right, @@ -356,6 +372,8 @@ static const char *const slope_opt[] = { "flags", NULL}; +static int slope_fields_ref = LUA_NOREF; + // shared by both vector2_t and vector3_t enum vector_e { vector_x = 0, @@ -575,7 +593,7 @@ static int sectorlines_num(lua_State *L) static int sector_get(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); - enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt); + enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref); INT16 i; if (!sector) @@ -697,7 +715,7 @@ static int sector_get(lua_State *L) static int sector_set(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); - enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt); + enum sector_e field = Lua_optoption(L, 2, sector_valid, sector_fields_ref); if (!sector) return luaL_error(L, "accessed sector_t doesn't exist anymore."); @@ -814,7 +832,7 @@ static int sector_num(lua_State *L) static int subsector_get(lua_State *L) { subsector_t *subsector = *((subsector_t **)luaL_checkudata(L, 1, META_SUBSECTOR)); - enum subsector_e field = luaL_checkoption(L, 2, subsector_opt[0], subsector_opt); + enum subsector_e field = Lua_optoption(L, 2, subsector_valid, subsector_fields_ref); if (!subsector) { @@ -898,7 +916,7 @@ static int linestringargs_len(lua_State *L) static int line_get(lua_State *L) { line_t *line = *((line_t **)luaL_checkudata(L, 1, META_LINE)); - enum line_e field = luaL_checkoption(L, 2, line_opt[0], line_opt); + enum line_e field = Lua_optoption(L, 2, line_valid, line_fields_ref); if (!line) { @@ -1057,7 +1075,7 @@ static int sidenum_get(lua_State *L) static int side_get(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); - enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt); + enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref); if (!side) { @@ -1110,7 +1128,7 @@ static int side_get(lua_State *L) static int side_set(lua_State *L) { side_t *side = *((side_t **)luaL_checkudata(L, 1, META_SIDE)); - enum side_e field = luaL_checkoption(L, 2, side_opt[0], side_opt); + enum side_e field = Lua_optoption(L, 2, side_valid, side_fields_ref); if (!side) { @@ -1166,7 +1184,7 @@ static int side_num(lua_State *L) static int vertex_get(lua_State *L) { vertex_t *vertex = *((vertex_t **)luaL_checkudata(L, 1, META_VERTEX)); - enum vertex_e field = luaL_checkoption(L, 2, vertex_opt[0], vertex_opt); + enum vertex_e field = Lua_optoption(L, 2, vertex_valid, vertex_fields_ref); if (!vertex) { @@ -1220,7 +1238,7 @@ static int vertex_num(lua_State *L) static int seg_get(lua_State *L) { seg_t *seg = *((seg_t **)luaL_checkudata(L, 1, META_SEG)); - enum seg_e field = luaL_checkoption(L, 2, seg_opt[0], seg_opt); + enum seg_e field = Lua_optoption(L, 2, seg_valid, seg_fields_ref); if (!seg) { @@ -1284,7 +1302,7 @@ static int seg_num(lua_State *L) static int node_get(lua_State *L) { node_t *node = *((node_t **)luaL_checkudata(L, 1, META_NODE)); - enum node_e field = luaL_checkoption(L, 2, node_opt[0], node_opt); + enum node_e field = Lua_optoption(L, 2, node_valid, node_fields_ref); if (!node) { @@ -1920,7 +1938,7 @@ static INT32 P_GetOldFOFFlags(ffloor_t *fflr) static int ffloor_get(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); - enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt); + enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref); INT16 i; if (!ffloor) @@ -2102,7 +2120,7 @@ static void P_SetOldFOFFlags(ffloor_t *fflr, oldffloortype_e oldflags) static int ffloor_set(lua_State *L) { ffloor_t *ffloor = *((ffloor_t **)luaL_checkudata(L, 1, META_FFLOOR)); - enum ffloor_e field = luaL_checkoption(L, 2, ffloor_opt[0], ffloor_opt); + enum ffloor_e field = Lua_optoption(L, 2, ffloor_valid, ffloor_fields_ref); if (!ffloor) return luaL_error(L, "accessed ffloor_t doesn't exist anymore."); @@ -2197,7 +2215,7 @@ static int ffloor_set(lua_State *L) static int slope_get(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); - enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref); if (!slope) { @@ -2241,7 +2259,7 @@ static int slope_get(lua_State *L) static int slope_set(lua_State *L) { pslope_t *slope = *((pslope_t **)luaL_checkudata(L, 1, META_SLOPE)); - enum slope_e field = luaL_checkoption(L, 2, slope_opt[0], slope_opt); + enum slope_e field = Lua_optoption(L, 2, slope_valid, slope_fields_ref); if (!slope) return luaL_error(L, "accessed pslope_t doesn't exist anymore."); @@ -2405,110 +2423,258 @@ static int lib_nummapheaders(lua_State *L) // mapheader_t // ///////////////// +enum mapheaderinfo_e +{ + mapheaderinfo_lvlttl, + mapheaderinfo_subttl, + mapheaderinfo_actnum, + mapheaderinfo_typeoflevel, + mapheaderinfo_nextlevel, + mapheaderinfo_marathonnext, + mapheaderinfo_keywords, + mapheaderinfo_musname, + mapheaderinfo_mustrack, + mapheaderinfo_muspos, + mapheaderinfo_musinterfadeout, + mapheaderinfo_musintername, + mapheaderinfo_muspostbossname, + mapheaderinfo_muspostbosstrack, + mapheaderinfo_muspostbosspos, + mapheaderinfo_muspostbossfadein, + mapheaderinfo_musforcereset, + mapheaderinfo_forcecharacter, + mapheaderinfo_weather, + mapheaderinfo_skynum, + mapheaderinfo_skybox_scalex, + mapheaderinfo_skybox_scaley, + mapheaderinfo_skybox_scalez, + mapheaderinfo_interscreen, + mapheaderinfo_runsoc, + mapheaderinfo_scriptname, + mapheaderinfo_precutscenenum, + mapheaderinfo_cutscenenum, + mapheaderinfo_countdown, + mapheaderinfo_palette, + mapheaderinfo_numlaps, + mapheaderinfo_unlockrequired, + mapheaderinfo_levelselect, + mapheaderinfo_bonustype, + mapheaderinfo_ltzzpatch, + mapheaderinfo_ltzztext, + mapheaderinfo_ltactdiamond, + mapheaderinfo_maxbonuslives, + mapheaderinfo_levelflags, + mapheaderinfo_menuflags, + mapheaderinfo_selectheading, + mapheaderinfo_startrings, + mapheaderinfo_sstimer, + mapheaderinfo_ssspheres, + mapheaderinfo_gravity, +}; + +static const char *const mapheaderinfo_opt[] = { + "lvlttl", + "subttl", + "actnum", + "typeoflevel", + "nextlevel", + "marathonnext", + "keywords", + "musname", + "mustrack", + "muspos", + "musinterfadeout", + "musintername", + "muspostbossname", + "muspostbosstrack", + "muspostbosspos", + "muspostbossfadein", + "musforcereset", + "forcecharacter", + "weather", + "skynum", + "skybox_scalex", + "skybox_scaley", + "skybox_scalez", + "interscreen", + "runsoc", + "scriptname", + "precutscenenum", + "cutscenenum", + "countdown", + "palette", + "numlaps", + "unlockrequired", + "levelselect", + "bonustype", + "ltzzpatch", + "ltzztext", + "ltactdiamond", + "maxbonuslives", + "levelflags", + "menuflags", + "selectheading", + "startrings", + "sstimer", + "ssspheres", + "gravity", + NULL, +}; + +static int mapheaderinfo_fields_ref = LUA_NOREF; + static int mapheaderinfo_get(lua_State *L) { mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER)); - const char *field = luaL_checkstring(L, 2); + enum mapheaderinfo_e field = Lua_optoption(L, 2, -1, mapheaderinfo_fields_ref); INT16 i; - if (fastcmp(field,"lvlttl")) + + switch (field) + { + case mapheaderinfo_lvlttl: lua_pushstring(L, header->lvlttl); - else if (fastcmp(field,"subttl")) + break; + case mapheaderinfo_subttl: lua_pushstring(L, header->subttl); - else if (fastcmp(field,"actnum")) + break; + case mapheaderinfo_actnum: lua_pushinteger(L, header->actnum); - else if (fastcmp(field,"typeoflevel")) + break; + case mapheaderinfo_typeoflevel: lua_pushinteger(L, header->typeoflevel); - else if (fastcmp(field,"nextlevel")) + break; + case mapheaderinfo_nextlevel: lua_pushinteger(L, header->nextlevel); - else if (fastcmp(field,"marathonnext")) + break; + case mapheaderinfo_marathonnext: lua_pushinteger(L, header->marathonnext); - else if (fastcmp(field,"keywords")) + break; + case mapheaderinfo_keywords: lua_pushstring(L, header->keywords); - else if (fastcmp(field,"musname")) + break; + case mapheaderinfo_musname: lua_pushstring(L, header->musname); - else if (fastcmp(field,"mustrack")) + break; + case mapheaderinfo_mustrack: lua_pushinteger(L, header->mustrack); - else if (fastcmp(field,"muspos")) + break; + case mapheaderinfo_muspos: lua_pushinteger(L, header->muspos); - else if (fastcmp(field,"musinterfadeout")) + break; + case mapheaderinfo_musinterfadeout: lua_pushinteger(L, header->musinterfadeout); - else if (fastcmp(field,"musintername")) + break; + case mapheaderinfo_musintername: lua_pushstring(L, header->musintername); - else if (fastcmp(field,"muspostbossname")) + break; + case mapheaderinfo_muspostbossname: lua_pushstring(L, header->muspostbossname); - else if (fastcmp(field,"muspostbosstrack")) + break; + case mapheaderinfo_muspostbosstrack: lua_pushinteger(L, header->muspostbosstrack); - else if (fastcmp(field,"muspostbosspos")) + break; + case mapheaderinfo_muspostbosspos: lua_pushinteger(L, header->muspostbosspos); - else if (fastcmp(field,"muspostbossfadein")) + break; + case mapheaderinfo_muspostbossfadein: lua_pushinteger(L, header->muspostbossfadein); - else if (fastcmp(field,"musforcereset")) + break; + case mapheaderinfo_musforcereset: lua_pushinteger(L, header->musforcereset); - else if (fastcmp(field,"forcecharacter")) + break; + case mapheaderinfo_forcecharacter: lua_pushstring(L, header->forcecharacter); - else if (fastcmp(field,"weather")) + break; + case mapheaderinfo_weather: lua_pushinteger(L, header->weather); - else if (fastcmp(field,"skynum")) + break; + case mapheaderinfo_skynum: lua_pushinteger(L, header->skynum); - else if (fastcmp(field,"skybox_scalex")) + break; + case mapheaderinfo_skybox_scalex: lua_pushinteger(L, header->skybox_scalex); - else if (fastcmp(field,"skybox_scaley")) + break; + case mapheaderinfo_skybox_scaley: lua_pushinteger(L, header->skybox_scaley); - else if (fastcmp(field,"skybox_scalez")) + break; + case mapheaderinfo_skybox_scalez: lua_pushinteger(L, header->skybox_scalez); - else if (fastcmp(field,"interscreen")) { + break; + case mapheaderinfo_interscreen: for (i = 0; i < 8; i++) if (!header->interscreen[i]) break; lua_pushlstring(L, header->interscreen, i); - } else if (fastcmp(field,"runsoc")) + break; + case mapheaderinfo_runsoc: lua_pushstring(L, header->runsoc); - else if (fastcmp(field,"scriptname")) + break; + case mapheaderinfo_scriptname: lua_pushstring(L, header->scriptname); - else if (fastcmp(field,"precutscenenum")) + break; + case mapheaderinfo_precutscenenum: lua_pushinteger(L, header->precutscenenum); - else if (fastcmp(field,"cutscenenum")) + break; + case mapheaderinfo_cutscenenum: lua_pushinteger(L, header->cutscenenum); - else if (fastcmp(field,"countdown")) + break; + case mapheaderinfo_countdown: lua_pushinteger(L, header->countdown); - else if (fastcmp(field,"palette")) + break; + case mapheaderinfo_palette: lua_pushinteger(L, header->palette); - else if (fastcmp(field,"numlaps")) + break; + case mapheaderinfo_numlaps: lua_pushinteger(L, header->numlaps); - else if (fastcmp(field,"unlockrequired")) + break; + case mapheaderinfo_unlockrequired: lua_pushinteger(L, header->unlockrequired); - else if (fastcmp(field,"levelselect")) + break; + case mapheaderinfo_levelselect: lua_pushinteger(L, header->levelselect); - else if (fastcmp(field,"bonustype")) + break; + case mapheaderinfo_bonustype: lua_pushinteger(L, header->bonustype); - else if (fastcmp(field,"ltzzpatch")) + break; + case mapheaderinfo_ltzzpatch: lua_pushstring(L, header->ltzzpatch); - else if (fastcmp(field,"ltzztext")) + break; + case mapheaderinfo_ltzztext: lua_pushstring(L, header->ltzztext); - else if (fastcmp(field,"ltactdiamond")) + break; + case mapheaderinfo_ltactdiamond: lua_pushstring(L, header->ltactdiamond); - else if (fastcmp(field,"maxbonuslives")) + break; + case mapheaderinfo_maxbonuslives: lua_pushinteger(L, header->maxbonuslives); - else if (fastcmp(field,"levelflags")) + break; + case mapheaderinfo_levelflags: lua_pushinteger(L, header->levelflags); - else if (fastcmp(field,"menuflags")) + break; + case mapheaderinfo_menuflags: lua_pushinteger(L, header->menuflags); - else if (fastcmp(field,"selectheading")) + break; + case mapheaderinfo_selectheading: lua_pushstring(L, header->selectheading); - else if (fastcmp(field,"startrings")) + break; + case mapheaderinfo_startrings: lua_pushinteger(L, header->startrings); - else if (fastcmp(field, "sstimer")) + break; + case mapheaderinfo_sstimer: lua_pushinteger(L, header->sstimer); - else if (fastcmp(field, "ssspheres")) + break; + case mapheaderinfo_ssspheres: lua_pushinteger(L, header->ssspheres); - else if (fastcmp(field, "gravity")) + break; + case mapheaderinfo_gravity: lua_pushfixed(L, header->gravity); + break; // TODO add support for reading numGradedMares and grades - else { + default: // Read custom vars now // (note: don't include the "LUA." in your lua scripts!) UINT8 j = 0; - for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j); + for (;j < header->numCustomOptions && !fastcmp(lua_tostring(L, 2), header->customopts[j].option); ++j); if(j < header->numCustomOptions) lua_pushstring(L, header->customopts[j].value); @@ -2539,6 +2705,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + sector_fields_ref = Lua_CreateFieldTable(L, sector_opt); + luaL_newmetatable(L, META_SUBSECTOR); lua_pushcfunction(L, subsector_get); lua_setfield(L, -2, "__index"); @@ -2547,6 +2715,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + subsector_fields_ref = Lua_CreateFieldTable(L, subsector_opt); + luaL_newmetatable(L, META_LINE); lua_pushcfunction(L, line_get); lua_setfield(L, -2, "__index"); @@ -2555,6 +2725,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + line_fields_ref = Lua_CreateFieldTable(L, line_opt); + luaL_newmetatable(L, META_LINEARGS); lua_pushcfunction(L, lineargs_get); lua_setfield(L, -2, "__index"); @@ -2587,6 +2759,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + side_fields_ref = Lua_CreateFieldTable(L, side_opt); + luaL_newmetatable(L, META_VERTEX); lua_pushcfunction(L, vertex_get); lua_setfield(L, -2, "__index"); @@ -2595,6 +2769,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + vertex_fields_ref = Lua_CreateFieldTable(L, vertex_opt); + luaL_newmetatable(L, META_FFLOOR); lua_pushcfunction(L, ffloor_get); lua_setfield(L, -2, "__index"); @@ -2603,6 +2779,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + ffloor_fields_ref = Lua_CreateFieldTable(L, ffloor_opt); + #ifdef HAVE_LUA_SEGS luaL_newmetatable(L, META_SEG); lua_pushcfunction(L, seg_get); @@ -2612,6 +2790,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + seg_fields_ref = Lua_CreateFieldTable(L, seg_opt); + luaL_newmetatable(L, META_NODE); lua_pushcfunction(L, node_get); lua_setfield(L, -2, "__index"); @@ -2620,6 +2800,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); + node_fields_ref = Lua_CreateFieldTable(L, node_opt); + luaL_newmetatable(L, META_NODEBBOX); //lua_pushcfunction(L, nodebbox_get); //lua_setfield(L, -2, "__index"); @@ -2646,6 +2828,8 @@ int LUA_MapLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L, 1); + slope_fields_ref = Lua_CreateFieldTable(L, slope_opt); + luaL_newmetatable(L, META_VECTOR2); lua_pushcfunction(L, vector2_get); lua_setfield(L, -2, "__index"); @@ -2664,6 +2848,8 @@ int LUA_MapLib(lua_State *L) //lua_setfield(L, -2, "__len"); lua_pop(L, 1); + mapheaderinfo_fields_ref = Lua_CreateFieldTable(L, mapheaderinfo_opt); + LUA_PushTaggableObjectArray(L, "sectors", lib_iterateSectors, lib_getSector, diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 5c2b8b4d3..09d244c91 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -179,10 +179,12 @@ static const char *const mobj_opt[] = { #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) +static int mobj_fields_ref = LUA_NOREF; + static int mobj_get(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - enum mobj_e field = Lua_optoption(L, 2, NULL, mobj_opt); + enum mobj_e field = Lua_optoption(L, 2, -1, mobj_fields_ref); lua_settop(L, 2); if (!mo || !ISINLEVEL) { @@ -467,7 +469,7 @@ static int mobj_get(lua_State *L) static int mobj_set(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - enum mobj_e field = Lua_optoption(L, 2, mobj_opt[0], mobj_opt); + enum mobj_e field = Lua_optoption(L, 2, mobj_valid, mobj_fields_ref); lua_settop(L, 3); INLEVEL @@ -876,14 +878,55 @@ static int thingstringargs_len(lua_State *L) return 1; } +enum mapthing_e { + mapthing_valid = 0, + mapthing_x, + mapthing_y, + mapthing_angle, + mapthing_pitch, + mapthing_roll, + mapthing_type, + mapthing_options, + mapthing_scale, + mapthing_z, + mapthing_extrainfo, + mapthing_tag, + mapthing_taglist, + mapthing_args, + mapthing_stringargs, + mapthing_mobj, +}; + +const char *const mapthing_opt[] = { + "valid", + "x", + "y", + "angle", + "pitch", + "roll", + "type", + "options", + "scale", + "z", + "extrainfo", + "tag", + "taglist", + "args", + "stringargs", + "mobj", + NULL, +}; + +static int mapthing_fields_ref = LUA_NOREF; + static int mapthing_get(lua_State *L) { mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); - const char *field = luaL_checkstring(L, 2); - lua_Integer number; + enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref); + lua_settop(L, 2); if (!mt) { - if (fastcmp(field,"valid")) { + if (field == mapthing_valid) { lua_pushboolean(L, false); return 1; } @@ -892,62 +935,71 @@ static int mapthing_get(lua_State *L) return 0; } - if (fastcmp(field,"valid")) { - lua_pushboolean(L, true); - return 1; - } else if(fastcmp(field,"x")) - number = mt->x; - else if(fastcmp(field,"y")) - number = mt->y; - else if(fastcmp(field,"angle")) - number = mt->angle; - else if(fastcmp(field,"pitch")) - number = mt->pitch; - else if(fastcmp(field,"roll")) - number = mt->roll; - else if(fastcmp(field,"type")) - number = mt->type; - else if(fastcmp(field,"options")) - number = mt->options; - else if(fastcmp(field,"scale")) - number = mt->scale; - else if(fastcmp(field,"z")) - number = mt->z; - else if(fastcmp(field,"extrainfo")) - number = mt->extrainfo; - else if(fastcmp(field,"tag")) - number = Tag_FGet(&mt->tags); - else if(fastcmp(field,"taglist")) + switch (field) { - LUA_PushUserdata(L, &mt->tags, META_TAGLIST); - return 1; + case mapthing_valid: + lua_pushboolean(L, true); + break; + case mapthing_x: + lua_pushinteger(L, mt->x); + break; + case mapthing_y: + lua_pushinteger(L, mt->y); + break; + case mapthing_angle: + lua_pushinteger(L, mt->angle); + break; + case mapthing_pitch: + lua_pushinteger(L, mt->pitch); + break; + case mapthing_roll: + lua_pushinteger(L, mt->roll); + break; + case mapthing_type: + lua_pushinteger(L, mt->type); + break; + case mapthing_options: + lua_pushinteger(L, mt->options); + break; + case mapthing_scale: + lua_pushinteger(L, mt->scale); + break; + case mapthing_z: + lua_pushinteger(L, mt->z); + break; + case mapthing_extrainfo: + lua_pushinteger(L, mt->extrainfo); + break; + case mapthing_tag: + lua_pushinteger(L, Tag_FGet(&mt->tags)); + break; + case mapthing_taglist: + LUA_PushUserdata(L, &mt->tags, META_TAGLIST); + break; + case mapthing_args: + LUA_PushUserdata(L, mt->args, META_THINGARGS); + break; + case mapthing_stringargs: + LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS); + break; + case mapthing_mobj: + LUA_PushUserdata(L, mt->mobj, META_MOBJ); + break; + default: + if (devparm) + return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); + else + return 0; } - else if(fastcmp(field,"args")) - { - LUA_PushUserdata(L, mt->args, META_THINGARGS); - return 1; - } - else if(fastcmp(field,"stringargs")) - { - LUA_PushUserdata(L, mt->stringargs, META_THINGSTRINGARGS); - return 1; - } - else if(fastcmp(field,"mobj")) { - LUA_PushUserdata(L, mt->mobj, META_MOBJ); - return 1; - } else if (devparm) - return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); - else - return 0; - lua_pushinteger(L, number); return 1; } static int mapthing_set(lua_State *L) { mapthing_t *mt = *((mapthing_t **)luaL_checkudata(L, 1, META_MAPTHING)); - const char *field = luaL_checkstring(L, 2); + enum mapthing_e field = Lua_optoption(L, 2, -1, mapthing_fields_ref); + lua_settop(L, 3); if (!mt) return luaL_error(L, "accessed mapthing_t doesn't exist anymore."); @@ -957,39 +1009,52 @@ static int mapthing_set(lua_State *L) if (hook_cmd_running) return luaL_error(L, "Do not alter mapthing_t in CMD building code!"); - if(fastcmp(field,"x")) - mt->x = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"y")) - mt->y = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"angle")) - mt->angle = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"pitch")) - mt->pitch = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"roll")) - mt->roll = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"type")) - mt->type = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"options")) - mt->options = (UINT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"scale")) - mt->scale = luaL_checkfixed(L, 3); - else if(fastcmp(field,"z")) - mt->z = (INT16)luaL_checkinteger(L, 3); - else if(fastcmp(field,"extrainfo")) + switch (field) { - INT32 extrainfo = luaL_checkinteger(L, 3); - if (extrainfo & ~15) - return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); - mt->extrainfo = (UINT8)extrainfo; + case mapthing_x: + mt->x = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_y: + mt->y = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_angle: + mt->angle = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_pitch: + mt->pitch = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_roll: + mt->roll = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_type: + mt->type = (UINT16)luaL_checkinteger(L, 3); + break; + case mapthing_options: + mt->options = (UINT16)luaL_checkinteger(L, 3); + break; + case mapthing_scale: + mt->scale = luaL_checkfixed(L, 3); + break; + case mapthing_z: + mt->z = (INT16)luaL_checkinteger(L, 3); + break; + case mapthing_extrainfo: + INT32 extrainfo = luaL_checkinteger(L, 3); + if (extrainfo & ~15) + return luaL_error(L, "mapthing_t extrainfo set %d out of range (%d - %d)", extrainfo, 0, 15); + mt->extrainfo = (UINT8)extrainfo; + break; + case mapthing_tag: + Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); + break; + case mapthing_taglist: + return LUA_ErrSetDirectly(L, "mapthing_t", "taglist"); + case mapthing_mobj: + mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + break; + default: + return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); } - else if (fastcmp(field,"tag")) - Tag_FSet(&mt->tags, (INT16)luaL_checkinteger(L, 3)); - else if (fastcmp(field,"taglist")) - return LUA_ErrSetDirectly(L, "mapthing_t", "taglist"); - else if(fastcmp(field,"mobj")) - mt->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); - else - return luaL_error(L, LUA_QL("mapthing_t") " has no field named " LUA_QS, field); return 0; } @@ -1051,6 +1116,8 @@ int LUA_MobjLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + mobj_fields_ref = Lua_CreateFieldTable(L, mobj_opt); + luaL_newmetatable(L, META_THINGARGS); lua_pushcfunction(L, thingargs_get); lua_setfield(L, -2, "__index"); @@ -1078,6 +1145,8 @@ int LUA_MobjLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + mapthing_fields_ref = Lua_CreateFieldTable(L, mapthing_opt); + LUA_PushTaggableObjectArray(L, "mapthings", lib_iterateMapthings, lib_getMapthing, diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index f7e14e78f..1d06e081b 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -80,322 +80,764 @@ static int lib_lenPlayer(lua_State *L) return 1; } +enum player_e +{ + player_valid, + player_name, + player_realmo, + player_mo, + player_cmd, + player_playerstate, + player_camerascale, + player_shieldscale, + player_viewz, + player_viewheight, + player_deltaviewheight, + player_bob, + player_viewrollangle, + player_aiming, + player_drawangle, + player_rings, + player_spheres, + player_pity, + player_currentweapon, + player_ringweapons, + player_ammoremoval, + player_ammoremovaltimer, + player_ammoremovalweapon, + player_powers, + player_pflags, + player_panim, + player_flashcount, + player_flashpal, + player_skincolor, + player_skin, + player_availabilities, + player_score, + player_dashspeed, + player_normalspeed, + player_runspeed, + player_thrustfactor, + player_accelstart, + player_acceleration, + player_charability, + player_charability2, + player_charflags, + player_thokitem, + player_spinitem, + player_revitem, + player_followitem, + player_followmobj, + player_actionspd, + player_mindash, + player_maxdash, + player_jumpfactor, + player_height, + player_spinheight, + player_lives, + player_continues, + player_xtralife, + player_gotcontinue, + player_speed, + player_secondjump, + player_fly1, + player_scoreadd, + player_glidetime, + player_climbing, + player_deadtimer, + player_exiting, + player_homing, + player_dashmode, + player_skidtime, + player_cmomx, + player_cmomy, + player_rmomx, + player_rmomy, + player_numboxes, + player_totalring, + player_realtime, + player_laps, + player_ctfteam, + player_gotflag, + player_weapondelay, + player_tossdelay, + player_starpostx, + player_starposty, + player_starpostz, + player_starpostnum, + player_starposttime, + player_starpostangle, + player_starpostscale, + player_angle_pos, + player_old_angle_pos, + player_axis1, + player_axis2, + player_bumpertime, + player_flyangle, + player_drilltimer, + player_linkcount, + player_linktimer, + player_anotherflyangle, + player_nightstime, + player_drillmeter, + player_drilldelay, + player_bonustime, + player_capsule, + player_drone, + player_oldscale, + player_mare, + player_marelap, + player_marebonuslap, + player_marebegunat, + player_startedtime, + player_finishedtime, + player_lapbegunat, + player_lapstartedtime, + player_finishedspheres, + player_finishedrings, + player_marescore, + player_lastmarescore, + player_totalmarescore, + player_lastmare, + player_lastmarelap, + player_lastmarebonuslap, + player_totalmarelap, + player_totalmarebonuslap, + player_maxlink, + player_texttimer, + player_textvar, + player_lastsidehit, + player_lastlinehit, + player_losstime, + player_timeshit, + player_onconveyor, + player_awayviewmobj, + player_awayviewtics, + player_awayviewaiming, + player_spectator, + player_outofcoop, + player_bot, + player_botleader, + player_lastbuttons, + player_blocked, + player_jointime, + player_quittime, +#ifdef HWRENDER + player_fovadd, +#endif +}; + +static const char *const player_opt[] = { + "valid", + "name", + "realmo", + "mo", + "cmd", + "playerstate", + "camerascale", + "shieldscale", + "viewz", + "viewheight", + "deltaviewheight", + "bob", + "viewrollangle", + "aiming", + "drawangle", + "rings", + "spheres", + "pity", + "currentweapon", + "ringweapons", + "ammoremoval", + "ammoremovaltimer", + "ammoremovalweapon", + "powers", + "pflags", + "panim", + "flashcount", + "flashpal", + "skincolor", + "skin", + "availabilities", + "score", + "dashspeed", + "normalspeed", + "runspeed", + "thrustfactor", + "accelstart", + "acceleration", + "charability", + "charability2", + "charflags", + "thokitem", + "spinitem", + "revitem", + "followitem", + "followmobj", + "actionspd", + "mindash", + "maxdash", + "jumpfactor", + "height", + "spinheight", + "lives", + "continues", + "xtralife", + "gotcontinue", + "speed", + "secondjump", + "fly1", + "scoreadd", + "glidetime", + "climbing", + "deadtimer", + "exiting", + "homing", + "dashmode", + "skidtime", + "cmomx", + "cmomy", + "rmomx", + "rmomy", + "numboxes", + "totalring", + "realtime", + "laps", + "ctfteam", + "gotflag", + "weapondelay", + "tossdelay", + "starpostx", + "starposty", + "starpostz", + "starpostnum", + "starposttime", + "starpostangle", + "starpostscale", + "angle_pos", + "old_angle_pos", + "axis1", + "axis2", + "bumpertime", + "flyangle", + "drilltimer", + "linkcount", + "linktimer", + "anotherflyangle", + "nightstime", + "drillmeter", + "drilldelay", + "bonustime", + "capsule", + "drone", + "oldscale", + "mare", + "marelap", + "marebonuslap", + "marebegunat", + "startedtime", + "finishedtime", + "lapbegunat", + "lapstartedtime", + "finishedspheres", + "finishedrings", + "marescore", + "lastmarescore", + "totalmarescore", + "lastmare", + "lastmarelap", + "lastmarebonuslap", + "totalmarelap", + "totalmarebonuslap", + "maxlink", + "texttimer", + "textvar", + "lastsidehit", + "lastlinehit", + "losstime", + "timeshit", + "onconveyor", + "awayviewmobj", + "awayviewtics", + "awayviewaiming", + "spectator", + "outofcoop", + "bot", + "botleader", + "lastbuttons", + "blocked", + "jointime", + "quittime", +#ifdef HWRENDER + "fovadd", +#endif + NULL, +}; + +static int player_fields_ref = LUA_NOREF; + static int player_get(lua_State *L) { player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - const char *field = luaL_checkstring(L, 2); + enum player_e field = Lua_optoption(L, 2, -1, player_fields_ref); + lua_settop(L, 2); - if (!plr) { - if (fastcmp(field,"valid")) { + if (!plr) + { + if (field == player_valid) + { lua_pushboolean(L, false); return 1; } return LUA_ErrInvalid(L, "player_t"); } - if (fastcmp(field,"valid")) + switch (field) + { + case player_valid: lua_pushboolean(L, true); - else if (fastcmp(field,"name")) + break; + case player_name: lua_pushstring(L, player_names[plr-players]); - else if (fastcmp(field,"realmo")) + break; + case player_realmo: LUA_PushUserdata(L, plr->mo, META_MOBJ); + break; // Kept for backward-compatibility // Should be fixed to work like "realmo" later - else if (fastcmp(field,"mo")) - { + case player_mo: if (plr->spectator) lua_pushnil(L); else LUA_PushUserdata(L, plr->mo, META_MOBJ); - } - else if (fastcmp(field,"cmd")) + break; + case player_cmd: LUA_PushUserdata(L, &plr->cmd, META_TICCMD); - else if (fastcmp(field,"playerstate")) + break; + case player_playerstate: lua_pushinteger(L, plr->playerstate); - else if (fastcmp(field,"camerascale")) + break; + case player_camerascale: lua_pushfixed(L, plr->camerascale); - else if (fastcmp(field,"shieldscale")) + break; + case player_shieldscale: lua_pushfixed(L, plr->shieldscale); - else if (fastcmp(field,"viewz")) + break; + case player_viewz: lua_pushfixed(L, plr->viewz); - else if (fastcmp(field,"viewheight")) + break; + case player_viewheight: lua_pushfixed(L, plr->viewheight); - else if (fastcmp(field,"deltaviewheight")) + break; + case player_deltaviewheight: lua_pushfixed(L, plr->deltaviewheight); - else if (fastcmp(field,"bob")) + break; + case player_bob: lua_pushfixed(L, plr->bob); - else if (fastcmp(field,"viewrollangle")) + break; + case player_viewrollangle: lua_pushangle(L, plr->viewrollangle); - else if (fastcmp(field,"aiming")) + break; + case player_aiming: lua_pushangle(L, plr->aiming); - else if (fastcmp(field,"drawangle")) + break; + case player_drawangle: lua_pushangle(L, plr->drawangle); - else if (fastcmp(field,"rings")) + break; + case player_rings: lua_pushinteger(L, plr->rings); - else if (fastcmp(field,"spheres")) + break; + case player_spheres: lua_pushinteger(L, plr->spheres); - else if (fastcmp(field,"pity")) + break; + case player_pity: lua_pushinteger(L, plr->pity); - else if (fastcmp(field,"currentweapon")) + break; + case player_currentweapon: lua_pushinteger(L, plr->currentweapon); - else if (fastcmp(field,"ringweapons")) + break; + case player_ringweapons: lua_pushinteger(L, plr->ringweapons); - else if (fastcmp(field,"ammoremoval")) + break; + case player_ammoremoval: lua_pushinteger(L, plr->ammoremoval); - else if (fastcmp(field,"ammoremovaltimer")) + break; + case player_ammoremovaltimer: lua_pushinteger(L, plr->ammoremovaltimer); - else if (fastcmp(field,"ammoremovalweapon")) + break; + case player_ammoremovalweapon: lua_pushinteger(L, plr->ammoremovalweapon); - else if (fastcmp(field,"powers")) + break; + case player_powers: LUA_PushUserdata(L, plr->powers, META_POWERS); - else if (fastcmp(field,"pflags")) + break; + case player_pflags: lua_pushinteger(L, plr->pflags); - else if (fastcmp(field,"panim")) + break; + case player_panim: lua_pushinteger(L, plr->panim); - else if (fastcmp(field,"flashcount")) + break; + case player_flashcount: lua_pushinteger(L, plr->flashcount); - else if (fastcmp(field,"flashpal")) + break; + case player_flashpal: lua_pushinteger(L, plr->flashpal); - else if (fastcmp(field,"skincolor")) + break; + case player_skincolor: lua_pushinteger(L, plr->skincolor); - else if (fastcmp(field,"skin")) + break; + case player_skin: lua_pushinteger(L, plr->skin); - else if (fastcmp(field,"availabilities")) + break; + case player_availabilities: lua_pushinteger(L, plr->availabilities); - else if (fastcmp(field,"score")) + break; + case player_score: lua_pushinteger(L, plr->score); - else if (fastcmp(field,"dashspeed")) + break; + case player_dashspeed: lua_pushfixed(L, plr->dashspeed); - else if (fastcmp(field,"normalspeed")) + break; + case player_normalspeed: lua_pushfixed(L, plr->normalspeed); - else if (fastcmp(field,"runspeed")) + break; + case player_runspeed: lua_pushfixed(L, plr->runspeed); - else if (fastcmp(field,"thrustfactor")) + break; + case player_thrustfactor: lua_pushinteger(L, plr->thrustfactor); - else if (fastcmp(field,"accelstart")) + break; + case player_accelstart: lua_pushinteger(L, plr->accelstart); - else if (fastcmp(field,"acceleration")) + break; + case player_acceleration: lua_pushinteger(L, plr->acceleration); - else if (fastcmp(field,"charability")) + break; + case player_charability: lua_pushinteger(L, plr->charability); - else if (fastcmp(field,"charability2")) + break; + case player_charability2: lua_pushinteger(L, plr->charability2); - else if (fastcmp(field,"charflags")) + break; + case player_charflags: lua_pushinteger(L, plr->charflags); - else if (fastcmp(field,"thokitem")) + break; + case player_thokitem: lua_pushinteger(L, plr->thokitem); - else if (fastcmp(field,"spinitem")) + break; + case player_spinitem: lua_pushinteger(L, plr->spinitem); - else if (fastcmp(field,"revitem")) + break; + case player_revitem: lua_pushinteger(L, plr->revitem); - else if (fastcmp(field,"followitem")) + break; + case player_followitem: lua_pushinteger(L, plr->followitem); - else if (fastcmp(field,"followmobj")) + break; + case player_followmobj: LUA_PushUserdata(L, plr->followmobj, META_MOBJ); - else if (fastcmp(field,"actionspd")) + break; + case player_actionspd: lua_pushfixed(L, plr->actionspd); - else if (fastcmp(field,"mindash")) + break; + case player_mindash: lua_pushfixed(L, plr->mindash); - else if (fastcmp(field,"maxdash")) + break; + case player_maxdash: lua_pushfixed(L, plr->maxdash); - else if (fastcmp(field,"jumpfactor")) + break; + case player_jumpfactor: lua_pushfixed(L, plr->jumpfactor); - else if (fastcmp(field,"height")) + break; + case player_height: lua_pushfixed(L, plr->height); - else if (fastcmp(field,"spinheight")) + break; + case player_spinheight: lua_pushfixed(L, plr->spinheight); - else if (fastcmp(field,"lives")) + break; + case player_lives: lua_pushinteger(L, plr->lives); - else if (fastcmp(field,"continues")) + break; + case player_continues: lua_pushinteger(L, plr->continues); - else if (fastcmp(field,"xtralife")) + break; + case player_xtralife: lua_pushinteger(L, plr->xtralife); - else if (fastcmp(field,"gotcontinue")) + break; + case player_gotcontinue: lua_pushinteger(L, plr->gotcontinue); - else if (fastcmp(field,"speed")) + break; + case player_speed: lua_pushfixed(L, plr->speed); - else if (fastcmp(field,"secondjump")) + break; + case player_secondjump: lua_pushinteger(L, plr->secondjump); - else if (fastcmp(field,"fly1")) + break; + case player_fly1: lua_pushinteger(L, plr->fly1); - else if (fastcmp(field,"scoreadd")) + break; + case player_scoreadd: lua_pushinteger(L, plr->scoreadd); - else if (fastcmp(field,"glidetime")) + break; + case player_glidetime: lua_pushinteger(L, plr->glidetime); - else if (fastcmp(field,"climbing")) + break; + case player_climbing: lua_pushinteger(L, plr->climbing); - else if (fastcmp(field,"deadtimer")) + break; + case player_deadtimer: lua_pushinteger(L, plr->deadtimer); - else if (fastcmp(field,"exiting")) + break; + case player_exiting: lua_pushinteger(L, plr->exiting); - else if (fastcmp(field,"homing")) + break; + case player_homing: lua_pushinteger(L, plr->homing); - else if (fastcmp(field,"dashmode")) + break; + case player_dashmode: lua_pushinteger(L, plr->dashmode); - else if (fastcmp(field,"skidtime")) + break; + case player_skidtime: lua_pushinteger(L, plr->skidtime); - else if (fastcmp(field,"cmomx")) + break; + case player_cmomx: lua_pushfixed(L, plr->cmomx); - else if (fastcmp(field,"cmomy")) + break; + case player_cmomy: lua_pushfixed(L, plr->cmomy); - else if (fastcmp(field,"rmomx")) + break; + case player_rmomx: lua_pushfixed(L, plr->rmomx); - else if (fastcmp(field,"rmomy")) + break; + case player_rmomy: lua_pushfixed(L, plr->rmomy); - else if (fastcmp(field,"numboxes")) + break; + case player_numboxes: lua_pushinteger(L, plr->numboxes); - else if (fastcmp(field,"totalring")) + break; + case player_totalring: lua_pushinteger(L, plr->totalring); - else if (fastcmp(field,"realtime")) + break; + case player_realtime: lua_pushinteger(L, plr->realtime); - else if (fastcmp(field,"laps")) + break; + case player_laps: lua_pushinteger(L, plr->laps); - else if (fastcmp(field,"ctfteam")) + break; + case player_ctfteam: lua_pushinteger(L, plr->ctfteam); - else if (fastcmp(field,"gotflag")) + break; + case player_gotflag: lua_pushinteger(L, plr->gotflag); - else if (fastcmp(field,"weapondelay")) + break; + case player_weapondelay: lua_pushinteger(L, plr->weapondelay); - else if (fastcmp(field,"tossdelay")) + break; + case player_tossdelay: lua_pushinteger(L, plr->tossdelay); - else if (fastcmp(field,"starpostx")) + break; + case player_starpostx: lua_pushinteger(L, plr->starpostx); - else if (fastcmp(field,"starposty")) + break; + case player_starposty: lua_pushinteger(L, plr->starposty); - else if (fastcmp(field,"starpostz")) + break; + case player_starpostz: lua_pushinteger(L, plr->starpostz); - else if (fastcmp(field,"starpostnum")) + break; + case player_starpostnum: lua_pushinteger(L, plr->starpostnum); - else if (fastcmp(field,"starposttime")) + break; + case player_starposttime: lua_pushinteger(L, plr->starposttime); - else if (fastcmp(field,"starpostangle")) + break; + case player_starpostangle: lua_pushangle(L, plr->starpostangle); - else if (fastcmp(field,"starpostscale")) + break; + case player_starpostscale: lua_pushfixed(L, plr->starpostscale); - else if (fastcmp(field,"angle_pos")) + break; + case player_angle_pos: lua_pushangle(L, plr->angle_pos); - else if (fastcmp(field,"old_angle_pos")) + break; + case player_old_angle_pos: lua_pushangle(L, plr->old_angle_pos); - else if (fastcmp(field,"axis1")) + break; + case player_axis1: LUA_PushUserdata(L, plr->axis1, META_MOBJ); - else if (fastcmp(field,"axis2")) + break; + case player_axis2: LUA_PushUserdata(L, plr->axis2, META_MOBJ); - else if (fastcmp(field,"bumpertime")) + break; + case player_bumpertime: lua_pushinteger(L, plr->bumpertime); - else if (fastcmp(field,"flyangle")) + break; + case player_flyangle: lua_pushinteger(L, plr->flyangle); - else if (fastcmp(field,"drilltimer")) + break; + case player_drilltimer: lua_pushinteger(L, plr->drilltimer); - else if (fastcmp(field,"linkcount")) + break; + case player_linkcount: lua_pushinteger(L, plr->linkcount); - else if (fastcmp(field,"linktimer")) + break; + case player_linktimer: lua_pushinteger(L, plr->linktimer); - else if (fastcmp(field,"anotherflyangle")) + break; + case player_anotherflyangle: lua_pushinteger(L, plr->anotherflyangle); - else if (fastcmp(field,"nightstime")) + break; + case player_nightstime: lua_pushinteger(L, plr->nightstime); - else if (fastcmp(field,"drillmeter")) + break; + case player_drillmeter: lua_pushinteger(L, plr->drillmeter); - else if (fastcmp(field,"drilldelay")) + break; + case player_drilldelay: lua_pushinteger(L, plr->drilldelay); - else if (fastcmp(field,"bonustime")) + break; + case player_bonustime: lua_pushboolean(L, plr->bonustime); - else if (fastcmp(field,"capsule")) + break; + case player_capsule: LUA_PushUserdata(L, plr->capsule, META_MOBJ); - else if (fastcmp(field,"drone")) + break; + case player_drone: LUA_PushUserdata(L, plr->drone, META_MOBJ); - else if (fastcmp(field,"oldscale")) + break; + case player_oldscale: lua_pushfixed(L, plr->oldscale); - else if (fastcmp(field,"mare")) + break; + case player_mare: lua_pushinteger(L, plr->mare); - else if (fastcmp(field,"marelap")) + break; + case player_marelap: lua_pushinteger(L, plr->marelap); - else if (fastcmp(field,"marebonuslap")) + break; + case player_marebonuslap: lua_pushinteger(L, plr->marebonuslap); - else if (fastcmp(field,"marebegunat")) + break; + case player_marebegunat: lua_pushinteger(L, plr->marebegunat); - else if (fastcmp(field,"startedtime")) + break; + case player_startedtime: lua_pushinteger(L, plr->startedtime); - else if (fastcmp(field,"finishedtime")) + break; + case player_finishedtime: lua_pushinteger(L, plr->finishedtime); - else if (fastcmp(field,"lapbegunat")) + break; + case player_lapbegunat: lua_pushinteger(L, plr->lapbegunat); - else if (fastcmp(field,"lapstartedtime")) + break; + case player_lapstartedtime: lua_pushinteger(L, plr->lapstartedtime); - else if (fastcmp(field,"finishedspheres")) + break; + case player_finishedspheres: lua_pushinteger(L, plr->finishedspheres); - else if (fastcmp(field,"finishedrings")) + break; + case player_finishedrings: lua_pushinteger(L, plr->finishedrings); - else if (fastcmp(field,"marescore")) + break; + case player_marescore: lua_pushinteger(L, plr->marescore); - else if (fastcmp(field,"lastmarescore")) + break; + case player_lastmarescore: lua_pushinteger(L, plr->lastmarescore); - else if (fastcmp(field,"totalmarescore")) + break; + case player_totalmarescore: lua_pushinteger(L, plr->totalmarescore); - else if (fastcmp(field,"lastmare")) + break; + case player_lastmare: lua_pushinteger(L, plr->lastmare); - else if (fastcmp(field,"lastmarelap")) + break; + case player_lastmarelap: lua_pushinteger(L, plr->lastmarelap); - else if (fastcmp(field,"lastmarebonuslap")) + break; + case player_lastmarebonuslap: lua_pushinteger(L, plr->lastmarebonuslap); - else if (fastcmp(field,"totalmarelap")) + break; + case player_totalmarelap: lua_pushinteger(L, plr->totalmarelap); - else if (fastcmp(field,"totalmarebonuslap")) + break; + case player_totalmarebonuslap: lua_pushinteger(L, plr->totalmarebonuslap); - else if (fastcmp(field,"maxlink")) + break; + case player_maxlink: lua_pushinteger(L, plr->maxlink); - else if (fastcmp(field,"texttimer")) + break; + case player_texttimer: lua_pushinteger(L, plr->texttimer); - else if (fastcmp(field,"textvar")) + break; + case player_textvar: lua_pushinteger(L, plr->textvar); - else if (fastcmp(field,"lastsidehit")) + break; + case player_lastsidehit: lua_pushinteger(L, plr->lastsidehit); - else if (fastcmp(field,"lastlinehit")) + break; + case player_lastlinehit: lua_pushinteger(L, plr->lastlinehit); - else if (fastcmp(field,"losstime")) + break; + case player_losstime: lua_pushinteger(L, plr->losstime); - else if (fastcmp(field,"timeshit")) + break; + case player_timeshit: lua_pushinteger(L, plr->timeshit); - else if (fastcmp(field,"onconveyor")) + break; + case player_onconveyor: lua_pushinteger(L, plr->onconveyor); - else if (fastcmp(field,"awayviewmobj")) + break; + case player_awayviewmobj: LUA_PushUserdata(L, plr->awayviewmobj, META_MOBJ); - else if (fastcmp(field,"awayviewtics")) + break; + case player_awayviewtics: lua_pushinteger(L, plr->awayviewtics); - else if (fastcmp(field,"awayviewaiming")) + break; + case player_awayviewaiming: lua_pushangle(L, plr->awayviewaiming); - else if (fastcmp(field,"spectator")) + break; + case player_spectator: lua_pushboolean(L, plr->spectator); - else if (fastcmp(field,"outofcoop")) + break; + case player_outofcoop: lua_pushboolean(L, plr->outofcoop); - else if (fastcmp(field,"bot")) + break; + case player_bot: lua_pushinteger(L, plr->bot); - else if (fastcmp(field,"botleader")) + break; + case player_botleader: LUA_PushUserdata(L, plr->botleader, META_PLAYER); - else if (fastcmp(field,"lastbuttons")) + break; + case player_lastbuttons: lua_pushinteger(L, plr->lastbuttons); - else if (fastcmp(field,"blocked")) + break; + case player_blocked: lua_pushboolean(L, plr->blocked); - else if (fastcmp(field,"jointime")) + break; + case player_jointime: lua_pushinteger(L, plr->jointime); - else if (fastcmp(field,"quittime")) + break; + case player_quittime: lua_pushinteger(L, plr->quittime); + break; #ifdef HWRENDER - else if (fastcmp(field,"fovadd")) + case player_fovadd: lua_pushfixed(L, plr->fovadd); + break; #endif - else { + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, plr); lua_rawget(L, -2); if (!lua_istable(L, -1)) { // no extra values table - CONS_Debug(DBG_LUA, M_GetText("'%s' has no extvars table or field named '%s'; returning nil.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no extvars table or field named '%s'; returning nil.\n"), "player_t", lua_tostring(L, 2)); return 0; } - lua_getfield(L, -1, field); + lua_pushvalue(L, 2); // field name + lua_gettable(L, -2); if (lua_isnil(L, -1)) // no value for this field - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "player_t", lua_tostring(L, 2)); + break; } return 1; @@ -405,7 +847,7 @@ static int player_get(lua_State *L) static int player_set(lua_State *L) { player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); - const char *field = luaL_checkstring(L, 2); + enum player_e field = Lua_optoption(L, 2, player_cmd, player_fields_ref); if (!plr) return LUA_ErrInvalid(L, "player_t"); @@ -414,337 +856,473 @@ static int player_set(lua_State *L) if (hook_cmd_running) return luaL_error(L, "Do not alter player_t in CMD building code!"); - if (fastcmp(field,"mo") || fastcmp(field,"realmo")) { + switch (field) + { + case player_mo: + case player_realmo: + { mobj_t *newmo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); plr->mo->player = NULL; // remove player pointer from old mobj (newmo->player = plr)->mo = newmo; // set player pointer for new mobj, and set new mobj as the player's mobj + break; } - else if (fastcmp(field,"cmd")) + case player_cmd: return NOSET; - else if (fastcmp(field,"playerstate")) + case player_playerstate: plr->playerstate = luaL_checkinteger(L, 3); - else if (fastcmp(field,"camerascale")) + break; + case player_camerascale: plr->camerascale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"shieldscale")) + break; + case player_shieldscale: plr->shieldscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewz")) + break; + case player_viewz: plr->viewz = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewheight")) + break; + case player_viewheight: plr->viewheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"deltaviewheight")) + break; + case player_deltaviewheight: plr->deltaviewheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"bob")) + break; + case player_bob: plr->bob = luaL_checkfixed(L, 3); - else if (fastcmp(field,"viewrollangle")) + break; + case player_viewrollangle: plr->viewrollangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"aiming")) { + break; + case player_aiming: + { plr->aiming = luaL_checkangle(L, 3); if (plr == &players[consoleplayer]) localaiming = plr->aiming; else if (plr == &players[secondarydisplayplayer]) localaiming2 = plr->aiming; + break; } - else if (fastcmp(field,"drawangle")) + case player_drawangle: plr->drawangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"rings")) + break; + case player_rings: plr->rings = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"spheres")) + break; + case player_spheres: plr->spheres = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"pity")) + break; + case player_pity: plr->pity = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"currentweapon")) + break; + case player_currentweapon: plr->currentweapon = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ringweapons")) + break; + case player_ringweapons: plr->ringweapons = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremoval")) + break; + case player_ammoremoval: plr->ammoremoval = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremovaltimer")) + break; + case player_ammoremovaltimer: plr->ammoremovaltimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ammoremovalweapon")) + break; + case player_ammoremovalweapon: plr->ammoremovalweapon = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"powers")) + break; + case player_powers: return NOSET; - else if (fastcmp(field,"pflags")) + case player_pflags: plr->pflags = luaL_checkinteger(L, 3); - else if (fastcmp(field,"panim")) + break; + case player_panim: plr->panim = luaL_checkinteger(L, 3); - else if (fastcmp(field,"flashcount")) + break; + case player_flashcount: plr->flashcount = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"flashpal")) + break; + case player_flashpal: plr->flashpal = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"skincolor")) + break; + case player_skincolor: { UINT16 newcolor = (UINT16)luaL_checkinteger(L,3); if (newcolor >= numskincolors) return luaL_error(L, "player.skincolor %d out of range (0 - %d).", newcolor, numskincolors-1); plr->skincolor = newcolor; + break; } - else if (fastcmp(field,"skin")) + case player_skin: return NOSET; - else if (fastcmp(field,"availabilities")) + case player_availabilities: return NOSET; - else if (fastcmp(field,"score")) + case player_score: plr->score = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"dashspeed")) + break; + case player_dashspeed: plr->dashspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"normalspeed")) + break; + case player_normalspeed: plr->normalspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"runspeed")) + break; + case player_runspeed: plr->runspeed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"thrustfactor")) + break; + case player_thrustfactor: plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"accelstart")) + break; + case player_accelstart: plr->accelstart = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"acceleration")) + break; + case player_acceleration: plr->acceleration = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charability")) + break; + case player_charability: plr->charability = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charability2")) + break; + case player_charability2: plr->charability2 = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"charflags")) + break; + case player_charflags: plr->charflags = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"thokitem")) + break; + case player_thokitem: plr->thokitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"spinitem")) + break; + case player_spinitem: plr->spinitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"revitem")) + break; + case player_revitem: plr->revitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"followitem")) + break; + case player_followitem: plr->followitem = luaL_checkinteger(L, 3); - else if (fastcmp(field,"followmobj")) + break; + case player_followmobj: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->followmobj, mo); + break; } - else if (fastcmp(field,"actionspd")) + case player_actionspd: plr->actionspd = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"mindash")) + break; + case player_mindash: plr->mindash = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"maxdash")) + break; + case player_maxdash: plr->maxdash = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"jumpfactor")) + break; + case player_jumpfactor: plr->jumpfactor = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"height")) + break; + case player_height: plr->height = luaL_checkfixed(L, 3); - else if (fastcmp(field,"spinheight")) + break; + case player_spinheight: plr->spinheight = luaL_checkfixed(L, 3); - else if (fastcmp(field,"lives")) + break; + case player_lives: plr->lives = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"continues")) + break; + case player_continues: plr->continues = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"xtralife")) + break; + case player_xtralife: plr->xtralife = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotcontinue")) + break; + case player_gotcontinue: plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"speed")) + break; + case player_speed: plr->speed = luaL_checkfixed(L, 3); - else if (fastcmp(field,"secondjump")) + break; + case player_secondjump: plr->secondjump = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"fly1")) + break; + case player_fly1: plr->fly1 = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"scoreadd")) + break; + case player_scoreadd: plr->scoreadd = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"glidetime")) + break; + case player_glidetime: plr->glidetime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"climbing")) + break; + case player_climbing: plr->climbing = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"deadtimer")) + break; + case player_deadtimer: plr->deadtimer = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"exiting")) + break; + case player_exiting: plr->exiting = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"homing")) + break; + case player_homing: plr->homing = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"dashmode")) + break; + case player_dashmode: plr->dashmode = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"skidtime")) + break; + case player_skidtime: plr->skidtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"cmomx")) + break; + case player_cmomx: plr->cmomx = luaL_checkfixed(L, 3); - else if (fastcmp(field,"cmomy")) + break; + case player_cmomy: plr->cmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"rmomx")) + break; + case player_rmomx: plr->rmomx = luaL_checkfixed(L, 3); - else if (fastcmp(field,"rmomy")) + break; + case player_rmomy: plr->rmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"numboxes")) + break; + case player_numboxes: plr->numboxes = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalring")) + break; + case player_totalring: plr->totalring = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"realtime")) + break; + case player_realtime: plr->realtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"laps")) + break; + case player_laps: plr->laps = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"ctfteam")) + break; + case player_ctfteam: plr->ctfteam = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"gotflag")) + break; + case player_gotflag: plr->gotflag = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"weapondelay")) + break; + case player_weapondelay: plr->weapondelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"tossdelay")) + break; + case player_tossdelay: plr->tossdelay = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostx")) + break; + case player_starpostx: plr->starpostx = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposty")) + break; + case player_starposty: plr->starposty = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostz")) + break; + case player_starpostz: plr->starpostz = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostnum")) + break; + case player_starpostnum: plr->starpostnum = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starposttime")) + break; + case player_starposttime: plr->starposttime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"starpostangle")) + break; + case player_starpostangle: plr->starpostangle = luaL_checkangle(L, 3); - else if (fastcmp(field,"starpostscale")) + break; + case player_starpostscale: plr->starpostscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"angle_pos")) + break; + case player_angle_pos: plr->angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"old_angle_pos")) + break; + case player_old_angle_pos: plr->old_angle_pos = luaL_checkangle(L, 3); - else if (fastcmp(field,"axis1")) + break; + case player_axis1: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->axis1, mo); + break; } - else if (fastcmp(field,"axis2")) + case player_axis2: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->axis2, mo); + break; } - else if (fastcmp(field,"bumpertime")) + case player_bumpertime: plr->bumpertime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"flyangle")) + break; + case player_flyangle: plr->flyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilltimer")) + break; + case player_drilltimer: plr->drilltimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linkcount")) + break; + case player_linkcount: plr->linkcount = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"linktimer")) + break; + case player_linktimer: plr->linktimer = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"anotherflyangle")) + break; + case player_anotherflyangle: plr->anotherflyangle = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"nightstime")) + break; + case player_nightstime: plr->nightstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drillmeter")) + break; + case player_drillmeter: plr->drillmeter = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"drilldelay")) + break; + case player_drilldelay: plr->drilldelay = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"bonustime")) + break; + case player_bonustime: plr->bonustime = luaL_checkboolean(L, 3); - else if (fastcmp(field,"capsule")) + break; + case player_capsule: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->capsule, mo); + break; } - else if (fastcmp(field,"drone")) + case player_drone: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->drone, mo); + break; } - else if (fastcmp(field,"oldscale")) + case player_oldscale: plr->oldscale = luaL_checkfixed(L, 3); - else if (fastcmp(field,"mare")) + break; + case player_mare: plr->mare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marelap")) + break; + case player_marelap: plr->marelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebonuslap")) + break; + case player_marebonuslap: plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marebegunat")) + break; + case player_marebegunat: plr->marebegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"startedtime")) + break; + case player_startedtime: plr->startedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedtime")) + break; + case player_finishedtime: plr->finishedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapbegunat")) + break; + case player_lapbegunat: plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lapstartedtime")) + break; + case player_lapstartedtime: plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedspheres")) + break; + case player_finishedspheres: plr->finishedspheres = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"finishedrings")) + break; + case player_finishedrings: plr->finishedrings = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"marescore")) + break; + case player_marescore: plr->marescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarescore")) + break; + case player_lastmarescore: plr->lastmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarescore")) + break; + case player_totalmarescore: plr->totalmarescore = (UINT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmare")) + break; + case player_lastmare: plr->lastmare = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarelap")) + break; + case player_lastmarelap: plr->lastmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastmarebonuslap")) + break; + case player_lastmarebonuslap: plr->lastmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarelap")) + break; + case player_totalmarelap: plr->totalmarelap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"totalmarebonuslap")) + break; + case player_totalmarebonuslap: plr->totalmarebonuslap = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"maxlink")) + break; + case player_maxlink: plr->maxlink = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"texttimer")) + break; + case player_texttimer: plr->texttimer = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"textvar")) + break; + case player_textvar: plr->textvar = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastsidehit")) + break; + case player_lastsidehit: plr->lastsidehit = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"lastlinehit")) + break; + case player_lastlinehit: plr->lastlinehit = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"losstime")) + break; + case player_losstime: plr->losstime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"timeshit")) + break; + case player_timeshit: plr->timeshit = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"onconveyor")) + break; + case player_onconveyor: plr->onconveyor = (INT32)luaL_checkinteger(L, 3); - else if (fastcmp(field,"awayviewmobj")) + break; + case player_awayviewmobj: { mobj_t *mo = NULL; if (!lua_isnil(L, 3)) mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); P_SetTarget(&plr->awayviewmobj, mo); + break; } - else if (fastcmp(field,"awayviewtics")) - { + case player_awayviewtics: plr->awayviewtics = (INT32)luaL_checkinteger(L, 3); if (plr->awayviewtics && !plr->awayviewmobj) // awayviewtics must ALWAYS have an awayviewmobj set!! P_SetTarget(&plr->awayviewmobj, plr->mo); // but since the script might set awayviewmobj immediately AFTER setting awayviewtics, use player mobj as filler for now. - } - else if (fastcmp(field,"awayviewaiming")) + break; + case player_awayviewaiming: plr->awayviewaiming = luaL_checkangle(L, 3); - else if (fastcmp(field,"spectator")) + break; + case player_spectator: plr->spectator = lua_toboolean(L, 3); - else if (fastcmp(field,"outofcoop")) + break; + case player_outofcoop: plr->outofcoop = lua_toboolean(L, 3); - else if (fastcmp(field,"bot")) + break; + case player_bot: return NOSET; - else if (fastcmp(field,"botleader")) + case player_botleader: { player_t *player = NULL; if (!lua_isnil(L, 3)) player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); plr->botleader = player; + break; } - else if (fastcmp(field,"lastbuttons")) + case player_lastbuttons: plr->lastbuttons = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"blocked")) + break; + case player_blocked: plr->blocked = (UINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"jointime")) + break; + case player_jointime: plr->jointime = (tic_t)luaL_checkinteger(L, 3); - else if (fastcmp(field,"quittime")) + break; + case player_quittime: plr->quittime = (tic_t)luaL_checkinteger(L, 3); + break; #ifdef HWRENDER - else if (fastcmp(field,"fovadd")) + case player_fovadd: plr->fovadd = luaL_checkfixed(L, 3); + break; #endif - else { + default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); lua_pushlightuserdata(L, plr); @@ -752,15 +1330,17 @@ static int player_set(lua_State *L) if (lua_isnil(L, -1)) { // This index doesn't have a table for extra values yet, let's make one. lua_pop(L, 1); - CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "player_t", field); + CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; adding it as Lua data.\n"), "player_t", lua_tostring(L, 2)); lua_newtable(L); lua_pushlightuserdata(L, plr); lua_pushvalue(L, -2); // ext value table lua_rawset(L, -4); // LREG_EXTVARS table } + lua_pushvalue(L, 2); // key lua_pushvalue(L, 3); // value to store - lua_setfield(L, -2, field); + lua_settable(L, -3); lua_pop(L, 2); + break; } return 0; @@ -814,27 +1394,58 @@ static int power_len(lua_State *L) #define NOFIELD luaL_error(L, LUA_QL("ticcmd_t") " has no field named " LUA_QS, field) #define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field " LUA_QS " should not be set directly.", field) +enum ticcmd_e +{ + ticcmd_forwardmove, + ticcmd_sidemove, + ticcmd_angleturn, + ticcmd_aiming, + ticcmd_buttons, + ticcmd_latency, +}; + +static const char *const ticcmd_opt[] = { + "forwardmove", + "sidemove", + "angleturn", + "aiming", + "buttons", + "latency", + NULL, +}; + +static int ticcmd_fields_ref = LUA_NOREF; + static int ticcmd_get(lua_State *L) { ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD)); - const char *field = luaL_checkstring(L, 2); + enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref); if (!cmd) return LUA_ErrInvalid(L, "player_t"); - if (fastcmp(field,"forwardmove")) + switch (field) + { + case ticcmd_forwardmove: lua_pushinteger(L, cmd->forwardmove); - else if (fastcmp(field,"sidemove")) + break; + case ticcmd_sidemove: lua_pushinteger(L, cmd->sidemove); - else if (fastcmp(field,"angleturn")) + break; + case ticcmd_angleturn: lua_pushinteger(L, cmd->angleturn); - else if (fastcmp(field,"aiming")) + break; + case ticcmd_aiming: lua_pushinteger(L, cmd->aiming); - else if (fastcmp(field,"buttons")) + break; + case ticcmd_buttons: lua_pushinteger(L, cmd->buttons); - else if (fastcmp(field,"latency")) + break; + case ticcmd_latency: lua_pushinteger(L, cmd->latency); - else + break; + default: return NOFIELD; + } return 1; } @@ -842,27 +1453,35 @@ static int ticcmd_get(lua_State *L) static int ticcmd_set(lua_State *L) { ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD)); - const char *field = luaL_checkstring(L, 2); + enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref); if (!cmd) return LUA_ErrInvalid(L, "ticcmd_t"); if (hud_running) return luaL_error(L, "Do not alter player_t in HUD rendering code!"); - if (fastcmp(field,"forwardmove")) + switch (field) + { + case ticcmd_forwardmove: cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"sidemove")) + break; + case ticcmd_sidemove: cmd->sidemove = (SINT8)luaL_checkinteger(L, 3); - else if (fastcmp(field,"angleturn")) + break; + case ticcmd_angleturn: cmd->angleturn = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"aiming")) + break; + case ticcmd_aiming: cmd->aiming = (INT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"buttons")) + break; + case ticcmd_buttons: cmd->buttons = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"latency")) + break; + case ticcmd_latency: return NOSET; - else + default: return NOFIELD; + } return 0; } @@ -883,6 +1502,8 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + player_fields_ref = Lua_CreateFieldTable(L, player_opt); + luaL_newmetatable(L, META_POWERS); lua_pushcfunction(L, power_get); lua_setfield(L, -2, "__index"); @@ -902,6 +1523,8 @@ int LUA_PlayerLib(lua_State *L) lua_setfield(L, -2, "__newindex"); lua_pop(L,1); + ticcmd_fields_ref = Lua_CreateFieldTable(L, ticcmd_opt); + lua_newuserdata(L, 0); lua_createtable(L, 0, 2); lua_pushcfunction(L, lib_getPlayer); diff --git a/src/lua_script.c b/src/lua_script.c index 9cb146c12..6893265d5 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -1729,17 +1729,39 @@ void LUA_UnArchive(void) } // For mobj_t, player_t, etc. to take custom variables. -int Lua_optoption(lua_State *L, int narg, - const char *def, const char *const lst[]) +int Lua_optoption(lua_State *L, int narg, int def, int list_ref) { - const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); - int i; - for (i=0; lst[i]; i++) - if (fastcmp(lst[i], name)) - return i; + if (lua_isnoneornil(L, narg)) + return def; + + I_Assert(lua_checkstack(L, 2)); + luaL_checkstring(L, narg); + + lua_rawgeti(L, LUA_REGISTRYINDEX, list_ref); + I_Assert(lua_istable(L, -1)); + lua_pushvalue(L, narg); + lua_rawget(L, -2); + + if (lua_isnumber(L, -1)) + return lua_tointeger(L, -1); return -1; } +int Lua_CreateFieldTable(lua_State *L, const char *const lst[]) +{ + int i; + + lua_newtable(L); + for (i = 0; lst[i] != NULL; i++) + { + lua_pushstring(L, lst[i]); + lua_pushinteger(L, i); + lua_settable(L, -3); + } + + return luaL_ref(L, LUA_REGISTRYINDEX); +} + void LUA_PushTaggableObjectArray ( lua_State *L, const char *field, diff --git a/src/lua_script.h b/src/lua_script.h index fe04e5e60..d0b06a719 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -57,8 +57,8 @@ int LUA_PushGlobals(lua_State *L, const char *word); int LUA_CheckGlobals(lua_State *L, const char *word); void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c void LUA_CVarChanged(void *cvar); // lua_consolelib.c -int Lua_optoption(lua_State *L, int narg, - const char *def, const char *const lst[]); +int Lua_optoption(lua_State *L, int narg, int def, int list_ref); +int Lua_CreateFieldTable(lua_State *L, const char *const lst[]); void LUA_HookNetArchive(lua_CFunction archFunc); void LUA_PushTaggableObjectArray diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 5c21b04c3..b7890a6c7 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -55,6 +55,7 @@ enum skin { skin_soundsid, skin_sprites }; + static const char *const skin_opt[] = { "valid", "name", @@ -95,10 +96,12 @@ static const char *const skin_opt[] = { #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) +static int skin_fields_ref = LUA_NOREF; + static int skin_get(lua_State *L) { skin_t *skin = *((skin_t **)luaL_checkudata(L, 1, META_SKIN)); - enum skin field = luaL_checkoption(L, 2, NULL, skin_opt); + enum skin field = Lua_optoption(L, 2, -1, skin_fields_ref); // skins are always valid, only added, never removed I_Assert(skin != NULL); @@ -376,6 +379,8 @@ int LUA_SkinLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L,1); + skin_fields_ref = Lua_CreateFieldTable(L, skin_opt); + luaL_newmetatable(L, META_SOUNDSID); lua_pushcfunction(L, soundsid_get); lua_setfield(L, -2, "__index");