Bot library for Lua (botvars getter/setter, bot functions)
This commit is contained in:
parent
e8d43ec8a3
commit
dc9bec000a
16 changed files with 521 additions and 16 deletions
|
|
@ -109,6 +109,7 @@ lua_maplib.c
|
|||
lua_taglib.c
|
||||
lua_polyobjlib.c
|
||||
lua_blockmaplib.c
|
||||
lua_botvarslib.c
|
||||
lua_hudlib.c
|
||||
lua_hudlib_drawlist.c
|
||||
lua_followerlib.c
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
#include "r_data.h" // patchalphastyle_t
|
||||
#include "k_boss.h" // spottype_t (for lua)
|
||||
#include "k_follower.h" // followermode_t (for lua)
|
||||
#include "k_bot.h" // bot constants (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"
|
||||
|
||||
|
|
@ -1553,6 +1553,47 @@ struct int_const_s const INT_CONST[] = {
|
|||
{"SNEAKERTYPE_ROCKETSNEAKER", SNEAKERTYPE_ROCKETSNEAKER},
|
||||
{"SNEAKERTYPE_WATERPANEL", SNEAKERTYPE_WATERPANEL},
|
||||
|
||||
// k_bot.h constants
|
||||
{"MAXBOTDIFFICULTY",MAXBOTDIFFICULTY},
|
||||
{"DIFFICULTBOT",DIFFICULTBOT},
|
||||
{"BOTTURNCONFIRM",BOTTURNCONFIRM},
|
||||
{"BOTSPINDASHCONFIRM",BOTSPINDASHCONFIRM},
|
||||
{"BOTRESPAWNCONFIRM",BOTRESPAWNCONFIRM},
|
||||
{"BOT_ITEM_DECISION_TIME",BOT_ITEM_DECISION_TIME},
|
||||
|
||||
// botStyle_e
|
||||
{"BOT_STYLE_NORMAL",BOT_STYLE_NORMAL},
|
||||
{"BOT_STYLE_STAY",BOT_STYLE_STAY},
|
||||
{"BOT_STYLE__MAX",BOT_STYLE__MAX},
|
||||
|
||||
// botItemPriority_e
|
||||
/*
|
||||
{"BOT_ITEM_PR__FALLBACK",BOT_ITEM_PR__FALLBACK},
|
||||
{"BOT_ITEM_PR_NEUTRAL",BOT_ITEM_PR_NEUTRAL},
|
||||
{"BOT_ITEM_PR_FRONTRUNNER",BOT_ITEM_PR_FRONTRUNNER},
|
||||
{"BOT_ITEM_PR_SPEED",BOT_ITEM_PR_SPEED},
|
||||
{"BOT_ITEM_PR__OVERRIDES",BOT_ITEM_PR__OVERRIDES},
|
||||
{"BOT_ITEM_PR_RINGDEBT",BOT_ITEM_PR_RINGDEBT},
|
||||
{"BOT_ITEM_PR_POWER",BOT_ITEM_PR_POWER},
|
||||
{"BOT_ITEM_PR_SPB",BOT_ITEM_PR_SPB},
|
||||
{"BOT_ITEM_PR__MAX",BOT_ITEM_PR__MAX},
|
||||
*/
|
||||
|
||||
// textmapbotcontroller_t
|
||||
{"TMBOT_NORUBBERBAND",TMBOT_NORUBBERBAND},
|
||||
{"TMBOT_NOCONTROL",TMBOT_NOCONTROL},
|
||||
{"TMBOT_FORCEDIR",TMBOT_FORCEDIR},
|
||||
//{"TMBOT_FASTFALL",TMBOT_FASTFALL},
|
||||
|
||||
// textmapbottrick_t
|
||||
/*
|
||||
{"TMBOTTR_NONE",TMBOTTR_NONE},
|
||||
{"TMBOTTR_LEFT",TMBOTTR_LEFT},
|
||||
{"TMBOTTR_RIGHT",TMBOTTR_RIGHT},
|
||||
{"TMBOTTR_UP",TMBOTTR_UP},
|
||||
{"TMBOTTR_DOWN",TMBOTTR_DOWN},
|
||||
*/
|
||||
|
||||
// t_overlay_action_t
|
||||
{"TOV_UNDEFINED",TOV_UNDEFINED},
|
||||
{"TOV_STILL",TOV_STILL},
|
||||
|
|
|
|||
|
|
@ -2410,6 +2410,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
boolean spectator;
|
||||
boolean bot;
|
||||
UINT8 botdifficulty;
|
||||
botStyle_e style;
|
||||
|
||||
INT16 rings;
|
||||
angle_t playerangleturn;
|
||||
|
|
@ -2469,6 +2470,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
followitem = players[player].followitem;
|
||||
|
||||
bot = players[player].bot;
|
||||
style = players[player].botvars.style;
|
||||
botdifficulty = players[player].botvars.difficulty;
|
||||
|
||||
botdiffincrease = players[player].botvars.diffincrease;
|
||||
|
|
@ -2631,6 +2633,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->totalring = totalring;
|
||||
|
||||
p->bot = bot;
|
||||
p->botvars.style = style;
|
||||
p->botvars.difficulty = botdifficulty;
|
||||
p->rings = rings;
|
||||
p->botvars.diffincrease = botdiffincrease;
|
||||
|
|
|
|||
|
|
@ -168,6 +168,8 @@ void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e s
|
|||
|
||||
SetPlayerSkinByNum(newplayernum, skinnum);
|
||||
|
||||
LUA_HookPlayer(&players[newplayernum], HOOK(BotJoin));
|
||||
|
||||
for (UINT8 i = 0; i < PWRLV_NUMTYPES; i++)
|
||||
{
|
||||
clientpowerlevels[newplayernum][i] = 0;
|
||||
|
|
@ -395,6 +397,17 @@ void K_UpdateMatchRaceBots(void)
|
|||
--------------------------------------------------*/
|
||||
boolean K_PlayerUsesBotMovement(const player_t *player)
|
||||
{
|
||||
// Lua can't override the podium sequence result, but it can
|
||||
// override the following results:
|
||||
{
|
||||
UINT8 shouldOverride = LUA_HookPlayerForceResults(const_cast<player_t*>(player),
|
||||
HOOK(PlayerUsesBotMovement));
|
||||
if (shouldOverride == 1)
|
||||
return true;
|
||||
if (shouldOverride == 2)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->bot)
|
||||
return true;
|
||||
|
||||
|
|
@ -489,11 +502,11 @@ static fixed_t K_BotSpeedScaled(const player_t *player, fixed_t speed)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
const botcontroller_t *K_GetBotController(const mobj_t *mobj)
|
||||
botcontroller_t *K_GetBotController(const mobj_t *mobj)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
const botcontroller_t *K_GetBotController(const mobj_t *mobj)
|
||||
botcontroller_t *K_GetBotController(const mobj_t *mobj)
|
||||
{
|
||||
botcontroller_t *ret = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ boolean K_BotCanTakeCut(const player_t *player);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
const botcontroller_t *K_GetBotController(const mobj_t *mobj);
|
||||
botcontroller_t *K_GetBotController(const mobj_t *mobj);
|
||||
|
||||
Retrieves the current bot controller values from
|
||||
the player's current sector.
|
||||
|
|
@ -147,7 +147,7 @@ boolean K_BotCanTakeCut(const player_t *player);
|
|||
Pointer to the sector's bot controller struct.
|
||||
--------------------------------------------------*/
|
||||
|
||||
const botcontroller_t *K_GetBotController(const mobj_t *mobj);
|
||||
botcontroller_t *K_GetBotController(const mobj_t *mobj);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "k_kart.h"
|
||||
#include "m_random.h"
|
||||
#include "r_things.h"
|
||||
#include "lua_hook.h" // LUA_HookGPRankPoints
|
||||
#include "lua_hook.h"
|
||||
|
||||
struct grandprixinfo grandprixinfo;
|
||||
|
||||
|
|
@ -641,6 +641,7 @@ void K_RetireBots(void)
|
|||
K_SetNameForBot(i, skins[skinnum].realname);
|
||||
|
||||
bot->score = 0;
|
||||
LUA_HookPlayer(bot, HOOK(BotJoin));
|
||||
bot->pflags &= ~PF_NOCONTEST;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@
|
|||
#include "p_spec.h" // P_StartQuake
|
||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||
#include "v_video.h"
|
||||
#include "k_terrain.h"
|
||||
#include "k_bot.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
|
@ -45,8 +47,6 @@
|
|||
#include "taglist.h" // P_FindSpecialLineFromTag
|
||||
#include "lua_hook.h" // hook_cmd_running errors
|
||||
|
||||
#include "k_terrain.h"
|
||||
|
||||
#define NOHUD if (hud_running)\
|
||||
return luaL_error(L, "HUD rendering code should not call this function!");\
|
||||
else if (hook_cmd_running)\
|
||||
|
|
@ -230,15 +230,20 @@ static const struct {
|
|||
{META_LUABANKS, "luabanks[]"},
|
||||
|
||||
{META_ACTIVATOR, "activator_t"},
|
||||
|
||||
|
||||
{META_FOLLOWER, "follower_t"},
|
||||
|
||||
{META_SONICLOOPVARS, "sonicloopvars_t"},
|
||||
{META_SONICLOOPCAMVARS, "sonicloopcamvars_t"},
|
||||
|
||||
{META_BOTVARS, "botvars_t"},
|
||||
{META_BOTCONTROLLER, "botcontroller_t"},
|
||||
|
||||
{META_SPLASH, "t_splash_t"},
|
||||
{META_FOOTSTEP, "t_footstep_t"},
|
||||
{META_OVERLAY, "t_overlay_t"},
|
||||
{META_TERRAIN, "terrain_t"},
|
||||
|
||||
{META_SONICLOOPVARS, "sonicloopvars_t"},
|
||||
{META_SONICLOOPCAMVARS, "sonicloopcamvars_t"},
|
||||
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
@ -2484,7 +2489,6 @@ static int lib_rSetPlayerSkin(lua_State *L)
|
|||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INT32 i = -1, j = -1;
|
||||
NOHUD
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
|
|
@ -4344,6 +4348,148 @@ static int lib_kAwardScaledPlayerRings(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kPlayerUsesBotMovement(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushboolean(L, K_PlayerUsesBotMovement(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kBotCanTakeCut(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushboolean(L, K_BotCanTakeCut(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kGetBotController(lua_State *L)
|
||||
{
|
||||
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
INLEVEL
|
||||
if (!mobj)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
|
||||
botcontroller_t *botController = K_GetBotController(mobj);
|
||||
if (botController != NULL)
|
||||
LUA_PushUserdata(L, botController, META_BOTCONTROLLER);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kBotMapModifier(lua_State *L)
|
||||
{
|
||||
INLEVEL
|
||||
lua_pushfixed(L, K_BotMapModifier());
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kBotRubberband(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushfixed(L, K_BotRubberband(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kUpdateRubberband(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
|
||||
lua_pushfixed(L, K_UpdateRubberband(player));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kDistanceOfLineFromPoint(lua_State *L)
|
||||
{
|
||||
fixed_t v1x = luaL_checkfixed(L, 1);
|
||||
fixed_t v1y = luaL_checkfixed(L, 2);
|
||||
fixed_t v2x = luaL_checkfixed(L, 3);
|
||||
fixed_t v2y = luaL_checkfixed(L, 4);
|
||||
fixed_t cx = luaL_checkfixed(L, 5);
|
||||
fixed_t cy = luaL_checkfixed(L, 6);
|
||||
lua_pushfixed(L, K_DistanceOfLineFromPoint(v1x, v1y, v2x, v2y, cx, cy));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_kAddBot(lua_State *L)
|
||||
{
|
||||
INT32 skinid = -1;
|
||||
UINT8 difficulty = luaL_checkinteger(L, 2);
|
||||
botStyle_e style = luaL_checkinteger(L, 3);
|
||||
UINT8 newplayernum = 0;
|
||||
|
||||
// Copypaste of libd_getSprite2Patch, but fails loudly on each fail state instead.
|
||||
// get skin first!
|
||||
if (lua_isnumber(L, 1)) // find skin by number
|
||||
{
|
||||
skinid = lua_tonumber(L, 1);
|
||||
if (skinid < 0 || skinid >= numskins)
|
||||
return luaL_error(L, "skin number %d out of range (0 - %d)", skinid, numskins-1);
|
||||
}
|
||||
else // find skin by name
|
||||
{
|
||||
const char *name = luaL_checkstring(L, 1);
|
||||
skinid = R_SkinAvailable(name);
|
||||
if (skinid == -1)
|
||||
return luaL_error(L, "could not find skin %s by name", name);
|
||||
}
|
||||
|
||||
INLEVEL
|
||||
|
||||
boolean success = K_AddBot(skinid, difficulty, style, &newplayernum);
|
||||
lua_pushboolean(L, success);
|
||||
if (success)
|
||||
LUA_PushUserdata(L, &players[newplayernum - 1], META_PLAYER);
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int lib_kSetNameForBot(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
const char *realname = luaL_checkstring(L, 2);
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (!player->bot)
|
||||
return luaL_error(L, "You may only change bot names.");
|
||||
|
||||
K_SetNameForBot(player-players, realname);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kRemoveBot(lua_State *L)
|
||||
{
|
||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||
INLEVEL
|
||||
if (!player)
|
||||
return LUA_ErrInvalid(L, "player_t");
|
||||
if (!player->bot)
|
||||
return luaL_error(L, "You may only remove bots.");
|
||||
|
||||
CL_RemovePlayer(player-players, KR_LEAVE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_kNextRespawnWaypointIndex(lua_State *L)
|
||||
{
|
||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||
|
|
@ -5141,6 +5287,19 @@ static luaL_Reg lib[] = {
|
|||
// I_System
|
||||
{"I_GetPreciseTime",lib_iGetPreciseTime},
|
||||
|
||||
// k_bot
|
||||
{"K_PlayerUsesBotMovement", lib_kPlayerUsesBotMovement},
|
||||
{"K_BotCanTakeCut", lib_kBotCanTakeCut},
|
||||
{"K_GetBotController", lib_kGetBotController},
|
||||
{"K_BotMapModifier", lib_kBotMapModifier},
|
||||
{"K_BotRubberband", lib_kBotRubberband},
|
||||
{"K_UpdateRubberband", lib_kUpdateRubberband},
|
||||
{"K_DistanceOfLineFromPoint", lib_kDistanceOfLineFromPoint},
|
||||
{"K_AddBot", lib_kAddBot},
|
||||
{"K_SetNameForBot", lib_kSetNameForBot},
|
||||
// Lua-only function to allow safely removing bots.
|
||||
{"K_RemoveBot", lib_kRemoveBot},
|
||||
|
||||
// k_terrain
|
||||
{"K_AffectingTerrainActive", lib_kAffectingTerrainActive},
|
||||
{"K_GetDefaultTerrain", lib_kGetDefaultTerrain},
|
||||
|
|
|
|||
185
src/lua_botvarslib.c
Normal file
185
src/lua_botvarslib.c
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
// 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_botvarslib.c
|
||||
/// \brief player botvars structure library for Lua scripting
|
||||
|
||||
#include "doomdef.h"
|
||||
#include "fastcmp.h"
|
||||
|
||||
#include "lua_script.h"
|
||||
#include "lua_libs.h"
|
||||
|
||||
enum botvars {
|
||||
botvars_valid = 0,
|
||||
botvars_style,
|
||||
botvars_difficulty,
|
||||
botvars_diffincrease,
|
||||
botvars_rival,
|
||||
botvars_rubberband,
|
||||
/*
|
||||
botvars_itemdelay,
|
||||
botvars_itemconfirm,
|
||||
botvars_turnconfirm,
|
||||
botvars_spindashconfirm,
|
||||
botvars_respawnconfirm,
|
||||
botvars_roulettepriority,
|
||||
botvars_roulettetimeout,
|
||||
*/
|
||||
};
|
||||
|
||||
static const char *const botvars_opt[] = {
|
||||
"valid",
|
||||
"style",
|
||||
"difficulty",
|
||||
"diffincrease",
|
||||
"rival",
|
||||
"rubberband",
|
||||
/*
|
||||
"itemdelay",
|
||||
"itemconfirm",
|
||||
"turnconfirm",
|
||||
"spindashconfirm",
|
||||
"respawnconfirm",
|
||||
"roulettepriority",
|
||||
"roulettetimeout",
|
||||
*/
|
||||
NULL
|
||||
};
|
||||
|
||||
#define UNIMPLEMENTED luaL_error(L, LUA_QL("botvars_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", follower_opt[field])
|
||||
|
||||
static int botvars_get(lua_State *L)
|
||||
{
|
||||
botvars_t *botvars = *((botvars_t **)luaL_checkudata(L, 1, META_BOTVARS));
|
||||
enum botvars field = luaL_checkoption(L, 2, NULL, botvars_opt);
|
||||
|
||||
// This is a property that always exists in a player.
|
||||
I_Assert(botvars != NULL);
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case botvars_valid:
|
||||
lua_pushboolean(L, botvars != NULL);
|
||||
break;
|
||||
case botvars_style:
|
||||
lua_pushinteger(L, botvars->style);
|
||||
break;
|
||||
case botvars_difficulty:
|
||||
lua_pushinteger(L, botvars->difficulty);
|
||||
break;
|
||||
case botvars_diffincrease:
|
||||
lua_pushinteger(L, botvars->diffincrease);
|
||||
break;
|
||||
case botvars_rival:
|
||||
lua_pushboolean(L, botvars->rival);
|
||||
break;
|
||||
case botvars_rubberband:
|
||||
lua_pushfixed(L, botvars->rubberband);
|
||||
break;
|
||||
/*
|
||||
case botvars_itemdelay:
|
||||
lua_pushinteger(L, botvars->itemdelay);
|
||||
break;
|
||||
case botvars_itemconfirm:
|
||||
lua_pushinteger(L, botvars->itemconfirm);
|
||||
break;
|
||||
case botvars_turnconfirm:
|
||||
lua_pushinteger(L, botvars->turnconfirm);
|
||||
break;
|
||||
case botvars_spindashconfirm:
|
||||
lua_pushinteger(L, botvars->spindashconfirm);
|
||||
break;
|
||||
case botvars_respawnconfirm:
|
||||
lua_pushinteger(L, botvars->respawnconfirm);
|
||||
break;
|
||||
case botvars_roulettepriority:
|
||||
lua_pushinteger(L, botvars->roulettePriority);
|
||||
break;
|
||||
case botvars_roulettetimeout:
|
||||
lua_pushinteger(L, botvars->rouletteTimeout);
|
||||
break;
|
||||
*/
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define NOSET luaL_error(L, LUA_QL("itemroulette_t") " field " LUA_QS " should not be set directly.", botvars_opt[field])
|
||||
|
||||
static int botvars_set(lua_State *L)
|
||||
{
|
||||
botvars_t *botvars = *((botvars_t **)luaL_checkudata(L, 1, META_BOTVARS));
|
||||
enum botvars field = luaL_checkoption(L, 2, botvars_opt[0], botvars_opt);
|
||||
|
||||
// This is a property that always exists in a player.
|
||||
I_Assert(botvars != NULL);
|
||||
|
||||
INLEVEL
|
||||
|
||||
switch(field)
|
||||
{
|
||||
case botvars_valid:
|
||||
return NOSET;
|
||||
case botvars_style:
|
||||
botvars->style = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_difficulty:
|
||||
botvars->difficulty = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_diffincrease:
|
||||
botvars->diffincrease = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_rival:
|
||||
botvars->rival = luaL_checkboolean(L, 3);
|
||||
break;
|
||||
case botvars_rubberband:
|
||||
botvars->rubberband = luaL_checkfixed(L, 3);
|
||||
break;
|
||||
/*
|
||||
case botvars_itemdelay:
|
||||
botvars->itemdelay = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_itemconfirm:
|
||||
botvars->itemconfirm = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_turnconfirm:
|
||||
botvars->turnconfirm = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_spindashconfirm:
|
||||
botvars->spindashconfirm = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_respawnconfirm:
|
||||
botvars->respawnconfirm = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_roulettepriority:
|
||||
botvars->roulettePriority = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case botvars_roulettetimeout:
|
||||
botvars->rouletteTimeout = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
*/
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef NOSET
|
||||
|
||||
int LUA_BotVarsLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_BOTVARS);
|
||||
lua_pushcfunction(L, botvars_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
|
||||
lua_pushcfunction(L, botvars_set);
|
||||
lua_setfield(L, -2, "__newindex");
|
||||
lua_pop(L,1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -82,6 +82,8 @@ automatically.
|
|||
X (PlayerCmd),/* building the player's ticcmd struct */\
|
||||
X (MusicChange),\
|
||||
X (VoteThinker),/* Y_VoteTicker */\
|
||||
X (PlayerUsesBotMovement),/* K_PlayerUsesBotMovement */\
|
||||
X (BotJoin),\
|
||||
X (GPRankPoints),/* K_CalculateGPRankPoints */\
|
||||
X (AddonLoaded),\
|
||||
|
||||
|
|
@ -136,6 +138,7 @@ void LUA_HookInt(INT32 integer, int hook);
|
|||
void LUA_HookGamemap(int hook);
|
||||
void LUA_HookBool(boolean value, int hook);
|
||||
int LUA_HookPlayer(player_t *, int hook);
|
||||
int LUA_HookPlayerForceResults(player_t *, int hook);
|
||||
int LUA_HookTiccmd(player_t *, ticcmd_t *, int hook);
|
||||
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
|
||||
|
||||
|
|
|
|||
|
|
@ -676,6 +676,17 @@ int LUA_HookPlayer(player_t *player, int hook_type)
|
|||
return hook.status;
|
||||
}
|
||||
|
||||
int LUA_HookPlayerForceResults(player_t *player, int hook_type)
|
||||
{
|
||||
Hook_State hook;
|
||||
if (prepare_hook(&hook, 0, hook_type))
|
||||
{
|
||||
LUA_PushUserdata(gL, player, META_PLAYER);
|
||||
call_hooks(&hook, 1, res_force);
|
||||
}
|
||||
return hook.status;
|
||||
}
|
||||
|
||||
int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
|
||||
{
|
||||
Hook_State hook;
|
||||
|
|
|
|||
|
|
@ -107,14 +107,17 @@ extern lua_State *gL;
|
|||
#define META_FOLLOWER "FOLLOWER_T*"
|
||||
#define META_WAYPOINT "WAYPOINT_T*"
|
||||
|
||||
#define META_SONICLOOPVARS "SONICLOOPVARS_T*"
|
||||
#define META_SONICLOOPCAMVARS "SONICLOOPCAMVARS_T*"
|
||||
|
||||
#define META_BOTVARS "BOTVARS_T*"
|
||||
#define META_BOTCONTROLLER "BOTCONTROLLER_T*"
|
||||
|
||||
#define META_SPLASH "T_SPLASH_T*"
|
||||
#define META_FOOTSTEP "T_FOOTSTEP_T*"
|
||||
#define META_OVERLAY "T_OVERLAY_T*"
|
||||
#define META_TERRAIN "TERRAIN_T*"
|
||||
|
||||
#define META_SONICLOOPVARS "SONICLOOPVARS_T*"
|
||||
#define META_SONICLOOPCAMVARS "SONICLOOPCAMVARS_T*"
|
||||
|
||||
boolean luaL_checkboolean(lua_State *L, int narg);
|
||||
|
||||
int LUA_EnumLib(lua_State *L);
|
||||
|
|
@ -134,6 +137,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_BotVarsLib(lua_State *L);
|
||||
int LUA_TerrainLib(lua_State *L);
|
||||
int LUA_WaypointLib(lua_State *L);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ enum sector_e {
|
|||
sector_triggerer,
|
||||
sector_friction,
|
||||
sector_gravity,
|
||||
sector_botcontroller,
|
||||
sector_action,
|
||||
sector_args,
|
||||
sector_stringargs,
|
||||
|
|
@ -91,6 +92,7 @@ static const char *const sector_opt[] = {
|
|||
"triggerer",
|
||||
"friction",
|
||||
"gravity",
|
||||
"botcontroller",
|
||||
"action",
|
||||
"args"
|
||||
"stringargs",
|
||||
|
|
@ -409,6 +411,20 @@ static const char *const activator_opt[] = {
|
|||
"sector",
|
||||
"po",
|
||||
NULL};
|
||||
|
||||
enum botcontroller_e {
|
||||
botcontroller_valid = 0,
|
||||
//botcontroller_trick,
|
||||
botcontroller_flags,
|
||||
botcontroller_forceangle,
|
||||
};
|
||||
|
||||
static const char *const botcontroller_opt[] = {
|
||||
"valid",
|
||||
//"trick",
|
||||
"flags",
|
||||
"forceangle",
|
||||
NULL};
|
||||
|
||||
static const char *const array_opt[] ={"iterate",NULL};
|
||||
static const char *const valid_opt[] ={"valid",NULL};
|
||||
|
|
@ -767,6 +783,9 @@ static int sector_get(lua_State *L)
|
|||
case sector_gravity: // gravity
|
||||
lua_pushfixed(L, sector->gravity);
|
||||
return 1;
|
||||
case sector_botcontroller: // botController
|
||||
LUA_PushUserdata(L, §or->botController, META_BOTCONTROLLER);
|
||||
return 1;
|
||||
case sector_action: // action
|
||||
lua_pushinteger(L, (INT16)sector->action);
|
||||
return 1;
|
||||
|
|
@ -2690,6 +2709,49 @@ static int activator_get(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////
|
||||
// botcontroller_t //
|
||||
/////////////////////
|
||||
|
||||
static int botcontroller_get(lua_State *L)
|
||||
{
|
||||
botcontroller_t *botcontroller = *((botcontroller_t **)luaL_checkudata(L, 1, META_BOTCONTROLLER));
|
||||
enum botcontroller_e field = luaL_checkoption(L, 2, botcontroller_opt[0], botcontroller_opt);
|
||||
|
||||
if (!botcontroller)
|
||||
{
|
||||
if (field == botcontroller_valid) {
|
||||
lua_pushboolean(L, false);
|
||||
return 1;
|
||||
}
|
||||
return luaL_error(L, "accessed botcontroller_t doesn't exist anymore.");
|
||||
}
|
||||
|
||||
switch (field)
|
||||
{
|
||||
case botcontroller_valid:
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
|
||||
//case botcontroller_trick:
|
||||
//lua_pushinteger(L, botcontroller->trick);
|
||||
//return 1;
|
||||
|
||||
case botcontroller_flags:
|
||||
lua_pushinteger(L, botcontroller->flags);
|
||||
return 1;
|
||||
|
||||
case botcontroller_forceangle:
|
||||
lua_pushangle(L, botcontroller->forceAngle);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LUA_MapLib(lua_State *L)
|
||||
{
|
||||
luaL_newmetatable(L, META_SECTORLINES);
|
||||
|
|
@ -2856,6 +2918,12 @@ int LUA_MapLib(lua_State *L)
|
|||
lua_pushcfunction(L, activator_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_newmetatable(L, META_BOTCONTROLLER);
|
||||
lua_pushcfunction(L, botcontroller_get);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
||||
LUA_PushTaggableObjectArray(L, "sectors",
|
||||
lib_iterateSectors,
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ enum player_e
|
|||
player_spectator,
|
||||
player_spectatewait,
|
||||
player_bot,
|
||||
player_botvars,
|
||||
player_jointime,
|
||||
player_spectatorreentry,
|
||||
player_grieftime,
|
||||
|
|
@ -539,6 +540,7 @@ static const char *const player_opt[] = {
|
|||
"spectator",
|
||||
"spectatewait",
|
||||
"bot",
|
||||
"botvars",
|
||||
"jointime",
|
||||
"spectatorreentry",
|
||||
"grieftime",
|
||||
|
|
@ -1135,6 +1137,9 @@ static int player_get(lua_State *L)
|
|||
case player_bot:
|
||||
lua_pushboolean(L, plr->bot);
|
||||
break;
|
||||
case player_botvars:
|
||||
LUA_PushUserdata(L, &plr->botvars, META_BOTVARS);
|
||||
break;
|
||||
case player_jointime:
|
||||
lua_pushinteger(L, plr->jointime);
|
||||
break;
|
||||
|
|
@ -1786,6 +1791,8 @@ static int player_set(lua_State *L)
|
|||
break;
|
||||
case player_bot:
|
||||
return NOSET;
|
||||
case player_botvars:
|
||||
return NOSET;
|
||||
case player_jointime:
|
||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ static lua_CFunction liblist[] = {
|
|||
LUA_BlockmapLib, // blockmap stuff
|
||||
LUA_HudLib, // HUD stuff
|
||||
LUA_FollowerLib, // follower_t, followers[]
|
||||
LUA_BotVarsLib, // botvars_t
|
||||
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
||||
LUA_WaypointLib, // waypoint_t
|
||||
NULL
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
|
||||
// botvars_t
|
||||
WRITEUINT8(save->p, players[i].bot);
|
||||
WRITEUINT8(save->p, players[i].botvars.style);
|
||||
WRITEUINT8(save->p, players[i].botvars.difficulty);
|
||||
WRITEUINT8(save->p, players[i].botvars.diffincrease);
|
||||
WRITEUINT8(save->p, players[i].botvars.rival);
|
||||
|
|
@ -743,6 +744,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
|
||||
// botvars_t
|
||||
players[i].bot = READUINT8(save->p);
|
||||
players[i].botvars.style = READUINT8(save->p);
|
||||
players[i].botvars.difficulty = READUINT8(save->p);
|
||||
players[i].botvars.diffincrease = READUINT8(save->p);
|
||||
players[i].botvars.rival = (boolean)READUINT8(save->p);
|
||||
|
|
|
|||
|
|
@ -2934,6 +2934,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
}
|
||||
else if (P_IsMachineLocalPlayer(player))
|
||||
{
|
||||
// Players-turned-bots outside of end of race contexts (Lua)
|
||||
// don't update their local camera angle, so it should be updated
|
||||
// somewhere - I choose here because it makes the most sense.
|
||||
if (K_PlayerUsesBotMovement(player) && !player->bot)
|
||||
P_ForceLocalAngle(player, mo->angle, true);
|
||||
|
||||
focusangle = localangle[num];
|
||||
focusaiming = localaiming[num];
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue