mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 01:01:33 +00:00
ae8bfbe763
check if LUA field exists before accessing it Closes #1168 See merge request STJr/SRB2!2261
1541 lines
36 KiB
C
1541 lines
36 KiB
C
// SONIC ROBO BLAST 2
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
|
// Copyright (C) 2012-2023 by Sonic Team Junior.
|
|
//
|
|
// 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_playerlib.c
|
|
/// \brief player object library for Lua scripting
|
|
|
|
#include "doomdef.h"
|
|
#include "fastcmp.h"
|
|
#include "p_mobj.h"
|
|
#include "d_player.h"
|
|
#include "g_game.h"
|
|
#include "p_local.h"
|
|
|
|
#include "lua_script.h"
|
|
#include "lua_libs.h"
|
|
#include "lua_hud.h" // hud_running errors
|
|
#include "lua_hook.h" // hook_cmd_running errors
|
|
|
|
static int lib_iteratePlayers(lua_State *L)
|
|
{
|
|
INT32 i = -1;
|
|
if (lua_gettop(L) < 2)
|
|
{
|
|
//return luaL_error(L, "Don't call players.iterate() directly, use it as 'for player in players.iterate do <block> end'.");
|
|
lua_pushcfunction(L, lib_iteratePlayers);
|
|
return 1;
|
|
}
|
|
lua_settop(L, 2);
|
|
lua_remove(L, 1); // state is unused.
|
|
if (!lua_isnil(L, 1))
|
|
i = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players);
|
|
for (i++; i < MAXPLAYERS; i++)
|
|
{
|
|
if (!playeringame[i])
|
|
continue;
|
|
if (!players[i].mo)
|
|
continue;
|
|
LUA_PushUserdata(L, &players[i], META_PLAYER);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lib_getPlayer(lua_State *L)
|
|
{
|
|
const char *field;
|
|
// i -> players[i]
|
|
if (lua_type(L, 2) == LUA_TNUMBER)
|
|
{
|
|
lua_Integer i = luaL_checkinteger(L, 2);
|
|
if (i < 0 || i >= MAXPLAYERS)
|
|
return luaL_error(L, "players[] index %d out of range (0 - %d)", i, MAXPLAYERS-1);
|
|
if (!playeringame[i])
|
|
return 0;
|
|
if (!players[i].mo)
|
|
return 0;
|
|
LUA_PushUserdata(L, &players[i], META_PLAYER);
|
|
return 1;
|
|
}
|
|
|
|
field = luaL_checkstring(L, 2);
|
|
if (fastcmp(field,"iterate"))
|
|
{
|
|
lua_pushcfunction(L, lib_iteratePlayers);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// #players -> MAXPLAYERS
|
|
static int lib_lenPlayer(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, MAXPLAYERS);
|
|
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_recordscore,
|
|
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,
|
|
player_lastinputtime,
|
|
player_ping,
|
|
player_fovadd
|
|
};
|
|
|
|
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",
|
|
"recordscore",
|
|
"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",
|
|
"lastinputtime",
|
|
"ping",
|
|
"fovadd",
|
|
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));
|
|
enum player_e field = Lua_optoption(L, 2, -1, player_fields_ref);
|
|
lua_settop(L, 2);
|
|
|
|
if (!plr)
|
|
{
|
|
if (field == player_valid)
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
return LUA_ErrInvalid(L, "player_t");
|
|
}
|
|
|
|
switch (field)
|
|
{
|
|
case player_valid:
|
|
lua_pushboolean(L, true);
|
|
break;
|
|
case player_name:
|
|
lua_pushstring(L, player_names[plr-players]);
|
|
break;
|
|
case player_realmo:
|
|
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
|
break;
|
|
// TODO: 2.3: Kept for backward-compatibility
|
|
// Should be fixed to work like "realmo" later
|
|
case player_mo:
|
|
if (plr->spectator)
|
|
lua_pushnil(L);
|
|
else
|
|
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
|
break;
|
|
case player_cmd:
|
|
LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
|
|
break;
|
|
case player_playerstate:
|
|
lua_pushinteger(L, plr->playerstate);
|
|
break;
|
|
case player_camerascale:
|
|
lua_pushfixed(L, plr->camerascale);
|
|
break;
|
|
case player_shieldscale:
|
|
lua_pushfixed(L, plr->shieldscale);
|
|
break;
|
|
case player_viewz:
|
|
lua_pushfixed(L, plr->viewz);
|
|
break;
|
|
case player_viewheight:
|
|
lua_pushfixed(L, plr->viewheight);
|
|
break;
|
|
case player_deltaviewheight:
|
|
lua_pushfixed(L, plr->deltaviewheight);
|
|
break;
|
|
case player_bob:
|
|
lua_pushfixed(L, plr->bob);
|
|
break;
|
|
case player_viewrollangle:
|
|
lua_pushangle(L, plr->viewrollangle);
|
|
break;
|
|
case player_aiming:
|
|
lua_pushangle(L, plr->aiming);
|
|
break;
|
|
case player_drawangle:
|
|
lua_pushangle(L, plr->drawangle);
|
|
break;
|
|
case player_rings:
|
|
lua_pushinteger(L, plr->rings);
|
|
break;
|
|
case player_spheres:
|
|
lua_pushinteger(L, plr->spheres);
|
|
break;
|
|
case player_pity:
|
|
lua_pushinteger(L, plr->pity);
|
|
break;
|
|
case player_currentweapon:
|
|
lua_pushinteger(L, plr->currentweapon);
|
|
break;
|
|
case player_ringweapons:
|
|
lua_pushinteger(L, plr->ringweapons);
|
|
break;
|
|
case player_ammoremoval:
|
|
lua_pushinteger(L, plr->ammoremoval);
|
|
break;
|
|
case player_ammoremovaltimer:
|
|
lua_pushinteger(L, plr->ammoremovaltimer);
|
|
break;
|
|
case player_ammoremovalweapon:
|
|
lua_pushinteger(L, plr->ammoremovalweapon);
|
|
break;
|
|
case player_powers:
|
|
LUA_PushUserdata(L, plr->powers, META_POWERS);
|
|
break;
|
|
case player_pflags:
|
|
lua_pushinteger(L, plr->pflags);
|
|
break;
|
|
case player_panim:
|
|
lua_pushinteger(L, plr->panim);
|
|
break;
|
|
case player_flashcount:
|
|
lua_pushinteger(L, plr->flashcount);
|
|
break;
|
|
case player_flashpal:
|
|
lua_pushinteger(L, plr->flashpal);
|
|
break;
|
|
case player_skincolor:
|
|
lua_pushinteger(L, plr->skincolor);
|
|
break;
|
|
case player_skin:
|
|
lua_pushinteger(L, plr->skin);
|
|
break;
|
|
case player_availabilities:
|
|
lua_pushinteger(L, plr->availabilities);
|
|
break;
|
|
case player_score:
|
|
lua_pushinteger(L, plr->score);
|
|
break;
|
|
case player_recordscore:
|
|
lua_pushinteger(L, plr->recordscore);
|
|
break;
|
|
case player_dashspeed:
|
|
lua_pushfixed(L, plr->dashspeed);
|
|
break;
|
|
case player_normalspeed:
|
|
lua_pushfixed(L, plr->normalspeed);
|
|
break;
|
|
case player_runspeed:
|
|
lua_pushfixed(L, plr->runspeed);
|
|
break;
|
|
case player_thrustfactor:
|
|
lua_pushinteger(L, plr->thrustfactor);
|
|
break;
|
|
case player_accelstart:
|
|
lua_pushinteger(L, plr->accelstart);
|
|
break;
|
|
case player_acceleration:
|
|
lua_pushinteger(L, plr->acceleration);
|
|
break;
|
|
case player_charability:
|
|
lua_pushinteger(L, plr->charability);
|
|
break;
|
|
case player_charability2:
|
|
lua_pushinteger(L, plr->charability2);
|
|
break;
|
|
case player_charflags:
|
|
lua_pushinteger(L, plr->charflags);
|
|
break;
|
|
case player_thokitem:
|
|
lua_pushinteger(L, plr->thokitem);
|
|
break;
|
|
case player_spinitem:
|
|
lua_pushinteger(L, plr->spinitem);
|
|
break;
|
|
case player_revitem:
|
|
lua_pushinteger(L, plr->revitem);
|
|
break;
|
|
case player_followitem:
|
|
lua_pushinteger(L, plr->followitem);
|
|
break;
|
|
case player_followmobj:
|
|
LUA_PushUserdata(L, plr->followmobj, META_MOBJ);
|
|
break;
|
|
case player_actionspd:
|
|
lua_pushfixed(L, plr->actionspd);
|
|
break;
|
|
case player_mindash:
|
|
lua_pushfixed(L, plr->mindash);
|
|
break;
|
|
case player_maxdash:
|
|
lua_pushfixed(L, plr->maxdash);
|
|
break;
|
|
case player_jumpfactor:
|
|
lua_pushfixed(L, plr->jumpfactor);
|
|
break;
|
|
case player_height:
|
|
lua_pushfixed(L, plr->height);
|
|
break;
|
|
case player_spinheight:
|
|
lua_pushfixed(L, plr->spinheight);
|
|
break;
|
|
case player_lives:
|
|
lua_pushinteger(L, plr->lives);
|
|
break;
|
|
case player_continues:
|
|
lua_pushinteger(L, plr->continues);
|
|
break;
|
|
case player_xtralife:
|
|
lua_pushinteger(L, plr->xtralife);
|
|
break;
|
|
case player_gotcontinue:
|
|
lua_pushinteger(L, plr->gotcontinue);
|
|
break;
|
|
case player_speed:
|
|
lua_pushfixed(L, plr->speed);
|
|
break;
|
|
case player_secondjump:
|
|
lua_pushinteger(L, plr->secondjump);
|
|
break;
|
|
case player_fly1:
|
|
lua_pushinteger(L, plr->fly1);
|
|
break;
|
|
case player_scoreadd:
|
|
lua_pushinteger(L, plr->scoreadd);
|
|
break;
|
|
case player_glidetime:
|
|
lua_pushinteger(L, plr->glidetime);
|
|
break;
|
|
case player_climbing:
|
|
lua_pushinteger(L, plr->climbing);
|
|
break;
|
|
case player_deadtimer:
|
|
lua_pushinteger(L, plr->deadtimer);
|
|
break;
|
|
case player_exiting:
|
|
lua_pushinteger(L, plr->exiting);
|
|
break;
|
|
case player_homing:
|
|
lua_pushinteger(L, plr->homing);
|
|
break;
|
|
case player_dashmode:
|
|
lua_pushinteger(L, plr->dashmode);
|
|
break;
|
|
case player_skidtime:
|
|
lua_pushinteger(L, plr->skidtime);
|
|
break;
|
|
case player_cmomx:
|
|
lua_pushfixed(L, plr->cmomx);
|
|
break;
|
|
case player_cmomy:
|
|
lua_pushfixed(L, plr->cmomy);
|
|
break;
|
|
case player_rmomx:
|
|
lua_pushfixed(L, plr->rmomx);
|
|
break;
|
|
case player_rmomy:
|
|
lua_pushfixed(L, plr->rmomy);
|
|
break;
|
|
case player_numboxes:
|
|
lua_pushinteger(L, plr->numboxes);
|
|
break;
|
|
case player_totalring:
|
|
lua_pushinteger(L, plr->totalring);
|
|
break;
|
|
case player_realtime:
|
|
lua_pushinteger(L, plr->realtime);
|
|
break;
|
|
case player_laps:
|
|
lua_pushinteger(L, plr->laps);
|
|
break;
|
|
case player_ctfteam:
|
|
lua_pushinteger(L, plr->ctfteam);
|
|
break;
|
|
case player_gotflag:
|
|
lua_pushinteger(L, plr->gotflag);
|
|
break;
|
|
case player_weapondelay:
|
|
lua_pushinteger(L, plr->weapondelay);
|
|
break;
|
|
case player_tossdelay:
|
|
lua_pushinteger(L, plr->tossdelay);
|
|
break;
|
|
case player_starpostx:
|
|
lua_pushinteger(L, plr->starpostx);
|
|
break;
|
|
case player_starposty:
|
|
lua_pushinteger(L, plr->starposty);
|
|
break;
|
|
case player_starpostz:
|
|
lua_pushinteger(L, plr->starpostz);
|
|
break;
|
|
case player_starpostnum:
|
|
lua_pushinteger(L, plr->starpostnum);
|
|
break;
|
|
case player_starposttime:
|
|
lua_pushinteger(L, plr->starposttime);
|
|
break;
|
|
case player_starpostangle:
|
|
lua_pushangle(L, plr->starpostangle);
|
|
break;
|
|
case player_starpostscale:
|
|
lua_pushfixed(L, plr->starpostscale);
|
|
break;
|
|
case player_angle_pos:
|
|
lua_pushangle(L, plr->angle_pos);
|
|
break;
|
|
case player_old_angle_pos:
|
|
lua_pushangle(L, plr->old_angle_pos);
|
|
break;
|
|
case player_axis1:
|
|
LUA_PushUserdata(L, plr->axis1, META_MOBJ);
|
|
break;
|
|
case player_axis2:
|
|
LUA_PushUserdata(L, plr->axis2, META_MOBJ);
|
|
break;
|
|
case player_bumpertime:
|
|
lua_pushinteger(L, plr->bumpertime);
|
|
break;
|
|
case player_flyangle:
|
|
lua_pushinteger(L, plr->flyangle);
|
|
break;
|
|
case player_drilltimer:
|
|
lua_pushinteger(L, plr->drilltimer);
|
|
break;
|
|
case player_linkcount:
|
|
lua_pushinteger(L, plr->linkcount);
|
|
break;
|
|
case player_linktimer:
|
|
lua_pushinteger(L, plr->linktimer);
|
|
break;
|
|
case player_anotherflyangle:
|
|
lua_pushinteger(L, plr->anotherflyangle);
|
|
break;
|
|
case player_nightstime:
|
|
lua_pushinteger(L, plr->nightstime);
|
|
break;
|
|
case player_drillmeter:
|
|
lua_pushinteger(L, plr->drillmeter);
|
|
break;
|
|
case player_drilldelay:
|
|
lua_pushinteger(L, plr->drilldelay);
|
|
break;
|
|
case player_bonustime:
|
|
lua_pushboolean(L, plr->bonustime);
|
|
break;
|
|
case player_capsule:
|
|
LUA_PushUserdata(L, plr->capsule, META_MOBJ);
|
|
break;
|
|
case player_drone:
|
|
LUA_PushUserdata(L, plr->drone, META_MOBJ);
|
|
break;
|
|
case player_oldscale:
|
|
lua_pushfixed(L, plr->oldscale);
|
|
break;
|
|
case player_mare:
|
|
lua_pushinteger(L, plr->mare);
|
|
break;
|
|
case player_marelap:
|
|
lua_pushinteger(L, plr->marelap);
|
|
break;
|
|
case player_marebonuslap:
|
|
lua_pushinteger(L, plr->marebonuslap);
|
|
break;
|
|
case player_marebegunat:
|
|
lua_pushinteger(L, plr->marebegunat);
|
|
break;
|
|
case player_startedtime:
|
|
lua_pushinteger(L, plr->startedtime);
|
|
break;
|
|
case player_finishedtime:
|
|
lua_pushinteger(L, plr->finishedtime);
|
|
break;
|
|
case player_lapbegunat:
|
|
lua_pushinteger(L, plr->lapbegunat);
|
|
break;
|
|
case player_lapstartedtime:
|
|
lua_pushinteger(L, plr->lapstartedtime);
|
|
break;
|
|
case player_finishedspheres:
|
|
lua_pushinteger(L, plr->finishedspheres);
|
|
break;
|
|
case player_finishedrings:
|
|
lua_pushinteger(L, plr->finishedrings);
|
|
break;
|
|
case player_marescore:
|
|
lua_pushinteger(L, plr->marescore);
|
|
break;
|
|
case player_lastmarescore:
|
|
lua_pushinteger(L, plr->lastmarescore);
|
|
break;
|
|
case player_totalmarescore:
|
|
lua_pushinteger(L, plr->totalmarescore);
|
|
break;
|
|
case player_lastmare:
|
|
lua_pushinteger(L, plr->lastmare);
|
|
break;
|
|
case player_lastmarelap:
|
|
lua_pushinteger(L, plr->lastmarelap);
|
|
break;
|
|
case player_lastmarebonuslap:
|
|
lua_pushinteger(L, plr->lastmarebonuslap);
|
|
break;
|
|
case player_totalmarelap:
|
|
lua_pushinteger(L, plr->totalmarelap);
|
|
break;
|
|
case player_totalmarebonuslap:
|
|
lua_pushinteger(L, plr->totalmarebonuslap);
|
|
break;
|
|
case player_maxlink:
|
|
lua_pushinteger(L, plr->maxlink);
|
|
break;
|
|
case player_texttimer:
|
|
lua_pushinteger(L, plr->texttimer);
|
|
break;
|
|
case player_textvar:
|
|
lua_pushinteger(L, plr->textvar);
|
|
break;
|
|
case player_lastsidehit:
|
|
lua_pushinteger(L, plr->lastsidehit);
|
|
break;
|
|
case player_lastlinehit:
|
|
lua_pushinteger(L, plr->lastlinehit);
|
|
break;
|
|
case player_losstime:
|
|
lua_pushinteger(L, plr->losstime);
|
|
break;
|
|
case player_timeshit:
|
|
lua_pushinteger(L, plr->timeshit);
|
|
break;
|
|
case player_onconveyor:
|
|
lua_pushinteger(L, plr->onconveyor);
|
|
break;
|
|
case player_awayviewmobj:
|
|
LUA_PushUserdata(L, plr->awayviewmobj, META_MOBJ);
|
|
break;
|
|
case player_awayviewtics:
|
|
lua_pushinteger(L, plr->awayviewtics);
|
|
break;
|
|
case player_awayviewaiming:
|
|
lua_pushangle(L, plr->awayviewaiming);
|
|
break;
|
|
case player_spectator:
|
|
lua_pushboolean(L, plr->spectator);
|
|
break;
|
|
case player_outofcoop:
|
|
lua_pushboolean(L, plr->outofcoop);
|
|
break;
|
|
case player_bot:
|
|
lua_pushinteger(L, plr->bot);
|
|
break;
|
|
case player_botleader:
|
|
LUA_PushUserdata(L, plr->botleader, META_PLAYER);
|
|
break;
|
|
case player_lastbuttons:
|
|
lua_pushinteger(L, plr->lastbuttons);
|
|
break;
|
|
case player_blocked:
|
|
lua_pushboolean(L, plr->blocked);
|
|
break;
|
|
case player_jointime:
|
|
lua_pushinteger(L, plr->jointime);
|
|
break;
|
|
case player_quittime:
|
|
lua_pushinteger(L, plr->quittime);
|
|
break;
|
|
case player_lastinputtime:
|
|
lua_pushinteger(L, plr->lastinputtime);
|
|
break;
|
|
case player_ping:
|
|
lua_pushinteger(L, playerpingtable[plr - players]);
|
|
break;
|
|
case player_fovadd:
|
|
lua_pushfixed(L, plr->fovadd);
|
|
break;
|
|
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", lua_tostring(L, 2));
|
|
return 0;
|
|
}
|
|
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", lua_tostring(L, 2));
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
#define NOSET luaL_error(L, LUA_QL("player_t") " field " LUA_QS " should not be set directly.", player_opt[field])
|
|
static int player_set(lua_State *L)
|
|
{
|
|
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
|
enum player_e field = Lua_optoption(L, 2, player_cmd, player_fields_ref);
|
|
if (!plr)
|
|
return LUA_ErrInvalid(L, "player_t");
|
|
|
|
if (hud_running)
|
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
|
if (hook_cmd_running)
|
|
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
|
|
|
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;
|
|
}
|
|
case player_cmd:
|
|
return NOSET;
|
|
case player_playerstate:
|
|
plr->playerstate = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_camerascale:
|
|
plr->camerascale = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_shieldscale:
|
|
plr->shieldscale = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_viewz:
|
|
plr->viewz = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_viewheight:
|
|
plr->viewheight = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_deltaviewheight:
|
|
plr->deltaviewheight = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_bob:
|
|
plr->bob = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_viewrollangle:
|
|
plr->viewrollangle = luaL_checkangle(L, 3);
|
|
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;
|
|
}
|
|
case player_drawangle:
|
|
plr->drawangle = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_rings:
|
|
plr->rings = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_spheres:
|
|
plr->spheres = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_pity:
|
|
plr->pity = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_currentweapon:
|
|
plr->currentweapon = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringweapons:
|
|
plr->ringweapons = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ammoremoval:
|
|
plr->ammoremoval = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ammoremovaltimer:
|
|
plr->ammoremovaltimer = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ammoremovalweapon:
|
|
plr->ammoremovalweapon = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_powers:
|
|
return NOSET;
|
|
case player_pflags:
|
|
plr->pflags = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_panim:
|
|
plr->panim = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flashcount:
|
|
plr->flashcount = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flashpal:
|
|
plr->flashpal = (UINT16)luaL_checkinteger(L, 3);
|
|
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;
|
|
}
|
|
case player_skin:
|
|
return NOSET;
|
|
case player_availabilities:
|
|
return NOSET;
|
|
case player_score:
|
|
plr->score = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_recordscore:
|
|
plr->recordscore = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashspeed:
|
|
plr->dashspeed = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_normalspeed:
|
|
plr->normalspeed = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_runspeed:
|
|
plr->runspeed = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_thrustfactor:
|
|
plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_accelstart:
|
|
plr->accelstart = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_acceleration:
|
|
plr->acceleration = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_charability:
|
|
plr->charability = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_charability2:
|
|
plr->charability2 = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_charflags:
|
|
plr->charflags = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_thokitem:
|
|
plr->thokitem = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_spinitem:
|
|
plr->spinitem = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_revitem:
|
|
plr->revitem = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_followitem:
|
|
plr->followitem = luaL_checkinteger(L, 3);
|
|
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;
|
|
}
|
|
case player_actionspd:
|
|
plr->actionspd = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_mindash:
|
|
plr->mindash = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_maxdash:
|
|
plr->maxdash = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_jumpfactor:
|
|
plr->jumpfactor = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_height:
|
|
plr->height = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_spinheight:
|
|
plr->spinheight = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_lives:
|
|
plr->lives = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_continues:
|
|
plr->continues = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_xtralife:
|
|
plr->xtralife = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_gotcontinue:
|
|
plr->gotcontinue = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_speed:
|
|
plr->speed = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_secondjump:
|
|
plr->secondjump = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_fly1:
|
|
plr->fly1 = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_scoreadd:
|
|
plr->scoreadd = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_glidetime:
|
|
plr->glidetime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_climbing:
|
|
plr->climbing = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_deadtimer:
|
|
plr->deadtimer = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_exiting:
|
|
plr->exiting = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_homing:
|
|
plr->homing = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashmode:
|
|
plr->dashmode = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_skidtime:
|
|
plr->skidtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_cmomx:
|
|
plr->cmomx = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_cmomy:
|
|
plr->cmomy = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_rmomx:
|
|
plr->rmomx = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_rmomy:
|
|
plr->rmomy = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_numboxes:
|
|
plr->numboxes = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_totalring:
|
|
plr->totalring = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_realtime:
|
|
plr->realtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_laps:
|
|
plr->laps = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ctfteam:
|
|
plr->ctfteam = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_gotflag:
|
|
plr->gotflag = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_weapondelay:
|
|
plr->weapondelay = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tossdelay:
|
|
plr->tossdelay = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starpostx:
|
|
plr->starpostx = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starposty:
|
|
plr->starposty = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starpostz:
|
|
plr->starpostz = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starpostnum:
|
|
plr->starpostnum = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starposttime:
|
|
plr->starposttime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starpostangle:
|
|
plr->starpostangle = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_starpostscale:
|
|
plr->starpostscale = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_angle_pos:
|
|
plr->angle_pos = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_old_angle_pos:
|
|
plr->old_angle_pos = luaL_checkangle(L, 3);
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
case player_bumpertime:
|
|
plr->bumpertime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flyangle:
|
|
plr->flyangle = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_drilltimer:
|
|
plr->drilltimer = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_linkcount:
|
|
plr->linkcount = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_linktimer:
|
|
plr->linktimer = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_anotherflyangle:
|
|
plr->anotherflyangle = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_nightstime:
|
|
plr->nightstime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_drillmeter:
|
|
plr->drillmeter = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_drilldelay:
|
|
plr->drilldelay = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bonustime:
|
|
plr->bonustime = luaL_checkboolean(L, 3);
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
case player_oldscale:
|
|
plr->oldscale = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_mare:
|
|
plr->mare = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_marelap:
|
|
plr->marelap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_marebonuslap:
|
|
plr->marebonuslap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_marebegunat:
|
|
plr->marebegunat = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_startedtime:
|
|
plr->startedtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_finishedtime:
|
|
plr->finishedtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lapbegunat:
|
|
plr->lapbegunat = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lapstartedtime:
|
|
plr->lapstartedtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_finishedspheres:
|
|
plr->finishedspheres = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_finishedrings:
|
|
plr->finishedrings = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_marescore:
|
|
plr->marescore = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastmarescore:
|
|
plr->lastmarescore = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_totalmarescore:
|
|
plr->totalmarescore = (UINT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastmare:
|
|
plr->lastmare = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastmarelap:
|
|
plr->lastmarelap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastmarebonuslap:
|
|
plr->lastmarebonuslap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_totalmarelap:
|
|
plr->totalmarelap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_totalmarebonuslap:
|
|
plr->totalmarebonuslap = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_maxlink:
|
|
plr->maxlink = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_texttimer:
|
|
plr->texttimer = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_textvar:
|
|
plr->textvar = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastsidehit:
|
|
plr->lastsidehit = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastlinehit:
|
|
plr->lastlinehit = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_losstime:
|
|
plr->losstime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_timeshit:
|
|
plr->timeshit = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_onconveyor:
|
|
plr->onconveyor = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_awayviewmobj:
|
|
{
|
|
mobj_t *mo = NULL;
|
|
if (!lua_isnil(L, 3))
|
|
mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
|
|
if (plr->awayviewmobj != mo) {
|
|
P_SetTarget(&plr->awayviewmobj, mo);
|
|
if (plr->awayviewtics) {
|
|
if (!plr->awayviewmobj)
|
|
plr->awayviewtics = 0; // can't have a NULL awayviewmobj with awayviewtics!
|
|
if (plr == &players[displayplayer])
|
|
P_ResetCamera(plr, &camera); // reset p1 camera on p1 getting an awayviewmobj
|
|
else if (splitscreen && plr == &players[secondarydisplayplayer])
|
|
P_ResetCamera(plr, &camera2); // reset p2 camera on p2 getting an awayviewmobj
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case player_awayviewtics:
|
|
{
|
|
INT32 tics = (INT32)luaL_checkinteger(L, 3);
|
|
if (tics && !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.
|
|
if ((tics && !plr->awayviewtics) || (!tics && plr->awayviewtics)) {
|
|
if (plr == &players[displayplayer])
|
|
P_ResetCamera(plr, &camera); // reset p1 camera on p1 transitioning to/from zero awayviewtics
|
|
else if (splitscreen && plr == &players[secondarydisplayplayer])
|
|
P_ResetCamera(plr, &camera2); // reset p2 camera on p2 transitioning to/from zero awayviewtics
|
|
}
|
|
plr->awayviewtics = tics;
|
|
break;
|
|
}
|
|
case player_awayviewaiming:
|
|
plr->awayviewaiming = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_spectator:
|
|
plr->spectator = lua_toboolean(L, 3);
|
|
break;
|
|
case player_outofcoop:
|
|
plr->outofcoop = lua_toboolean(L, 3);
|
|
break;
|
|
case player_bot:
|
|
return NOSET;
|
|
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;
|
|
}
|
|
case player_lastbuttons:
|
|
plr->lastbuttons = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_blocked:
|
|
plr->blocked = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_jointime:
|
|
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_quittime:
|
|
plr->quittime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastinputtime:
|
|
plr->lastinputtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_fovadd:
|
|
plr->fovadd = luaL_checkfixed(L, 3);
|
|
break;
|
|
default:
|
|
lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS);
|
|
I_Assert(lua_istable(L, -1));
|
|
lua_pushlightuserdata(L, plr);
|
|
lua_rawget(L, -2);
|
|
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", 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_settable(L, -3);
|
|
lua_pop(L, 2);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#undef NOSET
|
|
|
|
static int player_num(lua_State *L)
|
|
{
|
|
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
|
if (!plr)
|
|
return luaL_error(L, "accessed player_t doesn't exist anymore.");
|
|
lua_pushinteger(L, plr-players);
|
|
return 1;
|
|
}
|
|
|
|
// powers, p -> powers[p]
|
|
static int power_get(lua_State *L)
|
|
{
|
|
UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS));
|
|
powertype_t p = luaL_checkinteger(L, 2);
|
|
if (p >= NUMPOWERS)
|
|
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
|
|
lua_pushinteger(L, powers[p]);
|
|
return 1;
|
|
}
|
|
|
|
// powers, p, value -> powers[p] = value
|
|
static int power_set(lua_State *L)
|
|
{
|
|
UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS));
|
|
powertype_t p = luaL_checkinteger(L, 2);
|
|
UINT16 i = (UINT16)luaL_checkinteger(L, 3);
|
|
if (p >= NUMPOWERS)
|
|
return luaL_error(L, LUA_QL("powertype_t") " cannot be %d", (INT16)p);
|
|
if (hud_running)
|
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
|
if (hook_cmd_running)
|
|
return luaL_error(L, "Do not alter player_t in CMD building code!");
|
|
powers[p] = i;
|
|
return 0;
|
|
}
|
|
|
|
// #powers -> NUMPOWERS
|
|
static int power_len(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, NUMPOWERS);
|
|
return 1;
|
|
}
|
|
|
|
#define NOFIELD luaL_error(L, "%s %s", LUA_QL("ticcmd_t"), va("has no field named %ui", field))
|
|
#define NOSET luaL_error(L, LUA_QL("ticcmd_t") " field %s should not be set directly.", ticcmd_opt[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));
|
|
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
|
if (!cmd)
|
|
return LUA_ErrInvalid(L, "player_t");
|
|
|
|
if (field == (enum ticcmd_e)-1)
|
|
return LUA_ErrInvalid(L, "fields");
|
|
|
|
switch (field)
|
|
{
|
|
case ticcmd_forwardmove:
|
|
lua_pushinteger(L, cmd->forwardmove);
|
|
break;
|
|
case ticcmd_sidemove:
|
|
lua_pushinteger(L, cmd->sidemove);
|
|
break;
|
|
case ticcmd_angleturn:
|
|
lua_pushinteger(L, cmd->angleturn);
|
|
break;
|
|
case ticcmd_aiming:
|
|
lua_pushinteger(L, cmd->aiming);
|
|
break;
|
|
case ticcmd_buttons:
|
|
lua_pushinteger(L, cmd->buttons);
|
|
break;
|
|
case ticcmd_latency:
|
|
lua_pushinteger(L, cmd->latency);
|
|
break;
|
|
default:
|
|
return NOFIELD;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int ticcmd_set(lua_State *L)
|
|
{
|
|
ticcmd_t *cmd = *((ticcmd_t **)luaL_checkudata(L, 1, META_TICCMD));
|
|
enum ticcmd_e field = Lua_optoption(L, 2, -1, ticcmd_fields_ref);
|
|
if (!cmd)
|
|
return LUA_ErrInvalid(L, "ticcmd_t");
|
|
|
|
if (field == (enum ticcmd_e)-1)
|
|
return LUA_ErrInvalid(L, "fields");
|
|
|
|
if (hud_running)
|
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
|
|
|
switch (field)
|
|
{
|
|
case ticcmd_forwardmove:
|
|
cmd->forwardmove = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_sidemove:
|
|
cmd->sidemove = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_angleturn:
|
|
cmd->angleturn = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_aiming:
|
|
cmd->aiming = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_buttons:
|
|
cmd->buttons = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_latency:
|
|
return NOSET;
|
|
default:
|
|
return NOFIELD;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#undef NOFIELD
|
|
#undef NOSET
|
|
|
|
int LUA_PlayerLib(lua_State *L)
|
|
{
|
|
LUA_RegisterUserdataMetatable(L, META_PLAYER, player_get, player_set, player_num);
|
|
LUA_RegisterUserdataMetatable(L, META_POWERS, power_get, power_set, power_len);
|
|
LUA_RegisterUserdataMetatable(L, META_TICCMD, ticcmd_get, ticcmd_set, NULL);
|
|
|
|
player_fields_ref = Lua_CreateFieldTable(L, player_opt);
|
|
ticcmd_fields_ref = Lua_CreateFieldTable(L, ticcmd_opt);
|
|
|
|
LUA_RegisterGlobalUserdata(L, "players", lib_getPlayer, NULL, lib_lenPlayer);
|
|
return 0;
|
|
}
|