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_taglib.c
|
||||||
lua_polyobjlib.c
|
lua_polyobjlib.c
|
||||||
lua_blockmaplib.c
|
lua_blockmaplib.c
|
||||||
|
lua_botvarslib.c
|
||||||
lua_hudlib.c
|
lua_hudlib.c
|
||||||
lua_hudlib_drawlist.c
|
lua_hudlib_drawlist.c
|
||||||
lua_followerlib.c
|
lua_followerlib.c
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@
|
||||||
#include "r_data.h" // patchalphastyle_t
|
#include "r_data.h" // patchalphastyle_t
|
||||||
#include "k_boss.h" // spottype_t (for lua)
|
#include "k_boss.h" // spottype_t (for lua)
|
||||||
#include "k_follower.h" // followermode_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 "g_input.h" // Game controls (for lua)
|
||||||
#include "k_kart.h" // awardscaledrings_t
|
#include "k_kart.h" // awardscaledrings_t
|
||||||
#include "k_waypoint.h" // waypoint values (for lua)
|
#include "k_waypoint.h" // waypoint values (for lua)
|
||||||
|
|
||||||
|
|
||||||
#include "deh_tables.h"
|
#include "deh_tables.h"
|
||||||
#include "fastcmp.h"
|
#include "fastcmp.h"
|
||||||
|
|
||||||
|
|
@ -1553,6 +1553,47 @@ struct int_const_s const INT_CONST[] = {
|
||||||
{"SNEAKERTYPE_ROCKETSNEAKER", SNEAKERTYPE_ROCKETSNEAKER},
|
{"SNEAKERTYPE_ROCKETSNEAKER", SNEAKERTYPE_ROCKETSNEAKER},
|
||||||
{"SNEAKERTYPE_WATERPANEL", SNEAKERTYPE_WATERPANEL},
|
{"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
|
// t_overlay_action_t
|
||||||
{"TOV_UNDEFINED",TOV_UNDEFINED},
|
{"TOV_UNDEFINED",TOV_UNDEFINED},
|
||||||
{"TOV_STILL",TOV_STILL},
|
{"TOV_STILL",TOV_STILL},
|
||||||
|
|
|
||||||
|
|
@ -2410,6 +2410,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
boolean spectator;
|
boolean spectator;
|
||||||
boolean bot;
|
boolean bot;
|
||||||
UINT8 botdifficulty;
|
UINT8 botdifficulty;
|
||||||
|
botStyle_e style;
|
||||||
|
|
||||||
INT16 rings;
|
INT16 rings;
|
||||||
angle_t playerangleturn;
|
angle_t playerangleturn;
|
||||||
|
|
@ -2469,6 +2470,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
followitem = players[player].followitem;
|
followitem = players[player].followitem;
|
||||||
|
|
||||||
bot = players[player].bot;
|
bot = players[player].bot;
|
||||||
|
style = players[player].botvars.style;
|
||||||
botdifficulty = players[player].botvars.difficulty;
|
botdifficulty = players[player].botvars.difficulty;
|
||||||
|
|
||||||
botdiffincrease = players[player].botvars.diffincrease;
|
botdiffincrease = players[player].botvars.diffincrease;
|
||||||
|
|
@ -2631,6 +2633,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
||||||
p->totalring = totalring;
|
p->totalring = totalring;
|
||||||
|
|
||||||
p->bot = bot;
|
p->bot = bot;
|
||||||
|
p->botvars.style = style;
|
||||||
p->botvars.difficulty = botdifficulty;
|
p->botvars.difficulty = botdifficulty;
|
||||||
p->rings = rings;
|
p->rings = rings;
|
||||||
p->botvars.diffincrease = botdiffincrease;
|
p->botvars.diffincrease = botdiffincrease;
|
||||||
|
|
|
||||||
|
|
@ -168,6 +168,8 @@ void K_SetBot(UINT8 newplayernum, UINT16 skinnum, UINT8 difficulty, botStyle_e s
|
||||||
|
|
||||||
SetPlayerSkinByNum(newplayernum, skinnum);
|
SetPlayerSkinByNum(newplayernum, skinnum);
|
||||||
|
|
||||||
|
LUA_HookPlayer(&players[newplayernum], HOOK(BotJoin));
|
||||||
|
|
||||||
for (UINT8 i = 0; i < PWRLV_NUMTYPES; i++)
|
for (UINT8 i = 0; i < PWRLV_NUMTYPES; i++)
|
||||||
{
|
{
|
||||||
clientpowerlevels[newplayernum][i] = 0;
|
clientpowerlevels[newplayernum][i] = 0;
|
||||||
|
|
@ -395,6 +397,17 @@ void K_UpdateMatchRaceBots(void)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
boolean K_PlayerUsesBotMovement(const player_t *player)
|
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)
|
if (player->bot)
|
||||||
return true;
|
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.
|
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;
|
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
|
Retrieves the current bot controller values from
|
||||||
the player's current sector.
|
the player's current sector.
|
||||||
|
|
@ -147,7 +147,7 @@ boolean K_BotCanTakeCut(const player_t *player);
|
||||||
Pointer to the sector's bot controller struct.
|
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 "k_kart.h"
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
#include "r_things.h"
|
#include "r_things.h"
|
||||||
#include "lua_hook.h" // LUA_HookGPRankPoints
|
#include "lua_hook.h"
|
||||||
|
|
||||||
struct grandprixinfo grandprixinfo;
|
struct grandprixinfo grandprixinfo;
|
||||||
|
|
||||||
|
|
@ -641,6 +641,7 @@ void K_RetireBots(void)
|
||||||
K_SetNameForBot(i, skins[skinnum].realname);
|
K_SetNameForBot(i, skins[skinnum].realname);
|
||||||
|
|
||||||
bot->score = 0;
|
bot->score = 0;
|
||||||
|
LUA_HookPlayer(bot, HOOK(BotJoin));
|
||||||
bot->pflags &= ~PF_NOCONTEST;
|
bot->pflags &= ~PF_NOCONTEST;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
#include "p_spec.h" // P_StartQuake
|
#include "p_spec.h" // P_StartQuake
|
||||||
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
#include "i_system.h" // I_GetPreciseTime, I_GetPrecisePrecision
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
#include "k_terrain.h"
|
||||||
|
#include "k_bot.h"
|
||||||
|
|
||||||
#include "lua_script.h"
|
#include "lua_script.h"
|
||||||
#include "lua_libs.h"
|
#include "lua_libs.h"
|
||||||
|
|
@ -45,8 +47,6 @@
|
||||||
#include "taglist.h" // P_FindSpecialLineFromTag
|
#include "taglist.h" // P_FindSpecialLineFromTag
|
||||||
#include "lua_hook.h" // hook_cmd_running errors
|
#include "lua_hook.h" // hook_cmd_running errors
|
||||||
|
|
||||||
#include "k_terrain.h"
|
|
||||||
|
|
||||||
#define NOHUD if (hud_running)\
|
#define NOHUD if (hud_running)\
|
||||||
return luaL_error(L, "HUD rendering code should not call this function!");\
|
return luaL_error(L, "HUD rendering code should not call this function!");\
|
||||||
else if (hook_cmd_running)\
|
else if (hook_cmd_running)\
|
||||||
|
|
@ -230,15 +230,20 @@ static const struct {
|
||||||
{META_LUABANKS, "luabanks[]"},
|
{META_LUABANKS, "luabanks[]"},
|
||||||
|
|
||||||
{META_ACTIVATOR, "activator_t"},
|
{META_ACTIVATOR, "activator_t"},
|
||||||
|
|
||||||
{META_FOLLOWER, "follower_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_SPLASH, "t_splash_t"},
|
||||||
{META_FOOTSTEP, "t_footstep_t"},
|
{META_FOOTSTEP, "t_footstep_t"},
|
||||||
{META_OVERLAY, "t_overlay_t"},
|
{META_OVERLAY, "t_overlay_t"},
|
||||||
{META_TERRAIN, "terrain_t"},
|
{META_TERRAIN, "terrain_t"},
|
||||||
|
|
||||||
{META_SONICLOOPVARS, "sonicloopvars_t"},
|
|
||||||
{META_SONICLOOPCAMVARS, "sonicloopcamvars_t"},
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -2484,7 +2489,6 @@ static int lib_rSetPlayerSkin(lua_State *L)
|
||||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||||
INT32 i = -1, j = -1;
|
INT32 i = -1, j = -1;
|
||||||
NOHUD
|
NOHUD
|
||||||
INLEVEL
|
|
||||||
if (!player)
|
if (!player)
|
||||||
return LUA_ErrInvalid(L, "player_t");
|
return LUA_ErrInvalid(L, "player_t");
|
||||||
|
|
||||||
|
|
@ -4344,6 +4348,148 @@ static int lib_kAwardScaledPlayerRings(lua_State *L)
|
||||||
return 0;
|
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)
|
static int lib_kNextRespawnWaypointIndex(lua_State *L)
|
||||||
{
|
{
|
||||||
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
waypoint_t *waypoint = *((waypoint_t **)luaL_checkudata(L, 1, META_WAYPOINT));
|
||||||
|
|
@ -5141,6 +5287,19 @@ static luaL_Reg lib[] = {
|
||||||
// I_System
|
// I_System
|
||||||
{"I_GetPreciseTime",lib_iGetPreciseTime},
|
{"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_terrain
|
||||||
{"K_AffectingTerrainActive", lib_kAffectingTerrainActive},
|
{"K_AffectingTerrainActive", lib_kAffectingTerrainActive},
|
||||||
{"K_GetDefaultTerrain", lib_kGetDefaultTerrain},
|
{"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 (PlayerCmd),/* building the player's ticcmd struct */\
|
||||||
X (MusicChange),\
|
X (MusicChange),\
|
||||||
X (VoteThinker),/* Y_VoteTicker */\
|
X (VoteThinker),/* Y_VoteTicker */\
|
||||||
|
X (PlayerUsesBotMovement),/* K_PlayerUsesBotMovement */\
|
||||||
|
X (BotJoin),\
|
||||||
X (GPRankPoints),/* K_CalculateGPRankPoints */\
|
X (GPRankPoints),/* K_CalculateGPRankPoints */\
|
||||||
X (AddonLoaded),\
|
X (AddonLoaded),\
|
||||||
|
|
||||||
|
|
@ -136,6 +138,7 @@ void LUA_HookInt(INT32 integer, int hook);
|
||||||
void LUA_HookGamemap(int hook);
|
void LUA_HookGamemap(int hook);
|
||||||
void LUA_HookBool(boolean value, int hook);
|
void LUA_HookBool(boolean value, int hook);
|
||||||
int LUA_HookPlayer(player_t *, 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_HookTiccmd(player_t *, ticcmd_t *, int hook);
|
||||||
int LUA_HookKey(event_t *event, int hook); // Hooks for key events
|
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;
|
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)
|
int LUA_HookTiccmd(player_t *player, ticcmd_t *cmd, int hook_type)
|
||||||
{
|
{
|
||||||
Hook_State hook;
|
Hook_State hook;
|
||||||
|
|
|
||||||
|
|
@ -107,14 +107,17 @@ extern lua_State *gL;
|
||||||
#define META_FOLLOWER "FOLLOWER_T*"
|
#define META_FOLLOWER "FOLLOWER_T*"
|
||||||
#define META_WAYPOINT "WAYPOINT_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_SPLASH "T_SPLASH_T*"
|
||||||
#define META_FOOTSTEP "T_FOOTSTEP_T*"
|
#define META_FOOTSTEP "T_FOOTSTEP_T*"
|
||||||
#define META_OVERLAY "T_OVERLAY_T*"
|
#define META_OVERLAY "T_OVERLAY_T*"
|
||||||
#define META_TERRAIN "TERRAIN_T*"
|
#define META_TERRAIN "TERRAIN_T*"
|
||||||
|
|
||||||
#define META_SONICLOOPVARS "SONICLOOPVARS_T*"
|
|
||||||
#define META_SONICLOOPCAMVARS "SONICLOOPCAMVARS_T*"
|
|
||||||
|
|
||||||
boolean luaL_checkboolean(lua_State *L, int narg);
|
boolean luaL_checkboolean(lua_State *L, int narg);
|
||||||
|
|
||||||
int LUA_EnumLib(lua_State *L);
|
int LUA_EnumLib(lua_State *L);
|
||||||
|
|
@ -134,6 +137,7 @@ int LUA_PolyObjLib(lua_State *L);
|
||||||
int LUA_BlockmapLib(lua_State *L);
|
int LUA_BlockmapLib(lua_State *L);
|
||||||
int LUA_HudLib(lua_State *L);
|
int LUA_HudLib(lua_State *L);
|
||||||
int LUA_FollowerLib(lua_State *L);
|
int LUA_FollowerLib(lua_State *L);
|
||||||
|
int LUA_BotVarsLib(lua_State *L);
|
||||||
int LUA_TerrainLib(lua_State *L);
|
int LUA_TerrainLib(lua_State *L);
|
||||||
int LUA_WaypointLib(lua_State *L);
|
int LUA_WaypointLib(lua_State *L);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ enum sector_e {
|
||||||
sector_triggerer,
|
sector_triggerer,
|
||||||
sector_friction,
|
sector_friction,
|
||||||
sector_gravity,
|
sector_gravity,
|
||||||
|
sector_botcontroller,
|
||||||
sector_action,
|
sector_action,
|
||||||
sector_args,
|
sector_args,
|
||||||
sector_stringargs,
|
sector_stringargs,
|
||||||
|
|
@ -91,6 +92,7 @@ static const char *const sector_opt[] = {
|
||||||
"triggerer",
|
"triggerer",
|
||||||
"friction",
|
"friction",
|
||||||
"gravity",
|
"gravity",
|
||||||
|
"botcontroller",
|
||||||
"action",
|
"action",
|
||||||
"args"
|
"args"
|
||||||
"stringargs",
|
"stringargs",
|
||||||
|
|
@ -409,6 +411,20 @@ static const char *const activator_opt[] = {
|
||||||
"sector",
|
"sector",
|
||||||
"po",
|
"po",
|
||||||
NULL};
|
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 array_opt[] ={"iterate",NULL};
|
||||||
static const char *const valid_opt[] ={"valid",NULL};
|
static const char *const valid_opt[] ={"valid",NULL};
|
||||||
|
|
@ -767,6 +783,9 @@ static int sector_get(lua_State *L)
|
||||||
case sector_gravity: // gravity
|
case sector_gravity: // gravity
|
||||||
lua_pushfixed(L, sector->gravity);
|
lua_pushfixed(L, sector->gravity);
|
||||||
return 1;
|
return 1;
|
||||||
|
case sector_botcontroller: // botController
|
||||||
|
LUA_PushUserdata(L, §or->botController, META_BOTCONTROLLER);
|
||||||
|
return 1;
|
||||||
case sector_action: // action
|
case sector_action: // action
|
||||||
lua_pushinteger(L, (INT16)sector->action);
|
lua_pushinteger(L, (INT16)sector->action);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -2690,6 +2709,49 @@ static int activator_get(lua_State *L)
|
||||||
return 0;
|
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)
|
int LUA_MapLib(lua_State *L)
|
||||||
{
|
{
|
||||||
luaL_newmetatable(L, META_SECTORLINES);
|
luaL_newmetatable(L, META_SECTORLINES);
|
||||||
|
|
@ -2856,6 +2918,12 @@ int LUA_MapLib(lua_State *L)
|
||||||
lua_pushcfunction(L, activator_get);
|
lua_pushcfunction(L, activator_get);
|
||||||
lua_setfield(L, -2, "__index");
|
lua_setfield(L, -2, "__index");
|
||||||
lua_pop(L, 1);
|
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",
|
LUA_PushTaggableObjectArray(L, "sectors",
|
||||||
lib_iterateSectors,
|
lib_iterateSectors,
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,7 @@ enum player_e
|
||||||
player_spectator,
|
player_spectator,
|
||||||
player_spectatewait,
|
player_spectatewait,
|
||||||
player_bot,
|
player_bot,
|
||||||
|
player_botvars,
|
||||||
player_jointime,
|
player_jointime,
|
||||||
player_spectatorreentry,
|
player_spectatorreentry,
|
||||||
player_grieftime,
|
player_grieftime,
|
||||||
|
|
@ -539,6 +540,7 @@ static const char *const player_opt[] = {
|
||||||
"spectator",
|
"spectator",
|
||||||
"spectatewait",
|
"spectatewait",
|
||||||
"bot",
|
"bot",
|
||||||
|
"botvars",
|
||||||
"jointime",
|
"jointime",
|
||||||
"spectatorreentry",
|
"spectatorreentry",
|
||||||
"grieftime",
|
"grieftime",
|
||||||
|
|
@ -1135,6 +1137,9 @@ static int player_get(lua_State *L)
|
||||||
case player_bot:
|
case player_bot:
|
||||||
lua_pushboolean(L, plr->bot);
|
lua_pushboolean(L, plr->bot);
|
||||||
break;
|
break;
|
||||||
|
case player_botvars:
|
||||||
|
LUA_PushUserdata(L, &plr->botvars, META_BOTVARS);
|
||||||
|
break;
|
||||||
case player_jointime:
|
case player_jointime:
|
||||||
lua_pushinteger(L, plr->jointime);
|
lua_pushinteger(L, plr->jointime);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1786,6 +1791,8 @@ static int player_set(lua_State *L)
|
||||||
break;
|
break;
|
||||||
case player_bot:
|
case player_bot:
|
||||||
return NOSET;
|
return NOSET;
|
||||||
|
case player_botvars:
|
||||||
|
return NOSET;
|
||||||
case player_jointime:
|
case player_jointime:
|
||||||
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
plr->jointime = (tic_t)luaL_checkinteger(L, 3);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ static lua_CFunction liblist[] = {
|
||||||
LUA_BlockmapLib, // blockmap stuff
|
LUA_BlockmapLib, // blockmap stuff
|
||||||
LUA_HudLib, // HUD stuff
|
LUA_HudLib, // HUD stuff
|
||||||
LUA_FollowerLib, // follower_t, followers[]
|
LUA_FollowerLib, // follower_t, followers[]
|
||||||
|
LUA_BotVarsLib, // botvars_t
|
||||||
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
LUA_TerrainLib, // t_splash_t, t_footstep_t, t_overlay_t, terrain_t
|
||||||
LUA_WaypointLib, // waypoint_t
|
LUA_WaypointLib, // waypoint_t
|
||||||
NULL
|
NULL
|
||||||
|
|
|
||||||
|
|
@ -396,6 +396,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
// botvars_t
|
// botvars_t
|
||||||
WRITEUINT8(save->p, players[i].bot);
|
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.difficulty);
|
||||||
WRITEUINT8(save->p, players[i].botvars.diffincrease);
|
WRITEUINT8(save->p, players[i].botvars.diffincrease);
|
||||||
WRITEUINT8(save->p, players[i].botvars.rival);
|
WRITEUINT8(save->p, players[i].botvars.rival);
|
||||||
|
|
@ -743,6 +744,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
||||||
|
|
||||||
// botvars_t
|
// botvars_t
|
||||||
players[i].bot = READUINT8(save->p);
|
players[i].bot = READUINT8(save->p);
|
||||||
|
players[i].botvars.style = READUINT8(save->p);
|
||||||
players[i].botvars.difficulty = READUINT8(save->p);
|
players[i].botvars.difficulty = READUINT8(save->p);
|
||||||
players[i].botvars.diffincrease = READUINT8(save->p);
|
players[i].botvars.diffincrease = READUINT8(save->p);
|
||||||
players[i].botvars.rival = (boolean)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))
|
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];
|
focusangle = localangle[num];
|
||||||
focusaiming = localaiming[num];
|
focusaiming = localaiming[num];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue