mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Skins, rudimentary ticcmd building for bots
This commit is contained in:
parent
e5ae9d1513
commit
ff621d3e46
9 changed files with 214 additions and 313 deletions
|
|
@ -49,6 +49,7 @@
|
||||||
#include "k_kart.h"
|
#include "k_kart.h"
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
|
#include "k_bot.h"
|
||||||
|
|
||||||
#ifdef CLIENT_LOADINGSCREEN
|
#ifdef CLIENT_LOADINGSCREEN
|
||||||
// cl loading screen
|
// cl loading screen
|
||||||
|
|
@ -3612,6 +3613,7 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
|
||||||
static void Got_AddBot(UINT8 **p, INT32 playernum)
|
static void Got_AddBot(UINT8 **p, INT32 playernum)
|
||||||
{
|
{
|
||||||
INT16 newplayernum;
|
INT16 newplayernum;
|
||||||
|
UINT8 skinnum = 0;
|
||||||
|
|
||||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
{
|
{
|
||||||
|
|
@ -3629,6 +3631,7 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
newplayernum = (UINT8)READUINT8(*p);
|
newplayernum = (UINT8)READUINT8(*p);
|
||||||
|
skinnum = (UINT8)READUINT8(*p);
|
||||||
|
|
||||||
CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum);
|
CONS_Debug(DBG_NETPLAY, "addbot: %d\n", newplayernum);
|
||||||
|
|
||||||
|
|
@ -3643,7 +3646,9 @@ static void Got_AddBot(UINT8 **p, INT32 playernum)
|
||||||
players[newplayernum].splitscreenindex = 0;
|
players[newplayernum].splitscreenindex = 0;
|
||||||
players[newplayernum].bot = true;
|
players[newplayernum].bot = true;
|
||||||
|
|
||||||
playerconsole[newplayernum] = 0;
|
players[newplayernum].skincolor = skins[skinnum].prefcolor;
|
||||||
|
sprintf(player_names[newplayernum], "%s", skins[skinnum].realname);
|
||||||
|
SetPlayerSkinByNum(newplayernum, skinnum);
|
||||||
|
|
||||||
if (netgame)
|
if (netgame)
|
||||||
{
|
{
|
||||||
|
|
@ -3777,6 +3782,8 @@ boolean SV_SpawnServer(void)
|
||||||
if (!dedicated)
|
if (!dedicated)
|
||||||
CL_ConnectToServer(false);
|
CL_ConnectToServer(false);
|
||||||
else doomcom->numslots = 1;
|
else doomcom->numslots = 1;
|
||||||
|
|
||||||
|
K_AddBots(7); // test
|
||||||
}
|
}
|
||||||
|
|
||||||
return SV_AddWaitingPlayers();
|
return SV_AddWaitingPlayers();
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@
|
||||||
#include "k_kart.h" // SRB2kart
|
#include "k_kart.h" // SRB2kart
|
||||||
#include "k_battle.h"
|
#include "k_battle.h"
|
||||||
#include "k_pwrlv.h"
|
#include "k_pwrlv.h"
|
||||||
#include "k_bot.h"
|
|
||||||
#include "y_inter.h"
|
#include "y_inter.h"
|
||||||
|
|
||||||
#ifdef NETGAME_DEVMODE
|
#ifdef NETGAME_DEVMODE
|
||||||
|
|
@ -2737,8 +2736,6 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
K_AddBots(13);
|
|
||||||
|
|
||||||
chmappending++;
|
chmappending++;
|
||||||
if (netgame)
|
if (netgame)
|
||||||
WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed
|
WRITEUINT32(buf_p, M_RandomizedSeed()); // random seed
|
||||||
|
|
|
||||||
16
src/g_game.c
16
src/g_game.c
|
|
@ -1297,6 +1297,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (K_PlayerUsesBotMovement(player))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ssplayer)
|
switch (ssplayer)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -1601,9 +1606,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||||
|
|
||||||
//Reset away view if a command is given.
|
//Reset away view if a command is given.
|
||||||
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
if ((cmd->forwardmove || cmd->sidemove || cmd->buttons)
|
||||||
&& ! r_splitscreen && displayplayers[0] != consoleplayer && ssplayer == 1)
|
&& !r_splitscreen && displayplayers[0] != consoleplayer && ssplayer == 1)
|
||||||
displayplayers[0] = consoleplayer;
|
displayplayers[0] = consoleplayer;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User has designated that they want
|
// User has designated that they want
|
||||||
|
|
@ -2373,12 +2377,20 @@ void G_Ticker(boolean run)
|
||||||
cmd = &players[i].cmd;
|
cmd = &players[i].cmd;
|
||||||
|
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
|
{
|
||||||
|
if (K_PlayerUsesBotMovement(&players[i]))
|
||||||
|
{
|
||||||
|
K_BuildBotTiccmd(&players[i], cmd);
|
||||||
|
cmd->latency = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
|
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
|
||||||
// Use the leveltime sent in the player's ticcmd to determine control lag
|
// Use the leveltime sent in the player's ticcmd to determine control lag
|
||||||
cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
|
cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// do main actions
|
// do main actions
|
||||||
switch (gamestate)
|
switch (gamestate)
|
||||||
|
|
|
||||||
351
src/k_bot.c
351
src/k_bot.c
|
|
@ -19,24 +19,20 @@
|
||||||
#include "lua_hook.h"
|
#include "lua_hook.h"
|
||||||
#include "byteptr.h"
|
#include "byteptr.h"
|
||||||
#include "d_net.h" // nodetoplayer
|
#include "d_net.h" // nodetoplayer
|
||||||
|
#include "k_kart.h"
|
||||||
// If you want multiple bots, variables like this will
|
|
||||||
// have to be stuffed in something accessible through player_t.
|
|
||||||
static boolean lastForward = false;
|
|
||||||
static boolean lastBlocked = false;
|
|
||||||
static boolean blocked = false;
|
|
||||||
|
|
||||||
void K_AddBots(UINT8 numbots)
|
void K_AddBots(UINT8 numbots)
|
||||||
{
|
{
|
||||||
UINT8 newplayernum = 0;
|
UINT8 newplayernum = 0;
|
||||||
UINT8 buf[4];
|
|
||||||
UINT8 *buf_p = buf;
|
|
||||||
|
|
||||||
if (dedicated)
|
if (dedicated)
|
||||||
newplayernum = 1;
|
newplayernum = 1;
|
||||||
|
|
||||||
while (numbots > 0)
|
while (numbots > 0)
|
||||||
{
|
{
|
||||||
|
UINT8 buf[2];
|
||||||
|
UINT8 *buf_p = buf;
|
||||||
|
|
||||||
numbots--;
|
numbots--;
|
||||||
|
|
||||||
// search for a free playernum
|
// search for a free playernum
|
||||||
|
|
@ -56,13 +52,19 @@ void K_AddBots(UINT8 numbots)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// should never happen since we check the playernum
|
|
||||||
// before accepting the join
|
|
||||||
I_Assert(newplayernum < MAXPLAYERS);
|
|
||||||
|
|
||||||
WRITEUINT8(buf_p, newplayernum);
|
WRITEUINT8(buf_p, newplayernum);
|
||||||
|
|
||||||
SendNetXCmd(XD_ADDPLAYER, buf, buf_p - buf);
|
// test skins
|
||||||
|
if (numbots == 6)
|
||||||
|
WRITEUINT8(buf_p, 0);
|
||||||
|
else if (numbots == 5)
|
||||||
|
WRITEUINT8(buf_p, 1);
|
||||||
|
else if (numbots == 4)
|
||||||
|
WRITEUINT8(buf_p, 9);
|
||||||
|
else
|
||||||
|
WRITEUINT8(buf_p, 10);
|
||||||
|
|
||||||
|
SendNetXCmd(XD_ADDBOT, buf, buf_p - buf);
|
||||||
|
|
||||||
DEBFILE(va("Server added bot %d\n", newplayernum));
|
DEBFILE(va("Server added bot %d\n", newplayernum));
|
||||||
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
// use the next free slot (we can't put playeringame[newplayernum] = true here)
|
||||||
|
|
@ -70,90 +72,30 @@ void K_AddBots(UINT8 numbots)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
boolean K_PlayerUsesBotMovement(player_t *player)
|
||||||
{
|
{
|
||||||
boolean forward=false, backward=false, left=false, right=false, jump=false, spin=false;
|
if (player->bot || player->exiting)
|
||||||
angle_t angle;
|
return true;
|
||||||
INT16 rangle;
|
|
||||||
fixed_t dist;
|
|
||||||
|
|
||||||
// We can't follow Sonic if he's not around!
|
return false;
|
||||||
if (!sonic || sonic->health <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
|
||||||
// Lua can handle it!
|
|
||||||
if (LUAh_BotAI(sonic, tails, cmd))
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
|
|
||||||
{
|
|
||||||
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
|
|
||||||
if (sonic->player->cmd.buttons & BT_DRIFT && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG))
|
|
||||||
cmd->buttons |= BT_DRIFT;
|
|
||||||
if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
|
|
||||||
{
|
|
||||||
cmd->forwardmove = sonic->player->cmd.forwardmove;
|
|
||||||
cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16;
|
|
||||||
if (sonic->angle < tails->angle)
|
|
||||||
cmd->angleturn = -cmd->angleturn;
|
|
||||||
} else if (dist > FixedMul(512*FRACUNIT, tails->scale))
|
|
||||||
cmd->buttons |= BT_DRIFT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gather data about the environment
|
|
||||||
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
|
|
||||||
if (tails->player->pflags & PF_STARTDASH)
|
|
||||||
angle = sonic->angle;
|
|
||||||
else
|
|
||||||
angle = R_PointToAngle2(tails->x, tails->y, sonic->x, sonic->y);
|
|
||||||
|
|
||||||
// Decide which direction to turn
|
|
||||||
angle = (tails->angle - angle);
|
|
||||||
if (angle < ANGLE_180) {
|
|
||||||
right = true; // We need to turn right
|
|
||||||
rangle = AngleFixed(angle)>>FRACBITS;
|
|
||||||
} else {
|
|
||||||
left = true; // We need to turn left
|
|
||||||
rangle = 360-(AngleFixed(angle)>>FRACBITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decide to move forward if you're finished turning
|
|
||||||
if (abs(rangle) < 10) { // We're facing the right way?
|
|
||||||
left = right = false; // Stop turning
|
|
||||||
forward = true; // and walk forward instead.
|
|
||||||
}
|
|
||||||
if (dist < (sonic->radius+tails->radius)*3) // We're close enough?
|
|
||||||
forward = false; // Stop walking.
|
|
||||||
|
|
||||||
// Decide when to jump
|
|
||||||
if (!(tails->player->pflags & (PF_JUMPED|PF_JUMPDOWN))) { // We're not jumping yet...
|
|
||||||
if (forward && lastForward && blocked && lastBlocked) // We've been stopped by a wall or something
|
|
||||||
jump = true; // Try to jump up
|
|
||||||
} else if ((tails->player->pflags & (PF_JUMPDOWN|PF_JUMPED)) == (PF_JUMPDOWN|PF_JUMPED)) { // When we're already jumping...
|
|
||||||
if (lastForward && blocked) // We're still stuck on something?
|
|
||||||
jump = true;
|
|
||||||
if (sonic->floorz > tails->floorz) // He's still above us? Jump HIGHER, then!
|
|
||||||
jump = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decide when to spin
|
|
||||||
if (sonic->player->pflags & PF_STARTDASH
|
|
||||||
&& (tails->player->pflags & PF_STARTDASH || (P_AproxDistance(tails->momx, tails->momy) < 2*FRACUNIT && !forward)))
|
|
||||||
spin = true;
|
|
||||||
|
|
||||||
// Turn the virtual keypresses into ticcmd_t.
|
|
||||||
B_KeysToTiccmd(tails, cmd, forward, backward, left, right, false, false, jump, spin);
|
|
||||||
|
|
||||||
// Update our status
|
|
||||||
lastForward = forward;
|
|
||||||
lastBlocked = blocked;
|
|
||||||
blocked = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy)
|
||||||
|
{
|
||||||
|
fixed_t v1toc[2] = {cx - v1x, cy - v1y};
|
||||||
|
fixed_t v1tov2[2] = {v2x - v1x, v2y - v1y};
|
||||||
|
|
||||||
|
fixed_t mag = FixedMul(v1tov2[0], v1tov2[0]) + FixedMul(v1tov2[1], v1tov2[1]);
|
||||||
|
fixed_t dot = FixedMul(v1toc[0], v1tov2[0]) + FixedMul(v1toc[1], v1tov2[1]);
|
||||||
|
fixed_t t = FixedDiv(dot, mag);
|
||||||
|
|
||||||
|
fixed_t px = v1x + FixedMul(v1tov2[0], t);
|
||||||
|
fixed_t py = v1y + FixedMul(v1tov2[1], t);
|
||||||
|
|
||||||
|
return P_AproxDistance(cx - px, cy - py);
|
||||||
|
}
|
||||||
|
|
||||||
|
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
// Can't build a ticcmd if we aren't spawned...
|
// Can't build a ticcmd if we aren't spawned...
|
||||||
if (!player->mo)
|
if (!player->mo)
|
||||||
|
|
@ -161,162 +103,113 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
if (player->playerstate == PST_DEAD)
|
if (player->playerstate == PST_DEAD)
|
||||||
{
|
{
|
||||||
if (B_CheckRespawn(player))
|
cmd->buttons |= BT_ACCELERATE;
|
||||||
cmd->buttons |= BT_DRIFT;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bot AI isn't programmed in analog.
|
|
||||||
//CV_SetValue(&cv_analog2, false);
|
|
||||||
|
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
// Let Lua scripts build ticcmds
|
// Let Lua scripts build ticcmds
|
||||||
if (LUAh_BotTiccmd(player, cmd))
|
if (LUAh_BotTiccmd(player, cmd))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We don't have any main character AI, sorry. D:
|
if (player->nextwaypoint != NULL && player->nextwaypoint->mobj != NULL && !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||||
if (player-players == consoleplayer)
|
{
|
||||||
return;
|
INT16 turnamt = KART_FULLTURN;
|
||||||
|
SINT8 turnsign = 0;
|
||||||
|
angle_t wpangle, moveangle, angle;
|
||||||
|
INT16 anglediff;
|
||||||
|
|
||||||
// Basic Tails AI
|
wpangle = R_PointToAngle2(player->mo->x, player->mo->y, player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y);
|
||||||
B_BuildTailsTiccmd(players[consoleplayer].mo, player->mo, cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin)
|
if (player->mo->momx || player->mo->momy)
|
||||||
{
|
{
|
||||||
// Turn the virtual keypresses into ticcmd_t.
|
angle_t movevswp;
|
||||||
if (twodlevel || mo->flags2 & MF2_TWOD) {
|
|
||||||
if (players[consoleplayer].climbing
|
moveangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
|
||||||
|| mo->player->pflags & PF_GLIDING) {
|
|
||||||
// Don't mess with bot inputs during these unhandled movement conditions.
|
movevswp = (moveangle - wpangle);
|
||||||
// The normal AI doesn't use abilities, so custom AI should be sending us exactly what it wants anyway.
|
if (movevswp > ANGLE_180)
|
||||||
if (forward)
|
{
|
||||||
cmd->forwardmove += MAXPLMOVE<<FRACBITS>>16;
|
movevswp = InvAngle(movevswp);
|
||||||
if (backward)
|
}
|
||||||
cmd->forwardmove -= MAXPLMOVE<<FRACBITS>>16;
|
|
||||||
if (left || strafeleft)
|
if (movevswp > ANGLE_45)
|
||||||
cmd->sidemove -= MAXPLMOVE<<FRACBITS>>16;
|
{
|
||||||
if (right || straferight)
|
// Use facing direction when going the wrong way
|
||||||
cmd->sidemove += MAXPLMOVE<<FRACBITS>>16;
|
moveangle = player->mo->angle;
|
||||||
} else {
|
}
|
||||||
// In standard 2D mode, interpret "forward" as "the way you're facing" and everything else as "the way you're not facing"
|
}
|
||||||
if (left || right)
|
|
||||||
backward = true;
|
|
||||||
left = right = false;
|
|
||||||
if (forward) {
|
|
||||||
if (mo->angle < ANGLE_90 || mo->angle > ANGLE_270)
|
|
||||||
right = true;
|
|
||||||
else
|
else
|
||||||
left = true;
|
{
|
||||||
} else if (backward) {
|
// Default to facing direction
|
||||||
if (mo->angle < ANGLE_90 || mo->angle > ANGLE_270)
|
moveangle = player->mo->angle;
|
||||||
left = true;
|
}
|
||||||
|
|
||||||
|
angle = (moveangle - wpangle);
|
||||||
|
|
||||||
|
if (angle < ANGLE_180)
|
||||||
|
{
|
||||||
|
turnsign = -1; // Turn right
|
||||||
|
anglediff = AngleFixed(angle)>>FRACBITS;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
right = true;
|
{
|
||||||
|
turnsign = 1; // Turn left
|
||||||
|
anglediff = 360-(AngleFixed(angle)>>FRACBITS);
|
||||||
}
|
}
|
||||||
if (left || strafeleft)
|
|
||||||
cmd->sidemove -= MAXPLMOVE<<FRACBITS>>16;
|
anglediff = abs(anglediff);
|
||||||
if (right || straferight)
|
|
||||||
cmd->sidemove += MAXPLMOVE<<FRACBITS>>16;
|
if (anglediff > 90)
|
||||||
}
|
{
|
||||||
} else {
|
// Wrong way!
|
||||||
if (forward)
|
cmd->forwardmove = -25;
|
||||||
cmd->forwardmove += MAXPLMOVE<<FRACBITS>>16;
|
|
||||||
if (backward)
|
|
||||||
cmd->forwardmove -= MAXPLMOVE<<FRACBITS>>16;
|
|
||||||
if (left)
|
|
||||||
cmd->angleturn += 1280;
|
|
||||||
if (right)
|
|
||||||
cmd->angleturn -= 1280;
|
|
||||||
if (strafeleft)
|
|
||||||
cmd->sidemove -= MAXPLMOVE<<FRACBITS>>16;
|
|
||||||
if (straferight)
|
|
||||||
cmd->sidemove += MAXPLMOVE<<FRACBITS>>16;
|
|
||||||
}
|
|
||||||
if (jump)
|
|
||||||
cmd->buttons |= BT_DRIFT;
|
|
||||||
if (spin)
|
|
||||||
cmd->buttons |= BT_BRAKE;
|
cmd->buttons |= BT_BRAKE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_t rad = player->nextwaypoint->mobj->radius - (player->mo->radius*2);
|
||||||
|
fixed_t dirdist = K_DistanceOfLineFromPoint(
|
||||||
|
player->mo->x, player->mo->y,
|
||||||
|
player->mo->x + FINECOSINE(moveangle >> ANGLETOFINESHIFT), player->mo->y + FINESINE(moveangle >> ANGLETOFINESHIFT),
|
||||||
|
player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y
|
||||||
|
);
|
||||||
|
|
||||||
void B_MoveBlocked(player_t *player)
|
if (player == &players[displayplayers[0]])
|
||||||
{
|
CONS_Printf("perpendicular dist: %d\n", dirdist / FRACUNIT);
|
||||||
(void)player;
|
|
||||||
blocked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean B_CheckRespawn(player_t *player)
|
cmd->buttons |= BT_ACCELERATE;
|
||||||
{
|
|
||||||
mobj_t *sonic = players[consoleplayer].mo;
|
|
||||||
mobj_t *tails = player->mo;
|
|
||||||
|
|
||||||
// We can't follow Sonic if he's not around!
|
// Full speed ahead!
|
||||||
if (!sonic || sonic->health <= 0)
|
cmd->forwardmove = 50;
|
||||||
return false;
|
|
||||||
|
|
||||||
// Check if Sonic is busy first.
|
if (dirdist <= 3*rad/4)
|
||||||
// If he's doing any of these things, he probably doesn't want to see us.
|
{
|
||||||
if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE)
|
if (dirdist < rad/4)
|
||||||
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK))
|
{
|
||||||
return false;
|
// Don't need to turn!
|
||||||
|
turnamt = 0;
|
||||||
// Low ceiling, do not want!
|
}
|
||||||
if (sonic->ceilingz - sonic->z < 2*sonic->height)
|
else
|
||||||
return false;
|
{
|
||||||
|
// Make minor adjustments
|
||||||
// If you're dead, wait a few seconds to respawn.
|
turnamt /= 4;
|
||||||
if (player->playerstate == PST_DEAD) {
|
}
|
||||||
if (player->deadtimer > 4*TICRATE)
|
}
|
||||||
return true;
|
else
|
||||||
return false;
|
{
|
||||||
|
// Actually, don't go too fast...
|
||||||
|
cmd->forwardmove /= 2;
|
||||||
|
cmd->buttons |= BT_BRAKE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If you can't see Sonic, I guess we should?
|
if (turnamt != 0)
|
||||||
if (!P_CheckSight(sonic, tails) && P_AproxDistance(P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y), tails->z-sonic->z) > FixedMul(1024*FRACUNIT, tails->scale))
|
{
|
||||||
return true;
|
cmd->driftturn = KART_FULLTURN * turnsign;
|
||||||
return false;
|
cmd->angleturn += KART_FULLTURN * turnsign;
|
||||||
}
|
}
|
||||||
|
|
||||||
void B_RespawnBot(INT32 playernum)
|
|
||||||
{
|
|
||||||
player_t *player = &players[playernum];
|
|
||||||
fixed_t x,y,z;
|
|
||||||
mobj_t *sonic = players[consoleplayer].mo;
|
|
||||||
mobj_t *tails;
|
|
||||||
|
|
||||||
if (!sonic || sonic->health <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
P_SpawnPlayer(playernum);
|
|
||||||
tails = player->mo;
|
|
||||||
|
|
||||||
x = sonic->x;
|
|
||||||
y = sonic->y;
|
|
||||||
if (sonic->eflags & MFE_VERTICALFLIP) {
|
|
||||||
tails->eflags |= MFE_VERTICALFLIP;
|
|
||||||
z = sonic->z - FixedMul(512*FRACUNIT,sonic->scale);
|
|
||||||
if (z < sonic->floorz)
|
|
||||||
z = sonic->floorz;
|
|
||||||
} else {
|
|
||||||
z = sonic->z + sonic->height + FixedMul(512*FRACUNIT,sonic->scale);
|
|
||||||
if (z > sonic->ceilingz - sonic->height)
|
|
||||||
z = sonic->ceilingz - sonic->height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sonic->flags2 & MF2_OBJECTFLIP)
|
|
||||||
tails->flags2 |= MF2_OBJECTFLIP;
|
|
||||||
if (sonic->flags2 & MF2_TWOD)
|
|
||||||
tails->flags2 |= MF2_TWOD;
|
|
||||||
if (sonic->eflags & MFE_UNDERWATER)
|
|
||||||
tails->eflags |= MFE_UNDERWATER;
|
|
||||||
player->powers[pw_underwater] = sonic->player->powers[pw_underwater];
|
|
||||||
player->powers[pw_spacetime] = sonic->player->powers[pw_spacetime];
|
|
||||||
player->powers[pw_gravityboots] = sonic->player->powers[pw_gravityboots];
|
|
||||||
player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol];
|
|
||||||
|
|
||||||
P_TeleportMove(tails, x, y, z);
|
|
||||||
P_SetPlayerMobjState(tails, S_KART_STND1); // SRB2kart - was S_PLAY_FALL1
|
|
||||||
P_SetScale(tails, sonic->scale);
|
|
||||||
tails->destscale = sonic->destscale;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,6 @@
|
||||||
/// \brief Basic bot handling
|
/// \brief Basic bot handling
|
||||||
|
|
||||||
void K_AddBots(UINT8 numbots);
|
void K_AddBots(UINT8 numbots);
|
||||||
void B_BuildTiccmd(player_t *player, ticcmd_t *cmd);
|
boolean K_PlayerUsesBotMovement(player_t *player);
|
||||||
void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward, boolean left, boolean right, boolean strafeleft, boolean straferight, boolean jump, boolean spin);
|
fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy);
|
||||||
boolean B_CheckRespawn(player_t *player);
|
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd);
|
||||||
void B_MoveBlocked(player_t *player);
|
|
||||||
void B_RespawnBot(INT32 playernum);
|
|
||||||
|
|
|
||||||
19
src/k_kart.c
19
src/k_kart.c
|
|
@ -27,6 +27,7 @@
|
||||||
#include "lua_hook.h" // For MobjDamage and ShouldDamage
|
#include "lua_hook.h" // For MobjDamage and ShouldDamage
|
||||||
|
|
||||||
#include "k_waypoint.h"
|
#include "k_waypoint.h"
|
||||||
|
#include "k_bot.h"
|
||||||
|
|
||||||
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
// SOME IMPORTANT VARIABLES DEFINED IN DOOMDEF.H:
|
||||||
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
// gamespeed is cc (0 for easy, 1 for normal, 2 for hard)
|
||||||
|
|
@ -6402,7 +6403,8 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U))
|
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U)
|
||||||
|
&& !K_PlayerUsesBotMovement(player))
|
||||||
{
|
{
|
||||||
for (i = 0U; i < waypoint->numprevwaypoints; i++)
|
for (i = 0U; i < waypoint->numprevwaypoints; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -6556,13 +6558,6 @@ static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_
|
||||||
static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
{
|
{
|
||||||
if ((player != NULL) && (player->mo != NULL))
|
if ((player != NULL) && (player->mo != NULL))
|
||||||
{
|
|
||||||
if (player->exiting)
|
|
||||||
{
|
|
||||||
player->nextwaypoint = K_GetFinishLineWaypoint();
|
|
||||||
player->distancetofinish = 0U;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
waypoint_t *finishline = K_GetFinishLineWaypoint();
|
waypoint_t *finishline = K_GetFinishLineWaypoint();
|
||||||
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player);
|
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player);
|
||||||
|
|
@ -6575,7 +6570,12 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// nextwaypoint is now the waypoint that is in front of us
|
// nextwaypoint is now the waypoint that is in front of us
|
||||||
if ((player->nextwaypoint != NULL) && (finishline != NULL))
|
if (player->exiting)
|
||||||
|
{
|
||||||
|
// Player has finished, we don't need to calculate distance
|
||||||
|
player->distancetofinish = 0U;
|
||||||
|
}
|
||||||
|
else if ((player->nextwaypoint != NULL) && (finishline != NULL))
|
||||||
{
|
{
|
||||||
const boolean useshortcuts = false;
|
const boolean useshortcuts = false;
|
||||||
const boolean huntbackwards = false;
|
const boolean huntbackwards = false;
|
||||||
|
|
@ -6626,7 +6626,6 @@ static void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns false if this player being placed here causes them to collide with any other player
|
// Returns false if this player being placed here causes them to collide with any other player
|
||||||
|
|
|
||||||
|
|
@ -945,6 +945,12 @@ boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Hook for B_BuildTailsTiccmd by skin name
|
// Hook for B_BuildTailsTiccmd by skin name
|
||||||
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
|
#if 1
|
||||||
|
(void)sonic;
|
||||||
|
(void)tails;
|
||||||
|
(void)cmd;
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
hook_p hookp;
|
hook_p hookp;
|
||||||
boolean hooked = false;
|
boolean hooked = false;
|
||||||
if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
|
if (!gL || !(hooksAvailable[hook_BotAI/8] & (1<<(hook_BotAI%8))))
|
||||||
|
|
@ -1001,6 +1007,7 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd)
|
||||||
|
|
||||||
lua_settop(gL, 0);
|
lua_settop(gL, 0);
|
||||||
return hooked;
|
return hooked;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hook for linedef executors
|
// Hook for linedef executors
|
||||||
|
|
|
||||||
|
|
@ -1978,7 +1978,7 @@ boolean P_CheckRacers(void)
|
||||||
// Check if all the players in the race have finished. If so, end the level.
|
// Check if all the players in the race have finished. If so, end the level.
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
{
|
{
|
||||||
if (!playeringame[i] || players[i].spectator || players[i].exiting || !players[i].lives)
|
if (!playeringame[i] || players[i].spectator || players[i].exiting || players[i].bot || !players[i].lives)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
12
src/p_user.c
12
src/p_user.c
|
|
@ -8023,18 +8023,6 @@ void P_PlayerThink(player_t *player)
|
||||||
player->playerstate = PST_DEAD;
|
player->playerstate = PST_DEAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player->bot)
|
|
||||||
{
|
|
||||||
if (player->playerstate == PST_LIVE || player->playerstate == PST_DEAD)
|
|
||||||
{
|
|
||||||
if (B_CheckRespawn(player))
|
|
||||||
player->playerstate = PST_REBORN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->playerstate == PST_REBORN)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
if (netgame && player == &players[displayplayers[0]] && !(leveltime % (TICRATE/5)) && !r_splitscreen)
|
if (netgame && player == &players[displayplayers[0]] && !(leveltime % (TICRATE/5)) && !r_splitscreen)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue