From 135aa1091e8651193d0931116dead17dd5419bfa Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Thu, 12 Dec 2024 17:24:49 +0100
Subject: [PATCH 01/35] Move META_RESPAWN to lua_respawnvarslib.c, use switch
 instead of if..else hell

---
 src/CMakeLists.txt       |   1 +
 src/lua_libs.h           |   1 +
 src/lua_playerlib.c      |  84 ---------------
 src/lua_respawnvarslib.c | 219 +++++++++++++++++++++++++++++++++++++++
 src/lua_script.c         |   1 +
 5 files changed, 222 insertions(+), 84 deletions(-)
 create mode 100644 src/lua_respawnvarslib.c

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index da820419e..9e1f64d4c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -123,6 +123,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
 	lua_hudlib.c
 	lua_hudlib_drawlist.c
 	lua_followerlib.c
+	lua_respawnvarslib.c
 	lua_profile.cpp
 	k_kart.c
 	k_respawn.c
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 73d7b4f6e..311a39819 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -123,6 +123,7 @@ int LUA_PolyObjLib(lua_State *L);
 int LUA_BlockmapLib(lua_State *L);
 int LUA_HudLib(lua_State *L);
 int LUA_FollowerLib(lua_State *L);
+int LUA_RespawnVarsLib(lua_State *L);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index ee56da06f..7d464912d 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -1384,82 +1384,6 @@ static int ticcmd_set(lua_State *L)
 
 #undef NOFIELD
 
-// Same shit for player.respawn variable... Why is everything in different sub-variables again now???
-#define RNOFIELD luaL_error(L, LUA_QL("respawnvars_t") " has no field named " LUA_QS, field)
-#define RUNIMPLEMENTED luaL_error(L, LUA_QL("respawnvars_t") " unimplemented field " LUA_QS " cannot be read or set.", field)
-// @TODO: Waypoints in Lua possibly maybe? No don't count on me to do it...
-
-static int respawn_get(lua_State *L)
-{
-	respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
-	const char *field = luaL_checkstring(L, 2);
-	if (!rsp)
-		return LUA_ErrInvalid(L, "player_t");
-
-	if (fastcmp(field,"state"))
-		lua_pushinteger(L, rsp->state);
-	else if (fastcmp(field,"waypoint"))
-		return RUNIMPLEMENTED;
-	else if (fastcmp(field,"pointx"))
-		lua_pushfixed(L, rsp->pointx);
-	else if (fastcmp(field,"pointy"))
-		lua_pushfixed(L, rsp->pointy);
-	else if (fastcmp(field,"pointz"))
-		lua_pushfixed(L, rsp->pointz);
-	else if (fastcmp(field,"flip"))
-		lua_pushboolean(L, rsp->flip);
-	else if (fastcmp(field,"timer"))
-		lua_pushinteger(L, rsp->timer);
-	else if (fastcmp(field,"distanceleft"))
-		lua_pushinteger(L, rsp->distanceleft);	// Can't possibly foresee any problem when pushing UINT32 to Lua's INT32 hahahahaha, get ready for dumb hacky shit on high distances.
-	else if (fastcmp(field,"dropdash"))
-		lua_pushinteger(L, rsp->dropdash);
-	else
-		return RNOFIELD;
-
-	return 1;
-}
-
-static int respawn_set(lua_State *L)
-{
-	respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
-	const char *field = luaL_checkstring(L, 2);
-	if (!rsp)
-		return LUA_ErrInvalid(L, "respawnvars_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!");
-
-	if (fastcmp(field,"state"))
-		rsp->state = (UINT8)luaL_checkinteger(L, 3);
-	else if (fastcmp(field,"waypoint"))
-		return RUNIMPLEMENTED;
-	else if (fastcmp(field,"pointx"))
-		rsp->pointx = luaL_checkfixed(L, 3);
-	else if (fastcmp(field,"pointy"))
-		rsp->pointy = luaL_checkfixed(L, 3);
-	else if (fastcmp(field,"pointz"))
-		rsp->pointz = luaL_checkfixed(L, 3);
-	else if (fastcmp(field,"flip"))
-		rsp->flip = luaL_checkboolean(L, 3);
-	else if (fastcmp(field,"timer"))
-		rsp->timer = (tic_t)luaL_checkinteger(L, 3);
-	else if (fastcmp(field,"distanceleft"))
-		rsp->distanceleft = (UINT32)luaL_checkinteger(L, 3);
-	else if (fastcmp(field,"dropdash"))
-		rsp->dropdash = (tic_t)luaL_checkinteger(L, 3);
-	else
-		return RNOFIELD;
-
-	return 0;
-}
-
-#undef RNOFIELD
-#undef RUNIMPLEMENTED
-
-
 int LUA_PlayerLib(lua_State *L)
 {
 	luaL_newmetatable(L, META_PLAYER);
@@ -1484,14 +1408,6 @@ int LUA_PlayerLib(lua_State *L)
 		lua_setfield(L, -2, "__len");
 	lua_pop(L,1);
 
-	luaL_newmetatable(L, META_RESPAWN);
-		lua_pushcfunction(L, respawn_get);
-		lua_setfield(L, -2, "__index");
-
-		lua_pushcfunction(L, respawn_set);
-		lua_setfield(L, -2, "__newindex");
-	lua_pop(L,1);
-
 	luaL_newmetatable(L, META_TICCMD);
 		lua_pushcfunction(L, ticcmd_get);
 		lua_setfield(L, -2, "__index");
diff --git a/src/lua_respawnvarslib.c b/src/lua_respawnvarslib.c
new file mode 100644
index 000000000..928ea13b4
--- /dev/null
+++ b/src/lua_respawnvarslib.c
@@ -0,0 +1,219 @@
+// DR. ROBOTNIK'S RING RACERS
+//-----------------------------------------------------------------------------
+// Copyright (C) 2024 by Kart Krew.
+// Copyright (C) 2020 by Sonic Team Junior.
+// Copyright (C) 2016 by John "JTE" Muniz.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
+/// \file  lua_respawnvarslib.c
+/// \brief player respawn variables library for Lua scripting
+
+#include "doomdef.h"
+#include "fastcmp.h"
+
+#include "lua_script.h"
+#include "lua_libs.h"
+#include "lua_hud.h" // hud_running errors
+#include "lua_hook.h" // hook_cmd_running errors
+
+enum respawnvars {
+	respawnvars_state = 0,
+	respawnvars_waypoint,
+	respawnvars_pointx,
+	respawnvars_pointy,
+	respawnvars_pointz,
+	respawnvars_pointangle,
+	respawnvars_flip,
+	respawnvars_timer,
+	respawnvars_airtimer,
+	respawnvars_distanceleft,
+	respawnvars_dropdash,
+	respawnvars_truedeath,
+	respawnvars_manual,
+	respawnvars_fromringshooter,
+	respawnvars_init,
+	respawnvars_fast,
+	respawnvars_returnspeed,
+};
+
+static const char *const respawnvars_opt[] = {
+	"state",
+	"waypoint",
+	"pointx",
+	"pointy",
+	"pointz",
+	"pointangle",
+	"flip",
+	"timer",
+	"airtimer",
+	"distanceleft",
+	"dropdash",
+	"truedeath",
+	"manual",
+	"fromringshooter",
+	"init",
+	"fast",
+	"returnspeed",
+	NULL
+};
+
+#define RNOFIELD luaL_error(L, LUA_QL("respawnvars_t") " has no field named " LUA_QS, field)
+#define RUNIMPLEMENTED luaL_error(L, LUA_QL("respawnvars_t") " unimplemented field " LUA_QS " cannot be read or set.", field)
+
+static int respawn_get(lua_State *L)
+{
+	respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
+	enum respawnvars field = luaL_checkoption(L, 2, NULL, respawnvars_opt);
+	
+	if (!rsp)
+		return LUA_ErrInvalid(L, "player_t");
+	
+	switch (field)
+	{
+		case respawnvars_state:
+			lua_pushinteger(L, rsp->state);
+			break;
+		case respawnvars_waypoint:
+			return RUNIMPLEMENTED;
+		case respawnvars_pointx:
+			lua_pushfixed(L, rsp->pointx);
+			break;
+		case respawnvars_pointy:
+			lua_pushfixed(L, rsp->pointy);
+			break;
+		case respawnvars_pointz:
+			lua_pushfixed(L, rsp->pointz);
+			break;
+		case respawnvars_pointangle:
+			lua_pushangle(L, rsp->pointangle);
+			break;
+		case respawnvars_flip:
+			lua_pushboolean(L, rsp->flip);
+			break;
+		case respawnvars_timer:
+			lua_pushinteger(L, rsp->timer);
+			break;
+		case respawnvars_airtimer:
+			lua_pushinteger(L, rsp->airtimer);
+			break;
+		case respawnvars_distanceleft:
+			lua_pushinteger(L, rsp->distanceleft);
+			break;
+		case respawnvars_dropdash:
+			lua_pushinteger(L, rsp->dropdash);
+			break;
+		case respawnvars_truedeath:
+			lua_pushboolean(L, rsp->truedeath);
+			break;
+		case respawnvars_manual:
+			lua_pushboolean(L, rsp->manual);
+			break;
+		case respawnvars_fromringshooter:
+			lua_pushboolean(L, rsp->fromRingShooter);
+			break;
+		case respawnvars_init:
+			lua_pushboolean(L, rsp->init);
+			break;
+		case respawnvars_fast:
+			lua_pushboolean(L, rsp->fast);
+			break;
+		case respawnvars_returnspeed:
+			lua_pushfixed(L, rsp->returnspeed);
+			break;
+		default:
+			return RNOFIELD;
+	}
+
+	return 1;
+}
+
+static int respawn_set(lua_State *L)
+{
+	respawnvars_t *rsp = *((respawnvars_t **)luaL_checkudata(L, 1, META_RESPAWN));
+	enum respawnvars field = luaL_checkoption(L, 2, respawnvars_opt[0], respawnvars_opt);
+
+	if (!rsp)
+		return LUA_ErrInvalid(L, "respawnvars_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 respawnvars_state:
+			rsp->state = (UINT8)luaL_checkinteger(L, 3);
+			break;
+		case respawnvars_waypoint:
+			return RUNIMPLEMENTED;
+		case respawnvars_pointx:
+			rsp->pointx = luaL_checkfixed(L, 3);
+			break;
+		case respawnvars_pointy:
+			rsp->pointy = luaL_checkfixed(L, 3);
+			break;
+		case respawnvars_pointz:
+			rsp->pointz = luaL_checkfixed(L, 3);
+			break;
+		case respawnvars_pointangle:
+			rsp->pointangle = luaL_checkangle(L, 3);
+			break;
+		case respawnvars_flip:
+			rsp->flip = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_timer:
+			rsp->timer = (tic_t)luaL_checkinteger(L, 3);
+			break;
+		case respawnvars_airtimer:
+			rsp->airtimer = (tic_t)luaL_checkinteger(L, 3);
+			break;
+		case respawnvars_distanceleft:
+			rsp->distanceleft = (UINT32)luaL_checkinteger(L, 3);
+			break;
+		case respawnvars_dropdash:
+			rsp->dropdash = (tic_t)luaL_checkinteger(L, 3);
+			break;
+		case respawnvars_truedeath:
+			rsp->truedeath = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_manual:
+			rsp->manual = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_fromringshooter:
+			rsp->fromRingShooter = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_init:
+			rsp->init = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_fast:
+			rsp->fast = luaL_checkboolean(L, 3);
+			break;
+		case respawnvars_returnspeed:
+			rsp->returnspeed = luaL_checkfixed(L, 3);
+			break;
+		default:
+			return RNOFIELD;
+	}
+
+	return 0;
+}
+
+#undef RNOFIELD
+#undef RUNIMPLEMENTED
+
+int LUA_RespawnVarsLib(lua_State *L)
+{
+	luaL_newmetatable(L, META_RESPAWN);
+		lua_pushcfunction(L, respawn_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, respawn_set);
+		lua_setfield(L, -2, "__newindex");
+	lua_pop(L,1);
+
+	return 0;
+}
diff --git a/src/lua_script.c b/src/lua_script.c
index bfcf84bd4..a9a76f2f6 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -61,6 +61,7 @@ static lua_CFunction liblist[] = {
 	LUA_BlockmapLib, // blockmap stuff
 	LUA_HudLib, // HUD stuff
 	LUA_FollowerLib, // follower_t, followers[]
+	LUA_RespawnVarsLib, // respawnvars_t
 	NULL
 };
 
-- 
GitLab


From c904afea6b02b839f2f937178d34720814e54cd3 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Thu, 12 Dec 2024 19:24:35 +0100
Subject: [PATCH 02/35] Expose waypoint_t to Lua, as well as certain variables
 that depends on it.

---
 src/CMakeLists.txt       |   1 +
 src/lua_libs.h           |   2 +
 src/lua_playerlib.c      |   4 +
 src/lua_respawnvarslib.c |   6 +-
 src/lua_script.c         |   1 +
 src/lua_waypointslib.c   | 159 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 171 insertions(+), 2 deletions(-)
 create mode 100644 src/lua_waypointslib.c

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9e1f64d4c..a622e2e9e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -124,6 +124,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
 	lua_hudlib_drawlist.c
 	lua_followerlib.c
 	lua_respawnvarslib.c
+	lua_waypointslib.c
 	lua_profile.cpp
 	k_kart.c
 	k_respawn.c
diff --git a/src/lua_libs.h b/src/lua_libs.h
index 311a39819..43ea14809 100644
--- a/src/lua_libs.h
+++ b/src/lua_libs.h
@@ -103,6 +103,7 @@ extern lua_State *gL;
 #define META_ACTIVATOR "ACTIVATOR_T*"
 
 #define META_FOLLOWER "FOLLOWER_T*"
+#define META_WAYPOINT "WAYPOINT_T*"
 
 boolean luaL_checkboolean(lua_State *L, int narg);
 
@@ -124,6 +125,7 @@ int LUA_BlockmapLib(lua_State *L);
 int LUA_HudLib(lua_State *L);
 int LUA_FollowerLib(lua_State *L);
 int LUA_RespawnVarsLib(lua_State *L);
+int LUA_WaypointLib(lua_State *L);
 
 #ifdef __cplusplus
 } // extern "C"
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 7d464912d..1b8fb4cd6 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -234,6 +234,10 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->lastpickupdistance);
 	else if (fastcmp(field,"lastpickuptype"))
 		lua_pushinteger(L, plr->lastpickuptype);
+	else if (fastcmp(field,"currentwaypoint"))
+		LUA_PushUserdata(L, plr->currentwaypoint, META_WAYPOINT);
+	else if (fastcmp(field,"nextwaypoint"))
+		LUA_PushUserdata(L, plr->nextwaypoint, META_WAYPOINT);
 	else if (fastcmp(field,"airtime"))
 		lua_pushinteger(L, plr->airtime);
 	else if (fastcmp(field,"lastairtime"))
diff --git a/src/lua_respawnvarslib.c b/src/lua_respawnvarslib.c
index 928ea13b4..0f4b75262 100644
--- a/src/lua_respawnvarslib.c
+++ b/src/lua_respawnvarslib.c
@@ -77,7 +77,8 @@ static int respawn_get(lua_State *L)
 			lua_pushinteger(L, rsp->state);
 			break;
 		case respawnvars_waypoint:
-			return RUNIMPLEMENTED;
+			LUA_PushUserdata(L, rsp->wp, META_WAYPOINT);
+			break;
 		case respawnvars_pointx:
 			lua_pushfixed(L, rsp->pointx);
 			break;
@@ -149,7 +150,8 @@ static int respawn_set(lua_State *L)
 			rsp->state = (UINT8)luaL_checkinteger(L, 3);
 			break;
 		case respawnvars_waypoint:
-			return RUNIMPLEMENTED;
+			rsp->wp = *((waypoint_t **)luaL_checkudata(L, 3, META_WAYPOINT));
+			break;
 		case respawnvars_pointx:
 			rsp->pointx = luaL_checkfixed(L, 3);
 			break;
diff --git a/src/lua_script.c b/src/lua_script.c
index a9a76f2f6..07bfd91db 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -62,6 +62,7 @@ static lua_CFunction liblist[] = {
 	LUA_HudLib, // HUD stuff
 	LUA_FollowerLib, // follower_t, followers[]
 	LUA_RespawnVarsLib, // respawnvars_t
+	LUA_WaypointLib, // waypoint_t
 	NULL
 };
 
diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
new file mode 100644
index 000000000..be8ec9a51
--- /dev/null
+++ b/src/lua_waypointslib.c
@@ -0,0 +1,159 @@
+// DR. ROBOTNIK'S RING RACERS
+//-----------------------------------------------------------------------------
+// Copyright (C) 2024 by Kart Krew.
+// Copyright (C) 2020 by Sonic Team Junior.
+// Copyright (C) 2016 by John "JTE" Muniz.
+//
+// This program is free software distributed under the
+// terms of the GNU General Public License, version 2.
+// See the 'LICENSE' file for more details.
+//-----------------------------------------------------------------------------
+/// \file  lua_waypointslib.c
+/// \brief wapoint structure library for Lua scripting
+
+#include "doomdef.h"
+#include "fastcmp.h"
+
+#include "lua_script.h"
+#include "lua_libs.h"
+
+enum waypointvars {
+	waypointvars_mobj = 0,
+	waypointvars_onaline,
+	waypointvars_nextwaypoints,
+	waypointvars_prevwaypoints,
+	waypointvars_nextwaypointdistances,
+	waypointvars_prevwaypointdistances,
+	waypointvars_numnextwaypoints,
+	waypointvars_numprevwaypoints,
+};
+
+static const char *const waypointvars_opt[] = {
+	"mobj",
+	"onaline",
+	"nextwaypoints",
+	"prevwaypoints",
+	"nextwaypointdistances",
+	"prevwaypointdistances",
+	"numnextwaypoints",
+	"numprevwaypoints",
+	NULL
+};
+
+#define RNOFIELD luaL_error(L, LUA_QL("waypoint_t") " has no field named " LUA_QS, field)
+#define RNOSET luaL_error(L, LUA_QL("waypoint_t") " field " LUA_QS " cannot be set.", field)
+
+static int waypoint_get(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	enum waypointvars field = luaL_checkoption(L, 2, NULL, waypointvars_opt);
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	switch (field)
+	{
+		case waypointvars_mobj:
+			LUA_PushUserdata(L, waypoint->mobj, META_MOBJ);
+			break;
+		case waypointvars_onaline:
+			lua_pushboolean(L, waypoint->onaline);
+			break;
+		case waypointvars_nextwaypoints:
+			lua_createtable(L, waypoint->numnextwaypoints, 0);
+			for (size_t i = 0; i < waypoint->numnextwaypoints; i++)
+			{
+				LUA_PushUserdata(L, waypoint->nextwaypoints[i], META_WAYPOINT);
+				lua_rawseti(L, -2, 1 + i);
+			}
+			break;
+		case waypointvars_prevwaypoints:
+			lua_createtable(L, waypoint->numprevwaypoints, 0);
+			for (size_t i = 0; i < waypoint->numprevwaypoints; i++)
+			{
+				LUA_PushUserdata(L, waypoint->prevwaypoints[i], META_WAYPOINT);
+				lua_rawseti(L, -2, 1 + i);
+			}
+			break;
+		case waypointvars_nextwaypointdistances:
+			lua_createtable(L, waypoint->numnextwaypoints, 0);
+			for (size_t i = 0; i < waypoint->numnextwaypoints; i++)
+			{
+				lua_pushinteger(L, waypoint->nextwaypointdistances[i]);
+				lua_rawseti(L, -2, 1 + i);
+			}
+			break;
+		case waypointvars_prevwaypointdistances:
+			lua_createtable(L, waypoint->numprevwaypoints, 0);
+			for (size_t i = 0; i < waypoint->numprevwaypoints; i++)
+			{
+				lua_pushinteger(L, waypoint->prevwaypointdistances[i]);
+				lua_rawseti(L, -2, 1 + i);
+			}
+			break;
+		case waypointvars_numnextwaypoints:
+			lua_pushinteger(L, waypoint->numnextwaypoints);
+			break;
+		case waypointvars_numprevwaypoints:
+			lua_pushinteger(L, waypoint->numprevwaypoints);
+			break;
+		default:
+			return RNOFIELD;
+	}
+
+	return 1;
+}
+
+static int waypoint_set(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	enum waypointvars field = luaL_checkoption(L, 2, waypointvars_opt[0], waypointvars_opt);
+
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+
+	INLEVEL
+	
+	switch (field)
+	{
+		case waypointvars_mobj:
+			waypoint->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
+			break;
+		case waypointvars_onaline:
+			waypoint->onaline = luaL_checkboolean(L, 3);
+			break;
+		// A function should be used to set these instead.
+		case waypointvars_nextwaypoints:
+			return RNOSET;
+		case waypointvars_prevwaypoints:
+			return RNOSET;
+		case waypointvars_nextwaypointdistances:
+			return RNOSET;
+		case waypointvars_prevwaypointdistances:
+			return RNOSET;
+		case waypointvars_numnextwaypoints:
+			return RNOSET;
+		case waypointvars_numprevwaypoints:
+			return RNOSET;
+		default:
+			return RNOFIELD;
+	}
+
+	return 0;
+}
+
+#undef RNOFIELD
+#undef RUNIMPLEMENTED
+
+int LUA_WaypointLib(lua_State *L)
+{
+	luaL_newmetatable(L, META_WAYPOINT);
+		lua_pushcfunction(L, waypoint_get);
+		lua_setfield(L, -2, "__index");
+
+		lua_pushcfunction(L, waypoint_set);
+		lua_setfield(L, -2, "__newindex");
+	lua_pop(L,1);
+
+	return 0;
+}
\ No newline at end of file
-- 
GitLab


From 608acc0979ad1734ac207fb32de566c18e6cf35f Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 01:39:13 +0100
Subject: [PATCH 03/35] Expose K_GetFinishLineWaypoint to Lua

---
 src/lua_baselib.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 873056643..34e340d2a 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -32,6 +32,7 @@
 #include "k_collide.h"
 #include "k_color.h"
 #include "k_hud.h"
+#include "k_waypoint.h"
 #include "d_netcmd.h" // IsPlayerAdmin
 #include "k_menu.h" // Player Setup menu color stuff
 #include "p_spec.h" // P_StartQuake
@@ -4057,6 +4058,13 @@ static int lib_vsRandomPointOnArena(lua_State *L)
 	return 2;
 }
 
+static int lib_kGetFinishLineWaypoint(lua_State *L)
+{
+	INLEVEL
+	LUA_PushUserdata(L, K_GetFinishLineWaypoint(), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4342,6 +4350,9 @@ static luaL_Reg lib[] = {
 	{"VS_GetArena", lib_vsGetArena},
 	{"VS_PredictAroundArena", lib_vsPredictAroundArena},
 	{"VS_RandomPointOnArena", lib_vsRandomPointOnArena},
+	
+	// k_waypoint
+	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 79fc72a698b16f0c9d4a5261a4637db842595bed Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 01:44:50 +0100
Subject: [PATCH 04/35] Expose K_GetStartingWaypoint to Lua

---
 src/lua_baselib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 34e340d2a..af79f1837 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4065,6 +4065,13 @@ static int lib_kGetFinishLineWaypoint(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetStartingWaypoint(lua_State *L)
+{
+	INLEVEL
+	LUA_PushUserdata(L, K_GetStartingWaypoint(), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4353,6 +4360,7 @@ static luaL_Reg lib[] = {
 	
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
+	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 504b81d565445bebe18c78d21dfc0f8b08939808 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:00:41 +0100
Subject: [PATCH 05/35] Expose K_GetWaypointIsFinishline to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index af79f1837..2ce0e2d70 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4072,6 +4072,18 @@ static int lib_kGetStartingWaypoint(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointIsFinishline(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushboolean(L, K_GetWaypointIsFinishline(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4361,6 +4373,7 @@ static luaL_Reg lib[] = {
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
 	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
+	{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 627ad0a9ce3d9a07a2dbacbb68bd6ace47b6a9cc Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:11:25 +0100
Subject: [PATCH 06/35] Expose K_GetWaypointIsShortcut to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 2ce0e2d70..389be3853 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4084,6 +4084,18 @@ static int lib_kGetWaypointIsFinishline(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointIsShortcut(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushboolean(L, K_GetWaypointIsShortcut(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4374,6 +4386,7 @@ static luaL_Reg lib[] = {
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
 	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
 	{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
+	{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From d36aeb29621d4345ba52bebec6e8fa97a17073b1 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:23:13 +0100
Subject: [PATCH 07/35] Expose K_GetWaypointIsEnabled to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 389be3853..dd62b9a83 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4096,6 +4096,18 @@ static int lib_kGetWaypointIsShortcut(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointIsEnabled(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushboolean(L, K_GetWaypointIsEnabled(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4387,6 +4399,7 @@ static luaL_Reg lib[] = {
 	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
 	{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
 	{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
+	{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 63deefa3a3d155673cd51cea2fa6643595ee3a19 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:31:34 +0100
Subject: [PATCH 08/35] Expose K_GetWaypointIsSpawnpoint to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index dd62b9a83..4fd57f1f7 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4108,6 +4108,18 @@ static int lib_kGetWaypointIsEnabled(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointIsSpawnpoint(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushboolean(L, K_GetWaypointIsSpawnpoint(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4400,6 +4412,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
 	{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
 	{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
+	{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 2bf2390bcd65f0559a543caf122b4f11e6bb7968 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:41:14 +0100
Subject: [PATCH 09/35] Expose K_GetWaypointNextID to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 4fd57f1f7..ecd89dbce 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4120,6 +4120,18 @@ static int lib_kGetWaypointIsSpawnpoint(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointNextID(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushinteger(L, K_GetWaypointNextID(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4413,6 +4425,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
 	{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
 	{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
+	{"K_GetWaypointNextID", lib_kGetWaypointNextID},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 473ac81cfb84ae3322ea5a2b61decca9b54f70ae Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 02:54:38 +0100
Subject: [PATCH 10/35] Expose K_GetWaypointID to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index ecd89dbce..8e78c9b25 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4132,6 +4132,18 @@ static int lib_kGetWaypointNextID(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointID(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	INLEVEL
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushinteger(L, K_GetWaypointID(waypoint));
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4426,6 +4438,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
 	{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
 	{"K_GetWaypointNextID", lib_kGetWaypointNextID},
+	{"K_GetWaypointID", lib_kGetWaypointID},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 4d2eeb8122bd2d0db4b131889f517cc8d223dba4 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 03:04:35 +0100
Subject: [PATCH 11/35] Expose K_GetCircuitLength to Lua

---
 src/lua_baselib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 8e78c9b25..4f78f1371 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4144,6 +4144,13 @@ static int lib_kGetWaypointID(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetCircuitLength(lua_State *L)
+{
+	INLEVEL
+	lua_pushinteger(L, K_GetCircuitLength());
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4439,6 +4446,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
 	{"K_GetWaypointNextID", lib_kGetWaypointNextID},
 	{"K_GetWaypointID", lib_kGetWaypointID},
+	{"K_GetCircuitLength", lib_kGetCircuitLength},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 2a3e2a4e553de1a71c96d065740d0a84e173c280 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 03:24:55 +0100
Subject: [PATCH 12/35] Expose K_GetWaypointFromID to Lua

---
 src/lua_baselib.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 4f78f1371..ae86b526d 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4144,6 +4144,15 @@ static int lib_kGetWaypointID(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetWaypointFromID(lua_State *L)
+{
+	INT32 waypointId = luaL_checkinteger(L, 1);
+	INLEVEL
+	
+	LUA_PushUserdata(L, K_GetWaypointFromID(waypointId), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_kGetCircuitLength(lua_State *L)
 {
 	INLEVEL
@@ -4446,6 +4455,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
 	{"K_GetWaypointNextID", lib_kGetWaypointNextID},
 	{"K_GetWaypointID", lib_kGetWaypointID},
+	{"K_GetWaypointFromID", lib_kGetWaypointFromID},
 	{"K_GetCircuitLength", lib_kGetCircuitLength},
 
 	// hu_stuff technically?
-- 
GitLab


From 53cf34d8a68b79671cb13f20cadd5fe48c65f711 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Fri, 13 Dec 2024 03:41:30 +0100
Subject: [PATCH 13/35] Expose K_GetTrackComplexity to Lua

---
 src/lua_baselib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index ae86b526d..eab59266e 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4160,6 +4160,13 @@ static int lib_kGetCircuitLength(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetTrackComplexity(lua_State *L)
+{
+	INLEVEL
+	lua_pushinteger(L, K_GetTrackComplexity());
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4457,6 +4464,7 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointID", lib_kGetWaypointID},
 	{"K_GetWaypointFromID", lib_kGetWaypointFromID},
 	{"K_GetCircuitLength", lib_kGetCircuitLength},
+	{"K_GetTrackComplexity", lib_kGetTrackComplexity},
 
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 07b1b812fe403ab2e6679054ef893ccff2a35841 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 11 Jan 2025 17:19:09 +0100
Subject: [PATCH 14/35] Expose K_GetClosestWaypointToMobj to Lua

---
 src/lua_baselib.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index eab59266e..3e25e3e4f 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4167,6 +4167,17 @@ static int lib_kGetTrackComplexity(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetClosestWaypointToMobj(lua_State *L)
+{
+	mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	INLEVEL
+	if (!mobj)
+		return LUA_ErrInvalid(L, "mobj_t");
+	
+	LUA_PushUserdata(L, K_GetClosestWaypointToMobj(mobj), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4465,7 +4476,8 @@ static luaL_Reg lib[] = {
 	{"K_GetWaypointFromID", lib_kGetWaypointFromID},
 	{"K_GetCircuitLength", lib_kGetCircuitLength},
 	{"K_GetTrackComplexity", lib_kGetTrackComplexity},
-
+	{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
+	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
 
-- 
GitLab


From 29a502cd2ab3f63e0a8034afb98aa152bffb4e26 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 11 Jan 2025 18:16:29 +0100
Subject: [PATCH 15/35] Expose K_GetBestWaypointForMobj to Lua

---
 src/lua_baselib.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 3e25e3e4f..c5b8b4860 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4178,6 +4178,39 @@ static int lib_kGetClosestWaypointToMobj(lua_State *L)
 	return 1;
 }
 
+static int lib_kGetBestWaypointForMobj(lua_State *L)
+{
+	mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	waypoint_t *hint = NULL;
+	INLEVEL
+	if (!mobj)
+		return LUA_ErrInvalid(L, "mobj_t");
+	// Optional waypoint parameter:
+	if (lua_isuserdata(L, 2) && lua_getmetatable(L, 2))
+	{
+		lua_getfield(L, LUA_REGISTRYINDEX, META_WAYPOINT);
+		int result = lua_rawequal(L, -1, -2);
+		lua_pop(L, 2);
+		
+		if (!result)
+		{
+			return LUA_ErrInvalid(L, "waypoint_t");
+		}
+		else
+			hint = *((waypoint_t **)lua_touserdata(L, 2));
+	}
+	else if (!lua_isnoneornil(L, 2))
+	{
+		// If we reach this point and it isn't an userdata,
+		// the scripter used a basic data type. Let them know
+		// they messed up. (Just use nil or nothing, please.)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	}
+	
+	LUA_PushUserdata(L, K_GetBestWaypointForMobj(mobj, hint), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4477,6 +4510,7 @@ static luaL_Reg lib[] = {
 	{"K_GetCircuitLength", lib_kGetCircuitLength},
 	{"K_GetTrackComplexity", lib_kGetTrackComplexity},
 	{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
+	{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From dca2945f7ec36862c46db43a5fb527857ebaef02 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 19:39:26 +0100
Subject: [PATCH 16/35] Create pushDeepCopyOfPathTypeAsTable to handle path_t
 and pathfindnode_t objects

---
 src/lua_baselib.c | 40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index c5b8b4860..54254d024 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4211,6 +4211,46 @@ static int lib_kGetBestWaypointForMobj(lua_State *L)
 	return 1;
 }
 
+/*
+	JugadorXEI @ 01/11/2025 (MM/DD/AAAA)
+	This was my way to work around giving path_t and pathfindnode_t objects
+	to Lua, as usually these are dynamically allocated. We give them a deep
+	copy of the values and then we free this memory after the fact.
+	Lua can manage its own copy itself.
+*/
+static void pushDeepCopyOfPathTypeAsTable(lua_State *L, path_t *const path)
+{
+	lua_createtable(L, 0, 3);
+	
+	lua_pushinteger(L, path->numnodes);
+	lua_setfield(L, -2, "numnodes");
+	
+	lua_createtable(L, path->numnodes, 0);
+	for (size_t i = 0; i < path->numnodes; i++)
+	{
+		lua_createtable(L, 0, 3);
+		
+			// It doesn't make sense for heap-related stuff to be exposed to Lua.
+			// lua_pushinteger(L, path->array[i].heapindex);
+			// lua_setfield(L, -2, "heapindex");
+			
+			LUA_PushUserdata(L, (waypoint_t *)path->array[i].nodedata, META_WAYPOINT);
+			lua_setfield(L, -2, "nodedata");
+			
+			lua_pushinteger(L, path->array[i].gscore);
+			lua_setfield(L, -2, "gscore");
+			
+			lua_pushinteger(L, path->array[i].hscore);
+			lua_setfield(L, -2, "hscore");
+		
+		lua_rawseti(L, -2, 1 + i);
+	}
+	lua_setfield(L, -2, "array");
+	
+	lua_pushinteger(L, path->totaldist);
+	lua_setfield(L, -2, "totaldist");
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
-- 
GitLab


From 7ebccc7005947ae24d65bd9c0df1d5cb9cc3536d Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 19:39:49 +0100
Subject: [PATCH 17/35] Expose K_PathfindToWaypoint to Lua

---
 src/lua_baselib.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 54254d024..9aff5b81a 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4251,6 +4251,32 @@ static void pushDeepCopyOfPathTypeAsTable(lua_State *L, path_t *const path)
 	lua_setfield(L, -2, "totaldist");
 }
 
+static int lib_kPathfindToWaypoint(lua_State *L)
+{
+	waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	waypoint_t *destinationwaypoint = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
+	boolean useshortcuts = lua_optboolean(L, 3);
+	boolean huntbackwards = lua_optboolean(L, 4);
+	
+	INLEVEL
+	if (!sourcewaypoint || !destinationwaypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	path_t returnpath = {0};
+	boolean success = K_PathfindToWaypoint(sourcewaypoint, destinationwaypoint, &returnpath, useshortcuts, huntbackwards);
+	
+	lua_pushboolean(L, success);
+	if (success)
+	{
+		pushDeepCopyOfPathTypeAsTable(L, &returnpath);
+	}
+	else
+		lua_pushnil(L);
+	
+	Z_Free(returnpath.array);
+	return 2;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4551,6 +4577,7 @@ static luaL_Reg lib[] = {
 	{"K_GetTrackComplexity", lib_kGetTrackComplexity},
 	{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
 	{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
+	{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From e7c9c0b13b7e51835bee6a506f9c1d8703965de7 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 19:36:18 +0100
Subject: [PATCH 18/35] Expose K_PathfindThruCircuit to Lua

---
 src/lua_baselib.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 9aff5b81a..8c8e120a5 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4277,6 +4277,32 @@ static int lib_kPathfindToWaypoint(lua_State *L)
 	return 2;
 }
 
+static int lib_kPathfindThruCircuit(lua_State *L)
+{
+	waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	fixed_t traveldistance = luaL_checkfixed(L, 2);
+	boolean useshortcuts = lua_optboolean(L, 3);
+	boolean huntbackwards = lua_optboolean(L, 4);
+	
+	INLEVEL
+	if (!sourcewaypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	path_t returnpath = {0};
+	boolean success = K_PathfindThruCircuit(sourcewaypoint, traveldistance, &returnpath, useshortcuts, huntbackwards);
+	
+	lua_pushboolean(L, success);
+	if (success)
+	{
+		pushDeepCopyOfPathTypeAsTable(L, &returnpath);
+	}
+	else
+		lua_pushnil(L);
+	
+	Z_Free(returnpath.array);
+	return 2;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4578,6 +4604,7 @@ static luaL_Reg lib[] = {
 	{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
 	{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
 	{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
+	{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 9104550f114855ec2f9e23d0f6a983fbc18c3085 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 20:07:19 +0100
Subject: [PATCH 19/35] Expose K_PathfindThruCircuitSpawnable to Lua

---
 src/lua_baselib.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 8c8e120a5..99836e2f2 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4303,6 +4303,32 @@ static int lib_kPathfindThruCircuit(lua_State *L)
 	return 2;
 }
 
+static int lib_kPathfindThruCircuitSpawnable(lua_State *L)
+{
+	waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	fixed_t traveldistance = luaL_checkfixed(L, 2);
+	boolean useshortcuts = lua_optboolean(L, 3);
+	boolean huntbackwards = lua_optboolean(L, 4);
+	
+	INLEVEL
+	if (!sourcewaypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	path_t returnpath = {0};
+	boolean success = K_PathfindThruCircuitSpawnable(sourcewaypoint, traveldistance, &returnpath, useshortcuts, huntbackwards);
+	
+	lua_pushboolean(L, success);
+	if (success)
+	{
+		pushDeepCopyOfPathTypeAsTable(L, &returnpath);
+	}
+	else
+		lua_pushnil(L);
+	
+	Z_Free(returnpath.array);
+	return 2;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4605,6 +4631,7 @@ static luaL_Reg lib[] = {
 	{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
 	{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
 	{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
+	{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 14c1ec9a445790111c03492027c7b2937392e708 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 20:24:12 +0100
Subject: [PATCH 20/35] Expose K_GetNextWaypointToDestination to Lua

---
 src/lua_baselib.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 99836e2f2..d7471eaba 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4329,6 +4329,21 @@ static int lib_kPathfindThruCircuitSpawnable(lua_State *L)
 	return 2;
 }
 
+static int lib_kGetNextWaypointToDestination(lua_State *L)
+{
+	waypoint_t *sourcewaypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	waypoint_t *destinationwaypoint = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
+	boolean useshortcuts = lua_optboolean(L, 3);
+	boolean huntbackwards = lua_optboolean(L, 4);
+	
+	INLEVEL
+	if (!sourcewaypoint || !destinationwaypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	LUA_PushUserdata(L, K_GetNextWaypointToDestination(sourcewaypoint, destinationwaypoint, useshortcuts, huntbackwards), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4632,6 +4647,7 @@ static luaL_Reg lib[] = {
 	{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
 	{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
 	{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
+	{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From b67897a9abb25d1d861d40c226e803c1706182d1 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 20:35:52 +0100
Subject: [PATCH 21/35] Expose K_SearchWaypointGraphForMobj to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index d7471eaba..538fd514a 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4344,6 +4344,18 @@ static int lib_kGetNextWaypointToDestination(lua_State *L)
 	return 1;
 }
 
+static int lib_kSearchWaypointGraphForMobj(lua_State *L)
+{
+	mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	
+	INLEVEL
+	if (!mobj)
+		return LUA_ErrInvalid(L, "mobj_t");
+	
+	LUA_PushUserdata(L, K_SearchWaypointGraphForMobj(mobj), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4648,6 +4660,7 @@ static luaL_Reg lib[] = {
 	{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
 	{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
 	{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
+	{"K_SearchWaypointGraphForMobj", lib_kSearchWaypointGraphForMobj},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 36f6478e5dc46131171c7639395d11b8ab7b73b4 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 20:40:25 +0100
Subject: [PATCH 22/35] Expose K_SearchWaypointHeapForMobj to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 538fd514a..0a119f40e 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4356,6 +4356,18 @@ static int lib_kSearchWaypointGraphForMobj(lua_State *L)
 	return 1;
 }
 
+static int lib_kSearchWaypointHeapForMobj(lua_State *L)
+{
+	mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
+	
+	INLEVEL
+	if (!mobj)
+		return LUA_ErrInvalid(L, "mobj_t");
+	
+	LUA_PushUserdata(L, K_SearchWaypointHeapForMobj(mobj), META_WAYPOINT);
+	return 1;
+}
+
 static int lib_getTimeMicros(lua_State *L)
 {
 	lua_pushinteger(L, I_GetPreciseTime() / (I_GetPrecisePrecision() / 1000000));
@@ -4661,6 +4673,7 @@ static luaL_Reg lib[] = {
 	{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
 	{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
 	{"K_SearchWaypointGraphForMobj", lib_kSearchWaypointGraphForMobj},
+	{"K_SearchWaypointHeapForMobj", lib_kSearchWaypointHeapForMobj},
 	
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
-- 
GitLab


From 1e6fde888c20eb20e1d40f1b0b5566b9fbfe8287 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 21:23:56 +0100
Subject: [PATCH 23/35] Expose K_RespawnOffset to Lua

---
 src/lua_baselib.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 0a119f40e..25296a99f 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -33,6 +33,7 @@
 #include "k_color.h"
 #include "k_hud.h"
 #include "k_waypoint.h"
+#include "k_respawn.h"
 #include "d_netcmd.h" // IsPlayerAdmin
 #include "k_menu.h" // Player Setup menu color stuff
 #include "p_spec.h" // P_StartQuake
@@ -4058,6 +4059,19 @@ static int lib_vsRandomPointOnArena(lua_State *L)
 	return 2;
 }
 
+static int lib_kRespawnOffset(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	boolean flip = lua_optboolean(L, 2);
+	
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	
+	lua_pushfixed(L, K_RespawnOffset(player, flip));
+	return 1;
+}
+
 static int lib_kGetFinishLineWaypoint(lua_State *L)
 {
 	INLEVEL
@@ -4654,6 +4668,9 @@ static luaL_Reg lib[] = {
 	{"VS_PredictAroundArena", lib_vsPredictAroundArena},
 	{"VS_RandomPointOnArena", lib_vsRandomPointOnArena},
 	
+	// k_respawn
+	{"K_RespawnOffset", lib_kRespawnOffset},
+	
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
 	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
-- 
GitLab


From d453e8095fad802978d623c1dc169483500868b0 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 21:35:33 +0100
Subject: [PATCH 24/35] Expose K_DoFault to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 25296a99f..6cc57f456 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4072,6 +4072,18 @@ static int lib_kRespawnOffset(lua_State *L)
 	return 1;
 }
 
+static int lib_kDoFault(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	
+	K_DoFault(player);
+	return 0;
+}
+
 static int lib_kGetFinishLineWaypoint(lua_State *L)
 {
 	INLEVEL
@@ -4670,6 +4682,7 @@ static luaL_Reg lib[] = {
 	
 	// k_respawn
 	{"K_RespawnOffset", lib_kRespawnOffset},
+	{"K_DoFault", lib_kDoFault},
 	
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
-- 
GitLab


From 5bd2a0df107b4b649812be5cfe6ee4fe0ba67f2f Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 21:46:14 +0100
Subject: [PATCH 25/35] Expose K_DoIngameRespawn to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 6cc57f456..7a4ba6a43 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4084,6 +4084,18 @@ static int lib_kDoFault(lua_State *L)
 	return 0;
 }
 
+static int lib_kDoIngameRespawn(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	
+	K_DoIngameRespawn(player);
+	return 0;
+}
+
 static int lib_kGetFinishLineWaypoint(lua_State *L)
 {
 	INLEVEL
@@ -4683,6 +4695,7 @@ static luaL_Reg lib[] = {
 	// k_respawn
 	{"K_RespawnOffset", lib_kRespawnOffset},
 	{"K_DoFault", lib_kDoFault},
+	{"K_DoIngameRespawn", lib_kDoIngameRespawn},
 	
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
-- 
GitLab


From ef12c64c0279a93a034e0f6e74632fc97ff2b69d Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 21:56:59 +0100
Subject: [PATCH 26/35] Expose K_NextRespawnWaypointIndex to Lua

---
 src/lua_baselib.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 7a4ba6a43..f52ad0352 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4096,6 +4096,18 @@ static int lib_kDoIngameRespawn(lua_State *L)
 	return 0;
 }
 
+static int lib_kNextRespawnWaypointIndex(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	
+	INLEVEL
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushinteger(L, K_NextRespawnWaypointIndex(waypoint));
+	return 1;
+}
+
 static int lib_kGetFinishLineWaypoint(lua_State *L)
 {
 	INLEVEL
@@ -4696,6 +4708,7 @@ static luaL_Reg lib[] = {
 	{"K_RespawnOffset", lib_kRespawnOffset},
 	{"K_DoFault", lib_kDoFault},
 	{"K_DoIngameRespawn", lib_kDoIngameRespawn},
+	{"K_NextRespawnWaypointIndex", lib_kNextRespawnWaypointIndex},
 	
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
-- 
GitLab


From a361d145b3c86f6375c66c929cbb9a0a8ab0bd28 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sat, 18 Jan 2025 22:17:49 +0100
Subject: [PATCH 27/35] Expose K_RespawnAtWaypoint to Lua

---
 src/k_respawn.c   | 13 +++----------
 src/k_respawn.h   | 13 +++++++++++++
 src/lua_baselib.c | 16 ++++++++++++++++
 3 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/k_respawn.c b/src/k_respawn.c
index 6fe2f9897..8dea382d2 100644
--- a/src/k_respawn.c
+++ b/src/k_respawn.c
@@ -61,18 +61,11 @@ static void K_FudgeRespawn(player_t *player, const waypoint_t *const waypoint)
 }
 
 /*--------------------------------------------------
-	static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
+	void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
 
-		Updates a player's respawn variables to go to the provided waypoint.
-
-	Input Arguments:-
-		player - Player to preform for.
-		waypoint - Waypoint to respawn to.
-
-	Return:-
-		None
+		See header file for description.
 --------------------------------------------------*/
-static void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
+void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
 {
 	if (player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo))
 	{
diff --git a/src/k_respawn.h b/src/k_respawn.h
index fdf4f48e5..375fdde74 100644
--- a/src/k_respawn.h
+++ b/src/k_respawn.h
@@ -42,6 +42,19 @@ extern "C" {
 
 fixed_t K_RespawnOffset(player_t *player, boolean flip);
 
+/*--------------------------------------------------
+	void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint)
+
+		Updates a player's respawn variables to go to the provided waypoint.
+
+	Input Arguments:-
+		player - Player to preform for.
+		waypoint - Waypoint to respawn to.
+
+	Return:-
+		None
+--------------------------------------------------*/
+void K_RespawnAtWaypoint(player_t *player, waypoint_t *waypoint);
 
 /*--------------------------------------------------
 	void K_DoFault(player_t *player);
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index f52ad0352..405cb4306 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4072,6 +4072,21 @@ static int lib_kRespawnOffset(lua_State *L)
 	return 1;
 }
 
+static int lib_kRespawnAtWaypoint(lua_State *L)
+{
+	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
+	waypoint_t *wp = *((waypoint_t **)luaL_checkudata(L, 2, META_WAYPOINT));
+	
+	INLEVEL
+	if (!player)
+		return LUA_ErrInvalid(L, "player_t");
+	if (!wp)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	K_RespawnAtWaypoint(player, wp);
+	return 0;
+}
+
 static int lib_kDoFault(lua_State *L)
 {
 	player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@@ -4706,6 +4721,7 @@ static luaL_Reg lib[] = {
 	
 	// k_respawn
 	{"K_RespawnOffset", lib_kRespawnOffset},
+	{"K_RespawnAtWaypoint", lib_kRespawnAtWaypoint},
 	{"K_DoFault", lib_kDoFault},
 	{"K_DoIngameRespawn", lib_kDoIngameRespawn},
 	{"K_NextRespawnWaypointIndex", lib_kNextRespawnWaypointIndex},
-- 
GitLab


From 4158c263f412792f48d1ecae30591bd1db6295e9 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sun, 19 Jan 2025 01:53:16 +0100
Subject: [PATCH 28/35] Allow distancetofinish and distancetofinishprev from
 player_t to be set

---
 src/lua_playerlib.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 1b8fb4cd6..9adf60826 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -799,9 +799,9 @@ static int player_set(lua_State *L)
 	else if (fastcmp(field,"positiondelay"))
 		plr->positiondelay = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"distancetofinish"))
-		return NOSET;
+		plr->distancetofinish = luaL_checkfixed(L, 3);
 	else if (fastcmp(field,"distancetofinishprev"))
-		return NOSET;
+		plr->distancetofinishprev = luaL_checkfixed(L, 3);
 	else if (fastcmp(field,"lastpickupdistance"))
 		plr->lastpickupdistance = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"airtime"))
-- 
GitLab


From 0aa0dc3caf1f14e926202808ad6da1d3cdc37c0f Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Sun, 19 Jan 2025 02:47:48 +0100
Subject: [PATCH 29/35] Allow player_t's bigwaypointgap and dropdashboost to be
 get and set

---
 src/lua_playerlib.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 9adf60826..c711186f8 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -242,6 +242,8 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->airtime);
 	else if (fastcmp(field,"lastairtime"))
 		lua_pushinteger(L, plr->lastairtime);
+	else if (fastcmp(field,"bigwaypointgap"))
+		lua_pushinteger(L, plr->bigwaypointgap);
 	else if (fastcmp(field,"flashing"))
 		lua_pushinteger(L, plr->flashing);
 	else if (fastcmp(field,"spinouttimer"))
@@ -300,6 +302,8 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->gateSound);
 	else if (fastcmp(field,"startboost"))
 		lua_pushinteger(L, plr->startboost);
+	else if (fastcmp(field,"dropdashboost"))
+		lua_pushinteger(L, plr->dropdashboost);
 	else if (fastcmp(field,"aizdriftstrat"))
 		lua_pushinteger(L, plr->aizdriftstrat);
 	else if (fastcmp(field,"aizdriftextend"))
@@ -808,6 +812,8 @@ static int player_set(lua_State *L)
 		plr->airtime = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"lastairtime"))
 		plr->lastairtime = luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"bigwaypointgap"))
+		plr->bigwaypointgap = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"flashing"))
 		plr->flashing = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"spinouttimer"))
@@ -866,6 +872,8 @@ static int player_set(lua_State *L)
 		plr->gateSound = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"startboost"))
 		plr->startboost = luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"dropdashboost"))
+		plr->dropdashboost = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"aizdriftstrat"))
 		plr->aizdriftstrat = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"aizdrifttilt"))
-- 
GitLab


From abff309b1faf2acb6aaa81c27b7bdf8d5fa35672 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Mon, 27 Jan 2025 00:35:22 +0100
Subject: [PATCH 30/35] Expose k_respawn.h and k_waypoint.h #defined values to
 Lua

---
 src/deh_tables.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/deh_tables.c b/src/deh_tables.c
index 6a5255e8e..0081acb33 100644
--- a/src/deh_tables.c
+++ b/src/deh_tables.c
@@ -26,6 +26,8 @@
 #include "k_boss.h" // spottype_t (for lua)
 #include "k_follower.h" // followermode_t (for lua)
 #include "music.h" // tune flags (for lua)
+#include "k_respawn.h" // respawn values (for lua)
+#include "k_waypoint.h" // waypoint values (for lua)
 
 #include "deh_tables.h"
 
@@ -5206,6 +5208,16 @@ struct int_const_s const INT_CONST[] = {
 	{"TN_NIGHTCOREABLE",TN_NIGHTCOREABLE},
 	{"TN_CHANGEPITCH",TN_CHANGEPITCH},
 	{"TN_LOOPING",TN_LOOPING},
+	
+	// k_respawn.h values
+	{"RESPAWN_DIST",RESPAWN_DIST},
+	{"RESPAWN_TIME",RESPAWN_TIME},
+	{"RESPAWNST_NONE",RESPAWNST_NONE},
+	{"RESPAWNST_MOVE",RESPAWNST_MOVE},
+	{"RESPAWNST_DROP",RESPAWNST_DROP},
+	
+	// k_waypoint.h values
+	{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},
 
 	{NULL,0}
 };
-- 
GitLab


From 3c4b514c872f93de5a3046d97535c1452d0980ed Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Wed, 12 Mar 2025 00:05:10 +0100
Subject: [PATCH 31/35] Fix whitespace and EOF new line mistakes

---
 src/lua_baselib.c      | 6 +++---
 src/lua_waypointslib.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 405cb4306..81875a5a5 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -4718,14 +4718,14 @@ static luaL_Reg lib[] = {
 	{"VS_GetArena", lib_vsGetArena},
 	{"VS_PredictAroundArena", lib_vsPredictAroundArena},
 	{"VS_RandomPointOnArena", lib_vsRandomPointOnArena},
-	
+
 	// k_respawn
 	{"K_RespawnOffset", lib_kRespawnOffset},
 	{"K_RespawnAtWaypoint", lib_kRespawnAtWaypoint},
 	{"K_DoFault", lib_kDoFault},
 	{"K_DoIngameRespawn", lib_kDoIngameRespawn},
 	{"K_NextRespawnWaypointIndex", lib_kNextRespawnWaypointIndex},
-	
+
 	// k_waypoint
 	{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
 	{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
@@ -4746,7 +4746,7 @@ static luaL_Reg lib[] = {
 	{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
 	{"K_SearchWaypointGraphForMobj", lib_kSearchWaypointGraphForMobj},
 	{"K_SearchWaypointHeapForMobj", lib_kSearchWaypointHeapForMobj},
-	
+
 	// hu_stuff technically?
 	{"HU_DoTitlecardCEcho", lib_startTitlecardCecho},
 
diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
index be8ec9a51..943a281e2 100644
--- a/src/lua_waypointslib.c
+++ b/src/lua_waypointslib.c
@@ -156,4 +156,4 @@ int LUA_WaypointLib(lua_State *L)
 	lua_pop(L,1);
 
 	return 0;
-}
\ No newline at end of file
+}
-- 
GitLab


From 7e1f9135d03fd556e74cd855bc69ee57acfd499f Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Wed, 12 Mar 2025 13:44:09 +0100
Subject: [PATCH 32/35] Add valid value to waypoint_t for Lua, invalidate
 waypoints in LUA_InvalidateLevel

---
 src/lua_script.c       |  4 ++++
 src/lua_waypointslib.c | 20 +++++++++++++++++---
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/lua_script.c b/src/lua_script.c
index 07bfd91db..4591152e9 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -899,6 +899,10 @@ void LUA_InvalidateLevel(void)
 		LUA_InvalidateUserdata(nodes[i].children);
 	}
 #endif
+	for (i = 0; i < K_GetNumWaypoints(); i++)
+	{
+		LUA_InvalidateUserdata(K_GetWaypointFromIndex(i));
+	}
 }
 
 void LUA_InvalidateMapthings(void)
diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
index 943a281e2..b65cb767b 100644
--- a/src/lua_waypointslib.c
+++ b/src/lua_waypointslib.c
@@ -18,7 +18,8 @@
 #include "lua_libs.h"
 
 enum waypointvars {
-	waypointvars_mobj = 0,
+	waypointvars_valid = 0,
+	waypointvars_mobj,
 	waypointvars_onaline,
 	waypointvars_nextwaypoints,
 	waypointvars_prevwaypoints,
@@ -29,6 +30,7 @@ enum waypointvars {
 };
 
 static const char *const waypointvars_opt[] = {
+	"valid",
 	"mobj",
 	"onaline",
 	"nextwaypoints",
@@ -49,10 +51,22 @@ static int waypoint_get(lua_State *L)
 	enum waypointvars field = luaL_checkoption(L, 2, NULL, waypointvars_opt);
 	
 	if (!waypoint)
-		return LUA_ErrInvalid(L, "waypoint_t");
-	
+	{
+		switch (field)
+		{
+			case waypointvars_valid:
+				lua_pushboolean(L, false);
+				return 1;
+			default:
+				return LUA_ErrInvalid(L, "waypoint_t");
+		}
+	}
+
 	switch (field)
 	{
+		case waypointvars_valid:
+			lua_pushboolean(L, true);
+			break;
 		case waypointvars_mobj:
 			LUA_PushUserdata(L, waypoint->mobj, META_MOBJ);
 			break;
-- 
GitLab


From 10e565c202329b952cfe9898983ab0bb25b647f4 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Wed, 12 Mar 2025 18:50:37 +0100
Subject: [PATCH 33/35] `mobj` and `onaline` are no longer settable in
 waypoint_t through Lua

---
 src/lua_waypointslib.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
index b65cb767b..5f3b25085 100644
--- a/src/lua_waypointslib.c
+++ b/src/lua_waypointslib.c
@@ -131,11 +131,9 @@ static int waypoint_set(lua_State *L)
 	switch (field)
 	{
 		case waypointvars_mobj:
-			waypoint->mobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
-			break;
+			return RNOSET;
 		case waypointvars_onaline:
-			waypoint->onaline = luaL_checkboolean(L, 3);
-			break;
+			return RNOSET;
 		// A function should be used to set these instead.
 		case waypointvars_nextwaypoints:
 			return RNOSET;
-- 
GitLab


From 3cf53cd20f547984209a3b7ef1137ef37dbabb88 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Wed, 19 Mar 2025 16:59:19 +0100
Subject: [PATCH 34/35] Expose waypoints global, waypoints.iterate and
 #waypoints to Lua

---
 src/lua_waypointslib.c | 72 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)

diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
index 5f3b25085..93989689c 100644
--- a/src/lua_waypointslib.c
+++ b/src/lua_waypointslib.c
@@ -157,6 +157,67 @@ static int waypoint_set(lua_State *L)
 #undef RNOFIELD
 #undef RUNIMPLEMENTED
 
+static int lib_iterateWaypoints(lua_State *L)
+{
+	size_t i;
+
+	if (lua_gettop(L) < 2)
+	{
+		lua_pushcfunction(L, lib_iterateWaypoints);
+		return 1;
+	}
+
+	lua_settop(L, 2);
+	lua_remove(L, 1); // state is unused.
+
+	if (!lua_isnil(L, 1))
+		i = K_GetWaypointHeapIndex(*(waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT)) + 1;
+	else
+		i = 0;
+
+	if (i < K_GetNumWaypoints())
+	{
+		LUA_PushUserdata(L, K_GetWaypointFromIndex(i), META_WAYPOINT);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int lib_getWaypoint(lua_State *L)
+{
+	const char *field;
+	size_t i;
+
+	// find waypoint by number
+	if (lua_type(L, 2) == LUA_TNUMBER)
+	{
+		i = luaL_checkinteger(L, 2);
+		if (i >= K_GetNumWaypoints())
+			return luaL_error(L, "waypoints[] index %d out of range (0 - %d)", i, K_GetNumWaypoints()-1);
+		LUA_PushUserdata(L, K_GetWaypointFromIndex(i), META_WAYPOINT);
+		return 1;
+	}
+
+	field = luaL_checkstring(L, 2);
+
+	// special function iterate
+	if (fastcmp(field,"iterate"))
+	{
+		lua_pushcfunction(L, lib_iterateWaypoints);
+		return 1;
+	}
+
+	return 0;
+}
+
+static int lib_numWaypoints(lua_State *L)
+{
+	lua_pushinteger(L, K_GetNumWaypoints());
+	return 1;
+}
+
+
 int LUA_WaypointLib(lua_State *L)
 {
 	luaL_newmetatable(L, META_WAYPOINT);
@@ -166,6 +227,17 @@ int LUA_WaypointLib(lua_State *L)
 		lua_pushcfunction(L, waypoint_set);
 		lua_setfield(L, -2, "__newindex");
 	lua_pop(L,1);
+	
+	lua_newuserdata(L, 0);
+		lua_createtable(L, 0, 2);
+			lua_pushcfunction(L, lib_getWaypoint);
+			lua_setfield(L, -2, "__index");
+
+			lua_pushcfunction(L, lib_numWaypoints);
+			lua_setfield(L, -2, "__len");
+		lua_setmetatable(L, -2);
+	lua_setglobal(L, "waypoints");
+
 
 	return 0;
 }
-- 
GitLab


From c4b7562680caea35f9654b79cb5aa6c18b418096 Mon Sep 17 00:00:00 2001
From: JugadorXEI <eugeniom9@gmail.com>
Date: Wed, 19 Mar 2025 17:06:29 +0100
Subject: [PATCH 35/35] Expose #waypoint (from waypoint_t) to Lua

---
 src/lua_waypointslib.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/lua_waypointslib.c b/src/lua_waypointslib.c
index 93989689c..0af89b8e0 100644
--- a/src/lua_waypointslib.c
+++ b/src/lua_waypointslib.c
@@ -157,6 +157,17 @@ static int waypoint_set(lua_State *L)
 #undef RNOFIELD
 #undef RUNIMPLEMENTED
 
+static int waypoint_num(lua_State *L)
+{
+	waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
+	
+	if (!waypoint)
+		return LUA_ErrInvalid(L, "waypoint_t");
+	
+	lua_pushinteger(L, K_GetWaypointHeapIndex(waypoint));
+	return 1;
+}
+
 static int lib_iterateWaypoints(lua_State *L)
 {
 	size_t i;
@@ -226,6 +237,9 @@ int LUA_WaypointLib(lua_State *L)
 
 		lua_pushcfunction(L, waypoint_set);
 		lua_setfield(L, -2, "__newindex");
+		
+		lua_pushcfunction(L, waypoint_num);
+		lua_setfield(L, -2, "__len");
 	lua_pop(L,1);
 	
 	lua_newuserdata(L, 0);
@@ -238,6 +252,5 @@ int LUA_WaypointLib(lua_State *L)
 		lua_setmetatable(L, -2);
 	lua_setglobal(L, "waypoints");
 
-
 	return 0;
 }
-- 
GitLab