mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'bot-alt-turning' into 'master'
New bot swerving system See merge request KartKrew/Kart!400
This commit is contained in:
commit
731f0af25f
11 changed files with 405 additions and 171 deletions
|
|
@ -432,6 +432,7 @@ consvar_t cv_kartdebugdistribution = CVAR_INIT ("kartdebugdistribution", "Off",
|
||||||
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebughuddrop = CVAR_INIT ("kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
static CV_PossibleValue_t kartdebugwaypoint_cons_t[] = {{0, "Off"}, {1, "Forwards"}, {2, "Backwards"}, {0, NULL}};
|
||||||
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
consvar_t cv_kartdebugwaypoints = CVAR_INIT ("kartdebugwaypoints", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugwaypoint_cons_t, NULL);
|
||||||
|
consvar_t cv_kartdebugbotpredict = CVAR_INIT ("kartdebugbotpredict", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
|
|
||||||
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugcheckpoint = CVAR_INIT ("kartdebugcheckpoint", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
consvar_t cv_kartdebugnodes = CVAR_INIT ("kartdebugnodes", "Off", CV_NOSHOWHELP, CV_OnOff, NULL);
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ extern consvar_t cv_votetime;
|
||||||
|
|
||||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartallowgiveitem, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||||
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
|
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes, cv_kartdebugcolorize;
|
||||||
extern consvar_t cv_kartdebugwaypoints;
|
extern consvar_t cv_kartdebugwaypoints, cv_kartdebugbotpredict;
|
||||||
|
|
||||||
extern consvar_t cv_itemfinder;
|
extern consvar_t cv_itemfinder;
|
||||||
|
|
||||||
|
|
|
||||||
88
src/k_bot.c
88
src/k_bot.c
|
|
@ -572,9 +572,11 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
||||||
|
|
||||||
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
|
const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict
|
||||||
const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4);
|
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);
|
const INT32 startDist = (768 * mapobjectscale) / FRACUNIT;
|
||||||
|
const INT32 distance = ((FixedMul(speed, distreduce) / FRACUNIT) * futuresight) + startDist;
|
||||||
|
|
||||||
|
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||||
waypoint_t *wp = player->nextwaypoint;
|
waypoint_t *wp = player->nextwaypoint;
|
||||||
|
|
||||||
INT32 distanceleft = distance;
|
INT32 distanceleft = distance;
|
||||||
|
|
@ -837,6 +839,70 @@ static INT16 K_FindBotController(mobj_t *mo)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||||
|
|
||||||
|
Draws objects to show where the viewpoint bot is trying to go.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
predict - The prediction to visualize.
|
||||||
|
player - The bot player this prediction is for.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
|
||||||
|
{
|
||||||
|
mobj_t *debugMobj = NULL;
|
||||||
|
angle_t sideAngle = ANGLE_MAX;
|
||||||
|
UINT8 i = UINT8_MAX;
|
||||||
|
|
||||||
|
I_Assert(predict != NULL);
|
||||||
|
I_Assert(player != NULL);
|
||||||
|
I_Assert(player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
|
||||||
|
|
||||||
|
sideAngle = player->mo->angle + ANGLE_90;
|
||||||
|
|
||||||
|
debugMobj = P_SpawnMobj(predict->x, predict->y, player->mo->z, MT_SPARK);
|
||||||
|
P_SetMobjState(debugMobj, S_THOK);
|
||||||
|
|
||||||
|
debugMobj->frame &= ~FF_TRANSMASK;
|
||||||
|
debugMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
||||||
|
|
||||||
|
debugMobj->color = SKINCOLOR_ORANGE;
|
||||||
|
debugMobj->scale *= 2;
|
||||||
|
|
||||||
|
debugMobj->tics = 2;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
mobj_t *radiusMobj = NULL;
|
||||||
|
fixed_t radiusX = predict->x, radiusY = predict->y;
|
||||||
|
|
||||||
|
if (i & 1)
|
||||||
|
{
|
||||||
|
radiusX -= FixedMul(predict->radius, FINECOSINE(sideAngle >> ANGLETOFINESHIFT));
|
||||||
|
radiusY -= FixedMul(predict->radius, FINESINE(sideAngle >> ANGLETOFINESHIFT));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
radiusX += FixedMul(predict->radius, FINECOSINE(sideAngle >> ANGLETOFINESHIFT));
|
||||||
|
radiusY += FixedMul(predict->radius, FINESINE(sideAngle >> ANGLETOFINESHIFT));
|
||||||
|
}
|
||||||
|
|
||||||
|
radiusMobj = P_SpawnMobj(radiusX, radiusY, player->mo->z, MT_SPARK);
|
||||||
|
P_SetMobjState(radiusMobj, S_THOK);
|
||||||
|
|
||||||
|
radiusMobj->frame &= ~FF_TRANSMASK;
|
||||||
|
radiusMobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
||||||
|
|
||||||
|
radiusMobj->color = SKINCOLOR_YELLOW;
|
||||||
|
radiusMobj->scale /= 2;
|
||||||
|
|
||||||
|
radiusMobj->tics = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
|
|
@ -863,6 +929,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
gamestate != GS_LEVEL
|
gamestate != GS_LEVEL
|
||||||
|| player->mo->scale <= 1
|
|| player->mo->scale <= 1
|
||||||
|| player->playerstate == PST_DEAD
|
|| player->playerstate == PST_DEAD
|
||||||
|
|| leveltime <= introtime
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// No need to do anything else.
|
// No need to do anything else.
|
||||||
|
|
@ -927,7 +994,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset);
|
destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset);
|
||||||
|
|
||||||
// Overwritten prediction
|
// Overwritten prediction
|
||||||
predict = Z_Calloc(sizeof(botprediction_t), PU_LEVEL, NULL);
|
predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||||
|
|
||||||
predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT));
|
predict->x = player->mo->x + FixedMul(dist, FINECOSINE(destangle >> ANGLETOFINESHIFT));
|
||||||
predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT));
|
predict->y = player->mo->y + FixedMul(dist, FINESINE(destangle >> ANGLETOFINESHIFT));
|
||||||
|
|
@ -936,6 +1003,9 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
predict = K_CreateBotPrediction(player);
|
predict = K_CreateBotPrediction(player);
|
||||||
|
|
||||||
|
K_NudgePredictionTowardsObjects(predict, player);
|
||||||
|
|
||||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1033,11 +1103,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
cmd->forwardmove /= 2;
|
cmd->forwardmove /= 2;
|
||||||
cmd->buttons |= BT_BRAKE;
|
cmd->buttons |= BT_BRAKE;
|
||||||
}
|
}
|
||||||
else if (dirdist <= realrad)
|
|
||||||
{
|
|
||||||
// Steer towards/away from objects!
|
|
||||||
turnamt += K_BotFindObjects(player, turnamt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1053,7 +1118,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
finishBeamLine->v1->x, finishBeamLine->v1->y,
|
finishBeamLine->v1->x, finishBeamLine->v1->y,
|
||||||
finishBeamLine->v2->x, finishBeamLine->v2->y,
|
finishBeamLine->v2->x, finishBeamLine->v2->y,
|
||||||
player->mo->x, player->mo->y
|
player->mo->x, player->mo->y
|
||||||
);
|
) - player->speed;
|
||||||
|
|
||||||
// Don't run the spindash code at all until we're in the right place
|
// Don't run the spindash code at all until we're in the right place
|
||||||
trySpindash = false;
|
trySpindash = false;
|
||||||
|
|
@ -1163,6 +1228,11 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
||||||
// Free the prediction we made earlier
|
// Free the prediction we made earlier
|
||||||
if (predict != NULL)
|
if (predict != NULL)
|
||||||
{
|
{
|
||||||
|
if (cv_kartdebugbotpredict.value != 0 && player - players == displayplayers[0])
|
||||||
|
{
|
||||||
|
K_DrawPredictionDebug(predict, player);
|
||||||
|
}
|
||||||
|
|
||||||
Z_Free(predict);
|
Z_Free(predict);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
src/k_bot.h
10
src/k_bot.h
|
|
@ -198,19 +198,19 @@ fixed_t K_BotReducePrediction(player_t *player);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
INT16 K_BotFindObjects(player_t *player, INT16 turn);
|
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player);
|
||||||
|
|
||||||
Generates a sum for objects to steer towards/away from.
|
Moves the bot's prediction, based on objects around the bot.
|
||||||
|
|
||||||
Input Arguments:-
|
Input Arguments:-
|
||||||
|
predict - The bot's prediction to nudge.
|
||||||
player - Player to compare.
|
player - Player to compare.
|
||||||
turn - Turn value before object steering.
|
|
||||||
|
|
||||||
Return:-
|
Return:-
|
||||||
Turn amount sum to add to final product.
|
None
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
|
|
||||||
INT16 K_BotFindObjects(player_t *player, INT16 turn);
|
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -909,7 +909,7 @@ static void K_BotItemFlame(player_t *player, ticcmd_t *cmd)
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
static void K_BotItemRings(player_t *player, ticcmd_t *cmd)
|
||||||
{
|
{
|
||||||
INT32 saferingsval = 16 - K_GetKartRingPower(player);
|
INT32 saferingsval = 16 - K_GetKartRingPower(player, false);
|
||||||
|
|
||||||
if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much
|
if (player->speed < K_GetKartSpeed(player, false)/2 // Being slowed down too much
|
||||||
|| player->kartstuff[k_speedboost] > (FRACUNIT/5)) // Have another type of boost (tethering)
|
|| player->kartstuff[k_speedboost] > (FRACUNIT/5)) // Have another type of boost (tethering)
|
||||||
|
|
@ -971,7 +971,7 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt)
|
||||||
{
|
{
|
||||||
// Use rings!
|
// Use rings!
|
||||||
|
|
||||||
if (!player->exiting)
|
if (leveltime > starttime && !player->exiting)
|
||||||
{
|
{
|
||||||
K_BotItemRings(player, cmd);
|
K_BotItemRings(player, cmd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,16 @@
|
||||||
struct globalsmuggle
|
struct globalsmuggle
|
||||||
{
|
{
|
||||||
mobj_t *botmo;
|
mobj_t *botmo;
|
||||||
|
botprediction_t *predict;
|
||||||
fixed_t distancetocheck;
|
fixed_t distancetocheck;
|
||||||
|
|
||||||
fixed_t closestlinedist;
|
INT64 gotoAvgX[2], gotoAvgY[2];
|
||||||
|
UINT32 gotoObjs[2];
|
||||||
|
|
||||||
INT16 curturn;
|
INT64 avoidAvgX[2], avoidAvgY[2];
|
||||||
INT16 steer;
|
UINT32 avoidObjs[2];
|
||||||
|
|
||||||
|
fixed_t closestlinedist;
|
||||||
|
|
||||||
fixed_t eggboxx, eggboxy;
|
fixed_t eggboxx, eggboxy;
|
||||||
UINT8 randomitems;
|
UINT8 randomitems;
|
||||||
|
|
@ -383,7 +387,7 @@ fixed_t K_BotReducePrediction(player_t *player)
|
||||||
INT32 xl, xh, yl, yh, bx, by;
|
INT32 xl, xh, yl, yh, bx, by;
|
||||||
|
|
||||||
globalsmuggle.botmo = player->mo;
|
globalsmuggle.botmo = player->mo;
|
||||||
globalsmuggle.distancetocheck = (player->mo->radius * 16);
|
globalsmuggle.distancetocheck = (player->mo->radius * 32);
|
||||||
globalsmuggle.closestlinedist = INT32_MAX;
|
globalsmuggle.closestlinedist = INT32_MAX;
|
||||||
|
|
||||||
tmx = player->mo->x;
|
tmx = player->mo->x;
|
||||||
|
|
@ -415,87 +419,107 @@ fixed_t K_BotReducePrediction(player_t *player)
|
||||||
return FRACUNIT;
|
return FRACUNIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck);
|
return (FRACUNIT/2) + (FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixed_t xdist, boolean towards, INT16 amount)
|
static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||||
|
|
||||||
Handles steering away/towards the specified object.
|
Adds an object to the list that the bot wants to go towards.
|
||||||
|
|
||||||
Input Arguments:-
|
Input Arguments:-
|
||||||
bot - Bot's mobj.
|
thing - Object to move towards.
|
||||||
thing - Mobj to steer towards/away from.
|
side - Which side -- 0 for left, 1 for right
|
||||||
fulldist - Distance away from object.
|
weight - How important this object is.
|
||||||
xdist - Horizontal distance away from object.
|
|
||||||
towards - If true, steer towards the object. Otherwise, steer away.
|
|
||||||
amount - How hard to turn.
|
|
||||||
|
|
||||||
Return:-
|
Return:-
|
||||||
None
|
None
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixed_t xdist, boolean towards, INT16 amount)
|
static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||||
{
|
{
|
||||||
angle_t destangle = R_PointToAngle2(bot->x, bot->y, thing->x, thing->y);
|
UINT8 i;
|
||||||
angle_t angle;
|
|
||||||
SINT8 flip = 1;
|
|
||||||
|
|
||||||
amount = (amount * FixedDiv(globalsmuggle.distancetocheck - fulldist, globalsmuggle.distancetocheck)) / FRACUNIT;
|
I_Assert(side <= 1);
|
||||||
|
|
||||||
if (amount == 0)
|
if (weight == 0)
|
||||||
{
|
{
|
||||||
// Shouldn't happen
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (towards)
|
for (i = 0; i < weight; i++)
|
||||||
{
|
{
|
||||||
if (xdist < FixedHypot(bot->radius, thing->radius))
|
globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
|
||||||
{
|
globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
|
||||||
// Don't need to turn any harder!
|
globalsmuggle.gotoObjs[side]++;
|
||||||
|
|
||||||
if (abs(globalsmuggle.steer) <= amount)
|
|
||||||
{
|
|
||||||
globalsmuggle.steer = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (globalsmuggle.steer > 0)
|
|
||||||
{
|
|
||||||
globalsmuggle.steer -= amount;
|
|
||||||
}
|
|
||||||
else if (globalsmuggle.steer < 0)
|
|
||||||
{
|
|
||||||
globalsmuggle.steer += amount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Still turning towards it, flip.
|
|
||||||
flip = -flip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
angle = (bot->angle - destangle);
|
|
||||||
if (angle < ANGLE_180)
|
|
||||||
{
|
|
||||||
flip = -flip;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If going in the opposite direction of where you wanted to turn,
|
|
||||||
// then reduce the amount that you can turn in that direction.
|
|
||||||
if ((flip == 1 && globalsmuggle.curturn < 0)
|
|
||||||
|| (flip == -1 && globalsmuggle.curturn > 0))
|
|
||||||
{
|
|
||||||
amount /= 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
globalsmuggle.steer += amount * flip;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
static boolean K_BotSteerObjects(mobj_t *thing)
|
static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||||
|
|
||||||
|
Adds an object to the list that the bot wants to dodge.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
thing - Object to move away from.
|
||||||
|
side - Which side -- 0 for left, 1 for right
|
||||||
|
weight - How important this object is.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
None
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
|
I_Assert(side <= 1);
|
||||||
|
|
||||||
|
if (weight == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < weight; i++)
|
||||||
|
{
|
||||||
|
globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
|
||||||
|
globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
|
||||||
|
globalsmuggle.gotoObjs[side]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static boolean K_PlayerAttackSteer(mobj_t *thing, UINT8 side, UINT8 weight, boolean attackCond, boolean dodgeCond)
|
||||||
|
|
||||||
|
Checks two conditions to determine if the object should be
|
||||||
|
attacked or dodged.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
thing - Object to move towards/away from.
|
||||||
|
side - Which side -- 0 for left, 1 for right
|
||||||
|
weight - How important this object is.
|
||||||
|
attackCond - If this is true, and dodgeCond isn't, then we go towards the object.
|
||||||
|
dodgeCond - If this is true, and attackCond isn't, then we move away from the object.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
true if either condition is successful.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
static boolean K_PlayerAttackSteer(mobj_t *thing, UINT8 side, UINT8 weight, boolean attackCond, boolean dodgeCond)
|
||||||
|
{
|
||||||
|
if (attackCond == true && dodgeCond == false)
|
||||||
|
{
|
||||||
|
K_AddAttackObject(thing, side, weight);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (dodgeCond == true && attackCond == false)
|
||||||
|
{
|
||||||
|
K_AddDodgeObject(thing, side, weight);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
static boolean K_FindObjectsForNudging(mobj_t *thing)
|
||||||
|
|
||||||
Blockmap search function.
|
Blockmap search function.
|
||||||
Finds objects around the bot to steer towards/away from.
|
Finds objects around the bot to steer towards/away from.
|
||||||
|
|
@ -506,20 +530,19 @@ static void K_SteerFromObject(mobj_t *bot, mobj_t *thing, fixed_t fulldist, fixe
|
||||||
Return:-
|
Return:-
|
||||||
true continues searching, false ends the search early.
|
true continues searching, false ends the search early.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
static boolean K_BotSteerObjects(mobj_t *thing)
|
static boolean K_FindObjectsForNudging(mobj_t *thing)
|
||||||
{
|
{
|
||||||
INT16 anglediff;
|
INT16 anglediff;
|
||||||
fixed_t xdist, ydist, fulldist;
|
fixed_t fulldist;
|
||||||
angle_t destangle, angle;
|
angle_t destangle, angle, predictangle;
|
||||||
INT16 attack = ((9 - globalsmuggle.botmo->player->kartspeed) * KART_FULLTURN) / 8; // Acceleration chars are more aggressive
|
UINT8 side = 0;
|
||||||
INT16 dodge = ((9 - globalsmuggle.botmo->player->kartweight) * KART_FULLTURN) / 8; // Handling chars dodge better
|
|
||||||
|
|
||||||
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
|
if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!thing->health)
|
if (thing->health <= 0)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -529,32 +552,21 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
xdist = K_DistanceOfLineFromPoint(
|
fulldist = R_PointToDist2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y) - thing->radius;
|
||||||
globalsmuggle.botmo->x, globalsmuggle.botmo->y,
|
|
||||||
globalsmuggle.botmo->x + FINECOSINE(globalsmuggle.botmo->angle >> ANGLETOFINESHIFT), globalsmuggle.botmo->y + FINESINE(globalsmuggle.botmo->angle >> ANGLETOFINESHIFT),
|
|
||||||
thing->x, thing->y
|
|
||||||
) / 2; // weight x dist more heavily than y dist
|
|
||||||
|
|
||||||
ydist = K_DistanceOfLineFromPoint(
|
|
||||||
globalsmuggle.botmo->x, globalsmuggle.botmo->y,
|
|
||||||
globalsmuggle.botmo->x + FINECOSINE((globalsmuggle.botmo->angle + ANGLE_90) >> ANGLETOFINESHIFT), globalsmuggle.botmo->y + FINESINE((globalsmuggle.botmo->angle + ANGLE_90) >> ANGLETOFINESHIFT),
|
|
||||||
thing->x, thing->y
|
|
||||||
);
|
|
||||||
|
|
||||||
fulldist = FixedHypot(xdist, ydist);
|
|
||||||
|
|
||||||
if (fulldist > globalsmuggle.distancetocheck)
|
if (fulldist > globalsmuggle.distancetocheck)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!P_CheckSight(globalsmuggle.botmo, thing))
|
if (P_CheckSight(globalsmuggle.botmo, thing) == false)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predictangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, globalsmuggle.predict->x, globalsmuggle.predict->y);
|
||||||
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y);
|
destangle = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, thing->x, thing->y);
|
||||||
angle = (globalsmuggle.botmo->angle - destangle);
|
angle = (predictangle - destangle);
|
||||||
|
|
||||||
if (angle < ANGLE_180)
|
if (angle < ANGLE_180)
|
||||||
{
|
{
|
||||||
|
|
@ -563,20 +575,11 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
anglediff = 360-(AngleFixed(angle)>>FRACBITS);
|
anglediff = 360-(AngleFixed(angle)>>FRACBITS);
|
||||||
|
side = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
anglediff = abs(anglediff);
|
anglediff = abs(anglediff);
|
||||||
|
|
||||||
#define PlayerAttackSteer(botcond, thingcond) \
|
|
||||||
if ((botcond) && !(thingcond)) \
|
|
||||||
{ \
|
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, 2 * (KART_FULLTURN + attack)); \
|
|
||||||
} \
|
|
||||||
else if ((thingcond) && !(botcond)) \
|
|
||||||
{ \
|
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge)); \
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (thing->type)
|
switch (thing->type)
|
||||||
{
|
{
|
||||||
case MT_BANANA:
|
case MT_BANANA:
|
||||||
|
|
@ -593,21 +596,21 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
case MT_BALLHOG:
|
case MT_BALLHOG:
|
||||||
case MT_SPB:
|
case MT_SPB:
|
||||||
case MT_BUBBLESHIELDTRAP:
|
case MT_BUBBLESHIELDTRAP:
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
|
K_AddDodgeObject(thing, side, 20);
|
||||||
break;
|
break;
|
||||||
case MT_RANDOMITEM:
|
case MT_RANDOMITEM:
|
||||||
if (anglediff >= 60)
|
if (anglediff >= 45)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_CanPickupItem(globalsmuggle.botmo->player, 1))
|
if (P_CanPickupItem(globalsmuggle.botmo->player, 1))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack);
|
K_AddAttackObject(thing, side, 10);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_EGGMANITEM:
|
case MT_EGGMANITEM:
|
||||||
if (anglediff >= 60)
|
if (anglediff >= 45)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -619,28 +622,28 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
|
|
||||||
if (stealth >= requiredstealth)
|
if (stealth >= requiredstealth)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, 2 * (KART_FULLTURN + attack));
|
K_AddAttackObject(thing, side, 10);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
|
K_AddDodgeObject(thing, side, 10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_FLOATINGITEM:
|
case MT_FLOATINGITEM:
|
||||||
if (anglediff >= 60)
|
if (anglediff >= 45)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_CanPickupItem(globalsmuggle.botmo->player, 3))
|
if (P_CanPickupItem(globalsmuggle.botmo->player, 3))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack);
|
K_AddAttackObject(thing, side, 20);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_RING:
|
case MT_RING:
|
||||||
case MT_FLINGRING:
|
case MT_FLINGRING:
|
||||||
if (anglediff >= 60)
|
if (anglediff >= 45)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -650,11 +653,7 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
&& !thing->extravalue1
|
&& !thing->extravalue1
|
||||||
&& (globalsmuggle.botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD))
|
&& (globalsmuggle.botmo->player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true,
|
K_AddAttackObject(thing, side, (RINGTOTAL(globalsmuggle.botmo->player) < 3) ? 5 : 1);
|
||||||
(RINGTOTAL(globalsmuggle.botmo->player) < 3
|
|
||||||
? (4 * (KART_FULLTURN + attack))
|
|
||||||
: (KART_FULLTURN + attack))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_PLAYER:
|
case MT_PLAYER:
|
||||||
|
|
@ -664,40 +663,61 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
{
|
{
|
||||||
// There REALLY ought to be a better way to handle this logic, right?!
|
// There REALLY ought to be a better way to handle this logic, right?!
|
||||||
// Squishing
|
// Squishing
|
||||||
PlayerAttackSteer(
|
if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
globalsmuggle.botmo->scale > thing->scale + (mapobjectscale/8),
|
globalsmuggle.botmo->scale > thing->scale + (mapobjectscale/8),
|
||||||
thing->scale > globalsmuggle.botmo->scale + (mapobjectscale/8)
|
thing->scale > globalsmuggle.botmo->scale + (mapobjectscale/8)
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Invincibility
|
// Invincibility
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
globalsmuggle.botmo->player->kartstuff[k_invincibilitytimer],
|
globalsmuggle.botmo->player->kartstuff[k_invincibilitytimer],
|
||||||
thing->player->kartstuff[k_invincibilitytimer]
|
thing->player->kartstuff[k_invincibilitytimer]
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Thunder Shield
|
// Thunder Shield
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD,
|
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD,
|
||||||
thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD
|
thing->player->kartstuff[k_itemtype] == KITEM_THUNDERSHIELD
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Bubble Shield
|
// Bubble Shield
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD,
|
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD,
|
||||||
thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD
|
thing->player->kartstuff[k_itemtype] == KITEM_BUBBLESHIELD
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Flame Shield
|
// Flame Shield
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD,
|
globalsmuggle.botmo->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD,
|
||||||
thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
thing->player->kartstuff[k_itemtype] == KITEM_FLAMESHIELD
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Has held item shield
|
// Has held item shield
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
(globalsmuggle.botmo->player->kartstuff[k_itemheld] || globalsmuggle.botmo->player->kartstuff[k_eggmanheld]),
|
(globalsmuggle.botmo->player->kartstuff[k_itemheld] || globalsmuggle.botmo->player->kartstuff[k_eggmanheld]),
|
||||||
(thing->player->kartstuff[k_itemheld] || thing->player->kartstuff[k_eggmanheld])
|
(thing->player->kartstuff[k_itemheld] || thing->player->kartstuff[k_eggmanheld])
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Ring Sting
|
// Ring Sting
|
||||||
else PlayerAttackSteer(
|
else if (K_PlayerAttackSteer(thing, side, 20,
|
||||||
thing->player->rings <= 0,
|
thing->player->rings <= 0,
|
||||||
globalsmuggle.botmo->player->rings <= 0
|
globalsmuggle.botmo->player->rings <= 0
|
||||||
)
|
))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// After ALL of that, we can do standard bumping
|
// After ALL of that, we can do standard bumping
|
||||||
|
|
@ -716,33 +736,43 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
|
|
||||||
if (weightdiff > mapobjectscale)
|
if (weightdiff > mapobjectscale)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, KART_FULLTURN + attack);
|
K_AddAttackObject(thing, side, 20);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, KART_FULLTURN + dodge);
|
K_AddDodgeObject(thing, side, 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MT_BOTHINT:
|
case MT_BOTHINT:
|
||||||
if (anglediff >= 60)
|
if (anglediff >= 45)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UINT8 weight = 20;
|
||||||
|
|
||||||
if (thing->extravalue1 == 0)
|
if (thing->extravalue2 > 0)
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, thing->extravalue2 * (KART_FULLTURN + dodge));
|
weight = thing->extravalue2 * 5;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, true, thing->extravalue2 * (KART_FULLTURN + attack));
|
if (thing->extravalue1 == 0)
|
||||||
|
{
|
||||||
|
K_AddDodgeObject(thing, side, weight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
K_AddAttackObject(thing, side, weight);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE))
|
if (thing->flags & (MF_SOLID|MF_ENEMY|MF_BOSS|MF_PAIN|MF_MISSILE))
|
||||||
{
|
{
|
||||||
K_SteerFromObject(globalsmuggle.botmo, thing, fulldist, xdist, false, 2 * (KART_FULLTURN + dodge));
|
K_AddDodgeObject(thing, side, 20);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -751,18 +781,40 @@ static boolean K_BotSteerObjects(mobj_t *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
INT16 K_BotFindObjects(player_t *player, INT16 turn)
|
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
||||||
|
|
||||||
See header file for description.
|
See header file for description.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
INT16 K_BotFindObjects(player_t *player, INT16 turn)
|
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
||||||
{
|
{
|
||||||
INT32 xl, xh, yl, yh, bx, by;
|
INT32 xl, xh, yl, yh, bx, by;
|
||||||
|
|
||||||
globalsmuggle.steer = 0;
|
fixed_t distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||||
|
|
||||||
|
fixed_t avgX = 0, avgY = 0;
|
||||||
|
fixed_t avgDist = 0;
|
||||||
|
|
||||||
|
const fixed_t baseNudge = 128 * mapobjectscale;
|
||||||
|
fixed_t maxNudge = distToPredict;
|
||||||
|
fixed_t nudgeDist = 0;
|
||||||
|
angle_t nudgeDir = 0;
|
||||||
|
|
||||||
|
SINT8 gotoSide = -1;
|
||||||
|
UINT8 i;
|
||||||
|
|
||||||
globalsmuggle.botmo = player->mo;
|
globalsmuggle.botmo = player->mo;
|
||||||
globalsmuggle.curturn = turn;
|
globalsmuggle.predict = predict;
|
||||||
globalsmuggle.distancetocheck = (player->mo->radius * 32) + (player->speed * 4);
|
|
||||||
|
globalsmuggle.distancetocheck = distToPredict;
|
||||||
|
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
globalsmuggle.gotoAvgX[i] = globalsmuggle.gotoAvgY[i] = 0;
|
||||||
|
globalsmuggle.gotoObjs[i] = 0;
|
||||||
|
|
||||||
|
globalsmuggle.avoidAvgX[i] = globalsmuggle.avoidAvgY[i] = 0;
|
||||||
|
globalsmuggle.avoidObjs[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||||
|
|
@ -775,9 +827,120 @@ INT16 K_BotFindObjects(player_t *player, INT16 turn)
|
||||||
{
|
{
|
||||||
for (by = yl; by <= yh; by++)
|
for (by = yl; by <= yh; by++)
|
||||||
{
|
{
|
||||||
P_BlockThingsIterator(bx, by, K_BotSteerObjects);
|
P_BlockThingsIterator(bx, by, K_FindObjectsForNudging);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return globalsmuggle.steer;
|
// Handle dodge characters
|
||||||
|
if (globalsmuggle.avoidObjs[1] > 0 || globalsmuggle.avoidObjs[0] > 0)
|
||||||
|
{
|
||||||
|
if (globalsmuggle.avoidObjs[1] > globalsmuggle.avoidObjs[0])
|
||||||
|
{
|
||||||
|
gotoSide = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gotoSide = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
avgX = (globalsmuggle.avoidAvgX[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
|
||||||
|
avgY = (globalsmuggle.avoidAvgY[gotoSide] / globalsmuggle.avoidObjs[gotoSide]) * mapobjectscale;
|
||||||
|
|
||||||
|
avgDist = R_PointToDist2(
|
||||||
|
avgX, avgY,
|
||||||
|
predict->x, predict->y
|
||||||
|
);
|
||||||
|
|
||||||
|
// High handling characters dodge better
|
||||||
|
nudgeDist = ((9 - globalsmuggle.botmo->player->kartweight) + 1) * baseNudge;
|
||||||
|
|
||||||
|
maxNudge = max(distToPredict - predict->radius, predict->radius);
|
||||||
|
if (nudgeDist > maxNudge)
|
||||||
|
{
|
||||||
|
nudgeDist = maxNudge;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Point away
|
||||||
|
nudgeDir = R_PointToAngle2(
|
||||||
|
avgX, avgY,
|
||||||
|
predict->x, predict->y
|
||||||
|
);
|
||||||
|
|
||||||
|
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||||
|
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||||
|
|
||||||
|
// Flip side, since we want to check for objects to steer towards on the side we're NOT dodging.
|
||||||
|
if (gotoSide == 0)
|
||||||
|
{
|
||||||
|
gotoSide = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gotoSide = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotoSide == -1)
|
||||||
|
{
|
||||||
|
// Pick a side here if there were no objects to dodge.
|
||||||
|
// We don't want to pick contradictory sides, so keep the old side otherwise,
|
||||||
|
// even if there's more to grab on the other side.
|
||||||
|
|
||||||
|
if (globalsmuggle.gotoObjs[1] > globalsmuggle.gotoObjs[0])
|
||||||
|
{
|
||||||
|
gotoSide = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gotoSide = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if our side is invalid, if so, don't do the code below.
|
||||||
|
if (gotoSide != -1 && globalsmuggle.gotoObjs[gotoSide] == 0)
|
||||||
|
{
|
||||||
|
// Do not use a side
|
||||||
|
gotoSide = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gotoSide != -1)
|
||||||
|
{
|
||||||
|
avgX = (globalsmuggle.gotoAvgX[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
|
||||||
|
avgY = (globalsmuggle.gotoAvgY[gotoSide] / globalsmuggle.gotoObjs[gotoSide]) * mapobjectscale;
|
||||||
|
|
||||||
|
avgDist = R_PointToDist2(
|
||||||
|
predict->x, predict->y,
|
||||||
|
avgX, avgY
|
||||||
|
);
|
||||||
|
|
||||||
|
// Acceleration characters are more aggressive
|
||||||
|
nudgeDist = ((9 - globalsmuggle.botmo->player->kartspeed) + 1) * baseNudge;
|
||||||
|
|
||||||
|
maxNudge = max(distToPredict - predict->radius, predict->radius);
|
||||||
|
if (nudgeDist > maxNudge)
|
||||||
|
{
|
||||||
|
nudgeDist = maxNudge;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avgDist <= nudgeDist)
|
||||||
|
{
|
||||||
|
predict->x = avgX;
|
||||||
|
predict->y = avgY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Point towards
|
||||||
|
nudgeDir = R_PointToAngle2(
|
||||||
|
predict->x, predict->y,
|
||||||
|
avgX, avgY
|
||||||
|
);
|
||||||
|
|
||||||
|
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||||
|
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||||
|
|
||||||
|
//distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -252,6 +252,7 @@ void K_RegisterKartStuff(void)
|
||||||
CV_RegisterVar(&cv_kartdebugdistribution);
|
CV_RegisterVar(&cv_kartdebugdistribution);
|
||||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||||
CV_RegisterVar(&cv_kartdebugwaypoints);
|
CV_RegisterVar(&cv_kartdebugwaypoints);
|
||||||
|
CV_RegisterVar(&cv_kartdebugbotpredict);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||||
CV_RegisterVar(&cv_kartdebugnodes);
|
CV_RegisterVar(&cv_kartdebugnodes);
|
||||||
|
|
@ -6938,11 +6939,11 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INT32 K_GetKartRingPower(player_t *player)
|
INT32 K_GetKartRingPower(player_t *player, boolean boosted)
|
||||||
{
|
{
|
||||||
INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2;
|
INT32 ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) / 2;
|
||||||
|
|
||||||
if (K_PlayerUsesBotMovement(player))
|
if (boosted == true && K_PlayerUsesBotMovement(player))
|
||||||
{
|
{
|
||||||
// Double for Lv. 9
|
// Double for Lv. 9
|
||||||
ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY;
|
ringPower += (player->botvars.difficulty * ringPower) / MAXBOTDIFFICULTY;
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ void K_UpdateHnextList(player_t *player, boolean clean);
|
||||||
void K_DropHnextList(player_t *player, boolean keepshields);
|
void K_DropHnextList(player_t *player, boolean keepshields);
|
||||||
void K_RepairOrbitChain(mobj_t *orbit);
|
void K_RepairOrbitChain(mobj_t *orbit);
|
||||||
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
|
player_t *K_FindJawzTarget(mobj_t *actor, player_t *source);
|
||||||
INT32 K_GetKartRingPower(player_t *player);
|
INT32 K_GetKartRingPower(player_t *player, boolean boosted);
|
||||||
void K_UpdateDistanceFromFinishLine(player_t *const player);
|
void K_UpdateDistanceFromFinishLine(player_t *const player);
|
||||||
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
|
||||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
|
||||||
|
|
|
||||||
|
|
@ -535,9 +535,9 @@ static void K_DebugWaypointsSpawnLine(waypoint_t *const waypoint1, waypoint_t *c
|
||||||
{
|
{
|
||||||
spawnedmobj = P_SpawnMobj(x, y, z, MT_SPARK);
|
spawnedmobj = P_SpawnMobj(x, y, z, MT_SPARK);
|
||||||
P_SetMobjState(spawnedmobj, S_THOK);
|
P_SetMobjState(spawnedmobj, S_THOK);
|
||||||
spawnedmobj->state->nextstate = S_NULL;
|
spawnedmobj->tics = 1;
|
||||||
spawnedmobj->state->tics = 1;
|
spawnedmobj->frame &= ~FF_TRANSMASK;
|
||||||
spawnedmobj->frame = spawnedmobj->frame & ~FF_TRANSMASK;
|
spawnedmobj->frame |= FF_FULLBRIGHT;
|
||||||
spawnedmobj->color = linkcolour;
|
spawnedmobj->color = linkcolour;
|
||||||
spawnedmobj->scale = FixedMul(spawnedmobj->scale, FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT)));
|
spawnedmobj->scale = FixedMul(spawnedmobj->scale, FixedMul(FRACUNIT/4, FixedDiv((15 - ((leveltime + n) % 16))*FRACUNIT, 15*FRACUNIT)));
|
||||||
}
|
}
|
||||||
|
|
@ -582,9 +582,9 @@ static void K_DebugWaypointDrawRadius(waypoint_t *const waypoint)
|
||||||
|
|
||||||
radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK);
|
radiusOrb = P_SpawnMobj(spawnX, spawnY, spawnZ, MT_SPARK);
|
||||||
P_SetMobjState(radiusOrb, S_THOK);
|
P_SetMobjState(radiusOrb, S_THOK);
|
||||||
radiusOrb->state->nextstate = S_NULL;
|
radiusOrb->tics = 1;
|
||||||
radiusOrb->state->tics = 1;
|
radiusOrb->frame &= ~FF_TRANSMASK;
|
||||||
radiusOrb->frame = radiusOrb->frame & ~FF_TRANSMASK;
|
radiusOrb->frame |= FF_FULLBRIGHT;
|
||||||
radiusOrb->color = SKINCOLOR_PURPLE;
|
radiusOrb->color = SKINCOLOR_PURPLE;
|
||||||
radiusOrb->scale = radiusOrb->scale / 4;
|
radiusOrb->scale = radiusOrb->scale / 4;
|
||||||
}
|
}
|
||||||
|
|
@ -623,7 +623,7 @@ void K_DebugWaypointsVisualise(void)
|
||||||
P_SetMobjState(debugmobj, S_THOK);
|
P_SetMobjState(debugmobj, S_THOK);
|
||||||
|
|
||||||
debugmobj->frame &= ~FF_TRANSMASK;
|
debugmobj->frame &= ~FF_TRANSMASK;
|
||||||
debugmobj->frame |= FF_TRANS20;
|
debugmobj->frame |= FF_TRANS20|FF_FULLBRIGHT;
|
||||||
|
|
||||||
// There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections
|
// There's a waypoint setup for this mobj! So draw that it's a valid waypoint and draw lines to its connections
|
||||||
if (waypoint != NULL)
|
if (waypoint != NULL)
|
||||||
|
|
@ -683,8 +683,7 @@ void K_DebugWaypointsVisualise(void)
|
||||||
{
|
{
|
||||||
debugmobj->color = SKINCOLOR_RED;
|
debugmobj->color = SKINCOLOR_RED;
|
||||||
}
|
}
|
||||||
debugmobj->state->tics = 1;
|
debugmobj->tics = 1;
|
||||||
debugmobj->state->nextstate = S_NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4159,7 +4159,7 @@ void A_AttractChase(mobj_t *actor)
|
||||||
angle_t offset = FixedAngle(18<<FRACBITS);
|
angle_t offset = FixedAngle(18<<FRACBITS);
|
||||||
|
|
||||||
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
|
// Base add is 3 tics for 9,9, adds 1 tic for each point closer to the 1,1 end
|
||||||
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3;
|
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3;
|
||||||
S_StartSound(actor->target, sfx_s1b5);
|
S_StartSound(actor->target, sfx_s1b5);
|
||||||
|
|
||||||
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
|
sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS);
|
||||||
|
|
@ -4187,7 +4187,7 @@ void A_AttractChase(mobj_t *actor)
|
||||||
if (actor->extravalue1 >= 16)
|
if (actor->extravalue1 >= 16)
|
||||||
{
|
{
|
||||||
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
|
if (!P_GivePlayerRings(actor->target->player, 1)) // returns 0 if addition failed
|
||||||
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player)+3;
|
actor->target->player->kartstuff[k_ringboost] += K_GetKartRingPower(actor->target->player, true) + 3;
|
||||||
|
|
||||||
if (actor->cvmem) // caching
|
if (actor->cvmem) // caching
|
||||||
S_StartSound(actor->target, sfx_s1c5);
|
S_StartSound(actor->target, sfx_s1c5);
|
||||||
|
|
|
||||||
|
|
@ -11769,7 +11769,7 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean
|
||||||
// Steering amount
|
// Steering amount
|
||||||
if (mthing->args[1] == 0)
|
if (mthing->args[1] == 0)
|
||||||
{
|
{
|
||||||
mobj->extravalue2 = 2;
|
mobj->extravalue2 = 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue