Allow bots to reflect with the Bubble Shield rework since it no longer hits players.

This commit is contained in:
NepDisk 2025-08-31 22:37:18 -04:00
parent 0efd36ac5d
commit 8637fd772a
4 changed files with 130 additions and 46 deletions

View file

@ -349,6 +349,21 @@ void K_NudgePredictionTowardsObjects(botdata_t *bd, const player_t *player);
INT32 K_PositionBully(const player_t *player);
/*--------------------------------------------------
boolean K_GetBlockedBubbleItem(const player_t *player, , fixed_t radius)
Searches the blockmap for items to block with the Bubble Shield
Input Arguments:-
player - Bot to run this for.
radius - Radius around player to check for items.
Return:-
false if couldn't find anything, otherwise true to attempt blocking item.
--------------------------------------------------*/
boolean K_GetBlockedBubbleItem(const player_t *player, fixed_t radius);
/*--------------------------------------------------
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd);

View file

@ -919,55 +919,27 @@ static void K_BotItemBubble(botdata_t *bd, const player_t *player)
boolean hold = false;
if (player->bubbleblowup <= 0)
// We are holding this thing too long, lets get rid of it.
if (bd->itemconfirm > 20*TICRATE)
{
UINT8 i;
bd->itemconfirm++;
if (player->itemflags & IF_HOLDREADY)
{
bd->itemdown = true;
}
return;
}
if (player->bubbleblowup <= 0)
{
if (player->bubblecool <= 0)
{
fixed_t radius = 192 * player->mo->scale;
radius = Easing_Linear(FRACUNIT * player->botvars.difficulty / MAXBOTDIFFICULTY, 2*radius, radius);
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->flashing)
{
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 <= radius)
{
hold = true;
break;
}
}
}
}
else if (player->bubbleblowup >= bubbletime)
{
if (bd->itemconfirm > 10*TICRATE)
{
hold = true;
hold = K_GetBlockedBubbleItem(player, radius);
}
}
else if (player->bubbleblowup < bubbletime)
@ -979,6 +951,8 @@ static void K_BotItemBubble(botdata_t *bd, const player_t *player)
{
bd->itemdown = true;
}
bd->itemconfirm++;
}
// Item usage for Flame Shield.
@ -1203,7 +1177,7 @@ static boolean K_CanHandleItemDelay(botdata_t *bd, const player_t *player)
if (player->flametimer > 0)
{
// Flame Shield? We handle this there instead.
return false
return false;
}

View file

@ -981,3 +981,90 @@ INT32 K_PositionBully(const player_t *player)
return KART_FULLTURN;
}
static mobj_t *bubbleSource;
static fixed_t bubbleDist;
static boolean bubbleBlock;
static inline BlockItReturn_t PIT_BubbleShieldBlock(mobj_t *thing)
{
if (bubbleSource == NULL || P_MobjWasRemoved(bubbleSource))
{
// Invalid?
return BMIT_ABORT;
}
if (thing == NULL || P_MobjWasRemoved(thing))
{
// Invalid?
return BMIT_ABORT;
}
if (thing == bubbleSource)
{
// Don't block yourself!!
return BMIT_CONTINUE;
}
if (thing->player)
{
// We don't block players.
return BMIT_CONTINUE;
}
if (thing->health <= 0)
{
// Dead
return BMIT_CONTINUE;
}
if (!P_IsKartItem(thing->type) && !(thing->flags & MF_SHOOTABLE))
{
// Not a Item.
return BMIT_CONTINUE;
}
if (P_AproxDistance(P_AproxDistance(
bubbleSource->x - thing->x,
bubbleSource->y - thing->y),
(bubbleSource->z - thing->z) / 4) > bubbleDist)
{
// Too far away
return BMIT_CONTINUE;
}
#if 0
if (P_CheckSight(bubbleSource, thing) == false)
{
// Not in sight
return BMIT_CONTINUE;
}
#endif
bubbleBlock = true;
return BMIT_CONTINUE;
}
// Searches the blockmap for items to block with the Bubble Shield
boolean K_GetBlockedBubbleItem(const player_t *player, fixed_t radius)
{
INT32 bx, by, xl, xh, yl, yh;
bubbleSource = player->mo;
bubbleDist = radius;
bubbleBlock = false;
// Use blockmap to check for nearby harmful items.
yh = (unsigned)(bubbleSource->y + bubbleDist - bmaporgy)>>MAPBLOCKSHIFT;
yl = (unsigned)(bubbleSource->y - bubbleDist - bmaporgy)>>MAPBLOCKSHIFT;
xh = (unsigned)(bubbleSource->x + bubbleDist - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(bubbleSource->x - bubbleDist - bmaporgx)>>MAPBLOCKSHIFT;
BMBOUNDFIX (xl, xh, yl, yh);
for (by = yl; by <= yh; by++)
for (bx = xl; bx <= xh; bx++)
P_BlockThingsIterator(bx, by, PIT_BubbleShieldBlock);
return bubbleBlock;
}

View file

@ -554,9 +554,9 @@ boolean K_BubbleShieldReflect(mobj_t *t1, mobj_t *t2)
}
else
{
t2->momx = -6*t2->momx;
t2->momy = -6*t2->momy;
t2->momz = -6*t2->momz;
t2->momx = (-1*t2->momx)/2;
t2->momy = (-1*t2->momy)/2;
t2->momz = (-1*t2->momz)/2;
t2->angle += ANGLE_180;
}
if (t2->type == MT_JAWZ)
@ -598,7 +598,15 @@ boolean K_BubbleShieldCollide(mobj_t *t1, mobj_t *t2)
if (t2->flags & MF_SHOOTABLE)
{
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
boolean shootable = P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL);
if (shootable)
{
// Drain my stuff please.
K_BubbleShieldCollideDrain(t1->target->player, t1);
}
return shootable;
}
// no interaction