Merge branch 'master' into grand-pricks

This commit is contained in:
Sally Coolatta 2020-05-31 15:53:31 -04:00
commit 91b0246d99
8 changed files with 177 additions and 99 deletions

View file

@ -3,7 +3,6 @@
# Core sources
set(SRB2_CORE_SOURCES
am_map.c
b_bot.c
command.c
comptime.c
console.c
@ -50,7 +49,6 @@ set(SRB2_CORE_SOURCES
set(SRB2_CORE_HEADERS
am_map.h
b_bot.h
byteptr.h
command.h
console.h

View file

@ -231,9 +231,9 @@ void K_UpdateMatchRaceBots(void)
{
UINT8 buf[2];
i = 0;
i = MAXPLAYERS;
while (numbots > wantedbots && i < MAXPLAYERS)
while (numbots > wantedbots && i > 0)
{
if (playeringame[i] && players[i].bot)
{
@ -244,7 +244,7 @@ void K_UpdateMatchRaceBots(void)
numbots--;
}
i++;
i--;
}
}
@ -400,6 +400,59 @@ fixed_t K_BotRubberband(player_t *player)
return rubberband;
}
/*--------------------------------------------------
fixed_t K_BotTopSpeedRubberband(player_t *player)
See header file for description.
--------------------------------------------------*/
fixed_t K_BotTopSpeedRubberband(player_t *player)
{
fixed_t rubberband = K_BotRubberband(player);
if (rubberband < FRACUNIT)
{
// Never go below your regular top speed
rubberband = FRACUNIT;
}
// Only allow you to go faster than your regular top speed if you're facing the right direction
if (rubberband > FRACUNIT && player->mo != NULL && player->nextwaypoint != NULL)
{
const INT16 mindiff = 30;
const INT16 maxdiff = 60;
INT16 anglediff = 0;
fixed_t amt = rubberband - FRACUNIT;
angle_t destangle = R_PointToAngle2(
player->mo->x, player->mo->y,
player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y
);
angle_t angle = player->mo->angle - destangle;
if (angle < ANGLE_180)
{
anglediff = AngleFixed(angle) >> FRACBITS;
}
else
{
anglediff = 360 - (AngleFixed(angle) >> FRACBITS);
}
anglediff = abs(anglediff);
if (anglediff >= maxdiff)
{
rubberband = FRACUNIT;
}
else if (anglediff > mindiff)
{
amt = (amt * (maxdiff - anglediff)) / mindiff;
rubberband = FRACUNIT + amt;
}
}
return rubberband;
}
/*--------------------------------------------------
fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y, fixed_t cx, fixed_t cy)
@ -449,7 +502,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
const fixed_t radreduce = min(distreduce + FRACUNIT/4, FRACUNIT);
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
const fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy);
const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4);
const INT32 distance = (FixedMul(speed, distreduce) / FRACUNIT) * futuresight;
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL);
@ -694,7 +747,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (dirdist <= rad)
{
fixed_t speedmul = FixedMul(player->speed, K_GetKartSpeed(player, false));
fixed_t speedmul = FixedDiv(player->speed, K_GetKartSpeed(player, false));
fixed_t speedrad = rad/4;
if (speedmul > FRACUNIT)
@ -705,7 +758,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
// Increase radius with speed
// At low speed, the CPU will try to be more accurate
// At high speed, they're more likely to lawnmower
speedrad += FixedMul(speedmul, (3*rad/4) - speedrad);
speedrad += FixedMul(speedmul, rad - speedrad);
if (speedrad < playerwidth)
{

View file

@ -66,19 +66,35 @@ boolean K_BotCanTakeCut(player_t *player);
/*--------------------------------------------------
fixed_t K_BotRubberband(player_t *player);
Gives a multiplier for a bot's rubberbanding. Meant to be used for top speed,
acceleration, and handling.
Gives a multiplier for a bot's rubberbanding.
Meant to be used for acceleration and handling.
Input Arguments:-
player - Player to check.
Return:-
A multiplier in fixed point scale, between 0.875 and 2.0.
A multiplier in fixed point scale.
--------------------------------------------------*/
fixed_t K_BotRubberband(player_t *player);
/*--------------------------------------------------
fixed_t K_BotTopSpeedRubberband(player_t *player);
Gives a multiplier for a bot's rubberbanding.
Adjusted from K_BotRubberband to be used for top speed.
Input Arguments:-
player - Player to check.
Return:-
A multiplier in fixed point scale.
--------------------------------------------------*/
fixed_t K_BotTopSpeedRubberband(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);

View file

@ -25,6 +25,7 @@
#include "d_ticcmd.h"
#include "m_random.h"
#include "r_things.h" // numskins
#include "p_slopes.h" // P_GetZAt
struct globalsmuggle
{
@ -156,64 +157,99 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
}
/*--------------------------------------------------
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec)
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
Tells us if a bot will play more careful around
this sector.
this sector. Checks FOFs in the sector, as well.
Input Arguments:-
player - Player to check against.
sec - Sector to check against.
x - Linedef cross X position, for slopes
y - Linedef cross Y position, for slopes
Return:-
true if avoiding this sector, false otherwise.
--------------------------------------------------*/
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec)
static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
{
const boolean flip = (player->mo->eflags & MFE_VERTICALFLIP);
INT32 flag;
INT32 specialflag = 0;
fixed_t highestfloor = INT32_MAX;
sector_t *bestsector = NULL;
ffloor_t *rover;
if (flip)
if (flip == true)
{
flag = SF_FLIPSPECIAL_CEILING;
specialflag = SF_FLIPSPECIAL_CEILING;
highestfloor = (sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : sec->ceilingheight);
}
else
{
flag = SF_FLIPSPECIAL_FLOOR;
specialflag = SF_FLIPSPECIAL_FLOOR;
highestfloor = (sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight);
}
if (sec->flags & flag)
if (sec->flags & specialflag)
{
if (K_BotHatesThisSectorsSpecial(player, sec))
{
return true;
}
bestsector = sec;
}
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t top = INT32_MAX;
fixed_t bottom = INT32_MAX;
if (!(rover->flags & FF_EXISTS))
{
continue;
}
if (!(rover->master->frontsector->flags & flag))
top = (*rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight);
bottom = (*rover->b_slope ? P_GetZAt(*rover->b_slope, x, y) : *rover->bottomheight);
if (!(rover->flags & FF_BLOCKPLAYER))
{
if ((top >= player->mo->z) && (bottom <= player->mo->z + player->mo->height)
&& K_BotHatesThisSectorsSpecial(player, rover->master->frontsector))
{
// Bad intangible sector at our height, so we DEFINITELY want to avoid
return true;
}
}
if ((rover->flags & FF_BLOCKPLAYER) && !(rover->master->frontsector->flags & specialflag))
{
continue;
}
if (((*rover->bottomheight >= player->mo->z + player->mo->height) && (flip))
|| ((*rover->topheight <= player->mo->z) && (!flip)))
// Find the highest FOF floor beneath the player, and check it at the end.
if (flip == true)
{
if (K_BotHatesThisSectorsSpecial(player, sec))
if (bottom < highestfloor
&& bottom >= player->mo->z + player->mo->height)
{
return true;
bestsector = rover->master->frontsector;
highestfloor = bottom;
}
}
else
{
if (top > highestfloor
&& top <= player->mo->z)
{
bestsector = rover->master->frontsector;
highestfloor = top;
}
}
}
return false;
if (bestsector == NULL)
{
return false;
}
return K_BotHatesThisSectorsSpecial(player, bestsector);
}
/*--------------------------------------------------
@ -236,6 +272,7 @@ static boolean K_FindBlockingWalls(line_t *line)
fixed_t maxstep = maxstepmove;
fixed_t linedist = INT32_MAX;
INT32 lineside = 0;
vertex_t pos;
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
{
@ -295,20 +332,18 @@ static boolean K_FindBlockingWalls(line_t *line)
goto blocked;
}
if (!K_BotHatesThisSector(globalsmuggle.botmo->player, globalsmuggle.botmo->subsector->sector))
{
// Treat damage sectors like walls
// Treat damage sectors like walls
P_ClosestPointOnLine(globalsmuggle.botmo->x, globalsmuggle.botmo->y, line, &pos);
if (lineside)
{
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->frontsector))
goto blocked;
}
else
{
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->backsector))
goto blocked;
}
if (lineside)
{
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->frontsector, pos.x, pos.y))
goto blocked;
}
else
{
if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->backsector, pos.x, pos.y))
goto blocked;
}
// We weren't blocked!

View file

@ -2367,49 +2367,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower)
{
if (K_PlayerUsesBotMovement(player))
{
fixed_t rubberband = K_BotRubberband(player);
if (rubberband < FRACUNIT)
{
rubberband = FRACUNIT;
}
// Only allow you to go fast if you're facing the right direction
if (rubberband > FRACUNIT && player->mo != NULL && player->nextwaypoint != NULL)
{
const INT16 mindiff = 30;
const INT16 maxdiff = 60;
INT16 anglediff = 0;
fixed_t amt = rubberband - FRACUNIT;
angle_t destangle = R_PointToAngle2(
player->mo->x, player->mo->y,
player->nextwaypoint->mobj->x, player->nextwaypoint->mobj->y
);
angle_t angle = player->mo->angle - destangle;
if (angle < ANGLE_180)
{
anglediff = AngleFixed(angle) >> FRACBITS;
}
else
{
anglediff = 360 - (AngleFixed(angle) >> FRACBITS);
}
anglediff = abs(anglediff);
if (anglediff >= maxdiff)
{
rubberband = FRACUNIT;
}
else if (anglediff > mindiff)
{
amt = (amt * (maxdiff - anglediff)) / mindiff;
rubberband = FRACUNIT + amt;
}
}
finalspeed = FixedMul(finalspeed, rubberband);
finalspeed = FixedMul(finalspeed, K_BotTopSpeedRubberband(player));
}
return FixedMul(finalspeed, player->kartstuff[k_boostpower]+player->kartstuff[k_speedboost]);
@ -9471,9 +9429,17 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (players[tab[i].num].spectator || !players[tab[i].num].mo)
continue; //ignore them.
if (netgame // don't draw it offline
&& ( tab[i].num != serverplayer || ! server_lagless ))
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0);
if (netgame) // don't draw ping offline
{
if (players[tab[i].num].bot)
{
; // TODO: Put a graphic here to indicate this player is a bot!
}
else if (tab[i].num != serverplayer || !server_lagless)
{
HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0);
}
}
STRBUFCPY(strtime, tab[i].name);

View file

@ -327,9 +327,10 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss)
if (i == playernum)
continue;
theirpower = PWRLVRECORD_DEF;
if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests)
theirpower = clientpowerlevels[i][powertype];
if (clientpowerlevels[i][powertype] == 0) // No power level (splitscreen guests, bots)
continue;
theirpower = clientpowerlevels[i][powertype];
diff = yourpower - theirpower;
inc -= K_CalculatePowerLevelInc(diff);

View file

@ -4177,11 +4177,16 @@ static void P_3dMovement(player_t *player)
if (K_PlayerUsesBotMovement(player))
{
fixed_t rubberband = K_BotRubberband(player);
fixed_t baserubberband = K_BotRubberband(player);
fixed_t rubberband = FixedMul(baserubberband,
FixedMul(baserubberband,
FixedMul(baserubberband,
baserubberband
))); // This looks extremely goofy, but we need this really high, but at the same time, proportional.
if (rubberband > FRACUNIT)
{
div = FixedMul(div, 4*rubberband);
div = FixedMul(div, rubberband);
}
}

View file

@ -983,9 +983,11 @@ static void K_UpdatePowerLevels(void)
continue;
}
theirpower = PWRLVRECORD_DEF;
if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests)
theirpower = clientpowerlevels[jpnum][powertype];
if (clientpowerlevels[jpnum][powertype] == 0) // No power level (splitscreen guests, bots)
continue;
theirpower = clientpowerlevels[jpnum][powertype];
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
if (G_RaceGametype())
@ -1025,9 +1027,11 @@ static void K_UpdatePowerLevels(void)
CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum);
theirpower = PWRLVRECORD_DEF;
if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests)
theirpower = nospectategrief[jpnum];
if (nospectategrief[jpnum] == 0) // No power level (splitscreen guests, bots)
continue;
theirpower = nospectategrief[jpnum];
CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower);
diff = theirpower - yourpower;