mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-22 22:46:12 +00:00
Merge branch 'training-mode' into 'master'
Add bot styles & bot spawn ACS function Closes #564 See merge request KartKrew/Kart!1288
This commit is contained in:
commit
8b2b3aaee8
12 changed files with 330 additions and 121 deletions
|
|
@ -41,6 +41,7 @@
|
|||
#include "../r_skins.h"
|
||||
#include "../k_battle.h"
|
||||
#include "../k_podium.h"
|
||||
#include "../k_bot.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
#include "call-funcs.hpp"
|
||||
|
|
@ -1710,6 +1711,52 @@ bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Wor
|
|||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
Inserts a bot, if there's room for them.
|
||||
--------------------------------------------------*/
|
||||
bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
{
|
||||
ACSVM::MapScope *map = NULL;
|
||||
|
||||
ACSVM::String *skinStr = nullptr;
|
||||
INT32 skin = -1;
|
||||
|
||||
UINT8 difficulty = 0;
|
||||
botStyle_e style = BOT_STYLE_NORMAL;
|
||||
|
||||
UINT8 newplayernum = 0;
|
||||
bool success = false;
|
||||
|
||||
(void)argC;
|
||||
|
||||
map = thread->scopeMap;
|
||||
|
||||
skinStr = map->getString(argV[0]);
|
||||
if (skinStr->len != 0)
|
||||
{
|
||||
skin = R_SkinAvailable(skinStr->str);
|
||||
}
|
||||
|
||||
if (skin == -1)
|
||||
{
|
||||
skin = R_BotDefaultSkin();
|
||||
}
|
||||
|
||||
difficulty = std::clamp(static_cast<int>(argV[1]), 1, MAXBOTDIFFICULTY);
|
||||
|
||||
style = static_cast<botStyle_e>(argV[2]);
|
||||
if (style < BOT_STYLE_NORMAL || style >= BOT_STYLE__MAX)
|
||||
{
|
||||
style = BOT_STYLE_NORMAL;
|
||||
}
|
||||
|
||||
success = K_AddBot(skin, difficulty, style, &newplayernum);
|
||||
thread->dataStk.push(success ? newplayernum : -1);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
bool CallFunc_Get/SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC)
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ bool CallFunc_PodiumFinish(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM
|
|||
bool CallFunc_SetLineRenderStyle(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_MapWarp(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_AddBot(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
||||
bool CallFunc_GetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
bool CallFunc_SetLineProperty(ACSVM::Thread *thread, const ACSVM::Word *argV, ACSVM::Word argC);
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ Environment::Environment()
|
|||
addFuncDataACS0( 502, addCallFunc(CallFunc_PodiumFinish));
|
||||
addFuncDataACS0( 503, addCallFunc(CallFunc_SetLineRenderStyle));
|
||||
addFuncDataACS0( 504, addCallFunc(CallFunc_MapWarp));
|
||||
addFuncDataACS0( 505, addCallFunc(CallFunc_AddBot));
|
||||
}
|
||||
|
||||
ACSVM::Thread *Environment::allocThread()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
#include "thread.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "../doomtype.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
|
|
@ -26,7 +25,6 @@ extern "C" {
|
|||
#include "../r_defs.h"
|
||||
#include "../r_state.h"
|
||||
#include "../p_polyobj.h"
|
||||
}
|
||||
|
||||
using namespace srb2::acs;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "acsvm.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "../doomtype.h"
|
||||
#include "../doomdef.h"
|
||||
#include "../doomstat.h"
|
||||
|
|
@ -23,7 +24,7 @@
|
|||
#include "../r_defs.h"
|
||||
#include "../r_state.h"
|
||||
#include "../p_spec.h"
|
||||
|
||||
}
|
||||
|
||||
namespace srb2::acs {
|
||||
|
||||
|
|
|
|||
|
|
@ -4010,6 +4010,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
|||
INT16 newplayernum;
|
||||
UINT8 skinnum = 0;
|
||||
UINT8 difficulty = DIFFICULTBOT;
|
||||
botStyle_e style = BOT_STYLE_NORMAL;
|
||||
|
||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||
{
|
||||
|
|
@ -4025,41 +4026,9 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
|||
newplayernum = READUINT8(*p);
|
||||
skinnum = READUINT8(*p);
|
||||
difficulty = READUINT8(*p);
|
||||
style = READUINT8(*p);
|
||||
|
||||
CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum);
|
||||
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
CL_ClearPlayer(newplayernum);
|
||||
G_DestroyParty(newplayernum);
|
||||
|
||||
playeringame[newplayernum] = true;
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
||||
playernode[newplayernum] = servernode;
|
||||
|
||||
// this will permit unlocks
|
||||
memcpy(&players[newplayernum].availabilities, R_GetSkinAvailabilities(false, true), MAXAVAILABILITY*sizeof(UINT8));
|
||||
|
||||
players[newplayernum].splitscreenindex = 0;
|
||||
players[newplayernum].bot = true;
|
||||
players[newplayernum].botvars.difficulty = difficulty;
|
||||
players[newplayernum].lives = 9;
|
||||
|
||||
players[newplayernum].skincolor = skins[skinnum].prefcolor;
|
||||
sprintf(player_names[newplayernum], "%s", skins[skinnum].realname);
|
||||
SetPlayerSkinByNum(newplayernum, skinnum);
|
||||
|
||||
playerconsole[newplayernum] = newplayernum;
|
||||
G_BuildLocalSplitscreenParty(newplayernum);
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
HU_AddChatText(va("\x82*Bot %d has been added to the game", newplayernum+1), false);
|
||||
}
|
||||
|
||||
LUA_HookInt(newplayernum, HOOK(PlayerJoin));
|
||||
K_SetBot(newplayernum, skinnum, difficulty, style);
|
||||
}
|
||||
|
||||
static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
|
||||
|
|
|
|||
|
|
@ -313,9 +313,20 @@ struct respawnvars_t
|
|||
boolean init;
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BOT_STYLE_NORMAL,
|
||||
BOT_STYLE_STAY,
|
||||
//BOT_STYLE_CHASE,
|
||||
//BOT_STYLE_ESCAPE,
|
||||
BOT_STYLE__MAX
|
||||
} botStyle_e;
|
||||
|
||||
// player_t struct for all bot variables
|
||||
struct botvars_t
|
||||
{
|
||||
botStyle_e style; // Training mode-style CPU mode
|
||||
|
||||
UINT8 difficulty; // Bot's difficulty setting
|
||||
UINT8 diffincrease; // In GP: bot difficulty will increase this much next round
|
||||
boolean rival; // If true, they're the GP rival
|
||||
|
|
|
|||
268
src/k_bot.c
268
src/k_bot.c
|
|
@ -31,20 +31,102 @@
|
|||
#include "k_podium.h"
|
||||
#include "k_respawn.h"
|
||||
#include "m_easing.h"
|
||||
#include "d_clisrv.h"
|
||||
#include "g_party.h"
|
||||
#include "k_grandprix.h" // K_CanChangeRules
|
||||
#include "hu_stuff.h" // HU_AddChatText
|
||||
#include "discord.h" // DRPC_UpdatePresence
|
||||
#include "i_net.h" // doomcom
|
||||
|
||||
#ifdef DEVELOP
|
||||
consvar_t cv_botcontrol = CVAR_INIT ("botcontrol", "On", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL);
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *p)
|
||||
void K_SetBot(UINT8 playerNum, UINT8 skinnum, UINT8 difficulty, botStyle_e style)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *p)
|
||||
void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style)
|
||||
{
|
||||
CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum);
|
||||
|
||||
// Clear player before joining, lest some things get set incorrectly
|
||||
CL_ClearPlayer(newplayernum);
|
||||
G_DestroyParty(newplayernum);
|
||||
|
||||
playeringame[newplayernum] = true;
|
||||
G_AddPlayer(newplayernum);
|
||||
if (newplayernum+1 > doomcom->numslots)
|
||||
doomcom->numslots = (INT16)(newplayernum+1);
|
||||
|
||||
playernode[newplayernum] = servernode;
|
||||
|
||||
// this will permit unlocks
|
||||
memcpy(&players[newplayernum].availabilities, R_GetSkinAvailabilities(false, true), MAXAVAILABILITY*sizeof(UINT8));
|
||||
|
||||
players[newplayernum].splitscreenindex = 0;
|
||||
players[newplayernum].bot = true;
|
||||
players[newplayernum].botvars.difficulty = difficulty;
|
||||
players[newplayernum].botvars.style = style;
|
||||
players[newplayernum].lives = 9;
|
||||
|
||||
players[newplayernum].skincolor = skins[skinnum].prefcolor;
|
||||
sprintf(player_names[newplayernum], "%s", skins[skinnum].realname);
|
||||
SetPlayerSkinByNum(newplayernum, skinnum);
|
||||
|
||||
playerconsole[newplayernum] = newplayernum;
|
||||
G_BuildLocalSplitscreenParty(newplayernum);
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
HU_AddChatText(va("\x82*Bot %d has been added to the game", newplayernum+1), false);
|
||||
}
|
||||
|
||||
LUA_HookInt(newplayernum, HOOK(PlayerJoin));
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
{
|
||||
UINT8 newplayernum = *p;
|
||||
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
if (playeringame[newplayernum] == false)
|
||||
{
|
||||
// free player slot
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newplayernum >= MAXPLAYERS)
|
||||
{
|
||||
// nothing is free
|
||||
*p = MAXPLAYERS;
|
||||
return false;
|
||||
}
|
||||
|
||||
K_SetBot(newplayernum, skin, difficulty, style);
|
||||
DEBFILE(va("Everyone added bot %d\n", newplayernum));
|
||||
|
||||
// use the next free slot
|
||||
*p = newplayernum+1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p)
|
||||
{
|
||||
UINT8 buf[3];
|
||||
UINT8 *buf_p = buf;
|
||||
UINT8 newplayernum = *p;
|
||||
|
||||
// search for a free playernum
|
||||
|
|
@ -54,56 +136,66 @@ boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *p)
|
|||
UINT8 n;
|
||||
|
||||
for (n = 0; n < MAXNETNODES; n++)
|
||||
{
|
||||
if (nodetoplayer[n] == newplayernum
|
||||
|| nodetoplayer2[n] == newplayernum
|
||||
|| nodetoplayer3[n] == newplayernum
|
||||
|| nodetoplayer4[n] == newplayernum)
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == MAXNETNODES)
|
||||
break;
|
||||
}
|
||||
|
||||
while (playeringame[newplayernum]
|
||||
&& players[newplayernum].bot
|
||||
&& newplayernum < MAXPLAYERS)
|
||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||
{
|
||||
newplayernum++;
|
||||
if (playeringame[newplayernum] == false)
|
||||
{
|
||||
// free player slot
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newplayernum >= MAXPLAYERS)
|
||||
{
|
||||
*p = newplayernum;
|
||||
// nothing is free
|
||||
*p = MAXPLAYERS;
|
||||
return false;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, newplayernum);
|
||||
|
||||
if (skin > numskins)
|
||||
if (server)
|
||||
{
|
||||
skin = numskins;
|
||||
UINT8 buf[4];
|
||||
UINT8 *buf_p = buf;
|
||||
|
||||
WRITEUINT8(buf_p, newplayernum);
|
||||
|
||||
if (skin > numskins)
|
||||
{
|
||||
skin = numskins;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, skin);
|
||||
|
||||
if (difficulty < 1)
|
||||
{
|
||||
difficulty = 1;
|
||||
}
|
||||
else if (difficulty > MAXBOTDIFFICULTY)
|
||||
{
|
||||
difficulty = MAXBOTDIFFICULTY;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, difficulty);
|
||||
WRITEUINT8(buf_p, style);
|
||||
|
||||
SendNetXCmd(XD_ADDBOT, buf, buf_p - buf);
|
||||
DEBFILE(va("Server added bot %d\n", newplayernum));
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, skin);
|
||||
|
||||
if (difficulty < 1)
|
||||
{
|
||||
difficulty = 1;
|
||||
}
|
||||
else if (difficulty > MAXBOTDIFFICULTY)
|
||||
{
|
||||
difficulty = MAXBOTDIFFICULTY;
|
||||
}
|
||||
|
||||
WRITEUINT8(buf_p, difficulty);
|
||||
|
||||
SendNetXCmd(XD_ADDBOT, buf, buf_p - buf);
|
||||
|
||||
DEBFILE(va("Server added bot %d\n", newplayernum));
|
||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||
newplayernum++;
|
||||
|
||||
*p = newplayernum;
|
||||
*p = newplayernum+1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -125,11 +217,6 @@ void K_UpdateMatchRaceBots(void)
|
|||
UINT8 grabskins[MAXSKINS+1];
|
||||
UINT8 i;
|
||||
|
||||
if (!server)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Init usable bot skins list
|
||||
for (i = 0; i < numskins; i++)
|
||||
{
|
||||
|
|
@ -156,6 +243,9 @@ void K_UpdateMatchRaceBots(void)
|
|||
|
||||
// While we're here, we should update bot difficulty to the proper value.
|
||||
players[i].botvars.difficulty = difficulty;
|
||||
|
||||
// Enforce normal style for Match Race
|
||||
players[i].botvars.style = BOT_STYLE_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -169,12 +259,16 @@ void K_UpdateMatchRaceBots(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (difficulty == 0 || !(gametyperules & GTR_BOTS))
|
||||
if (K_CanChangeRules(true) == false
|
||||
|| (gametyperules & GTR_BOTS) == 0
|
||||
|| difficulty == 0)
|
||||
{
|
||||
// Remove bots if there are any.
|
||||
wantedbots = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add bots to fill up MAXPLAYERS
|
||||
wantedbots = pmax - numplayers - numwaiting;
|
||||
|
||||
if (wantedbots < 0)
|
||||
|
|
@ -197,11 +291,15 @@ void K_UpdateMatchRaceBots(void)
|
|||
for (i = 0; i < usableskins; i++)
|
||||
{
|
||||
if (!(grabskins[i] == MAXSKINS || !R_SkinUsable(-1, grabskins[i], true)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
while (usableskins > i && (grabskins[usableskins] == MAXSKINS || !R_SkinUsable(-1, grabskins[usableskins], true)))
|
||||
{
|
||||
usableskins--;
|
||||
}
|
||||
|
||||
grabskins[i] = grabskins[usableskins];
|
||||
grabskins[usableskins] = MAXSKINS;
|
||||
}
|
||||
|
|
@ -212,12 +310,12 @@ void K_UpdateMatchRaceBots(void)
|
|||
|
||||
if (usableskins > 0)
|
||||
{
|
||||
UINT8 index = M_RandomKey(usableskins);
|
||||
UINT8 index = P_RandomKey(PR_BOTS, usableskins);
|
||||
skinnum = grabskins[index];
|
||||
grabskins[index] = grabskins[--usableskins];
|
||||
}
|
||||
|
||||
if (!K_AddBot(skinnum, difficulty, &newplayernum))
|
||||
if (!K_AddBot(skinnum, difficulty, BOT_STYLE_NORMAL, &newplayernum))
|
||||
{
|
||||
// Not enough player slots to add the bot, break the loop.
|
||||
break;
|
||||
|
|
@ -228,26 +326,25 @@ void K_UpdateMatchRaceBots(void)
|
|||
}
|
||||
else if (numbots > wantedbots)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
||||
i = MAXPLAYERS;
|
||||
|
||||
while (numbots > wantedbots && i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
if (playeringame[i] && players[i].bot)
|
||||
{
|
||||
buf[0] = i;
|
||||
buf[1] = KR_LEAVE;
|
||||
SendNetXCmd(XD_REMOVEPLAYER, &buf, 2);
|
||||
|
||||
CL_RemovePlayer(i, KR_LEAVE);
|
||||
numbots--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We should have enough bots now :)
|
||||
|
||||
#ifdef HAVE_DISCORDRPC
|
||||
// Player count change was possible, so update presence
|
||||
DRPC_UpdatePresence();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -1473,11 +1570,11 @@ static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
See header file for description.
|
||||
Build ticcmd for bots with a style of BOT_STYLE_NORMAL
|
||||
--------------------------------------------------*/
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
precise_t t = 0;
|
||||
botprediction_t *predict = NULL;
|
||||
|
|
@ -1487,29 +1584,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
INT32 turnamt = 0;
|
||||
const line_t *botController = player->botvars.controller != UINT16_MAX ? &lines[player->botvars.controller] : NULL;
|
||||
|
||||
// Remove any existing controls
|
||||
memset(cmd, 0, sizeof(ticcmd_t));
|
||||
|
||||
if (player->mo == NULL
|
||||
|| player->spectator == true
|
||||
|| G_GamestateUsesLevel() == false)
|
||||
{
|
||||
// Not in the level.
|
||||
return;
|
||||
}
|
||||
|
||||
// Complete override of all ticcmd functionality
|
||||
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (K_PodiumSequence() == true)
|
||||
{
|
||||
K_BuildBotPodiumTiccmd(player, cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(gametyperules & GTR_BOTS) // No bot behaviors
|
||||
|| K_GetNumWaypoints() == 0 // No waypoints
|
||||
|| leveltime <= introtime // During intro camera
|
||||
|
|
@ -1762,6 +1836,54 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||
{
|
||||
// Remove any existing controls
|
||||
memset(cmd, 0, sizeof(ticcmd_t));
|
||||
|
||||
if (player->mo == NULL
|
||||
|| player->spectator == true
|
||||
|| G_GamestateUsesLevel() == false)
|
||||
{
|
||||
// Not in the level.
|
||||
return;
|
||||
}
|
||||
|
||||
// Complete override of all ticcmd functionality.
|
||||
// May add more hooks to individual pieces of bot ticcmd,
|
||||
// but this should always be here so anyone can roll
|
||||
// their own :)
|
||||
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)) == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (K_PodiumSequence() == true)
|
||||
{
|
||||
K_BuildBotPodiumTiccmd(player, cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (player->botvars.style)
|
||||
{
|
||||
case BOT_STYLE_STAY:
|
||||
{
|
||||
// Hey, this one's pretty easy :P
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
K_BuildBotTiccmdNormal(player, cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_UpdateBotGameplayVars(player_t *player);
|
||||
|
||||
|
|
|
|||
56
src/k_bot.h
56
src/k_bot.h
|
|
@ -138,25 +138,67 @@ fixed_t K_UpdateRubberband(player_t *player);
|
|||
fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy);
|
||||
|
||||
|
||||
// NOT AVAILABLE FOR LUA
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *newplayernum);
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
||||
|
||||
Returns the waypoint actually being used as the finish line.
|
||||
Adds a new bot, using code intended to run on all clients.
|
||||
|
||||
Input Arguments:-
|
||||
skin - Skin number that the bot will use.
|
||||
difficulty - Difficulty level this bot will use.
|
||||
style - Bot style to spawn this bot with, see botStyle_e.
|
||||
newplayernum - Pointer to the last valid player slot number.
|
||||
Is a pointer so that this function can be called multiple times to add more than one bot.
|
||||
|
||||
Return:-
|
||||
true if a bot packet can be sent, otherwise false.
|
||||
true if a bot was added, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, UINT8 *newplayernum);
|
||||
boolean K_AddBot(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
||||
|
||||
|
||||
// NOT AVAILABLE FOR LUA
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style);
|
||||
|
||||
Sets a player ID to be a new bot directly. Invoked directly
|
||||
by K_AddBot, and indirectly by K_AddBotFromServer by sending
|
||||
a packet.
|
||||
|
||||
Input Arguments:-
|
||||
newplayernum - Player slot number to set as a bot.
|
||||
skin - Skin number that the bot will use.
|
||||
difficulty - Difficulty level this bot will use.
|
||||
style - Bot style to spawn this bot with, see botStyle_e.
|
||||
|
||||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e style);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *newplayernum);
|
||||
|
||||
Adds a new bot, using a server-sided packet sent to all clients.
|
||||
Using regular K_AddBot wherever possible is better, but this is kept
|
||||
as a back-up measure if this is the only option.
|
||||
|
||||
Input Arguments:-
|
||||
skin - Skin number that the bot will use.
|
||||
difficulty - Difficulty level this bot will use.
|
||||
style - Bot style to spawn this bot with, see botStyle_e.
|
||||
newplayernum - Pointer to the last valid player slot number.
|
||||
Is a pointer so that this function can be called multiple times to add more than one bot.
|
||||
|
||||
Return:-
|
||||
true if a bot can be added via a packet later, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_AddBotFromServer(UINT8 skin, UINT8 difficulty, botStyle_e style, UINT8 *p);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -186,6 +186,13 @@ void K_InitGrandPrixBots(void)
|
|||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
if (players[i].bot == true)
|
||||
{
|
||||
// Remove existing bots.
|
||||
CL_RemovePlayer(i, KR_LEAVE);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numplayers < MAXSPLITSCREENPLAYERS && !players[i].spectator)
|
||||
{
|
||||
competitors[numplayers] = i;
|
||||
|
|
@ -227,11 +234,15 @@ void K_InitGrandPrixBots(void)
|
|||
for (i = 0; i < usableskins; i++)
|
||||
{
|
||||
if (!(grabskins[i] == MAXSKINS || !R_SkinUsable(-1, grabskins[i], true)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
while (usableskins > i && (grabskins[usableskins] == MAXSKINS || !R_SkinUsable(-1, grabskins[usableskins], true)))
|
||||
{
|
||||
usableskins--;
|
||||
}
|
||||
|
||||
grabskins[i] = grabskins[usableskins];
|
||||
grabskins[usableskins] = MAXSKINS;
|
||||
}
|
||||
|
|
@ -245,7 +256,7 @@ void K_InitGrandPrixBots(void)
|
|||
|
||||
if (usableskins > 0)
|
||||
{
|
||||
UINT8 index = M_RandomKey(usableskins);
|
||||
UINT8 index = P_RandomKey(PR_BOTS, usableskins);
|
||||
skinnum = grabskins[index];
|
||||
grabskins[index] = grabskins[--usableskins];
|
||||
}
|
||||
|
|
@ -256,7 +267,7 @@ void K_InitGrandPrixBots(void)
|
|||
|
||||
for (i = 0; i < wantedbots; i++)
|
||||
{
|
||||
if (!K_AddBot(botskinlist[i], difficultylevels[i], &newplayernum))
|
||||
if (!K_AddBot(botskinlist[i], difficultylevels[i], BOT_STYLE_NORMAL, &newplayernum))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
|
@ -327,8 +338,10 @@ void K_UpdateGrandPrixBots(void)
|
|||
UINT16 newrivalscore = 0;
|
||||
UINT8 i;
|
||||
|
||||
if (K_PodiumSequence())
|
||||
if (K_PodiumSequence() == true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ typedef enum
|
|||
// However each instance of RNG being used for
|
||||
// gameplay should be split up as much as possible.
|
||||
|
||||
// Place new ones at the end for demo compatibility.
|
||||
|
||||
PR_EXECUTOR, // Linedef executor
|
||||
PR_ACS, // ACS scripts
|
||||
|
||||
|
|
@ -72,6 +74,8 @@ typedef enum
|
|||
|
||||
PR_MOVINGTARGET, // Randomised moving targets
|
||||
|
||||
PR_BOTS, // Bot spawning
|
||||
|
||||
PRNUMCLASS
|
||||
} pr_class_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -7742,7 +7742,7 @@ static void P_InitGametype(void)
|
|||
grandprixinfo.wonround = false;
|
||||
}
|
||||
}
|
||||
else if (!modeattacking)
|
||||
else
|
||||
{
|
||||
// We're in a Match Race, use simplistic randomized bots.
|
||||
K_UpdateMatchRaceBots();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue