3120 lines
74 KiB
C
3120 lines
74 KiB
C
// BLANKART
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright (C) 2012-2016 by John "JTE" Muniz.
|
|
// Copyright (C) 2012-2020 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 "blua/lua.h"
|
|
#include "doomdef.h"
|
|
#include "p_mobj.h"
|
|
#include "d_player.h"
|
|
#include "g_game.h"
|
|
#include "p_local.h"
|
|
#include "d_clisrv.h"
|
|
#include "k_kart.h" // K_GetDriftAngleOffset
|
|
|
|
#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;
|
|
}
|
|
|
|
// Same deal as the three functions above but for displayplayers
|
|
|
|
static int lib_iterateDisplayplayers(lua_State *L)
|
|
{
|
|
INT32 i = -1;
|
|
INT32 temp = -1;
|
|
INT32 iter = 0;
|
|
|
|
if (lua_gettop(L) < 2)
|
|
{
|
|
//return luaL_error(L, "Don't call displayplayers.iterate() directly, use it as 'for player in displayplayers.iterate do <block> end'.");
|
|
lua_pushcfunction(L, lib_iterateDisplayplayers);
|
|
return 1;
|
|
}
|
|
lua_settop(L, 2);
|
|
lua_remove(L, 1); // state is unused.
|
|
if (!lua_isnil(L, 1))
|
|
{
|
|
temp = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players); // get the player # of the last iterated player.
|
|
|
|
// @FIXME:
|
|
// I didn't quite find a better way for this; Here, we go back to which player in displayplayers we last iterated to resume the for loop below for this new function call
|
|
// I don't understand enough about how the Lua stacks work to get this to work in possibly a single line.
|
|
// So anyone feel free to correct this!
|
|
|
|
for (; iter < MAXSPLITSCREENPLAYERS; iter++)
|
|
{
|
|
if (displayplayers[iter] == temp)
|
|
{
|
|
i = iter;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i++; i < MAXSPLITSCREENPLAYERS; i++)
|
|
{
|
|
if (i > r_splitscreen || !playeringame[displayplayers[i]])
|
|
return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers.
|
|
|
|
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
|
|
lua_pushinteger(L, i); // push this to recall what number we were on for the next function call. I suppose this also means you can retrieve the splitscreen player number with 'for p, n in displayplayers.iterate'!
|
|
return 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lib_getDisplayplayers(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 >= MAXSPLITSCREENPLAYERS)
|
|
return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1);
|
|
if (i > r_splitscreen)
|
|
return 0;
|
|
if (!playeringame[displayplayers[i]])
|
|
return 0;
|
|
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
|
|
return 1;
|
|
}
|
|
|
|
field = luaL_checkstring(L, 2);
|
|
if (fastcmp(field,"iterate"))
|
|
{
|
|
lua_pushcfunction(L, lib_iterateDisplayplayers);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// #displayplayers -> MAXSPLITSCREENPLAYERS
|
|
static int lib_lenDisplayplayers(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, MAXSPLITSCREENPLAYERS);
|
|
return 1;
|
|
}
|
|
|
|
// Same deal as the three functions above but for localplayers
|
|
// don't gotta fix what ain't broken
|
|
|
|
static int lib_iterateLocalplayers(lua_State *L)
|
|
{
|
|
INT32 i = lua_tonumber(L, lua_upvalueindex(1));
|
|
|
|
if (lua_gettop(L) < 2)
|
|
{
|
|
lua_pushcclosure(L, lib_iterateLocalplayers, 1);
|
|
return 1;
|
|
}
|
|
|
|
if (i <= splitscreen)
|
|
{
|
|
if (!playeringame[g_localplayers[i]] || (i > 0 && g_localplayers[i] == g_localplayers[0]))
|
|
return 0;
|
|
|
|
// Return player and splitscreen index.
|
|
LUA_PushUserdata(L, &players[g_localplayers[i]], META_PLAYER);
|
|
lua_pushnumber(L, i);
|
|
|
|
// Update splitscreen index value for next iteration.
|
|
lua_pushnumber(L, i + 1);
|
|
lua_pushvalue(L, -1);
|
|
lua_replace(L, lua_upvalueindex(1));
|
|
lua_pop(L, 1);
|
|
|
|
return 2;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int lib_getLocalplayers(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 >= MAXSPLITSCREENPLAYERS)
|
|
return luaL_error(L, "localplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1);
|
|
if (i > splitscreen)
|
|
return 0;
|
|
if (i > 0 && g_localplayers[i] == g_localplayers[0])
|
|
return 0;
|
|
if (!playeringame[g_localplayers[i]])
|
|
return 0;
|
|
LUA_PushUserdata(L, &players[g_localplayers[i]], META_PLAYER);
|
|
return 1;
|
|
}
|
|
|
|
field = luaL_checkstring(L, 2);
|
|
if (fastcmp(field,"iterate"))
|
|
{
|
|
lua_pushcclosure(L, lib_iterateLocalplayers, 1);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// #localplayers -> MAXSPLITSCREENPLAYERS
|
|
static int lib_lenLocalplayers(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, MAXSPLITSCREENPLAYERS);
|
|
return 1;
|
|
}
|
|
|
|
// player_ fields
|
|
// Please add blan-specific fields at the end (or at least after tossdelay)
|
|
#define PLAYERFIELDS(X) \
|
|
X(valid) \
|
|
X(name) \
|
|
X(mo) \
|
|
X(cmd) \
|
|
X(playerstate) \
|
|
X(viewz) \
|
|
X(viewheight) \
|
|
X(aiming) \
|
|
X(health) \
|
|
X(powers) \
|
|
X(kartstuff) \
|
|
X(frameangle) \
|
|
X(pflags) \
|
|
X(panim) \
|
|
X(flashcount) \
|
|
X(flashpal) \
|
|
X(skincolor) \
|
|
X(score) \
|
|
X(kartspeed) \
|
|
X(kartweight) \
|
|
X(charflags) \
|
|
X(lives) \
|
|
X(xtralife) \
|
|
X(speed) \
|
|
X(deadtimer) \
|
|
X(exiting) \
|
|
X(cmomx) \
|
|
X(cmomy) \
|
|
X(rmomx) \
|
|
X(rmomy) \
|
|
X(totalring) \
|
|
X(realtime) \
|
|
X(laps) \
|
|
X(ctfteam) \
|
|
X(tossdelay) \
|
|
X(starpostx) \
|
|
X(starposty) \
|
|
X(starpostz) \
|
|
X(starpostnum) \
|
|
X(starposttime) \
|
|
X(starpostangle) \
|
|
X(bumpertime) \
|
|
X(linkcount) \
|
|
X(linktimer) \
|
|
X(marescore) \
|
|
X(maxlink) \
|
|
X(lastsidehit) \
|
|
X(lastlinehit) \
|
|
X(onconveyor) \
|
|
X(awayviewmobj) \
|
|
X(awayviewtics) \
|
|
X(awayviewaiming) \
|
|
X(spectator) \
|
|
X(bot) \
|
|
X(jointime) \
|
|
X(spectatorreentry) \
|
|
X(grieftime) \
|
|
X(griefstrikes) \
|
|
X(splitscreenindex) \
|
|
X(fovadd) \
|
|
X(ping) \
|
|
\
|
|
X(realmo) \
|
|
X(oldcmd) \
|
|
X(cameraoffset) \
|
|
X(viewrollangle) \
|
|
X(tilt) \
|
|
X(drawangle) \
|
|
X(karthud) \
|
|
X(nocontrol) \
|
|
X(carry) \
|
|
X(dye) \
|
|
X(position) \
|
|
X(oldposition) \
|
|
X(positiondelay) \
|
|
X(prevcheck) \
|
|
X(nextcheck) \
|
|
X(distancetofinish) \
|
|
X(distancetofinishprev) \
|
|
X(currentwaypoint) \
|
|
X(nextwaypoint) \
|
|
X(airtime) \
|
|
X(bigwaypointgap) \
|
|
X(flashing) \
|
|
X(spinouttimer) \
|
|
X(spinouttype) \
|
|
X(flipovertimer) \
|
|
X(flipoverangle) \
|
|
X(instashield) \
|
|
X(wipeoutslow) \
|
|
X(justbumped) \
|
|
X(itemflags) \
|
|
X(outrun) \
|
|
X(outruntime) \
|
|
X(drift) \
|
|
X(driftcharge) \
|
|
X(driftboost) \
|
|
X(airdriftspeed) \
|
|
X(boostcharge) \
|
|
X(slopeboost) \
|
|
X(prevslopeboost) \
|
|
X(slopeaccel) \
|
|
X(startboost) \
|
|
X(dropdash) \
|
|
X(respawn) \
|
|
X(aizdriftstrat) \
|
|
X(aizdrifttilt) \
|
|
X(aizdriftturn) \
|
|
X(slipdashcharge) \
|
|
X(slipdashdir) \
|
|
X(offroad) \
|
|
X(pogospring) \
|
|
X(brakestop) \
|
|
X(waterskip) \
|
|
X(dashpadcooldown) \
|
|
X(boostpower) \
|
|
X(speedboost) \
|
|
X(prevspeedboost) \
|
|
X(accelboost) \
|
|
X(handleboost) \
|
|
X(boostangle) \
|
|
X(boostinfo) \
|
|
X(numsneakers) \
|
|
X(numpanels) \
|
|
X(numboosts) \
|
|
X(draftpower) \
|
|
X(draftleeway) \
|
|
X(lastdraft) \
|
|
X(tripwirestate) \
|
|
X(tripwirepass) \
|
|
X(tripwireleniency) \
|
|
X(tripwirerebounddelay) \
|
|
X(itemroulette) \
|
|
X(previtemroulette) \
|
|
X(itemblink) \
|
|
X(itemblinkmode) \
|
|
X(roulettetype) \
|
|
X(itemtype) \
|
|
X(itemamount) \
|
|
X(equippeditem) \
|
|
X(itemusecooldown) \
|
|
X(itemusecooldownmax) \
|
|
X(throwdir) \
|
|
X(sadtimer) \
|
|
X(rings) \
|
|
X(ringmin) \
|
|
X(ringmax) \
|
|
X(pickuprings) \
|
|
X(ringdelay) \
|
|
X(ringlock) \
|
|
X(ringboost) \
|
|
X(ringtime) \
|
|
X(superring) \
|
|
X(nextringaward) \
|
|
X(ringvolume) \
|
|
X(ringtransparency) \
|
|
X(airdroptime) \
|
|
X(airdropflags) \
|
|
X(ringdrop) \
|
|
X(shieldtracer) \
|
|
X(bubblecool) \
|
|
X(bubbleblowup) \
|
|
X(bubblehealth) \
|
|
X(bubbleboost) \
|
|
X(flamedash) \
|
|
X(flametimer) \
|
|
X(flamestore) \
|
|
X(hyudorotimer) \
|
|
X(stealingtimer) \
|
|
X(stolentimer) \
|
|
X(sneakertimer) \
|
|
X(realsneakertimer) \
|
|
X(floorboost) \
|
|
X(chaintimer) \
|
|
X(growshrinktimer) \
|
|
X(growcancel) \
|
|
X(squishedtimer) \
|
|
X(arrowbullet) \
|
|
X(rocketsneakertimer) \
|
|
X(invincibilitytimer) \
|
|
X(maxinvincibilitytime) \
|
|
X(invincibilitybottleneck) \
|
|
X(invincibilitycancel) \
|
|
X(invincibilitywarning) \
|
|
X(eggmanexplode) \
|
|
X(eggmanblame) \
|
|
X(bananadrag) \
|
|
X(lastjawztarget) \
|
|
X(jawztargetdelay) \
|
|
X(confirmvictim) \
|
|
X(confirmvictimdelay) \
|
|
X(dashringpulltics) \
|
|
X(dashringpushtics) \
|
|
X(dashrainbowpogo) \
|
|
X(glancedir) \
|
|
X(breathtimer) \
|
|
X(lastsafelap) \
|
|
X(lastsafestarpost) \
|
|
X(interpoints) \
|
|
X(roundscore) \
|
|
X(emeralds) \
|
|
X(bumpers) \
|
|
X(karmadelay) \
|
|
X(skin) \
|
|
X(voice_id) \
|
|
X(availabilities) \
|
|
X(followerskin) \
|
|
X(followerready) \
|
|
X(followercolor) \
|
|
X(follower) \
|
|
X(followitem) \
|
|
X(followmobj) \
|
|
X(lastspeed) \
|
|
X(latestlap) \
|
|
X(checkskip) \
|
|
X(starpostflip) \
|
|
X(spectatewait) \
|
|
X(botvars) \
|
|
X(packetloss) \
|
|
X(loop) \
|
|
X(prevonground) \
|
|
X(walltransfered) \
|
|
X(walltransferboost) \
|
|
X(recoverydashcharge) \
|
|
X(recoverydash)
|
|
|
|
enum player_e
|
|
{
|
|
#define ENUMITEM(name) player_##name,
|
|
PLAYERFIELDS(ENUMITEM)
|
|
NUMPLAYERFIELDS,
|
|
|
|
// For backward compat
|
|
player_lastlegacyfield = player_ping,
|
|
};
|
|
|
|
static const char *const player_opt[] = {
|
|
#define ENUMITEMNAME(name) #name,
|
|
PLAYERFIELDS(ENUMITEMNAME)
|
|
NULL,
|
|
};
|
|
|
|
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, NULL, player_opt);
|
|
lua_settop(L, 2);
|
|
|
|
if (!plr)
|
|
{
|
|
if (field == player_valid)
|
|
{
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
return LUA_ErrInvalid(L, "player_t");
|
|
}
|
|
|
|
// Do not let compatmode scripts access new fields
|
|
if (lua_compatmode && field > player_lastlegacyfield)
|
|
field = NUMPLAYERFIELDS;
|
|
|
|
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;
|
|
case player_mo:
|
|
if (!plr || plr->spectator)
|
|
lua_pushnil(L); // sigh
|
|
else
|
|
LUA_PushUserdata(L, plr->mo, META_MOBJ);
|
|
break;
|
|
case player_cmd:
|
|
LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
|
|
break;
|
|
case player_oldcmd:
|
|
LUA_PushUserdata(L, &plr->oldcmd, META_TICCMD);
|
|
break;
|
|
case player_playerstate:
|
|
lua_pushinteger(L, plr->playerstate);
|
|
break;
|
|
case player_health:
|
|
{
|
|
if (plr->mo)
|
|
lua_pushinteger(L, plr->mo->health);
|
|
else
|
|
lua_pushinteger(L, 0);
|
|
break;
|
|
}
|
|
case player_viewz:
|
|
lua_pushfixed(L, plr->viewz);
|
|
break;
|
|
case player_viewheight:
|
|
lua_pushfixed(L, plr->viewheight);
|
|
break;
|
|
case player_cameraoffset:
|
|
lua_pushfixed(L, plr->cameraOffset);
|
|
break;
|
|
case player_viewrollangle:
|
|
lua_pushangle(L, plr->viewrollangle);
|
|
break;
|
|
case player_tilt:
|
|
lua_pushangle(L, plr->tilt);
|
|
break;
|
|
case player_aiming:
|
|
lua_pushangle(L, plr->aiming);
|
|
break;
|
|
case player_drawangle:
|
|
if (lua_compatmode)
|
|
goto noexist;
|
|
/* FALLTHRU */
|
|
case player_frameangle:
|
|
{
|
|
angle_t angle = plr->drawangle;
|
|
if (lua_compatmode)
|
|
angle -= K_GetDriftAngleOffset(plr);
|
|
lua_pushangle(L, angle);
|
|
break;
|
|
}
|
|
case player_powers:
|
|
LUA_PushUserdata(L, plr->powers, META_POWERS);
|
|
break;
|
|
case player_kartstuff:
|
|
LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF);
|
|
break;
|
|
case player_karthud:
|
|
LUA_PushUserdata(L, plr->karthud, META_KARTHUD);
|
|
break;
|
|
case player_nocontrol:
|
|
lua_pushinteger(L, plr->nocontrol);
|
|
break;
|
|
case player_carry:
|
|
lua_pushinteger(L, plr->carry);
|
|
break;
|
|
case player_dye:
|
|
lua_pushinteger(L, plr->dye);
|
|
break;
|
|
case player_position:
|
|
lua_pushinteger(L, plr->position);
|
|
break;
|
|
case player_oldposition:
|
|
lua_pushinteger(L, plr->oldposition);
|
|
break;
|
|
case player_positiondelay:
|
|
lua_pushinteger(L, plr->positiondelay);
|
|
break;
|
|
case player_prevcheck:
|
|
lua_pushinteger(L, plr->prevcheck);
|
|
break;
|
|
case player_nextcheck:
|
|
lua_pushinteger(L, plr->nextcheck);
|
|
break;
|
|
case player_distancetofinish:
|
|
lua_pushinteger(L, plr->distancetofinish);
|
|
break;
|
|
case player_distancetofinishprev:
|
|
lua_pushinteger(L, plr->distancetofinishprev);
|
|
break;
|
|
case player_currentwaypoint:
|
|
LUA_PushUserdata(L, plr->currentwaypoint, META_WAYPOINT);
|
|
break;
|
|
case player_nextwaypoint:
|
|
LUA_PushUserdata(L, plr->nextwaypoint, META_WAYPOINT);
|
|
break;
|
|
case player_airtime:
|
|
lua_pushinteger(L, plr->airtime);
|
|
break;
|
|
case player_bigwaypointgap:
|
|
lua_pushinteger(L, plr->bigwaypointgap);
|
|
break;
|
|
case player_flashing:
|
|
lua_pushinteger(L, plr->flashing);
|
|
break;
|
|
case player_spinouttimer:
|
|
lua_pushinteger(L, plr->spinouttimer);
|
|
break;
|
|
case player_spinouttype:
|
|
lua_pushinteger(L, plr->spinouttype);
|
|
break;
|
|
case player_flipovertimer:
|
|
lua_pushinteger(L, plr->flipovertimer);
|
|
break;
|
|
case player_flipoverangle:
|
|
lua_pushinteger(L, plr->flipoverangle);
|
|
break;
|
|
case player_instashield:
|
|
lua_pushinteger(L, plr->instashield);
|
|
break;
|
|
case player_wipeoutslow:
|
|
lua_pushinteger(L, plr->wipeoutslow);
|
|
break;
|
|
case player_justbumped:
|
|
lua_pushinteger(L, plr->justbumped);
|
|
break;
|
|
case player_itemflags:
|
|
lua_pushinteger(L, plr->itemflags);
|
|
break;
|
|
case player_outrun:
|
|
lua_pushinteger(L, plr->outrun);
|
|
break;
|
|
case player_outruntime:
|
|
lua_pushinteger(L, plr->outruntime);
|
|
break;
|
|
case player_drift:
|
|
lua_pushinteger(L, plr->drift);
|
|
break;
|
|
case player_driftcharge:
|
|
lua_pushinteger(L, plr->driftcharge);
|
|
break;
|
|
case player_driftboost:
|
|
lua_pushinteger(L, plr->driftboost);
|
|
break;
|
|
case player_airdriftspeed:
|
|
lua_pushinteger(L, plr->airdriftspeed);
|
|
break;
|
|
case player_boostcharge:
|
|
lua_pushinteger(L, plr->boostcharge);
|
|
break;
|
|
case player_slopeboost:
|
|
lua_pushinteger(L, plr->slopeboost);
|
|
break;
|
|
case player_prevslopeboost:
|
|
lua_pushinteger(L, plr->prevslopeboost);
|
|
break;
|
|
case player_slopeaccel:
|
|
lua_pushinteger(L, plr->slopeaccel);
|
|
break;
|
|
case player_startboost:
|
|
lua_pushinteger(L, plr->startboost);
|
|
break;
|
|
case player_dropdash:
|
|
lua_pushinteger(L, plr->dropdash);
|
|
break;
|
|
case player_respawn:
|
|
lua_pushinteger(L, plr->respawn);
|
|
break;
|
|
case player_aizdriftstrat:
|
|
lua_pushinteger(L, plr->aizdriftstrat);
|
|
break;
|
|
case player_aizdrifttilt:
|
|
lua_pushinteger(L, plr->aizdrifttilt);
|
|
break;
|
|
case player_aizdriftturn:
|
|
lua_pushinteger(L, plr->aizdriftturn);
|
|
break;
|
|
case player_slipdashcharge:
|
|
lua_pushfixed(L, plr->slipdashcharge);
|
|
break;
|
|
case player_slipdashdir:
|
|
lua_pushinteger(L, plr->slipdashdir);
|
|
break;
|
|
case player_offroad:
|
|
lua_pushinteger(L, plr->offroad);
|
|
break;
|
|
case player_pogospring:
|
|
lua_pushinteger(L, plr->pogospring);
|
|
break;
|
|
case player_brakestop:
|
|
lua_pushinteger(L, plr->brakestop);
|
|
break;
|
|
case player_waterskip:
|
|
lua_pushinteger(L, plr->waterskip);
|
|
break;
|
|
case player_dashpadcooldown:
|
|
lua_pushinteger(L, plr->dashpadcooldown);
|
|
break;
|
|
case player_boostpower:
|
|
lua_pushinteger(L, plr->boostpower);
|
|
break;
|
|
case player_speedboost:
|
|
lua_pushinteger(L, plr->speedboost);
|
|
break;
|
|
case player_prevspeedboost:
|
|
lua_pushinteger(L, plr->prevspeedboost);
|
|
break;
|
|
case player_accelboost:
|
|
lua_pushinteger(L, plr->accelboost);
|
|
break;
|
|
case player_handleboost:
|
|
lua_pushinteger(L, plr->handleboost);
|
|
break;
|
|
case player_boostangle:
|
|
lua_pushangle(L, plr->boostangle);
|
|
break;
|
|
case player_boostinfo:
|
|
LUA_PushUserdata(L, &plr->boostinfo, META_BOOSTINFO);
|
|
break;
|
|
case player_numsneakers:
|
|
lua_pushinteger(L, plr->numsneakers);
|
|
break;
|
|
case player_numpanels:
|
|
lua_pushinteger(L, plr->numpanels);
|
|
break;
|
|
case player_numboosts:
|
|
lua_pushinteger(L, plr->numboosts);
|
|
break;
|
|
case player_draftpower:
|
|
lua_pushinteger(L, plr->draftpower);
|
|
break;
|
|
case player_draftleeway:
|
|
lua_pushinteger(L, plr->draftleeway);
|
|
break;
|
|
case player_lastdraft:
|
|
lua_pushinteger(L, plr->lastdraft);
|
|
break;
|
|
case player_tripwirestate:
|
|
lua_pushinteger(L, plr->tripwireState);
|
|
break;
|
|
case player_tripwirepass:
|
|
lua_pushinteger(L, plr->tripwirePass);
|
|
break;
|
|
case player_tripwireleniency:
|
|
lua_pushinteger(L, plr->tripwireLeniency);
|
|
break;
|
|
case player_tripwirerebounddelay:
|
|
lua_pushinteger(L, plr->tripwireReboundDelay);
|
|
break;
|
|
case player_itemroulette:
|
|
lua_pushinteger(L, plr->itemroulette);
|
|
break;
|
|
case player_previtemroulette:
|
|
lua_pushinteger(L, plr->previtemroulette);
|
|
break;
|
|
case player_itemblink:
|
|
lua_pushinteger(L, plr->itemblink);
|
|
break;
|
|
case player_itemblinkmode:
|
|
lua_pushinteger(L, plr->itemblinkmode);
|
|
break;
|
|
case player_roulettetype:
|
|
lua_pushinteger(L, plr->roulettetype);
|
|
break;
|
|
case player_itemtype:
|
|
lua_pushinteger(L, plr->itemtype);
|
|
break;
|
|
case player_itemamount:
|
|
lua_pushinteger(L, plr->itemamount);
|
|
break;
|
|
case player_equippeditem:
|
|
lua_pushinteger(L, plr->equippeditem);
|
|
break;
|
|
case player_itemusecooldown:
|
|
lua_pushinteger(L, plr->itemusecooldown);
|
|
break;
|
|
case player_itemusecooldownmax:
|
|
lua_pushinteger(L, plr->itemusecooldownmax);
|
|
break;
|
|
case player_throwdir:
|
|
lua_pushinteger(L, plr->throwdir);
|
|
break;
|
|
case player_sadtimer:
|
|
lua_pushinteger(L, plr->sadtimer);
|
|
break;
|
|
case player_rings:
|
|
lua_pushinteger(L, plr->rings);
|
|
break;
|
|
case player_ringmin:
|
|
lua_pushinteger(L, plr->ringmin);
|
|
break;
|
|
case player_ringmax:
|
|
lua_pushinteger(L, plr->ringmax);
|
|
break;
|
|
case player_pickuprings:
|
|
lua_pushinteger(L, plr->pickuprings);
|
|
break;
|
|
case player_ringdelay:
|
|
lua_pushinteger(L, plr->ringdelay);
|
|
break;
|
|
case player_ringlock:
|
|
lua_pushinteger(L, plr->ringlock);
|
|
break;
|
|
case player_ringboost:
|
|
lua_pushinteger(L, plr->ringboost);
|
|
break;
|
|
case player_ringtime:
|
|
lua_pushinteger(L, plr->ringtime);
|
|
break;
|
|
case player_superring:
|
|
lua_pushinteger(L, plr->superring);
|
|
break;
|
|
case player_nextringaward:
|
|
lua_pushinteger(L, plr->nextringaward);
|
|
break;
|
|
case player_ringvolume:
|
|
lua_pushinteger(L, plr->ringvolume);
|
|
break;
|
|
case player_ringtransparency:
|
|
lua_pushinteger(L, plr->ringtransparency);
|
|
break;
|
|
case player_airdroptime:
|
|
lua_pushinteger(L, plr->airdroptime);
|
|
break;
|
|
case player_airdropflags:
|
|
lua_pushinteger(L, plr->airdropflags);
|
|
break;
|
|
/*case player_ringdrop:
|
|
lua_pushinteger(L, plr->ringdrop);
|
|
break;*/
|
|
case player_shieldtracer:
|
|
LUA_PushUserdata(L, plr->shieldtracer, META_MOBJ);
|
|
break;
|
|
case player_bubblecool:
|
|
lua_pushinteger(L, plr->bubblecool);
|
|
break;
|
|
case player_bubbleblowup:
|
|
lua_pushinteger(L, plr->bubbleblowup);
|
|
break;
|
|
case player_bubblehealth:
|
|
lua_pushinteger(L, plr->bubblehealth);
|
|
break;
|
|
case player_bubbleboost:
|
|
lua_pushinteger(L, plr->bubbleboost);
|
|
break;
|
|
case player_flamedash:
|
|
lua_pushinteger(L, plr->flamedash);
|
|
break;
|
|
case player_flametimer:
|
|
lua_pushinteger(L, plr->flametimer);
|
|
break;
|
|
case player_flamestore:
|
|
lua_pushinteger(L, plr->flamestore);
|
|
break;
|
|
case player_hyudorotimer:
|
|
lua_pushinteger(L, plr->hyudorotimer);
|
|
break;
|
|
case player_stealingtimer:
|
|
lua_pushinteger(L, plr->stealingtimer);
|
|
break;
|
|
case player_stolentimer:
|
|
lua_pushinteger(L, plr->stolentimer);
|
|
break;
|
|
case player_sneakertimer:
|
|
lua_pushinteger(L, plr->sneakertimer);
|
|
break;
|
|
case player_realsneakertimer:
|
|
lua_pushinteger(L, plr->realsneakertimer);
|
|
break;
|
|
case player_floorboost:
|
|
lua_pushinteger(L, plr->floorboost);
|
|
break;
|
|
case player_chaintimer:
|
|
lua_pushinteger(L, plr->chaintimer);
|
|
break;
|
|
case player_growshrinktimer:
|
|
lua_pushinteger(L, plr->growshrinktimer);
|
|
break;
|
|
case player_growcancel:
|
|
lua_pushinteger(L, plr->growcancel);
|
|
break;
|
|
case player_squishedtimer:
|
|
lua_pushinteger(L, plr->squishedtimer);
|
|
break;
|
|
case player_arrowbullet:
|
|
LUA_PushUserdata(L, plr->arrowbullet, META_MOBJ);
|
|
break;
|
|
case player_rocketsneakertimer:
|
|
lua_pushinteger(L, plr->rocketsneakertimer);
|
|
break;
|
|
case player_invincibilitytimer:
|
|
lua_pushinteger(L, plr->invincibilitytimer);
|
|
break;
|
|
case player_maxinvincibilitytime:
|
|
lua_pushinteger(L, plr->maxinvincibilitytime);
|
|
break;
|
|
case player_invincibilitybottleneck:
|
|
// Push as an INT16 due to the negative value signal systems.
|
|
lua_pushinteger(L, (INT16)plr->invincibilitybottleneck);
|
|
break;
|
|
case player_invincibilitycancel:
|
|
lua_pushinteger(L, plr->invincibilitycancel);
|
|
break;
|
|
case player_invincibilitywarning:
|
|
lua_pushboolean(L, (boolean)plr->invincibilitywarning);
|
|
break;
|
|
case player_eggmanexplode:
|
|
lua_pushinteger(L, plr->eggmanexplode);
|
|
break;
|
|
case player_eggmanblame:
|
|
lua_pushinteger(L, plr->eggmanblame);
|
|
break;
|
|
case player_bananadrag:
|
|
lua_pushinteger(L, plr->bananadrag);
|
|
break;
|
|
case player_lastjawztarget:
|
|
lua_pushinteger(L, plr->lastjawztarget);
|
|
break;
|
|
case player_jawztargetdelay:
|
|
lua_pushinteger(L, plr->jawztargetdelay);
|
|
break;
|
|
case player_dashringpulltics:
|
|
lua_pushinteger(L, plr->dashRingPullTics);
|
|
break;
|
|
case player_dashringpushtics:
|
|
lua_pushinteger(L, plr->dashRingPushTics);
|
|
break;
|
|
case player_dashrainbowpogo:
|
|
lua_pushinteger(L, plr->dashRainbowPogo);
|
|
break;
|
|
case player_glancedir:
|
|
lua_pushinteger(L, plr->glanceDir);
|
|
break;
|
|
case player_breathtimer:
|
|
lua_pushinteger(L, plr->breathTimer);
|
|
break;
|
|
case player_lastsafelap:
|
|
lua_pushinteger(L, plr->lastsafelap);
|
|
break;
|
|
case player_lastsafestarpost:
|
|
lua_pushinteger(L, plr->lastsafestarpost);
|
|
break;
|
|
case player_interpoints:
|
|
lua_pushinteger(L, plr->interpoints);
|
|
break;
|
|
case player_roundscore:
|
|
case player_marescore:
|
|
lua_pushinteger(L, plr->roundscore);
|
|
break;
|
|
case player_emeralds:
|
|
lua_pushinteger(L, plr->emeralds);
|
|
break;
|
|
case player_bumpers:
|
|
lua_pushinteger(L, plr->bumper);
|
|
break;
|
|
case player_karmadelay:
|
|
lua_pushinteger(L, plr->karmadelay);
|
|
break;
|
|
case player_pflags:
|
|
{
|
|
UINT32 pflags = plr->pflags;
|
|
|
|
if (lua_compatmode && plr->carry == CR_SLIDING)
|
|
pflags |= PF_SLIDING;
|
|
|
|
if (lua_compatmode && (plr->oldcmd.buttons & BT_ATTACK))
|
|
pflags |= PF_ATTACKDOWN;
|
|
|
|
if (lua_compatmode && (plr->oldcmd.buttons & BT_BRAKE))
|
|
pflags |= PF_USEDOWN;
|
|
|
|
lua_pushinteger(L, 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_voice_id:
|
|
lua_pushinteger(L, plr->voice_id);
|
|
break;
|
|
/*case player_availabilities:
|
|
lua_pushinteger(L, plr->availabilities);
|
|
break;*/
|
|
case player_score:
|
|
lua_pushinteger(L, plr->score);
|
|
break;
|
|
// SRB2kart
|
|
case player_kartspeed:
|
|
lua_pushinteger(L, plr->kartspeed);
|
|
break;
|
|
case player_kartweight:
|
|
lua_pushinteger(L, plr->kartweight);
|
|
break;
|
|
case player_followerskin:
|
|
lua_pushinteger(L, plr->followerskin);
|
|
break;
|
|
case player_followerready:
|
|
lua_pushboolean(L, plr->followerready);
|
|
break;
|
|
case player_followercolor:
|
|
lua_pushinteger(L, plr->followercolor);
|
|
break;
|
|
case player_follower:
|
|
LUA_PushUserdata(L, plr->follower, META_MOBJ);
|
|
break;
|
|
//
|
|
case player_charflags:
|
|
lua_pushinteger(L, plr->charflags);
|
|
break;
|
|
case player_followitem:
|
|
lua_pushinteger(L, plr->followitem);
|
|
break;
|
|
case player_followmobj:
|
|
LUA_PushUserdata(L, plr->followmobj, META_MOBJ);
|
|
break;
|
|
case player_lives:
|
|
lua_pushinteger(L, plr->lives);
|
|
break;
|
|
case player_xtralife:
|
|
lua_pushinteger(L, plr->xtralife);
|
|
break;
|
|
case player_speed:
|
|
lua_pushfixed(L, plr->speed);
|
|
break;
|
|
case player_lastspeed:
|
|
lua_pushfixed(L, plr->lastspeed);
|
|
break;
|
|
case player_deadtimer:
|
|
lua_pushinteger(L, plr->deadtimer);
|
|
break;
|
|
case player_exiting:
|
|
lua_pushinteger(L, plr->exiting);
|
|
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_totalring:
|
|
lua_pushinteger(L, plr->totalring);
|
|
break;
|
|
case player_realtime:
|
|
lua_pushinteger(L, plr->realtime);
|
|
break;
|
|
case player_laps:
|
|
{
|
|
if (lua_compatmode)
|
|
lua_pushinteger(L, max(plr->laps - 1, 0));
|
|
else
|
|
lua_pushinteger(L, plr->laps);
|
|
break;
|
|
}
|
|
case player_latestlap:
|
|
{
|
|
if (lua_compatmode)
|
|
lua_pushinteger(L, max(plr->latestlap - 1, 0));
|
|
else
|
|
lua_pushinteger(L, plr->latestlap);
|
|
break;
|
|
}
|
|
case player_ctfteam:
|
|
lua_pushinteger(L, plr->ctfteam);
|
|
break;
|
|
case player_tossdelay:
|
|
case player_checkskip:
|
|
lua_pushinteger(L, plr->checkskip);
|
|
break;
|
|
case player_starpostx:
|
|
lua_pushfixed(L, plr->starpostx >> (lua_compatmode ? 16 : 0));
|
|
break;
|
|
case player_starposty:
|
|
lua_pushfixed(L, plr->starposty >> (lua_compatmode ? 16 : 0));
|
|
break;
|
|
case player_starpostz:
|
|
lua_pushfixed(L, plr->starpostz >> (lua_compatmode ? 16 : 0));
|
|
break;
|
|
case player_starpostangle:
|
|
lua_pushangle(L, plr->starpostangle);
|
|
break;
|
|
case player_starpostflip:
|
|
lua_pushboolean(L, plr->starpostflip);
|
|
break;
|
|
case player_starpostnum:
|
|
lua_pushinteger(L, plr->starpostnum);
|
|
break;
|
|
case player_starposttime:
|
|
lua_pushinteger(L, plr->starposttime);
|
|
break;
|
|
case player_lastsidehit:
|
|
lua_pushinteger(L, plr->lastsidehit);
|
|
break;
|
|
case player_lastlinehit:
|
|
lua_pushinteger(L, plr->lastlinehit);
|
|
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_spectatewait:
|
|
lua_pushinteger(L, plr->spectatewait);
|
|
break;
|
|
case player_bot:
|
|
lua_pushboolean(L, plr->bot);
|
|
break;
|
|
case player_botvars:
|
|
LUA_PushUserdata(L, &plr->botvars, META_BOTVARS);
|
|
break;
|
|
case player_jointime:
|
|
lua_pushinteger(L, plr->jointime);
|
|
break;
|
|
case player_spectatorreentry:
|
|
lua_pushinteger(L, plr->spectatorreentry);
|
|
break;
|
|
case player_grieftime:
|
|
lua_pushinteger(L, plr->grieftime);
|
|
break;
|
|
case player_griefstrikes:
|
|
lua_pushinteger(L, plr->griefstrikes);
|
|
break;
|
|
case player_splitscreenindex:
|
|
lua_pushinteger(L, plr->splitscreenindex);
|
|
break;
|
|
case player_bumpertime:
|
|
lua_pushinteger(L, plr->bumpertime);
|
|
break;
|
|
case player_linkcount:
|
|
lua_pushinteger(L, plr->linkcount);
|
|
break;
|
|
case player_linktimer:
|
|
lua_pushinteger(L, plr->linktimer);
|
|
break;
|
|
case player_maxlink:
|
|
lua_pushinteger(L, plr->maxlink);
|
|
break;
|
|
case player_ping:
|
|
lua_pushinteger(L, playerpingtable[( plr - players )]);
|
|
break;
|
|
case player_packetloss:
|
|
lua_pushinteger(L, playerpacketlosstable[plr - players]);
|
|
break;
|
|
case player_loop:
|
|
LUA_PushUserdata(L, &plr->loop, META_SONICLOOPVARS);
|
|
break;
|
|
case player_prevonground:
|
|
lua_pushboolean(L, plr->prevonground);
|
|
break;
|
|
case player_walltransfered:
|
|
lua_pushboolean(L, plr->walltransfered);
|
|
break;
|
|
case player_walltransferboost:
|
|
lua_pushinteger(L, plr->walltransferboost);
|
|
break;
|
|
case player_recoverydashcharge:
|
|
lua_pushinteger(L, plr->recoverydashcharge);
|
|
break;
|
|
case player_recoverydash:
|
|
lua_pushinteger(L, plr->recoverydash);
|
|
break;
|
|
#ifdef HWRENDER
|
|
case player_fovadd:
|
|
lua_pushfixed(L, plr->fovadd);
|
|
break;
|
|
#endif
|
|
default:
|
|
noexist:
|
|
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_opt[player_cmd], player_opt);
|
|
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!");
|
|
|
|
// Do not let compatmode scripts access new fields
|
|
if (lua_compatmode && field > player_lastlegacyfield)
|
|
field = NUMPLAYERFIELDS;
|
|
|
|
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_oldcmd:
|
|
return NOSET;
|
|
case player_playerstate:
|
|
plr->playerstate = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_health:
|
|
if (plr->mo)
|
|
plr->mo->health = luaL_checkinteger(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_cameraoffset:
|
|
plr->cameraOffset = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_viewrollangle:
|
|
plr->viewrollangle = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_tilt:
|
|
plr->tilt = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_aiming:
|
|
{
|
|
UINT8 i;
|
|
plr->aiming = luaL_checkangle(L, 3);
|
|
for (i = 0; i <= r_splitscreen; i++)
|
|
{
|
|
if (plr == &players[displayplayers[i]])
|
|
{
|
|
localaiming[i] = plr->aiming;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case player_drawangle:
|
|
if (lua_compatmode)
|
|
goto noexist;
|
|
/* FALLTHRU */
|
|
case player_frameangle:
|
|
{
|
|
angle_t angle = luaL_checkangle(L, 3);
|
|
if (lua_compatmode && plr->mo && angle == plr->mo->angle)
|
|
// attempt to fix e.g. acrobasics not accounting for drift when resetting frameangle
|
|
angle += K_GetDriftAngleOffset(plr);
|
|
plr->drawangle = angle;
|
|
break;
|
|
}
|
|
case player_pflags:
|
|
{
|
|
UINT32 pflags = luaL_checkinteger(L, 3);
|
|
|
|
if (lua_compatmode)
|
|
{
|
|
if (pflags & PF_SLIDING)
|
|
plr->carry = CR_SLIDING;
|
|
else if (plr->carry == CR_SLIDING)
|
|
plr->carry = CR_NONE;
|
|
|
|
if (pflags & PF_ATTACKDOWN)
|
|
plr->oldcmd.buttons |= BT_ATTACK;
|
|
else
|
|
plr->oldcmd.buttons &= ~BT_ATTACK;
|
|
|
|
if (pflags & PF_USEDOWN)
|
|
plr->oldcmd.buttons |= BT_BRAKE;
|
|
else
|
|
plr->oldcmd.buttons &= ~BT_BRAKE;
|
|
}
|
|
|
|
plr->pflags = pflags;
|
|
break;
|
|
}
|
|
case player_panim:
|
|
plr->panim = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flashcount:
|
|
plr->flashcount = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flashpal:
|
|
plr->flashpal = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_skincolor:
|
|
{
|
|
UINT16 newcolor = 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_voice_id:
|
|
return NOSET;
|
|
/*case player_availabilities:
|
|
return NOSET;*/
|
|
case player_score:
|
|
plr->score = luaL_checkinteger(L, 3);
|
|
break;
|
|
// SRB2kart
|
|
case player_kartstuff:
|
|
return NOSET;
|
|
case player_nocontrol:
|
|
plr->nocontrol = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_carry:
|
|
plr->carry = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dye:
|
|
plr->dye = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_position:
|
|
plr->position = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_oldposition:
|
|
plr->oldposition = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_positiondelay:
|
|
plr->positiondelay = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_prevcheck:
|
|
plr->prevcheck = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_nextcheck:
|
|
plr->nextcheck = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_distancetofinish:
|
|
plr->distancetofinish = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_distancetofinishprev:
|
|
plr->distancetofinishprev = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_currentwaypoint:
|
|
return NOSET;
|
|
break;
|
|
case player_nextwaypoint:
|
|
return NOSET;
|
|
break;
|
|
case player_airtime:
|
|
plr->airtime = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bigwaypointgap:
|
|
plr->bigwaypointgap = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flashing:
|
|
plr->flashing = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_spinouttimer:
|
|
plr->spinouttimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_spinouttype:
|
|
plr->spinouttype = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flipovertimer:
|
|
plr->flipovertimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flipoverangle:
|
|
plr->flipoverangle = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_instashield:
|
|
plr->instashield = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_wipeoutslow:
|
|
plr->wipeoutslow = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_justbumped:
|
|
plr->justbumped = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemflags:
|
|
plr->itemflags = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_outrun:
|
|
plr->outrun = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_outruntime:
|
|
plr->outruntime = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_drift:
|
|
plr->drift = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_driftcharge:
|
|
plr->driftcharge = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_driftboost:
|
|
plr->driftboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_airdriftspeed:
|
|
plr->airdriftspeed = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_boostcharge:
|
|
plr->boostcharge = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_slopeboost:
|
|
plr->slopeboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_prevslopeboost:
|
|
plr->prevslopeboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_slopeaccel:
|
|
plr->slopeaccel = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_startboost:
|
|
plr->startboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dropdash:
|
|
plr->dropdash = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_respawn:
|
|
plr->respawn = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_aizdriftstrat:
|
|
plr->aizdriftstrat = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_aizdrifttilt:
|
|
plr->aizdrifttilt = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_aizdriftturn:
|
|
plr->aizdriftturn = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_slipdashcharge:
|
|
plr->slipdashcharge = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_slipdashdir:
|
|
plr->slipdashdir = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_offroad:
|
|
plr->offroad = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_pogospring:
|
|
plr->pogospring = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_brakestop:
|
|
plr->brakestop = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_waterskip:
|
|
plr->waterskip = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashpadcooldown:
|
|
plr->dashpadcooldown = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_boostpower:
|
|
plr->boostpower = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_speedboost:
|
|
plr->speedboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_prevspeedboost:
|
|
plr->prevspeedboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_accelboost:
|
|
plr->accelboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_handleboost:
|
|
plr->handleboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_boostangle:
|
|
plr->boostangle = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_boostinfo:
|
|
return NOSET;
|
|
break;
|
|
case player_numsneakers:
|
|
plr->numsneakers = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_numpanels:
|
|
plr->numpanels = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_numboosts:
|
|
plr->numboosts = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_draftpower:
|
|
plr->draftpower = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_draftleeway:
|
|
plr->draftleeway = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastdraft:
|
|
plr->lastdraft = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tripwirestate:
|
|
plr->tripwireState = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tripwirepass:
|
|
plr->tripwirePass = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tripwireleniency:
|
|
plr->tripwireLeniency = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tripwirerebounddelay:
|
|
plr->tripwireReboundDelay = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemroulette:
|
|
plr->itemroulette = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_previtemroulette:
|
|
plr->previtemroulette = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemblink:
|
|
plr->itemblink = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemblinkmode:
|
|
plr->itemblinkmode = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_roulettetype:
|
|
plr->roulettetype = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemtype:
|
|
plr->itemtype = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemamount:
|
|
plr->itemamount = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemusecooldown:
|
|
plr->itemusecooldown = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_itemusecooldownmax:
|
|
plr->itemusecooldownmax = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_throwdir:
|
|
plr->throwdir = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_sadtimer:
|
|
plr->sadtimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_rings:
|
|
plr->rings = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringmin:
|
|
plr->ringmin = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringmax:
|
|
plr->ringmax = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_pickuprings:
|
|
plr->pickuprings = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringdelay:
|
|
plr->ringdelay = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringlock:
|
|
plr->ringlock = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringboost:
|
|
plr->ringboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringtime:
|
|
plr->ringtime = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_superring:
|
|
plr->superring = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_nextringaward:
|
|
plr->nextringaward = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringvolume:
|
|
plr->ringvolume = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ringtransparency:
|
|
plr->ringtransparency = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_airdroptime:
|
|
plr->airdroptime = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_airdropflags:
|
|
plr->airdropflags = luaL_checkinteger(L, 3);
|
|
break;
|
|
/*case player_ringdrop:
|
|
plr->ringdrop = luaL_checkinteger(L, 3);
|
|
break;*/
|
|
case player_shieldtracer:
|
|
return NOSET;
|
|
case player_bubblecool:
|
|
plr->bubblecool = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bubbleblowup:
|
|
plr->bubbleblowup = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bubblehealth:
|
|
plr->bubblehealth = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bubbleboost:
|
|
plr->bubbleboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flamedash:
|
|
plr->flamedash = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flametimer:
|
|
plr->flametimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_flamestore:
|
|
plr->flamestore = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_hyudorotimer:
|
|
plr->hyudorotimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_stealingtimer:
|
|
plr->stealingtimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_stolentimer:
|
|
plr->stealingtimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_sneakertimer:
|
|
plr->sneakertimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_realsneakertimer:
|
|
plr->realsneakertimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_floorboost:
|
|
plr->floorboost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_chaintimer:
|
|
plr->chaintimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_growshrinktimer:
|
|
plr->growshrinktimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_growcancel:
|
|
plr->growcancel = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_squishedtimer:
|
|
{
|
|
// Unsquish for the ease of Lua programmers
|
|
INT16 squishtimer = (INT16)luaL_checkinteger(L, 3);
|
|
|
|
if (squishtimer == 0)
|
|
plr->mo->spriteyscale = FRACUNIT;
|
|
|
|
plr->squishedtimer = squishtimer;
|
|
break;
|
|
}
|
|
case player_arrowbullet:
|
|
return NOSET;
|
|
case player_rocketsneakertimer:
|
|
plr->rocketsneakertimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_invincibilitytimer:
|
|
plr->invincibilitytimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_maxinvincibilitytime:
|
|
{
|
|
UINT16 maxinv = max(1, (UINT16)luaL_checkinteger(L, 3)); // Prevent zero-divides
|
|
plr->maxinvincibilitytime = maxinv;
|
|
break;
|
|
}
|
|
case player_invincibilitybottleneck:
|
|
plr->invincibilitybottleneck = (UINT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_invincibilitycancel:
|
|
plr->invincibilitycancel = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_invincibilitywarning:
|
|
plr->invincibilitywarning = (UINT8)luaL_checkboolean(L, 3);
|
|
break;
|
|
case player_eggmanexplode:
|
|
plr->eggmanexplode = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_eggmanblame:
|
|
plr->eggmanblame = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bananadrag:
|
|
plr->bananadrag = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastjawztarget:
|
|
plr->lastjawztarget = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_jawztargetdelay:
|
|
plr->jawztargetdelay = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashringpulltics:
|
|
plr->dashRingPullTics = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashringpushtics:
|
|
plr->dashRingPushTics = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_dashrainbowpogo:
|
|
plr->dashRainbowPogo = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_glancedir:
|
|
plr->glanceDir = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_breathtimer:
|
|
plr->breathTimer = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastsafelap:
|
|
plr->lastsafelap = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastsafestarpost:
|
|
plr->lastsafestarpost = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_interpoints:
|
|
plr->interpoints = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_roundscore:
|
|
case player_marescore:
|
|
plr->roundscore = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_emeralds:
|
|
plr->emeralds = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bumpers:
|
|
plr->bumper = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_karmadelay:
|
|
plr->karmadelay = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_kartspeed:
|
|
plr->kartspeed = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_kartweight:
|
|
plr->kartweight = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_followerskin:
|
|
plr->followerskin = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_followercolor:
|
|
plr->followercolor = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_followerready:
|
|
plr->followerready = luaL_checkboolean(L, 3);
|
|
break;
|
|
case player_follower: // it's probably best we don't allow the follower mobj to change.
|
|
return NOSET;
|
|
//
|
|
case player_charflags:
|
|
plr->charflags = (UINT32)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_lives:
|
|
plr->lives = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_xtralife:
|
|
plr->xtralife = (SINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_speed:
|
|
plr->speed = luaL_checkfixed(L, 3);
|
|
break;
|
|
case player_lastspeed:
|
|
plr->lastspeed = luaL_checkfixed(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_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_totalring:
|
|
plr->totalring = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_realtime:
|
|
plr->realtime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_laps:
|
|
{
|
|
UINT8 laps = (UINT8)luaL_checkinteger(L, 3);
|
|
if (lua_compatmode)
|
|
{
|
|
plr->laps = max(laps +1, 0);
|
|
}
|
|
else
|
|
plr->laps = laps;
|
|
break;
|
|
}
|
|
case player_latestlap:
|
|
{
|
|
UINT8 laps = (UINT8)luaL_checkinteger(L, 3);
|
|
|
|
if (lua_compatmode)
|
|
plr->latestlap = max(laps + 1, 0);
|
|
else
|
|
plr->latestlap = laps;
|
|
break;
|
|
}
|
|
case player_ctfteam:
|
|
plr->ctfteam = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_tossdelay:
|
|
case player_checkskip:
|
|
plr->checkskip = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_starpostx:
|
|
plr->starpostx = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0);
|
|
break;
|
|
case player_starposty:
|
|
plr->starposty = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0);
|
|
break;
|
|
case player_starpostz:
|
|
plr->starpostz = luaL_checkfixed(L, 3) << (lua_compatmode ? 16 : 0);
|
|
break;
|
|
case player_starpostangle:
|
|
plr->starpostangle = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_starpostflip:
|
|
plr->starpostflip = luaL_checkboolean(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_lastsidehit:
|
|
plr->lastsidehit = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_lastlinehit:
|
|
plr->lastlinehit = (INT16)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));
|
|
P_SetTarget(&plr->awayviewmobj, mo);
|
|
break;
|
|
}
|
|
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.
|
|
break;
|
|
}
|
|
case player_awayviewaiming:
|
|
plr->awayviewaiming = luaL_checkangle(L, 3);
|
|
break;
|
|
case player_spectator:
|
|
plr->spectator = lua_toboolean(L, 3);
|
|
break;
|
|
case player_spectatewait:
|
|
plr->spectatewait = luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_bot:
|
|
return NOSET;
|
|
case player_botvars:
|
|
return NOSET;
|
|
case player_jointime:
|
|
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_spectatorreentry:
|
|
plr->spectatorreentry = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_grieftime:
|
|
plr->grieftime = (tic_t)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_griefstrikes:
|
|
plr->griefstrikes = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_splitscreenindex:
|
|
return NOSET;
|
|
case player_bumpertime:
|
|
plr->bumpertime = (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_maxlink:
|
|
plr->maxlink = (INT32)luaL_checkinteger(L, 3);
|
|
break;
|
|
case player_ping:
|
|
return NOSET;
|
|
case player_packetloss:
|
|
return NOSET;
|
|
case player_loop:
|
|
return NOSET;
|
|
case player_prevonground:
|
|
return NOSET;
|
|
case player_walltransfered:
|
|
plr->walltransfered = lua_toboolean(L, 3);
|
|
break;
|
|
case player_walltransferboost:
|
|
plr->walltransferboost = lua_tointeger(L, 3);
|
|
break;
|
|
case player_recoverydashcharge:
|
|
plr->recoverydashcharge = lua_tointeger(L, 3);
|
|
break;
|
|
case player_recoverydash:
|
|
plr->recoverydash = lua_tointeger(L, 3);
|
|
break;
|
|
#ifdef HWRENDER
|
|
case player_fovadd:
|
|
plr->fovadd = luaL_checkfixed(L, 3);
|
|
break;
|
|
#endif
|
|
default:
|
|
noexist:
|
|
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);
|
|
player_t *plr = (player_t*)((char*)powers - offsetof(player_t, powers));
|
|
if (p >= NUMPOWERS)
|
|
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
|
switch (p)
|
|
{
|
|
case pw_flashing:
|
|
lua_pushinteger(L, plr->flashing);
|
|
return 1;
|
|
case pw_nocontrol:
|
|
lua_pushinteger(L, plr->nocontrol);
|
|
return 1;
|
|
case pw_emeralds:
|
|
lua_pushinteger(L, plr->emeralds);
|
|
return 1;
|
|
default:
|
|
lua_pushinteger(L, powers[p]);
|
|
return 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#define NOSET luaL_error(L, LUA_QL("powertype_t") " field " LUA_QS " should not be set directly.", p)
|
|
// powers, p, value -> powers[p] = value
|
|
static int power_set(lua_State *L)
|
|
{
|
|
UINT16 *powers = *((UINT16 **)luaL_checkudata(L, 1, META_POWERS));
|
|
powertype_t p = luaL_checkinteger(L, 2);
|
|
player_t *plr = (player_t*)((char*)powers - offsetof(player_t, powers));
|
|
UINT16 i = (UINT16)luaL_checkinteger(L, 3);
|
|
if (p >= NUMPOWERS)
|
|
return luaL_error(L, LUA_QL("powertype_t") " cannot be %u", p);
|
|
if (hud_running)
|
|
return luaL_error(L, "Do not alter player_t in HUD rendering code!");
|
|
if (hook_cmd_running)
|
|
return luaL_error(L, "Do not alter player_t in BuildCMD code!");
|
|
switch (p)
|
|
{
|
|
case pw_flashing:
|
|
plr->flashing = i;
|
|
break;
|
|
case pw_nocontrol:
|
|
plr->nocontrol = i;
|
|
break;
|
|
case pw_emeralds:
|
|
plr->emeralds = i;
|
|
break;
|
|
default:
|
|
powers[p] = i;
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
#undef NOSET
|
|
|
|
// #powers -> NUMPOWERS
|
|
static int power_len(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, NUMPOWERS);
|
|
return 1;
|
|
}
|
|
|
|
|
|
// ???, ks -> kartstuff[ks]
|
|
static int kartstuff_get(lua_State *L)
|
|
{
|
|
INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF));
|
|
player_t *plr = (player_t*)((char*)kartstuff - offsetof(player_t, kartstuff));
|
|
kartstufftype_t ks = luaL_checkinteger(L, 2);
|
|
|
|
if (ks >= NUMKARTSTUFF)
|
|
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
|
|
|
|
switch (ks)
|
|
{
|
|
case k_position:
|
|
lua_pushinteger(L, plr->position);
|
|
return 1;
|
|
case k_oldposition:
|
|
lua_pushinteger(L, plr->oldposition);
|
|
return 1;
|
|
case k_positiondelay:
|
|
lua_pushinteger(L, plr->positiondelay);
|
|
return 1;
|
|
case k_prevcheck:
|
|
lua_pushinteger(L, plr->prevcheck);
|
|
return 1;
|
|
case k_nextcheck:
|
|
lua_pushinteger(L, plr->nextcheck);
|
|
return 1;
|
|
/*case k_waypoint:
|
|
lua_pushinteger(L, plr->waypoint);
|
|
return 1;*/
|
|
/*case k_starpostwp:
|
|
lua_pushinteger(L, plr->starpostwp);
|
|
return 1;*/
|
|
case k_starpostflip:
|
|
lua_pushinteger(L, plr->starpostflip);
|
|
return 1;
|
|
case k_respawn:
|
|
lua_pushinteger(L, plr->respawn);
|
|
return 1;
|
|
case k_dropdash:
|
|
lua_pushinteger(L, plr->dropdash);
|
|
return 1;
|
|
case k_throwdir:
|
|
lua_pushinteger(L, plr->throwdir);
|
|
return 1;
|
|
|
|
case k_lapanimation:
|
|
lua_pushinteger(L, plr->karthud[khud_lapanimation]);
|
|
return 1;
|
|
case k_laphand:
|
|
lua_pushinteger(L, plr->karthud[khud_laphand]);
|
|
return 1;
|
|
case k_cardanimation:
|
|
lua_pushinteger(L, plr->karthud[khud_cardanimation]);
|
|
return 1;
|
|
case k_voices:
|
|
lua_pushinteger(L, plr->karthud[khud_voices]);
|
|
return 1;
|
|
case k_tauntvoices:
|
|
lua_pushinteger(L, plr->karthud[khud_tauntvoices]);
|
|
return 1;
|
|
case k_instashield:
|
|
lua_pushinteger(L, plr->instashield);
|
|
return 1;
|
|
case k_enginesnd:
|
|
lua_pushinteger(L, plr->karthud[khud_enginesnd]);
|
|
return 1;
|
|
case k_floorboost:
|
|
lua_pushinteger(L, plr->floorboost);
|
|
return 1;
|
|
case k_spinouttype:
|
|
lua_pushinteger(L, plr->spinouttype);
|
|
return 1;
|
|
case k_drift:
|
|
lua_pushinteger(L, plr->drift);
|
|
return 1;
|
|
case k_driftend:
|
|
lua_pushinteger(L, (plr->pflags & PF_DRIFTEND));
|
|
return 1;
|
|
case k_driftcharge:
|
|
lua_pushinteger(L, plr->driftcharge);
|
|
return 1;
|
|
case k_driftboost:
|
|
lua_pushinteger(L, plr->driftboost);
|
|
return 1;
|
|
case k_boostcharge:
|
|
lua_pushinteger(L, plr->boostcharge);
|
|
return 1;
|
|
case k_startboost:
|
|
lua_pushinteger(L, plr->startboost);
|
|
return 1;
|
|
case k_jmp:
|
|
lua_pushinteger(L, (plr->pflags & PF_DRIFTINPUT));
|
|
return 1;
|
|
case k_offroad:
|
|
lua_pushinteger(L, plr->offroad);
|
|
return 1;
|
|
case k_pogospring:
|
|
lua_pushinteger(L, plr->pogospring);
|
|
return 1;
|
|
case k_brakestop:
|
|
lua_pushinteger(L, plr->brakestop);
|
|
return 1;
|
|
case k_waterskip:
|
|
lua_pushinteger(L, plr->waterskip);
|
|
return 1;
|
|
case k_dashpadcooldown:
|
|
lua_pushinteger(L, plr->dashpadcooldown);
|
|
return 1;
|
|
case k_boostpower:
|
|
lua_pushinteger(L, plr->boostpower);
|
|
return 1;
|
|
case k_speedboost:
|
|
lua_pushinteger(L, plr->speedboost);
|
|
return 1;
|
|
case k_accelboost:
|
|
lua_pushinteger(L, plr->accelboost);
|
|
return 1;
|
|
case k_boostangle:
|
|
lua_pushinteger(L, plr->boostangle);
|
|
return 1;
|
|
case k_boostcam:
|
|
lua_pushinteger(L, plr->karthud[khud_boostcam]);
|
|
return 1;
|
|
case k_destboostcam:
|
|
lua_pushinteger(L, plr->karthud[khud_destboostcam]);
|
|
return 1;
|
|
case k_timeovercam:
|
|
lua_pushinteger(L, plr->karthud[khud_timeovercam]);
|
|
return 1;
|
|
case k_aizdriftstrat:
|
|
lua_pushinteger(L, plr->aizdriftstrat);
|
|
return 1;
|
|
case k_brakedrift:
|
|
lua_pushinteger(L, (plr->pflags & PF_BRAKEDRIFT));
|
|
return 1;
|
|
case k_itemroulette:
|
|
lua_pushinteger(L, plr->itemroulette);
|
|
return 1;
|
|
case k_roulettetype:
|
|
lua_pushinteger(L, plr->roulettetype);
|
|
return 1;
|
|
case k_itemtype:
|
|
lua_pushinteger(L, plr->itemtype);
|
|
return 1;
|
|
case k_itemamount:
|
|
lua_pushinteger(L, plr->itemamount);
|
|
return 1;
|
|
case k_itemheld:
|
|
lua_pushinteger(L, (plr->itemflags & IF_ITEMOUT));
|
|
return 1;
|
|
case k_curshield:
|
|
lua_pushinteger(L, K_GetShieldFromPlayer(plr));
|
|
return 1;
|
|
case k_hyudorotimer:
|
|
lua_pushinteger(L, plr->hyudorotimer);
|
|
return 1;
|
|
case k_stealingtimer:
|
|
lua_pushinteger(L, plr->stealingtimer);
|
|
return 1;
|
|
case k_stolentimer:
|
|
lua_pushinteger(L, plr->stolentimer);
|
|
return 1;
|
|
case k_sneakertimer:
|
|
lua_pushinteger(L, plr->sneakertimer);
|
|
return 1;
|
|
case k_growshrinktimer:
|
|
lua_pushinteger(L, plr->growshrinktimer);
|
|
return 1;
|
|
case k_squishedtimer:
|
|
lua_pushinteger(L, plr->squishedtimer);
|
|
return 1;
|
|
case k_rocketsneakertimer:
|
|
lua_pushinteger(L, plr->rocketsneakertimer);
|
|
return 1;
|
|
case k_invincibilitytimer:
|
|
lua_pushinteger(L, plr->invincibilitytimer);
|
|
return 1;
|
|
case k_eggmanheld:
|
|
lua_pushinteger(L, (plr->itemflags & IF_EGGMANOUT));
|
|
return 1;
|
|
case k_eggmanexplode:
|
|
lua_pushinteger(L, plr->eggmanexplode);
|
|
return 1;
|
|
case k_eggmanblame:
|
|
lua_pushinteger(L, plr->eggmanblame);
|
|
return 1;
|
|
case k_lastjawztarget:
|
|
lua_pushinteger(L, plr->lastjawztarget);
|
|
return 1;
|
|
case k_bananadrag:
|
|
lua_pushinteger(L, plr->bananadrag);
|
|
return 1;
|
|
case k_spinouttimer:
|
|
lua_pushinteger(L, plr->spinouttimer);
|
|
return 1;
|
|
case k_wipeoutslow:
|
|
lua_pushinteger(L, plr->wipeoutslow);
|
|
return 1;
|
|
case k_justbumped:
|
|
lua_pushinteger(L, plr->justbumped);
|
|
return 1;
|
|
case k_comebacktimer:
|
|
lua_pushinteger(L, plr->karmadelay);
|
|
return 1;
|
|
case k_sadtimer:
|
|
lua_pushinteger(L, plr->sadtimer);
|
|
return 1;
|
|
|
|
// Battle Mode vars
|
|
case k_bumper:
|
|
lua_pushinteger(L, plr->bumper);
|
|
return 1;
|
|
case k_comebackpoints:
|
|
lua_pushinteger(L, plr->karmapoints);
|
|
return 1;
|
|
case k_comebackmode:
|
|
lua_pushinteger(L, plr->karmamode);
|
|
return 1;
|
|
case k_wanted:
|
|
lua_pushinteger(L, plr->wanted);
|
|
return 1;
|
|
case k_yougotem:
|
|
lua_pushinteger(L, plr->karthud[khud_yougotem]);
|
|
return 1;
|
|
|
|
// v1.0.2+ vars
|
|
case k_itemblink:
|
|
lua_pushinteger(L, plr->itemblink);
|
|
return 1;
|
|
case k_itemblinkmode:
|
|
lua_pushinteger(L, plr->itemblinkmode);
|
|
return 1;
|
|
case k_getsparks:
|
|
lua_pushinteger(L, (plr->pflags & PF_GETSPARKS));
|
|
return 1;
|
|
case k_jawztargetdelay:
|
|
lua_pushinteger(L, plr->jawztargetdelay);
|
|
return 1;
|
|
case k_spectatewait:
|
|
lua_pushinteger(L, plr->spectatewait);
|
|
return 1;
|
|
case k_growcancel:
|
|
lua_pushinteger(L, plr->growcancel);
|
|
return 1;
|
|
default:
|
|
lua_pushinteger(L, kartstuff[ks]);
|
|
return 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// kartstuff, ks, value -> plt->??? = value
|
|
static int kartstuff_set(lua_State *L)
|
|
{
|
|
INT32 *kartstuff = *((INT32 **)luaL_checkudata(L, 1, META_KARTSTUFF));
|
|
player_t *plr = (player_t*)((char*)kartstuff - offsetof(player_t, kartstuff));
|
|
kartstufftype_t ks = luaL_checkinteger(L, 2);
|
|
INT32 i = (INT32)luaL_checkinteger(L, 3);
|
|
|
|
if (ks >= NUMKARTSTUFF)
|
|
return luaL_error(L, LUA_QL("kartstufftype_t") " cannot be %u", ks);
|
|
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 (ks)
|
|
{
|
|
case k_position:
|
|
plr->position = i;
|
|
break;
|
|
case k_oldposition:
|
|
plr->oldposition = i;
|
|
break;
|
|
case k_positiondelay:
|
|
plr->positiondelay = i;
|
|
break;
|
|
case k_prevcheck:
|
|
plr->prevcheck = i;
|
|
break;
|
|
case k_nextcheck:
|
|
plr->nextcheck = i;
|
|
break;
|
|
/*case k_waypoint:
|
|
* lua_pushinteger(L, plr->waypoint);
|
|
* break;*/
|
|
/*case k_starpostwp:
|
|
* lua_pushinteger(L, plr->starpostwp);
|
|
* break;*/
|
|
case k_starpostflip:
|
|
plr->starpostflip = i;
|
|
break;
|
|
case k_respawn:
|
|
plr->respawn = i;
|
|
break;
|
|
case k_dropdash:
|
|
plr->dropdash = i;
|
|
break;
|
|
case k_throwdir:
|
|
plr->throwdir = i;
|
|
break;
|
|
|
|
case k_lapanimation:
|
|
plr->karthud[khud_lapanimation] = i;
|
|
break;
|
|
case k_laphand:
|
|
plr->karthud[khud_laphand] = i;
|
|
break;
|
|
case k_cardanimation:
|
|
plr->karthud[khud_cardanimation] = i;
|
|
break;
|
|
case k_voices:
|
|
plr->karthud[khud_voices] = i;
|
|
break;
|
|
case k_tauntvoices:
|
|
plr->karthud[khud_tauntvoices] = i;
|
|
break;
|
|
case k_instashield:
|
|
plr->instashield = i;
|
|
break;
|
|
case k_enginesnd:
|
|
plr->karthud[khud_enginesnd] = i;
|
|
break;
|
|
|
|
case k_floorboost:
|
|
plr->floorboost = i;
|
|
break;
|
|
case k_spinouttype:
|
|
plr->spinouttype = i;
|
|
break;
|
|
case k_drift:
|
|
plr->drift = i;
|
|
break;
|
|
case k_driftend:
|
|
if (i > 0)
|
|
plr->pflags |= PF_DRIFTEND;
|
|
break;
|
|
case k_driftcharge:
|
|
plr->driftcharge = i;
|
|
break;
|
|
case k_driftboost:
|
|
plr->driftboost = CLAMP(i, 0, UINT8_MAX);
|
|
break;
|
|
case k_boostcharge:
|
|
plr->boostcharge = i;
|
|
break;
|
|
case k_startboost:
|
|
plr->startboost = CLAMP(i, 0, UINT8_MAX);
|
|
break;
|
|
/*case k_jmp:
|
|
plr->pflags |= PF_DRIFTINPUT;
|
|
return 1;*/
|
|
case k_offroad:
|
|
plr->offroad = i;
|
|
break;
|
|
case k_pogospring:
|
|
plr->pogospring = i;
|
|
break;
|
|
case k_brakestop:
|
|
plr->brakestop = i;
|
|
break;
|
|
case k_waterskip:
|
|
plr->waterskip = i;
|
|
break;
|
|
case k_dashpadcooldown:
|
|
plr->dashpadcooldown = i;
|
|
break;
|
|
case k_boostpower:
|
|
plr->boostpower = i;
|
|
break;
|
|
case k_speedboost:
|
|
plr->speedboost = i;
|
|
break;
|
|
case k_accelboost:
|
|
plr->accelboost = i;
|
|
break;
|
|
case k_boostangle:
|
|
plr->boostangle = i;
|
|
break;
|
|
case k_boostcam:
|
|
plr->karthud[khud_boostcam] = i;
|
|
break;
|
|
case k_destboostcam:
|
|
plr->karthud[khud_destboostcam] = i;
|
|
break;
|
|
case k_timeovercam:
|
|
plr->karthud[khud_timeovercam] = i;
|
|
break;
|
|
case k_aizdriftstrat:
|
|
plr->aizdriftstrat = i;
|
|
break;
|
|
case k_brakedrift:
|
|
if (i > 0)
|
|
plr->pflags |= PF_BRAKEDRIFT;
|
|
break;
|
|
case k_itemroulette:
|
|
plr->itemroulette = i;
|
|
break;
|
|
case k_roulettetype:
|
|
plr->roulettetype = i;
|
|
break;
|
|
case k_itemtype:
|
|
plr->itemtype = i;
|
|
break;
|
|
case k_itemamount:
|
|
plr->itemamount = i;
|
|
break;
|
|
case k_itemheld:
|
|
if (i > 0)
|
|
plr->itemflags |= IF_ITEMOUT;
|
|
break;
|
|
case k_curshield:
|
|
// i have no clue where you'd find a script that sets k_curshield, but... this will do?
|
|
if (!P_MobjWasRemoved(plr->shieldtracer) && K_GetShieldFromPlayer(plr) != i)
|
|
P_RemoveMobj(plr->shieldtracer);
|
|
break;
|
|
case k_hyudorotimer:
|
|
plr->hyudorotimer = i;
|
|
break;
|
|
case k_stealingtimer:
|
|
plr->stealingtimer = i;
|
|
break;
|
|
case k_stolentimer:
|
|
plr->stolentimer = i;
|
|
break;
|
|
case k_sneakertimer:
|
|
plr->sneakertimer = CLAMP(i, 0, UINT16_MAX);
|
|
break;
|
|
case k_growshrinktimer:
|
|
plr->growshrinktimer = CLAMP(i, INT16_MIN, INT16_MAX);
|
|
break;
|
|
case k_squishedtimer:
|
|
{
|
|
// Unsquish for the ease of Lua programmers
|
|
if (i == 0)
|
|
plr->mo->spriteyscale = FRACUNIT;
|
|
|
|
plr->squishedtimer = CLAMP(i, INT16_MIN, INT16_MAX);
|
|
break;
|
|
}
|
|
case k_rocketsneakertimer:
|
|
plr->rocketsneakertimer = CLAMP(i, 0, UINT16_MAX);
|
|
break;
|
|
case k_invincibilitytimer:
|
|
plr->invincibilitytimer = CLAMP(i, 0, UINT16_MAX);
|
|
break;
|
|
case k_eggmanheld:
|
|
if (i > 0)
|
|
plr->itemflags |= IF_EGGMANOUT;
|
|
break;
|
|
case k_eggmanexplode:
|
|
plr->eggmanexplode = CLAMP(i, 0, UINT8_MAX);
|
|
break;
|
|
case k_eggmanblame:
|
|
plr->eggmanblame = i;
|
|
break;
|
|
case k_lastjawztarget:
|
|
plr->lastjawztarget = i;
|
|
break;
|
|
case k_bananadrag:
|
|
plr->bananadrag = CLAMP(i, 0, UINT16_MAX);
|
|
break;
|
|
case k_spinouttimer:
|
|
plr->spinouttimer = CLAMP(i, 0, UINT16_MAX);
|
|
break;
|
|
case k_wipeoutslow:
|
|
plr->wipeoutslow = CLAMP(i, 0, UINT8_MAX);
|
|
break;
|
|
case k_justbumped:
|
|
plr->justbumped = i;
|
|
break;
|
|
case k_comebacktimer:
|
|
plr->karmadelay = i;
|
|
break;
|
|
case k_sadtimer:
|
|
plr->sadtimer = i;
|
|
break;
|
|
|
|
// Battle Mode vars
|
|
case k_bumper:
|
|
plr->bumper = i;
|
|
break;
|
|
case k_comebackpoints:
|
|
plr->karmapoints = i;
|
|
break;
|
|
case k_comebackmode:
|
|
plr->karmamode = i;
|
|
break;
|
|
case k_wanted:
|
|
plr->wanted = i;
|
|
break;
|
|
case k_yougotem:
|
|
plr->karthud[khud_yougotem] = i;
|
|
break;
|
|
|
|
// v1.0.2+ vars
|
|
case k_itemblink:
|
|
plr->itemblink = i;
|
|
break;
|
|
case k_itemblinkmode:
|
|
plr->itemblinkmode = i;
|
|
break;
|
|
case k_getsparks:
|
|
if (i > 0)
|
|
plr->pflags |= PF_GETSPARKS;
|
|
break;
|
|
case k_jawztargetdelay:
|
|
plr->jawztargetdelay = i;
|
|
break;
|
|
case k_spectatewait:
|
|
plr->spectatewait = i;
|
|
break;
|
|
case k_growcancel:
|
|
plr->growcancel = i;
|
|
break;
|
|
default:
|
|
kartstuff[ks] = i;
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// #kartstuff -> NUMKARTSTUFF
|
|
static int kartstuff_len(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, NUMKARTSTUFF);
|
|
return 1;
|
|
}
|
|
|
|
// karthud, ks -> karthud[ks]
|
|
static int karthud_get(lua_State *L)
|
|
{
|
|
INT32 *karthud = *((INT32 **)luaL_checkudata(L, 1, META_KARTHUD));
|
|
karthudtype_t ks = luaL_checkinteger(L, 2);
|
|
if (ks >= NUMKARTHUD)
|
|
return luaL_error(L, LUA_QL("karthudtype_t") " cannot be %u", ks);
|
|
lua_pushinteger(L, karthud[ks]);
|
|
return 1;
|
|
}
|
|
|
|
// karthud, ks, value -> karthud[ks] = value
|
|
static int karthud_set(lua_State *L)
|
|
{
|
|
INT32 *karthud = *((INT32 **)luaL_checkudata(L, 1, META_KARTHUD));
|
|
karthudtype_t ks = luaL_checkinteger(L, 2);
|
|
INT32 i = (INT32)luaL_checkinteger(L, 3);
|
|
if (ks >= NUMKARTHUD)
|
|
return luaL_error(L, LUA_QL("karthudtype_t") " cannot be %u", ks);
|
|
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!");
|
|
karthud[ks] = i;
|
|
return 0;
|
|
}
|
|
|
|
// #karthud -> NUMKARTHUD
|
|
static int karthud_len(lua_State *L)
|
|
{
|
|
lua_pushinteger(L, NUMKARTHUD);
|
|
return 1;
|
|
}
|
|
|
|
// player.cmd get/set
|
|
#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 " LUA_QS " cannot be set.", ticcmd_opt[field])
|
|
|
|
enum ticcmd_e
|
|
{
|
|
ticcmd_forwardmove,
|
|
ticcmd_sidemove,
|
|
ticcmd_turning,
|
|
ticcmd_driftturn,
|
|
ticcmd_angle,
|
|
ticcmd_angleturn,
|
|
ticcmd_throwdir,
|
|
ticcmd_aiming,
|
|
ticcmd_buttons,
|
|
ticcmd_latency,
|
|
ticcmd_flags,
|
|
};
|
|
|
|
static const char *const ticcmd_opt[] = {
|
|
"forwardmove",
|
|
"sidemove",
|
|
"turning",
|
|
"driftturn",
|
|
"angle",
|
|
"angleturn",
|
|
"throwdir",
|
|
"aiming",
|
|
"buttons",
|
|
"latency",
|
|
"flags",
|
|
NULL,
|
|
};
|
|
|
|
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, NULL, ticcmd_opt);
|
|
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_turning:
|
|
case ticcmd_driftturn:
|
|
lua_pushinteger(L, cmd->turning);
|
|
break;
|
|
case ticcmd_angle:
|
|
case ticcmd_angleturn:
|
|
lua_pushinteger(L, cmd->angle);
|
|
break;
|
|
case ticcmd_throwdir:
|
|
lua_pushinteger(L, cmd->throwdir);
|
|
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;
|
|
case ticcmd_flags:
|
|
lua_pushinteger(L, cmd->flags);
|
|
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, ticcmd_opt[0], ticcmd_opt);
|
|
if (!cmd)
|
|
return LUA_ErrInvalid(L, "ticcmd_t");
|
|
|
|
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_turning:
|
|
case ticcmd_driftturn:
|
|
cmd->turning = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_angle:
|
|
case ticcmd_angleturn:
|
|
cmd->angle = (INT16)luaL_checkinteger(L, 3);
|
|
break;
|
|
case ticcmd_throwdir:
|
|
cmd->throwdir = (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;
|
|
case ticcmd_flags:
|
|
return NOSET;
|
|
default:
|
|
return NOFIELD;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#undef NOFIELD
|
|
#undef NOSET
|
|
|
|
enum sonicloopvars {
|
|
sonicloopvars_radius = 0,
|
|
sonicloopvars_revolution,
|
|
sonicloopvars_min_revolution,
|
|
sonicloopvars_max_revolution,
|
|
sonicloopvars_yaw,
|
|
sonicloopvars_origin_x,
|
|
sonicloopvars_origin_y,
|
|
sonicloopvars_origin_z,
|
|
sonicloopvars_origin_shift_x,
|
|
sonicloopvars_origin_shift_y,
|
|
sonicloopvars_shift_x,
|
|
sonicloopvars_shift_y,
|
|
sonicloopvars_flip,
|
|
sonicloopvars_camera,
|
|
};
|
|
|
|
static const char *const sonicloopvars_opt[] = {
|
|
"radius",
|
|
"revolution",
|
|
"min_revolution",
|
|
"max_revolution",
|
|
"yaw",
|
|
"origin_x",
|
|
"origin_y",
|
|
"origin_z",
|
|
"origin_shift_x",
|
|
"origin_shift_y",
|
|
"shift_x",
|
|
"shift_y",
|
|
"flip",
|
|
"camera",
|
|
NULL
|
|
};
|
|
|
|
static int sonicloopvars_get(lua_State *L)
|
|
{
|
|
sonicloopvars_t *sonicloopvars = *((sonicloopvars_t **)luaL_checkudata(L, 1, META_SONICLOOPVARS));
|
|
enum sonicloopvars field = luaL_checkoption(L, 2, NULL, sonicloopvars_opt);
|
|
|
|
// This should always be valid.
|
|
I_Assert(sonicloopvars != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case sonicloopvars_radius:
|
|
lua_pushfixed(L, sonicloopvars->radius);
|
|
break;
|
|
case sonicloopvars_revolution:
|
|
lua_pushfixed(L, sonicloopvars->revolution);
|
|
break;
|
|
case sonicloopvars_min_revolution:
|
|
lua_pushfixed(L, sonicloopvars->min_revolution);
|
|
break;
|
|
case sonicloopvars_max_revolution:
|
|
lua_pushfixed(L, sonicloopvars->max_revolution);
|
|
break;
|
|
case sonicloopvars_yaw:
|
|
lua_pushangle(L, sonicloopvars->yaw);
|
|
break;
|
|
case sonicloopvars_origin_x:
|
|
lua_pushfixed(L, sonicloopvars->origin.x);
|
|
break;
|
|
case sonicloopvars_origin_y:
|
|
lua_pushfixed(L, sonicloopvars->origin.y);
|
|
break;
|
|
case sonicloopvars_origin_z:
|
|
lua_pushfixed(L, sonicloopvars->origin.z);
|
|
break;
|
|
case sonicloopvars_origin_shift_x:
|
|
lua_pushfixed(L, sonicloopvars->origin_shift.x);
|
|
break;
|
|
case sonicloopvars_origin_shift_y:
|
|
lua_pushfixed(L, sonicloopvars->origin_shift.y);
|
|
break;
|
|
case sonicloopvars_shift_x:
|
|
lua_pushfixed(L, sonicloopvars->shift.x);
|
|
break;
|
|
case sonicloopvars_shift_y:
|
|
lua_pushfixed(L, sonicloopvars->shift.y);
|
|
break;
|
|
case sonicloopvars_flip:
|
|
lua_pushboolean(L, sonicloopvars->flip);
|
|
break;
|
|
case sonicloopvars_camera:
|
|
LUA_PushUserdata(L, &sonicloopvars->camera, META_SONICLOOPCAMVARS);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
enum sonicloopcamvars {
|
|
sonicloopcamvars_enter_tic = 0,
|
|
sonicloopcamvars_exit_tic,
|
|
sonicloopcamvars_zoom_in_speed,
|
|
sonicloopcamvars_zoom_out_speed,
|
|
sonicloopcamvars_dist,
|
|
sonicloopcamvars_pan,
|
|
sonicloopcamvars_pan_speed,
|
|
sonicloopcamvars_pan_accel,
|
|
sonicloopcamvars_pan_back,
|
|
};
|
|
|
|
static const char *const sonicloopcamvars_opt[] = {
|
|
"enter_tic",
|
|
"exit_tic",
|
|
"zoom_in_speed",
|
|
"zoom_out_speed",
|
|
"dist",
|
|
"pan",
|
|
"pan_speed",
|
|
"pan_accel",
|
|
"pan_back",
|
|
NULL
|
|
};
|
|
|
|
static int sonicloopcamvars_get(lua_State *L)
|
|
{
|
|
sonicloopcamvars_t *sonicloopcamvars = *((sonicloopcamvars_t **)luaL_checkudata(L, 1, META_SONICLOOPCAMVARS));
|
|
enum sonicloopcamvars field = luaL_checkoption(L, 2, NULL, sonicloopcamvars_opt);
|
|
|
|
// This should always be valid.
|
|
I_Assert(sonicloopcamvars != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case sonicloopcamvars_enter_tic:
|
|
lua_pushinteger(L, sonicloopcamvars->enter_tic);
|
|
break;
|
|
case sonicloopcamvars_exit_tic:
|
|
lua_pushinteger(L, sonicloopcamvars->exit_tic);
|
|
break;
|
|
case sonicloopcamvars_zoom_in_speed:
|
|
lua_pushinteger(L, sonicloopcamvars->zoom_in_speed);
|
|
break;
|
|
case sonicloopcamvars_zoom_out_speed:
|
|
lua_pushinteger(L, sonicloopcamvars->zoom_out_speed);
|
|
break;
|
|
case sonicloopcamvars_dist:
|
|
lua_pushfixed(L, sonicloopcamvars->dist);
|
|
break;
|
|
case sonicloopcamvars_pan:
|
|
lua_pushangle(L, sonicloopcamvars->pan);
|
|
break;
|
|
case sonicloopcamvars_pan_speed:
|
|
lua_pushfixed(L, sonicloopcamvars->pan_speed);
|
|
break;
|
|
case sonicloopcamvars_pan_accel:
|
|
lua_pushinteger(L, sonicloopcamvars->pan_accel);
|
|
break;
|
|
case sonicloopcamvars_pan_back:
|
|
lua_pushinteger(L, sonicloopcamvars->pan_back);
|
|
break;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#define NOSET luaL_error(L, LUA_QL("boostinfo_t") " field " LUA_QS " should not be set directly.", boostinfo_opt[field])
|
|
#define NOFIELD luaL_error(L, "%s %s", LUA_QL("boostinfo_t"), va("has no field named %ui", field))
|
|
|
|
enum boostinfo
|
|
{
|
|
boostinfo_stackspeedboost = 0,
|
|
boostinfo_nonstackspeedboost,
|
|
boostinfo_accelboost,
|
|
boostinfo_handleboost,
|
|
boostinfo_grade,
|
|
};
|
|
|
|
static const char *const boostinfo_opt[] = {
|
|
"stackspeedboost",
|
|
"nonstackspeedboost",
|
|
"accelboost",
|
|
"handleboost",
|
|
"grade",
|
|
NULL,
|
|
};
|
|
|
|
static int boostinfo_get(lua_State *L)
|
|
{
|
|
boostinfo_t *boostinfo = *((boostinfo_t **)luaL_checkudata(L, 1, META_BOOSTINFO));
|
|
enum boostinfo field = luaL_checkoption(L, 2, NULL, boostinfo_opt);
|
|
|
|
// This should always be valid.
|
|
I_Assert(boostinfo != NULL);
|
|
|
|
switch (field)
|
|
{
|
|
case boostinfo_stackspeedboost:
|
|
lua_pushfixed(L, boostinfo->stackspeedboost);
|
|
break;
|
|
case boostinfo_nonstackspeedboost:
|
|
lua_pushfixed(L, boostinfo->nonstackspeedboost);
|
|
break;
|
|
case boostinfo_accelboost:
|
|
lua_pushfixed(L, boostinfo->accelboost);
|
|
break;
|
|
case boostinfo_handleboost:
|
|
lua_pushfixed(L, boostinfo->handleboost);
|
|
break;
|
|
case boostinfo_grade:
|
|
lua_pushinteger(L, boostinfo->grade);
|
|
break;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int boostinfo_set(lua_State *L)
|
|
{
|
|
boostinfo_t *boostinfo = *((boostinfo_t **)luaL_checkudata(L, 1, META_BOOSTINFO));
|
|
enum boostinfo field = luaL_checkoption(L, 2, boostinfo_opt[0], boostinfo_opt);
|
|
|
|
// This is a property that always exists in a player.
|
|
I_Assert(boostinfo != NULL);
|
|
|
|
INLEVEL
|
|
|
|
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 boostinfo_stackspeedboost:
|
|
boostinfo->stackspeedboost = luaL_checkfixed(L, 3);
|
|
break;
|
|
case boostinfo_nonstackspeedboost:
|
|
boostinfo->nonstackspeedboost = luaL_checkfixed(L, 3);
|
|
break;
|
|
case boostinfo_accelboost:
|
|
boostinfo->accelboost = luaL_checkfixed(L, 3);
|
|
break;
|
|
case boostinfo_handleboost:
|
|
boostinfo->handleboost = luaL_checkfixed(L, 3);
|
|
break;
|
|
case boostinfo_grade:
|
|
boostinfo->grade = (UINT8)luaL_checkinteger(L, 3);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#undef NOSET
|
|
#undef NOFIELD
|
|
|
|
int LUA_PlayerLib(lua_State *L)
|
|
{
|
|
luaL_newmetatable(L, META_PLAYER);
|
|
lua_pushcfunction(L, player_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, player_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
|
|
lua_pushcfunction(L, player_num);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_POWERS);
|
|
lua_pushcfunction(L, power_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, power_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
|
|
lua_pushcfunction(L, power_len);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_KARTSTUFF);
|
|
lua_pushcfunction(L, kartstuff_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, kartstuff_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
|
|
lua_pushcfunction(L, kartstuff_len);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_KARTHUD);
|
|
lua_pushcfunction(L, karthud_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, karthud_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
|
|
lua_pushcfunction(L, karthud_len);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_TICCMD);
|
|
lua_pushcfunction(L, ticcmd_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, ticcmd_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_SONICLOOPVARS);
|
|
lua_pushcfunction(L, sonicloopvars_get);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_SONICLOOPCAMVARS);
|
|
lua_pushcfunction(L, sonicloopcamvars_get);
|
|
lua_setfield(L, -2, "__index");
|
|
lua_pop(L,1);
|
|
|
|
luaL_newmetatable(L, META_BOOSTINFO);
|
|
lua_pushcfunction(L, boostinfo_get);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, boostinfo_set);
|
|
lua_setfield(L, -2, "__newindex");
|
|
lua_pop(L,1);
|
|
|
|
lua_newuserdata(L, 0);
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, lib_getPlayer);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, lib_lenPlayer);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_setmetatable(L, -2);
|
|
lua_setglobal(L, "players");
|
|
|
|
// push displayplayers in the same fashion
|
|
lua_newuserdata(L, 0);
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, lib_getDisplayplayers);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, lib_lenDisplayplayers);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_setmetatable(L, -2);
|
|
lua_setglobal(L, "displayplayers");
|
|
|
|
// ditto with localplayers
|
|
lua_newuserdata(L, 0);
|
|
lua_createtable(L, 0, 2);
|
|
lua_pushcfunction(L, lib_getLocalplayers);
|
|
lua_setfield(L, -2, "__index");
|
|
|
|
lua_pushcfunction(L, lib_lenLocalplayers);
|
|
lua_setfield(L, -2, "__len");
|
|
lua_setmetatable(L, -2);
|
|
lua_setglobal(L, "localplayers");
|
|
|
|
return 0;
|
|
}
|