Eggbox stuff

- Bots can roll & use eggboxes now
- Bots can be "tricked" by eggboxes and treat them like normal items, depending on their difficulty and how many normal items are around them.
- If exploding and in 1st place, they'll slow down to try and find someone to explode next to.
- Item usage is difficulty dependent, and thus far more aggressive for the rivals
This commit is contained in:
Sally Coolatta 2020-05-01 22:55:58 -04:00
parent b9e24d921c
commit 664a9528ed
2 changed files with 734 additions and 433 deletions

View file

@ -236,6 +236,96 @@ fixed_t closestlinedist = INT32_MAX;
INT16 badsteerglobal = 0; INT16 badsteerglobal = 0;
fixed_t eggboxx, eggboxy;
UINT8 randomitems = 0;
UINT8 eggboxes = 0;
static boolean K_FindRandomItems(mobj_t *thing)
{
fixed_t dist;
if (thing->type != MT_RANDOMITEM)
{
return true;
}
if (!thing->health)
{
return true;
}
dist = P_AproxDistance(thing->x - eggboxx, thing->y - eggboxy);
if (dist > distancetocheck)
{
return true;
}
randomitems++;
return true;
}
static boolean K_FindEggboxes(mobj_t *thing)
{
fixed_t dist;
if (thing->type != MT_EGGMANITEM)
{
return true;
}
if (!thing->health)
{
return true;
}
dist = P_AproxDistance(thing->x - eggboxx, thing->y - eggboxy);
if (dist > distancetocheck)
{
return true;
}
eggboxes++;
return true;
}
static UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
{
INT32 xl, xh, yl, yh, bx, by;
eggboxx = x;
eggboxy = y;
distancetocheck = (mapobjectscale * 256);
randomitems = 0;
eggboxes = 0;
xl = (unsigned)(eggboxx - distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
xh = (unsigned)(eggboxx + distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
yl = (unsigned)(eggboxy - distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
yh = (unsigned)(eggboxy + distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
for (bx = xl; bx <= xh; bx++)
{
for (by = yl; by <= yh; by++)
{
P_BlockThingsIterator(bx, by, K_FindRandomItems);
}
}
for (bx = xl; bx <= xh; bx++)
{
for (by = yl; by <= yh; by++)
{
P_BlockThingsIterator(bx, by, K_FindEggboxes);
}
}
return randomitems * eggboxes;
}
static inline boolean K_FindBlockingWalls(line_t *line) static inline boolean K_FindBlockingWalls(line_t *line)
{ {
// Condensed version of PIT_CheckLine // Condensed version of PIT_CheckLine
@ -579,7 +669,6 @@ static boolean K_BotSteerObjects(mobj_t *thing)
{ {
case MT_BANANA: case MT_BANANA:
case MT_BANANA_SHIELD: case MT_BANANA_SHIELD:
case MT_EGGMANITEM:
case MT_EGGMANITEM_SHIELD: case MT_EGGMANITEM_SHIELD:
case MT_ORBINAUT: case MT_ORBINAUT:
case MT_ORBINAUT_SHIELD: case MT_ORBINAUT_SHIELD:
@ -604,6 +693,27 @@ static boolean K_BotSteerObjects(mobj_t *thing)
K_SteerFromObject(botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack); K_SteerFromObject(botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack);
} }
break; break;
case MT_EGGMANITEM:
if (anglediff > 90)
{
break;
}
if (P_CanPickupItem(botmo->player, 1)) // Can pick up an actual item
{
const UINT8 stealth = K_EggboxStealth(thing->x, thing->y);
const UINT8 requiredstealth = (botmo->player->botvars.difficulty * botmo->player->botvars.difficulty);
if (stealth >= requiredstealth)
{
K_SteerFromObject(botmo, thing, fulldist, xdist, true, 2 * (KART_FULLTURN + attack));
}
else
{
K_SteerFromObject(botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
}
}
break;
case MT_FLOATINGITEM: case MT_FLOATINGITEM:
if (anglediff > 90) if (anglediff > 90)
{ {
@ -844,10 +954,11 @@ static boolean K_BotRevealsBanana(player_t *player, INT16 turnamt, boolean mine)
{ {
UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity); UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity);
fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); const angle_t momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{ {
return true; return true;
} }
@ -856,10 +967,10 @@ static boolean K_BotRevealsBanana(player_t *player, INT16 turnamt, boolean mine)
{ {
airtime = FixedDiv((40 * player->mo->scale) + player->mo->momz, gravity); airtime = FixedDiv((40 * player->mo->scale) + player->mo->momz, gravity);
throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) * 2; throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) * 2;
estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{ {
return true; return true;
} }
@ -919,6 +1030,79 @@ static boolean K_BotRevealsBanana(player_t *player, INT16 turnamt, boolean mine)
return false; return false;
} }
static boolean K_BotRevealsEggbox(player_t *player)
{
const UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity);
const fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const angle_t momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
const fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
const fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
UINT8 i;
if (stealth > 1)
{
return true;
}
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{
return true;
}
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *target = NULL;
fixed_t dist = INT32_MAX;
if (!playeringame[i])
{
continue;
}
target = &players[i];
if (target->mo == NULL || P_MobjWasRemoved(target->mo)
|| player == target || target->spectator
|| target->powers[pw_flashing]
|| !P_CheckSight(player->mo, target->mo))
{
continue;
}
dist = P_AproxDistance(P_AproxDistance(
player->mo->x - target->mo->x,
player->mo->y - target->mo->y),
(player->mo->z - target->mo->z) / 4
);
if (dist <= (player->mo->radius * 16))
{
angle_t a = player->mo->angle - R_PointToAngle2(player->mo->x, player->mo->y, target->mo->x, target->mo->y);
INT16 ad = 0;
const INT16 cone = 10;
if (a < ANGLE_180)
{
ad = AngleFixed(a)>>FRACBITS;
}
else
{
ad = 360-(AngleFixed(a)>>FRACBITS);
}
ad = abs(ad);
if (ad >= 180-cone)
{
return true;
}
}
}
return false;
}
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
{ {
botprediction_t *predict = NULL; botprediction_t *predict = NULL;
@ -1108,12 +1292,114 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
player->botvars.itemdelay--; player->botvars.itemdelay--;
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
} }
else if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0) else if (player->kartstuff[k_eggmanexplode])
{ {
if (player->kartstuff[k_eggmanexplode]) if (player->kartstuff[k_position] == 1)
{ {
cmd->forwardmove /= 2;
cmd->buttons |= BT_BRAKE;
}
K_BotUseItemNearPlayer(player, cmd, 128*player->mo->scale); K_BotUseItemNearPlayer(player, cmd, 128*player->mo->scale);
} }
else if (player->kartstuff[k_eggmanheld])
{
const UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity);
const fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const angle_t momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
const fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
const fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y);
SINT8 throwdir = -1;
UINT8 i;
player->botvars.itemconfirm++;
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{
player->botvars.itemconfirm += player->botvars.difficulty / 2;
throwdir = 1;
}
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *target = NULL;
fixed_t dist = INT32_MAX;
if (!playeringame[i])
{
continue;
}
target = &players[i];
if (target->mo == NULL || P_MobjWasRemoved(target->mo)
|| player == target || target->spectator
|| target->powers[pw_flashing]
|| !P_CheckSight(player->mo, target->mo))
{
continue;
}
dist = P_AproxDistance(P_AproxDistance(
player->mo->x - target->mo->x,
player->mo->y - target->mo->y),
(player->mo->z - target->mo->z) / 4
);
if (dist <= (player->mo->radius * 16))
{
angle_t a = player->mo->angle - R_PointToAngle2(player->mo->x, player->mo->y, target->mo->x, target->mo->y);
INT16 ad = 0;
const INT16 cone = 10;
if (a < ANGLE_180)
{
ad = AngleFixed(a)>>FRACBITS;
}
else
{
ad = 360-(AngleFixed(a)>>FRACBITS);
}
ad = abs(ad);
if (ad >= 180-cone)
{
player->botvars.itemconfirm += player->botvars.difficulty;
throwdir = -1;
}
}
}
if (stealth > 1)
{
player->botvars.itemconfirm += player->botvars.difficulty * 4;
throwdir = -1;
}
if (player->kartstuff[k_itemroulette] > 0) // Just grabbed an item
{
player->botvars.itemconfirm += player->botvars.difficulty * 4;
throwdir = -1;
}
if ((player->botvars.itemconfirm > 2*TICRATE || player->kartstuff[k_bananadrag] >= TICRATE)
&& !(player->pflags & PF_ATTACKDOWN))
{
if (throwdir == 1)
{
cmd->buttons |= BT_FORWARD;
}
else if (throwdir == -1)
{
cmd->buttons |= BT_BACKWARD;
}
cmd->buttons |= BT_ATTACK;
player->botvars.itemconfirm = 0;
}
}
else if (player->kartstuff[k_rocketsneakertimer] > 0) else if (player->kartstuff[k_rocketsneakertimer] > 0)
{ {
if (player->botvars.itemconfirm > TICRATE) if (player->botvars.itemconfirm > TICRATE)
@ -1129,7 +1415,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
player->botvars.itemconfirm++; player->botvars.itemconfirm++;
} }
} }
else else if (player->kartstuff[k_stealingtimer] == 0 && player->kartstuff[k_stolentimer] == 0)
{ {
switch (player->kartstuff[k_itemtype]) switch (player->kartstuff[k_itemtype])
{ {
@ -1189,18 +1475,19 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (abs(turnamt) >= KART_FULLTURN/2) if (abs(turnamt) >= KART_FULLTURN/2)
{ {
player->botvars.itemconfirm += 2; player->botvars.itemconfirm += player->botvars.difficulty / 2;
} }
else else
{ {
const UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity); const UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity);
const fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); const fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
const fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); const angle_t momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
const fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); const fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
const fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{ {
player->botvars.itemconfirm += 8; player->botvars.itemconfirm += player->botvars.difficulty * 2;
throwdir = 1; throwdir = 1;
} }
} }
@ -1250,7 +1537,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (ad >= 180-cone) if (ad >= 180-cone)
{ {
player->botvars.itemconfirm += 4; player->botvars.itemconfirm += player->botvars.difficulty;
throwdir = -1; throwdir = -1;
} }
} }
@ -1273,6 +1560,17 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
} }
} }
break; break;
case KITEM_EGGMAN:
if (!player->kartstuff[k_eggmanheld])
{
if ((K_BotRevealsEggbox(player) || (player->botvars.itemconfirm++ > 20*TICRATE))
&& !(player->pflags & PF_ATTACKDOWN))
{
cmd->buttons |= BT_ATTACK;
player->botvars.itemconfirm = 0;
}
}
break;
case KITEM_ORBINAUT: case KITEM_ORBINAUT:
if (!player->kartstuff[k_itemheld] && !(player->pflags & PF_ATTACKDOWN)) if (!player->kartstuff[k_itemheld] && !(player->pflags & PF_ATTACKDOWN))
{ {
@ -1338,12 +1636,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (ad <= cone) if (ad <= cone)
{ {
player->botvars.itemconfirm += 8; player->botvars.itemconfirm += player->botvars.difficulty * 2;
throwdir = 1; throwdir = 1;
} }
else if (ad >= 180-cone) else if (ad >= 180-cone)
{ {
player->botvars.itemconfirm += 4; player->botvars.itemconfirm += player->botvars.difficulty;
} }
} }
} }
@ -1423,7 +1721,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (ad >= 180-cone) if (ad >= 180-cone)
{ {
player->botvars.itemconfirm += 4; player->botvars.itemconfirm += player->botvars.difficulty;
throwdir = -1; throwdir = -1;
} }
} }
@ -1431,7 +1729,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_lastjawztarget] != -1) if (player->kartstuff[k_lastjawztarget] != -1)
{ {
player->botvars.itemconfirm += 8; player->botvars.itemconfirm += player->botvars.difficulty * 2;
throwdir = 1; throwdir = 1;
} }
@ -1514,7 +1812,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (ad >= 180-cone) if (ad >= 180-cone)
{ {
player->botvars.itemconfirm += 4; player->botvars.itemconfirm += player->botvars.difficulty;
throwdir = -1; throwdir = -1;
} }
} }
@ -1522,19 +1820,20 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
if (abs(turnamt) >= KART_FULLTURN/2) if (abs(turnamt) >= KART_FULLTURN/2)
{ {
player->botvars.itemconfirm += 2; player->botvars.itemconfirm += player->botvars.difficulty / 2;
throwdir = -1; throwdir = -1;
} }
else else
{ {
UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity); UINT32 airtime = FixedDiv((30 * player->mo->scale) + player->mo->momz, gravity);
fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); fixed_t throwspeed = FixedMul(82 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); angle_t momangle = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy);
fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); fixed_t estx = player->mo->x + P_ReturnThrustX(NULL, momangle, (throwspeed + player->speed) * airtime);
fixed_t esty = player->mo->y + P_ReturnThrustY(NULL, momangle, (throwspeed + player->speed) * airtime);
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{ {
player->botvars.itemconfirm += 8; player->botvars.itemconfirm += player->botvars.difficulty * 2;
throwdir = 0; throwdir = 0;
} }
@ -1543,9 +1842,9 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); estx = player->mo->x + P_ReturnThrustX(NULL, player->mo->angle, (throwspeed + player->speed) * airtime);
esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime); esty = player->mo->y + P_ReturnThrustY(NULL, player->mo->angle, (throwspeed + player->speed) * airtime);
if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 16)) if (K_PlayerNearSpot(player, estx, esty, player->mo->radius * 2))
{ {
player->botvars.itemconfirm += 4; player->botvars.itemconfirm += player->botvars.difficulty / 2;
throwdir = 1; throwdir = 1;
} }
} }
@ -1583,12 +1882,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
} }
break; break;
default: default:
if (player->kartstuff[k_itemtype] != KITEM_NONE && !(player->pflags & PF_ATTACKDOWN))
cmd->buttons |= BT_ATTACK;
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
break; break;
} }
} }
} }
}
if (turnamt != 0) if (turnamt != 0)
{ {

View file

@ -950,6 +950,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed, boolean sp
case KITEM_ROCKETSNEAKER: case KITEM_ROCKETSNEAKER:
case KITEM_INVINCIBILITY: case KITEM_INVINCIBILITY:
case KITEM_BANANA: case KITEM_BANANA:
case KITEM_EGGMAN:
case KITEM_ORBINAUT: case KITEM_ORBINAUT:
case KITEM_JAWZ: case KITEM_JAWZ:
case KITEM_MINE: case KITEM_MINE: