Waypoints library for Lua
https://git.do.srb2.org/KartKrew/RingRacers/-/merge_requests/81
This commit is contained in:
parent
bffc25f198
commit
2d57e09fae
9 changed files with 725 additions and 5 deletions
|
|
@ -111,6 +111,7 @@ lua_hudlib.c
|
|||
lua_hudlib_drawlist.c
|
||||
lua_followerlib.c
|
||||
lua_terrainlib.c
|
||||
lua_waypointslib.c
|
||||
k_kart.c
|
||||
k_collide.c
|
||||
k_color.c
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "k_follower.h" // followermode_t (for lua)
|
||||
#include "g_input.h" // Game controls (for lua)
|
||||
#include "k_kart.h" // awardscaledrings_t
|
||||
#include "k_waypoint.h" // waypoint values (for lua)
|
||||
|
||||
|
||||
#include "deh_tables.h"
|
||||
#include "fastcmp.h"
|
||||
|
|
@ -1573,6 +1575,8 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"KARTINVIN_LEGACY", KARTINVIN_LEGACY},
|
||||
{"KARTINVIN_ALTERN", KARTINVIN_ALTERN},
|
||||
|
||||
// k_waypoint.h values
|
||||
{"DEFAULT_WAYPOINT_RADIUS",DEFAULT_WAYPOINT_RADIUS},
|
||||
|
||||
{NULL,0}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -152,6 +152,27 @@ boolean K_GetWaypointIsEnabled(waypoint_t *waypoint)
|
|||
return waypointisenabled;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
* boolean K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
*
|
||||
* See header file for description.
|
||||
* --------------------------------------------------*/
|
||||
void K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
{
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_SetWaypointIsEnabled.\n");
|
||||
}
|
||||
else if ((waypoint->mobj == NULL) || (P_MobjWasRemoved(waypoint->mobj) == true))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_SetWaypointIsEnabled.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
waypoint->mobj->extravalue1 = enabled ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
||||
|
||||
|
|
@ -163,11 +184,11 @@ boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
|||
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointIsEnabled.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointIsSpawnpoint.\n");
|
||||
}
|
||||
else if ((waypoint->mobj == NULL) || (P_MobjWasRemoved(waypoint->mobj) == true))
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_GetWaypointIsEnabled.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint mobj in K_GetWaypointIsSpawnpoint.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -521,7 +542,7 @@ size_t K_GetWaypointHeapIndex(waypoint_t *waypoint)
|
|||
|
||||
if (waypoint == NULL)
|
||||
{
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointID.\n");
|
||||
CONS_Debug(DBG_GAMELOGIC, "NULL waypoint in K_GetWaypointHeapIndex.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -125,6 +125,17 @@ boolean K_GetWaypointIsShortcut(waypoint_t *waypoint);
|
|||
|
||||
boolean K_GetWaypointIsEnabled(waypoint_t *waypoint);
|
||||
|
||||
/*--------------------------------------------------
|
||||
* boolean K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled)
|
||||
*
|
||||
* Sets whether the waypoint is enabled or not.
|
||||
*
|
||||
* Input Arguments:-
|
||||
* waypoint - The waypoint to set its enabled status to.
|
||||
* enabled - Boolean that sets the waypoint's enabled status.
|
||||
* --------------------------------------------------*/
|
||||
|
||||
void K_SetWaypointIsEnabled(waypoint_t *waypoint, boolean enabled);
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_GetWaypointIsSpawnpoint(waypoint_t *waypoint)
|
||||
|
|
|
|||
|
|
@ -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 "m_menu.h" // Player Setup menu color stuff
|
||||
#include "p_spec.h" // P_StartQuake
|
||||
|
|
@ -4250,6 +4251,345 @@ static int lib_kAwardScaledPlayerRings(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
|
||||
LUA_PushUserdata(L, K_GetFinishLineWaypoint(), META_WAYPOINT);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetStartingWaypoint(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
LUA_PushUserdata(L, K_GetStartingWaypoint(), META_WAYPOINT);
|
||||
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_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_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_kSetWaypointIsEnabled(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
boolean enabled = luaL_checkboolean(L, 2);
|
||||
INLEVEL
|
||||
|
||||
if (!waypoint)
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
|
||||
K_SetWaypointIsEnabled(waypoint, enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_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_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_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
|
||||
lua_pushinteger(L, K_GetCircuitLength());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetTrackComplexity(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
lua_pushinteger(L, K_GetTrackComplexity());
|
||||
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_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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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_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_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_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_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_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_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));
|
||||
|
|
@ -4672,6 +5012,28 @@ static luaL_Reg lib[] = {
|
|||
{"K_AwardPlayerRings", lib_kAwardPlayerRings},
|
||||
{"K_AwardScaledPlayerRings", lib_kAwardScaledPlayerRings},
|
||||
|
||||
// k_waypoint
|
||||
{"K_GetFinishLineWaypoint", lib_kGetFinishLineWaypoint},
|
||||
{"K_GetStartingWaypoint", lib_kGetStartingWaypoint},
|
||||
{"K_GetWaypointIsFinishline", lib_kGetWaypointIsFinishline},
|
||||
{"K_GetWaypointIsShortcut", lib_kGetWaypointIsShortcut},
|
||||
{"K_GetWaypointIsEnabled", lib_kGetWaypointIsEnabled},
|
||||
{"K_SetWaypointIsEnabled", lib_kSetWaypointIsEnabled},
|
||||
{"K_GetWaypointIsSpawnpoint", lib_kGetWaypointIsSpawnpoint},
|
||||
{"K_GetWaypointNextID", lib_kGetWaypointNextID},
|
||||
{"K_GetWaypointID", lib_kGetWaypointID},
|
||||
{"K_GetWaypointFromID", lib_kGetWaypointFromID},
|
||||
{"K_GetCircuitLength", lib_kGetCircuitLength},
|
||||
{"K_GetTrackComplexity", lib_kGetTrackComplexity},
|
||||
{"K_GetClosestWaypointToMobj", lib_kGetClosestWaypointToMobj},
|
||||
{"K_GetBestWaypointForMobj", lib_kGetBestWaypointForMobj},
|
||||
{"K_PathfindToWaypoint", lib_kPathfindToWaypoint},
|
||||
{"K_PathfindThruCircuit", lib_kPathfindThruCircuit},
|
||||
{"K_PathfindThruCircuitSpawnable", lib_kPathfindThruCircuitSpawnable},
|
||||
{"K_GetNextWaypointToDestination", lib_kGetNextWaypointToDestination},
|
||||
{"K_SearchWaypointGraphForMobj", lib_kSearchWaypointGraphForMobj},
|
||||
{"K_SearchWaypointHeapForMobj", lib_kSearchWaypointHeapForMobj},
|
||||
|
||||
// k_boss
|
||||
{"K_InitBossHealthBar", lib_kInitBossHealthBar},
|
||||
{"K_UpdateBossHealthBar", lib_kUpdateBossHealthBar},
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ extern lua_State *gL;
|
|||
#define META_ACTIVATOR "ACTIVATOR_T*"
|
||||
|
||||
#define META_FOLLOWER "FOLLOWER_T*"
|
||||
#define META_WAYPOINT "WAYPOINT_T*"
|
||||
|
||||
#define META_SPLASH "T_SPLASH_T*"
|
||||
#define META_FOOTSTEP "T_FOOTSTEP_T*"
|
||||
|
|
@ -134,6 +135,7 @@ int LUA_BlockmapLib(lua_State *L);
|
|||
int LUA_HudLib(lua_State *L);
|
||||
int LUA_FollowerLib(lua_State *L);
|
||||
int LUA_TerrainLib(lua_State *L);
|
||||
int LUA_WaypointLib(lua_State *L);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
|
|
|
|||
|
|
@ -193,7 +193,10 @@ enum player_e
|
|||
player_nextcheck,
|
||||
player_distancetofinish,
|
||||
player_distancetofinishprev,
|
||||
player_currentwaypoint,
|
||||
player_nextwaypoint,
|
||||
player_airtime,
|
||||
player_bigwaypointgap,
|
||||
player_flashing,
|
||||
player_spinouttimer,
|
||||
player_spinouttype,
|
||||
|
|
@ -381,7 +384,10 @@ static const char *const player_opt[] = {
|
|||
"nextcheck",
|
||||
"distancetofinish",
|
||||
"distancetofinishprev",
|
||||
"currentwaypoint",
|
||||
"nextwaypoint",
|
||||
"airtime",
|
||||
"bigwaypointgap",
|
||||
"flashing",
|
||||
"spinouttimer",
|
||||
"spinouttype",
|
||||
|
|
@ -650,6 +656,9 @@ static int player_get(lua_State *L)
|
|||
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;
|
||||
|
|
@ -1295,12 +1304,23 @@ static int player_set(lua_State *L)
|
|||
plr->nextcheck = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case player_distancetofinish:
|
||||
return NOSET;
|
||||
plr->distancetofinish = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case player_distancetofinishprev:
|
||||
return NOSET;
|
||||
plr->distancetofinishprev = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
case player_currentwaypoint:
|
||||
NOSET;
|
||||
break;
|
||||
case player_nextwaypoint:
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ static lua_CFunction liblist[] = {
|
|||
LUA_HudLib, // HUD stuff
|
||||
LUA_FollowerLib, // follower_t, followers[]
|
||||
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
||||
LUA_WaypointLib, // waypoint_t
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
@ -1031,6 +1032,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)
|
||||
|
|
|
|||
294
src/lua_waypointslib.c
Normal file
294
src/lua_waypointslib.c
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
// 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"
|
||||
#include "p_local.h"
|
||||
|
||||
enum waypointvars {
|
||||
waypointvars_valid = 0,
|
||||
waypointvars_mobj,
|
||||
waypointvars_x,
|
||||
waypointvars_y,
|
||||
waypointvars_z,
|
||||
waypointvars_onaline,
|
||||
waypointvars_nextwaypoints,
|
||||
waypointvars_prevwaypoints,
|
||||
waypointvars_nextwaypointdistances,
|
||||
waypointvars_prevwaypointdistances,
|
||||
waypointvars_numnextwaypoints,
|
||||
waypointvars_numprevwaypoints,
|
||||
};
|
||||
|
||||
static const char *const waypointvars_opt[] = {
|
||||
"valid",
|
||||
"mobj",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"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)
|
||||
#define RNOGET luaL_error(L, LUA_QL("waypoint_t") " field " LUA_QS " cannot be get.", 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)
|
||||
{
|
||||
switch (field)
|
||||
{
|
||||
case waypointvars_valid:
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
default:
|
||||
return LUA_ErrInvalid(L, "waypoint_t");
|
||||
}
|
||||
}
|
||||
|
||||
// It could totally happen that some scripter just deletes the mobj,
|
||||
// which would have us check a null pointer, so we're checking against that
|
||||
// just in case.
|
||||
mobj_t *waypointMobj = NULL;
|
||||
if (waypoint->mobj != NULL && P_MobjWasRemoved(waypoint->mobj) == false)
|
||||
waypointMobj = waypoint->mobj;
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case waypointvars_valid:
|
||||
lua_pushboolean(L, true);
|
||||
break;
|
||||
case waypointvars_mobj:
|
||||
return RNOGET;
|
||||
case waypointvars_x:
|
||||
if (waypointMobj)
|
||||
lua_pushfixed(L, waypointMobj->x);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case waypointvars_y:
|
||||
if (waypointMobj)
|
||||
lua_pushinteger(L, waypointMobj->y);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
break;
|
||||
case waypointvars_z:
|
||||
if (waypointMobj)
|
||||
lua_pushinteger(L, waypointMobj->z);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
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:
|
||||
return RNOSET;
|
||||
case waypointvars_x:
|
||||
return RNOSET;
|
||||
case waypointvars_y:
|
||||
return RNOSET;
|
||||
case waypointvars_z:
|
||||
return RNOSET;
|
||||
case waypointvars_onaline:
|
||||
return RNOSET;
|
||||
// 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 RNOSET
|
||||
#undef RNOFIELD
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
lua_pushcfunction(L, waypoint_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
Loading…
Reference in a new issue