mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-24 23:46:16 +00:00
Merge branch 'bot-thingies' into 'master'
Lots of bot changes See merge request KartKrew/Kart!1229
This commit is contained in:
commit
cf304a09d4
9 changed files with 724 additions and 410 deletions
149
src/k_bot.c
149
src/k_bot.c
|
|
@ -439,7 +439,7 @@ static line_t *K_FindBotController(mobj_t *mo)
|
|||
--------------------------------------------------*/
|
||||
static UINT32 K_BotRubberbandDistance(player_t *player)
|
||||
{
|
||||
const UINT32 spacing = FixedDiv(640 * FRACUNIT, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
|
||||
const UINT32 spacing = FixedDiv(640 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
|
||||
const UINT8 portpriority = player - players;
|
||||
UINT8 pos = 0;
|
||||
UINT8 i;
|
||||
|
|
@ -625,7 +625,7 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
static fixed_t K_GetBotWaypointRadius(waypoint_t *waypoint)
|
||||
static void K_GetBotWaypointRadius(waypoint_t *waypoint, fixed_t *smallestRadius, fixed_t *smallestScaled)
|
||||
|
||||
Calculates a new waypoint radius size to use, making it
|
||||
thinner depending on how harsh the turn is.
|
||||
|
|
@ -634,12 +634,12 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t
|
|||
waypoint - Waypoint to retrieve the radius of.
|
||||
|
||||
Return:-
|
||||
New radius value.
|
||||
N/A
|
||||
--------------------------------------------------*/
|
||||
static fixed_t K_GetBotWaypointRadius(waypoint_t *const waypoint)
|
||||
static void K_GetBotWaypointRadius(waypoint_t *const waypoint, fixed_t *smallestRadius, fixed_t *smallestScaled)
|
||||
{
|
||||
static const fixed_t maxReduce = FRACUNIT/32;
|
||||
static const angle_t maxDelta = ANGLE_45;
|
||||
static const angle_t maxDelta = ANGLE_22h;
|
||||
|
||||
fixed_t radius = waypoint->mobj->radius;
|
||||
fixed_t reduce = FRACUNIT;
|
||||
|
|
@ -675,7 +675,37 @@ static fixed_t K_GetBotWaypointRadius(waypoint_t *const waypoint)
|
|||
reduce = FixedDiv(delta, maxDelta);
|
||||
reduce = FRACUNIT + FixedMul(reduce, maxReduce - FRACUNIT);
|
||||
|
||||
return FixedMul(radius, reduce);
|
||||
*smallestRadius = min(*smallestRadius, radius);
|
||||
*smallestScaled = min(*smallestScaled, FixedMul(radius, reduce));
|
||||
}
|
||||
|
||||
static fixed_t K_ScaleWPDistWithSlope(fixed_t disttonext, angle_t angletonext, const pslope_t *slope, SINT8 flip)
|
||||
{
|
||||
if (slope == NULL)
|
||||
{
|
||||
return disttonext;
|
||||
}
|
||||
|
||||
if ((slope->flags & SL_NOPHYSICS) == 0 && abs(slope->zdelta) >= FRACUNIT/21)
|
||||
{
|
||||
// Displace the prediction to go with the slope physics.
|
||||
fixed_t slopeMul = FRACUNIT;
|
||||
angle_t angle = angletonext - slope->xydirection;
|
||||
|
||||
if (flip * slope->zdelta < 0)
|
||||
{
|
||||
angle ^= ANGLE_180;
|
||||
}
|
||||
|
||||
// Going uphill: 0
|
||||
// Going downhill: FRACUNIT*2
|
||||
slopeMul = FRACUNIT + FINECOSINE(angle >> ANGLETOFINESHIFT);
|
||||
|
||||
// Range: 0.25 to 1.75
|
||||
return FixedMul(disttonext, (FRACUNIT >> 2) + ((slopeMul * 3) >> 2));
|
||||
}
|
||||
|
||||
return disttonext;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -701,17 +731,21 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
const tic_t futuresight = (TICRATE * KART_FULLTURN) / max(1, handling); // How far ahead into the future to try and predict
|
||||
const fixed_t speed = K_BotSpeedScaled(player, P_AproxDistance(player->mo->momx, player->mo->momy));
|
||||
|
||||
const INT32 startDist = (DEFAULT_WAYPOINT_RADIUS * 2 * mapobjectscale) / FRACUNIT;
|
||||
const INT32 maxDist = startDist * 4; // This function gets very laggy when it goes far distances, and going too far isn't very helpful anyway.
|
||||
const INT32 startDist = 0; //(DEFAULT_WAYPOINT_RADIUS * mapobjectscale) / FRACUNIT;
|
||||
const INT32 maxDist = (DEFAULT_WAYPOINT_RADIUS * 3 * mapobjectscale) / FRACUNIT; // This function gets very laggy when it goes far distances, and going too far isn't very helpful anyway.
|
||||
const INT32 distance = min(((speed / FRACUNIT) * (INT32)futuresight) + startDist, maxDist);
|
||||
|
||||
// Halves radius when encountering a wall on your way to your destination.
|
||||
fixed_t radreduce = FRACUNIT;
|
||||
fixed_t radReduce = FRACUNIT;
|
||||
|
||||
fixed_t radius = INT32_MAX;
|
||||
fixed_t radiusScaled = INT32_MAX;
|
||||
|
||||
INT32 distanceleft = distance;
|
||||
fixed_t smallestradius = INT32_MAX;
|
||||
angle_t angletonext = ANGLE_MAX;
|
||||
INT32 disttonext = INT32_MAX;
|
||||
INT32 distscaled = INT32_MAX;
|
||||
pslope_t *nextslope = player->mo->standingslope;
|
||||
|
||||
waypoint_t *wp = player->nextwaypoint;
|
||||
mobj_t *prevwpmobj = player->mo;
|
||||
|
|
@ -721,15 +755,25 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
boolean pathfindsuccess = false;
|
||||
path_t pathtofinish = {0};
|
||||
|
||||
botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
botprediction_t *predict = NULL;
|
||||
size_t i;
|
||||
|
||||
if (wp == NULL || P_MobjWasRemoved(wp->mobj) == true)
|
||||
{
|
||||
// Can't do any of this if we don't have a waypoint.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL);
|
||||
|
||||
// Init defaults in case of pathfind failure
|
||||
angletonext = R_PointToAngle2(prevwpmobj->x, prevwpmobj->y, wp->mobj->x, wp->mobj->y);
|
||||
disttonext = P_AproxDistance(prevwpmobj->x - wp->mobj->x, prevwpmobj->y - wp->mobj->y) / FRACUNIT;
|
||||
disttonext = P_AproxDistance(prevwpmobj->x - wp->mobj->x, prevwpmobj->y - wp->mobj->y);
|
||||
nextslope = wp->mobj->standingslope;
|
||||
distscaled = K_ScaleWPDistWithSlope(disttonext, angletonext, nextslope, P_MobjFlip(wp->mobj)) / FRACUNIT;
|
||||
|
||||
pathfindsuccess = K_PathfindThruCircuit(
|
||||
player->nextwaypoint, (unsigned)distanceleft,
|
||||
wp, (unsigned)distanceleft,
|
||||
&pathtofinish,
|
||||
useshortcuts, huntbackwards
|
||||
);
|
||||
|
|
@ -739,8 +783,6 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
{
|
||||
for (i = 0; i < pathtofinish.numnodes; i++)
|
||||
{
|
||||
fixed_t radius = 0;
|
||||
|
||||
wp = (waypoint_t *)pathtofinish.array[i].nodedata;
|
||||
|
||||
if (i == 0)
|
||||
|
|
@ -753,22 +795,19 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
}
|
||||
|
||||
angletonext = R_PointToAngle2(prevwpmobj->x, prevwpmobj->y, wp->mobj->x, wp->mobj->y);
|
||||
disttonext = P_AproxDistance(prevwpmobj->x - wp->mobj->x, prevwpmobj->y - wp->mobj->y) / FRACUNIT;
|
||||
disttonext = P_AproxDistance(prevwpmobj->x - wp->mobj->x, prevwpmobj->y - wp->mobj->y);
|
||||
nextslope = wp->mobj->standingslope;
|
||||
distscaled = K_ScaleWPDistWithSlope(disttonext, angletonext, nextslope, P_MobjFlip(wp->mobj)) / FRACUNIT;
|
||||
|
||||
if (P_TraceBotTraversal(player->mo, wp->mobj) == false)
|
||||
{
|
||||
// If we can't get a direct path to this waypoint, predict less.
|
||||
distanceleft /= 2;
|
||||
radreduce = FRACUNIT >> 1;
|
||||
// If we can't get a direct path to this waypoint, reduce our prediction drastically.
|
||||
distscaled *= 4;
|
||||
radReduce = FRACUNIT >> 1;
|
||||
}
|
||||
|
||||
radius = K_GetBotWaypointRadius(wp);
|
||||
if (radius < smallestradius)
|
||||
{
|
||||
smallestradius = radius;
|
||||
}
|
||||
|
||||
distanceleft -= disttonext;
|
||||
K_GetBotWaypointRadius(wp, &radius, &radiusScaled);
|
||||
distanceleft -= distscaled;
|
||||
|
||||
if (distanceleft <= 0)
|
||||
{
|
||||
|
|
@ -784,7 +823,9 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
// and use the smallest radius of all of the waypoints in the chain!
|
||||
predict->x = wp->mobj->x;
|
||||
predict->y = wp->mobj->y;
|
||||
predict->radius = FixedMul(smallestradius, radreduce);
|
||||
|
||||
predict->baseRadius = radius;
|
||||
predict->radius = FixedMul(radiusScaled, radReduce);
|
||||
|
||||
// Set the prediction coordinates between the 2 waypoints if there's still distance left.
|
||||
if (distanceleft > 0)
|
||||
|
|
@ -794,25 +835,6 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
|
|||
predict->y += P_ReturnThrustY(NULL, angletonext, min(disttonext, distanceleft) * FRACUNIT);
|
||||
}
|
||||
|
||||
if (player->mo->standingslope != NULL)
|
||||
{
|
||||
const pslope_t *slope = player->mo->standingslope;
|
||||
|
||||
if (!(slope->flags & SL_NOPHYSICS) && abs(slope->zdelta) >= FRACUNIT/21)
|
||||
{
|
||||
// Displace the prediction to go against the slope physics.
|
||||
angle_t angle = slope->xydirection;
|
||||
|
||||
if (P_MobjFlip(player->mo) * slope->zdelta < 0)
|
||||
{
|
||||
angle ^= ANGLE_180;
|
||||
}
|
||||
|
||||
predict->x -= P_ReturnThrustX(NULL, angle, startDist * abs(slope->zdelta));
|
||||
predict->y -= P_ReturnThrustY(NULL, angle, startDist * abs(slope->zdelta));
|
||||
}
|
||||
}
|
||||
|
||||
ps_bots[player - players].prediction += I_GetPreciseTime() - time;
|
||||
return predict;
|
||||
}
|
||||
|
|
@ -1109,7 +1131,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
|
|||
anglediff = abs(anglediff);
|
||||
turnamt = KART_FULLTURN * turnsign;
|
||||
|
||||
if (anglediff > ANGLE_90)
|
||||
if (anglediff > ANGLE_67h)
|
||||
{
|
||||
// Wrong way!
|
||||
cmd->forwardmove = -MAXPLMOVE;
|
||||
|
|
@ -1502,18 +1524,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
if (predict == NULL)
|
||||
{
|
||||
// Create a prediction.
|
||||
if (player->nextwaypoint != NULL
|
||||
&& player->nextwaypoint->mobj != NULL
|
||||
&& !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
{
|
||||
predict = K_CreateBotPrediction(player);
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
}
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
turnamt = K_HandleBotTrack(player, cmd, predict, destangle);
|
||||
}
|
||||
cmd->buttons &= ~(BT_ACCELERATE|BT_BRAKE);
|
||||
|
|
@ -1539,18 +1556,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
if (predict == NULL)
|
||||
{
|
||||
// Create a prediction.
|
||||
if (player->nextwaypoint != NULL
|
||||
&& player->nextwaypoint->mobj != NULL
|
||||
&& !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
{
|
||||
predict = K_CreateBotPrediction(player);
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
}
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
turnamt = K_HandleBotTrack(player, cmd, predict, destangle);
|
||||
}
|
||||
}
|
||||
|
|
@ -1561,18 +1573,13 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
|
|||
if (predict == NULL)
|
||||
{
|
||||
// Create a prediction.
|
||||
if (player->nextwaypoint != NULL
|
||||
&& player->nextwaypoint->mobj != NULL
|
||||
&& !P_MobjWasRemoved(player->nextwaypoint->mobj))
|
||||
{
|
||||
predict = K_CreateBotPrediction(player);
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
}
|
||||
predict = K_CreateBotPrediction(player);
|
||||
}
|
||||
|
||||
if (predict != NULL)
|
||||
{
|
||||
K_NudgePredictionTowardsObjects(predict, player);
|
||||
destangle = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
turnamt = K_HandleBotTrack(player, cmd, predict, destangle);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
// Point for bots to aim for
|
||||
struct botprediction_t {
|
||||
fixed_t x, y;
|
||||
fixed_t radius;
|
||||
fixed_t radius, baseRadius;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -142,16 +142,33 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
|
|||
Return:-
|
||||
true if avoiding this sector special, false otherwise.
|
||||
--------------------------------------------------*/
|
||||
static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
|
||||
static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec, const boolean flip)
|
||||
{
|
||||
if (sec->damagetype != SD_NONE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
terrain_t *terrain = K_GetTerrainForFlatNum(flip ? sec->ceilingpic : sec->floorpic);
|
||||
|
||||
if (sec->offroad > 0)
|
||||
if (terrain != NULL)
|
||||
{
|
||||
return !K_BotCanTakeCut(player);
|
||||
if (terrain->damageType != SD_NONE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (terrain->offroad > 0)
|
||||
{
|
||||
return !K_BotCanTakeCut(player);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sec->damagetype != SD_NONE)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sec->offroad > 0)
|
||||
{
|
||||
return !K_BotCanTakeCut(player);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -200,7 +217,7 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t
|
|||
if (!(rover->fofflags & FOF_BLOCKPLAYER))
|
||||
{
|
||||
if ((top >= player->mo->z) && (bottom <= player->mo->z + player->mo->height)
|
||||
&& K_BotHatesThisSectorsSpecial(player, rover->master->frontsector))
|
||||
&& K_BotHatesThisSectorsSpecial(player, rover->master->frontsector, flip))
|
||||
{
|
||||
// Bad intangible sector at our height, so we DEFINITELY want to avoid
|
||||
return true;
|
||||
|
|
@ -236,7 +253,7 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t
|
|||
return false;
|
||||
}
|
||||
|
||||
return K_BotHatesThisSectorsSpecial(player, bestsector);
|
||||
return K_BotHatesThisSectorsSpecial(player, bestsector, flip);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
@ -254,6 +271,8 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t
|
|||
--------------------------------------------------*/
|
||||
static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||
{
|
||||
fixed_t x, y;
|
||||
angle_t a, dir;
|
||||
UINT8 i;
|
||||
|
||||
I_Assert(side <= 1);
|
||||
|
|
@ -263,10 +282,21 @@ static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
return;
|
||||
}
|
||||
|
||||
x = thing->x;
|
||||
y = thing->y;
|
||||
a = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, x, y);
|
||||
|
||||
dir = a + (side ? -ANGLE_90 : ANGLE_90);
|
||||
x += FixedMul(thing->radius, FINECOSINE(dir >> ANGLETOFINESHIFT));
|
||||
y += FixedMul(thing->radius, FINESINE(dir >> ANGLETOFINESHIFT));
|
||||
|
||||
x /= mapobjectscale;
|
||||
y /= mapobjectscale;
|
||||
|
||||
for (i = 0; i < weight; i++)
|
||||
{
|
||||
globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
|
||||
globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
|
||||
globalsmuggle.gotoAvgX[side] += x;
|
||||
globalsmuggle.gotoAvgY[side] += y;
|
||||
globalsmuggle.gotoObjs[side]++;
|
||||
}
|
||||
}
|
||||
|
|
@ -286,6 +316,8 @@ static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
--------------------------------------------------*/
|
||||
static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
||||
{
|
||||
fixed_t x, y;
|
||||
angle_t a, dir;
|
||||
UINT8 i;
|
||||
|
||||
I_Assert(side <= 1);
|
||||
|
|
@ -295,11 +327,22 @@ static void K_AddDodgeObject(mobj_t *thing, UINT8 side, UINT8 weight)
|
|||
return;
|
||||
}
|
||||
|
||||
x = thing->x;
|
||||
y = thing->y;
|
||||
a = R_PointToAngle2(globalsmuggle.botmo->x, globalsmuggle.botmo->y, x, y);
|
||||
|
||||
dir = a + (side ? -ANGLE_90 : ANGLE_90);
|
||||
x += FixedMul(thing->radius, FINECOSINE(dir >> ANGLETOFINESHIFT));
|
||||
y += FixedMul(thing->radius, FINESINE(dir >> ANGLETOFINESHIFT));
|
||||
|
||||
x /= mapobjectscale;
|
||||
y /= mapobjectscale;
|
||||
|
||||
for (i = 0; i < weight; i++)
|
||||
{
|
||||
globalsmuggle.gotoAvgX[side] += thing->x / mapobjectscale;
|
||||
globalsmuggle.gotoAvgY[side] += thing->y / mapobjectscale;
|
||||
globalsmuggle.gotoObjs[side]++;
|
||||
globalsmuggle.avoidAvgX[side] += x;
|
||||
globalsmuggle.avoidAvgY[side] += y;
|
||||
globalsmuggle.avoidObjs[side]++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +392,7 @@ static boolean K_PlayerAttackSteer(mobj_t *thing, UINT8 side, UINT8 weight, bool
|
|||
--------------------------------------------------*/
|
||||
static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
||||
{
|
||||
INT16 anglediff;
|
||||
INT16 angledelta, anglediff;
|
||||
fixed_t fulldist;
|
||||
angle_t destangle, angle, predictangle;
|
||||
UINT8 side = 0;
|
||||
|
|
@ -387,15 +430,15 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
|
|||
|
||||
if (angle < ANGLE_180)
|
||||
{
|
||||
anglediff = AngleFixed(angle)>>FRACBITS;
|
||||
angledelta = AngleFixed(angle)>>FRACBITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
anglediff = 360-(AngleFixed(angle)>>FRACBITS);
|
||||
angledelta = 360-(AngleFixed(angle)>>FRACBITS);
|
||||
side = 1;
|
||||
}
|
||||
|
||||
anglediff = abs(anglediff);
|
||||
anglediff = abs(angledelta);
|
||||
|
||||
switch (thing->type)
|
||||
{
|
||||
|
|
@ -621,23 +664,42 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
INT32 xl, xh, yl, yh, bx, by;
|
||||
|
||||
fixed_t distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
fixed_t distToPredict = 0;
|
||||
fixed_t radToPredict = 0;
|
||||
angle_t angleToPredict = 0;
|
||||
|
||||
fixed_t avgX = 0, avgY = 0;
|
||||
fixed_t avgDist = 0;
|
||||
|
||||
const fixed_t baseNudge = predict->radius;
|
||||
fixed_t maxNudge = distToPredict;
|
||||
fixed_t baseNudge = 0;
|
||||
fixed_t maxNudge = 0;
|
||||
fixed_t nudgeDist = 0;
|
||||
angle_t nudgeDir = 0;
|
||||
|
||||
SINT8 gotoSide = -1;
|
||||
UINT8 i;
|
||||
|
||||
if (predict == NULL)
|
||||
{
|
||||
ps_bots[player - players].nudge += I_GetPreciseTime() - time;
|
||||
return;
|
||||
}
|
||||
|
||||
distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
radToPredict = distToPredict >> 1;
|
||||
angleToPredict = R_PointToAngle2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
||||
globalsmuggle.distancetocheck = distToPredict;
|
||||
|
||||
baseNudge = predict->baseRadius >> 3;
|
||||
maxNudge = predict->baseRadius - baseNudge;
|
||||
|
||||
globalsmuggle.botmo = player->mo;
|
||||
globalsmuggle.predict = predict;
|
||||
|
||||
globalsmuggle.distancetocheck = distToPredict;
|
||||
// silly variable reuse
|
||||
avgX = globalsmuggle.botmo->x + FixedMul(radToPredict, FINECOSINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
avgY = globalsmuggle.botmo->y + FixedMul(radToPredict, FINESINE(angleToPredict >> ANGLETOFINESHIFT));
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
|
|
@ -648,10 +710,10 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
globalsmuggle.avoidObjs[i] = 0;
|
||||
}
|
||||
|
||||
xl = (unsigned)(globalsmuggle.botmo->x - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(globalsmuggle.botmo->x + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(globalsmuggle.botmo->y - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(globalsmuggle.botmo->y + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
xl = (unsigned)(avgX - (distToPredict + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
xh = (unsigned)(avgX + (distToPredict + MAXRADIUS) - bmaporgx)>>MAPBLOCKSHIFT;
|
||||
yl = (unsigned)(avgY - (distToPredict + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
yh = (unsigned)(avgY + (distToPredict + MAXRADIUS) - bmaporgy)>>MAPBLOCKSHIFT;
|
||||
|
||||
BMBOUNDFIX(xl, xh, yl, yh);
|
||||
|
||||
|
|
@ -685,8 +747,6 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
// 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;
|
||||
|
|
@ -700,6 +760,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||
predict->radius = max(predict->radius - nudgeDist, baseNudge);
|
||||
|
||||
distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
|
||||
|
|
@ -749,8 +810,6 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
// 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;
|
||||
|
|
@ -760,6 +819,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
{
|
||||
predict->x = avgX;
|
||||
predict->y = avgY;
|
||||
predict->radius = baseNudge;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -771,6 +831,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
|
|||
|
||||
predict->x += FixedMul(nudgeDist, FINECOSINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||
predict->y += FixedMul(nudgeDist, FINESINE(nudgeDir >> ANGLETOFINESHIFT));
|
||||
predict->radius = max(predict->radius - nudgeDist, baseNudge);
|
||||
|
||||
//distToPredict = R_PointToDist2(player->mo->x, player->mo->y, predict->x, predict->y);
|
||||
}
|
||||
|
|
|
|||
14
src/k_kart.c
14
src/k_kart.c
|
|
@ -8386,7 +8386,12 @@ static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
|
|||
boolean updaterespawn = false;
|
||||
|
||||
// Our current waypoint.
|
||||
player->currentwaypoint = bestwaypoint = waypoint;
|
||||
bestwaypoint = waypoint;
|
||||
|
||||
if (bestwaypoint != NULL)
|
||||
{
|
||||
player->currentwaypoint = bestwaypoint;
|
||||
}
|
||||
|
||||
// check the waypoint's location in relation to the player
|
||||
// If it's generally in front, it's fine, otherwise, use the best next/previous waypoint.
|
||||
|
|
@ -10258,22 +10263,23 @@ static void K_AirFailsafe(player_t *player)
|
|||
//
|
||||
fixed_t K_PlayerBaseFriction(player_t *player, fixed_t original)
|
||||
{
|
||||
const fixed_t factor = FixedDiv(FRACUNIT - original, FRACUNIT - ORIG_FRICTION);
|
||||
fixed_t frict = original;
|
||||
|
||||
if (K_PodiumSequence() == true)
|
||||
{
|
||||
frict -= FRACUNIT >> 4;
|
||||
frict -= FixedMul(FRACUNIT >> 4, factor);
|
||||
}
|
||||
else if (K_PlayerUsesBotMovement(player) == true)
|
||||
{
|
||||
// A bit extra friction to help them without drifting.
|
||||
// Remove this line once they can drift.
|
||||
frict -= FRACUNIT >> 5;
|
||||
frict -= FixedMul(FRACUNIT >> 5, factor);
|
||||
|
||||
// Bots gain more traction as they rubberband.
|
||||
if (player->botvars.rubberband > FRACUNIT)
|
||||
{
|
||||
static const fixed_t extraFriction = FRACUNIT >> 5;
|
||||
const fixed_t extraFriction = FixedMul(FRACUNIT >> 5, factor);
|
||||
const fixed_t mul = player->botvars.rubberband - FRACUNIT;
|
||||
frict -= FixedMul(extraFriction, mul);
|
||||
}
|
||||
|
|
|
|||
78
src/p_map.c
78
src/p_map.c
|
|
@ -1671,6 +1671,8 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
|
|||
// Adjusts tm.floorz and tm.ceilingz as lines are contacted - FOR CAMERA ONLY
|
||||
static BlockItReturn_t PIT_CheckCameraLine(line_t *ld)
|
||||
{
|
||||
opening_t open = {0};
|
||||
|
||||
if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID))
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
|
|
@ -1704,25 +1706,25 @@ static BlockItReturn_t PIT_CheckCameraLine(line_t *ld)
|
|||
}
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_CameraLineOpening(ld);
|
||||
P_CameraLineOpening(ld, &open);
|
||||
|
||||
// adjust floor / ceiling heights
|
||||
if (opentop < tm.ceilingz)
|
||||
if (open.ceiling < tm.ceilingz)
|
||||
{
|
||||
tm.ceilingz = opentop;
|
||||
tm.ceilingz = open.ceiling;
|
||||
tm.ceilingline = ld;
|
||||
}
|
||||
|
||||
if (openbottom > tm.floorz)
|
||||
if (open.floor > tm.floorz)
|
||||
{
|
||||
tm.floorz = openbottom;
|
||||
tm.floorz = open.floor;
|
||||
}
|
||||
|
||||
if (highceiling > tm.drpoffceilz)
|
||||
tm.drpoffceilz = highceiling;
|
||||
if (open.highceiling > tm.drpoffceilz)
|
||||
tm.drpoffceilz = open.highceiling;
|
||||
|
||||
if (lowfloor < tm.dropoffz)
|
||||
tm.dropoffz = lowfloor;
|
||||
if (open.lowfloor < tm.dropoffz)
|
||||
tm.dropoffz = open.lowfloor;
|
||||
|
||||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
|
@ -1773,6 +1775,7 @@ boolean P_IsLineTripWire(const line_t *ld)
|
|||
static BlockItReturn_t PIT_CheckLine(line_t *ld)
|
||||
{
|
||||
const fixed_t thingtop = tm.thing->z + tm.thing->height;
|
||||
opening_t open = {0};
|
||||
|
||||
if (ld->polyobj && !(ld->polyobj->flags & POF_SOLID))
|
||||
return BMIT_CONTINUE;
|
||||
|
|
@ -1845,41 +1848,41 @@ static BlockItReturn_t PIT_CheckLine(line_t *ld)
|
|||
return BMIT_ABORT;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(ld, tm.thing);
|
||||
P_LineOpening(ld, tm.thing, &open);
|
||||
|
||||
// adjust floor / ceiling heights
|
||||
if (opentop < tm.ceilingz)
|
||||
if (open.ceiling < tm.ceilingz)
|
||||
{
|
||||
tm.ceilingz = opentop;
|
||||
tm.ceilingz = open.ceiling;
|
||||
tm.ceilingline = ld;
|
||||
tm.ceilingrover = openceilingrover;
|
||||
tm.ceilingslope = opentopslope;
|
||||
tm.ceilingpic = opentoppic;
|
||||
tm.ceilingstep = openceilingstep;
|
||||
tm.ceilingrover = open.ceilingrover;
|
||||
tm.ceilingslope = open.ceilingslope;
|
||||
tm.ceilingpic = open.ceilingpic;
|
||||
tm.ceilingstep = open.ceilingstep;
|
||||
if (thingtop == tm.thing->ceilingz)
|
||||
{
|
||||
tm.thing->ceilingdrop = openceilingdrop;
|
||||
tm.thing->ceilingdrop = open.ceilingdrop;
|
||||
}
|
||||
}
|
||||
|
||||
if (openbottom > tm.floorz)
|
||||
if (open.floor > tm.floorz)
|
||||
{
|
||||
tm.floorz = openbottom;
|
||||
tm.floorrover = openfloorrover;
|
||||
tm.floorslope = openbottomslope;
|
||||
tm.floorpic = openbottompic;
|
||||
tm.floorstep = openfloorstep;
|
||||
tm.floorz = open.floor;
|
||||
tm.floorrover = open.floorrover;
|
||||
tm.floorslope = open.floorslope;
|
||||
tm.floorpic = open.floorpic;
|
||||
tm.floorstep = open.floorstep;
|
||||
if (tm.thing->z == tm.thing->floorz)
|
||||
{
|
||||
tm.thing->floordrop = openfloordrop;
|
||||
tm.thing->floordrop = open.floordrop;
|
||||
}
|
||||
}
|
||||
|
||||
if (highceiling > tm.drpoffceilz)
|
||||
tm.drpoffceilz = highceiling;
|
||||
if (open.highceiling > tm.drpoffceilz)
|
||||
tm.drpoffceilz = open.highceiling;
|
||||
|
||||
if (lowfloor < tm.dropoffz)
|
||||
tm.dropoffz = lowfloor;
|
||||
if (open.lowfloor < tm.dropoffz)
|
||||
tm.dropoffz = open.lowfloor;
|
||||
|
||||
// we've crossed the line
|
||||
if (P_SpecialIsLinedefCrossType(ld))
|
||||
|
|
@ -3462,6 +3465,7 @@ static void P_HitBounceLine(line_t *ld)
|
|||
static boolean PTR_SlideCameraTraverse(intercept_t *in)
|
||||
{
|
||||
line_t *li;
|
||||
opening_t open = {0};
|
||||
|
||||
I_Assert(in->isaline);
|
||||
|
||||
|
|
@ -3476,15 +3480,15 @@ static boolean PTR_SlideCameraTraverse(intercept_t *in)
|
|||
}
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_CameraLineOpening(li);
|
||||
P_CameraLineOpening(li, &open);
|
||||
|
||||
if (openrange < mapcampointer->height)
|
||||
if (open.range < mapcampointer->height)
|
||||
goto isblocking; // doesn't fit
|
||||
|
||||
if (opentop - mapcampointer->z < mapcampointer->height)
|
||||
if (open.ceiling - mapcampointer->z < mapcampointer->height)
|
||||
goto isblocking; // mobj is too high
|
||||
|
||||
if (openbottom - mapcampointer->z > 0) // We don't want to make the camera step up.
|
||||
if (open.floor - mapcampointer->z > 0) // We don't want to make the camera step up.
|
||||
goto isblocking; // too big a step up
|
||||
|
||||
// this line doesn't block movement
|
||||
|
|
@ -3509,6 +3513,8 @@ isblocking:
|
|||
/*
|
||||
static boolean PTR_LineIsBlocking(line_t *li)
|
||||
{
|
||||
opening_t open = {0};
|
||||
|
||||
// one-sided linedefs are always solid to sliding movement.
|
||||
if (!li->backsector)
|
||||
return !P_PointOnLineSide(slidemo->x, slidemo->y, li);
|
||||
|
|
@ -3517,15 +3523,15 @@ static boolean PTR_LineIsBlocking(line_t *li)
|
|||
return true;
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
P_LineOpening(li, slidemo);
|
||||
P_LineOpening(li, slidemo, &open);
|
||||
|
||||
if (openrange < slidemo->height)
|
||||
if (open.range < slidemo->height)
|
||||
return true; // doesn't fit
|
||||
|
||||
if (opentop - slidemo->z < slidemo->height)
|
||||
if (open.ceiling - slidemo->z < slidemo->height)
|
||||
return true; // mobj is too high
|
||||
|
||||
if (openbottom - slidemo->z > P_GetThingStepUp(slidemo, slidemo->x, slidemo->y))
|
||||
if (open.floor - slidemo->z > P_GetThingStepUp(slidemo, slidemo->x, slidemo->y))
|
||||
return true; // too big a step up
|
||||
|
||||
return false;
|
||||
|
|
|
|||
615
src/p_maputl.c
615
src/p_maputl.c
|
|
@ -335,28 +335,24 @@ line_t * P_FindNearestLine
|
|||
// Sets opentop and openbottom to the window through a two sided line.
|
||||
// OPTIMIZE: keep this precalculated
|
||||
//
|
||||
fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
||||
pslope_t *opentopslope, *openbottomslope;
|
||||
ffloor_t *openfloorrover, *openceilingrover;
|
||||
fixed_t openceilingstep;
|
||||
fixed_t openceilingdrop;
|
||||
fixed_t openfloorstep;
|
||||
fixed_t openfloordrop;
|
||||
INT32 opentoppic, openbottompic;
|
||||
|
||||
// P_CameraLineOpening
|
||||
// P_LineOpening, but for camera
|
||||
// Tails 09-29-2002
|
||||
void P_CameraLineOpening(line_t *linedef)
|
||||
void P_CameraLineOpening(line_t *linedef, opening_t *open)
|
||||
{
|
||||
sector_t *front;
|
||||
sector_t *back;
|
||||
fixed_t frontfloor, frontceiling, backfloor, backceiling;
|
||||
fixed_t thingtop;
|
||||
|
||||
open->ceiling = open->highceiling = INT32_MAX;
|
||||
open->floor = open->lowfloor = INT32_MIN;
|
||||
open->range = 0;
|
||||
|
||||
if (linedef->sidenum[1] == 0xffff)
|
||||
{
|
||||
// single sided line
|
||||
openrange = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -368,14 +364,14 @@ void P_CameraLineOpening(line_t *linedef)
|
|||
if (front->camsec >= 0)
|
||||
{
|
||||
// SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
|
||||
frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], camera[0].x, camera[0].y);
|
||||
frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], camera[0].x, camera[0].y);
|
||||
frontfloor = P_GetSectorFloorZAt (§ors[front->camsec], mapcampointer->x, mapcampointer->y);
|
||||
frontceiling = P_GetSectorCeilingZAt(§ors[front->camsec], mapcampointer->x, mapcampointer->y);
|
||||
}
|
||||
else if (front->heightsec >= 0)
|
||||
{
|
||||
// SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
|
||||
frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], camera[0].x, camera[0].y);
|
||||
frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], camera[0].x, camera[0].y);
|
||||
frontfloor = P_GetSectorFloorZAt (§ors[front->heightsec], mapcampointer->x, mapcampointer->x);
|
||||
frontceiling = P_GetSectorCeilingZAt(§ors[front->heightsec], mapcampointer->x, mapcampointer->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -386,103 +382,101 @@ void P_CameraLineOpening(line_t *linedef)
|
|||
if (back->camsec >= 0)
|
||||
{
|
||||
// SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
|
||||
backfloor = P_GetSectorFloorZAt (§ors[back->camsec], camera[0].x, camera[0].y);
|
||||
backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], camera[0].x, camera[0].y);
|
||||
backfloor = P_GetSectorFloorZAt (§ors[back->camsec], mapcampointer->x, mapcampointer->y);
|
||||
backceiling = P_GetSectorCeilingZAt(§ors[back->camsec], mapcampointer->x, mapcampointer->y);
|
||||
}
|
||||
else if (back->heightsec >= 0)
|
||||
{
|
||||
// SRB2CBTODO: ESLOPE (sectors[back->heightsec].f_slope)
|
||||
backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], camera[0].x, camera[0].y);
|
||||
backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], camera[0].x, camera[0].y);
|
||||
backfloor = P_GetSectorFloorZAt (§ors[back->heightsec], mapcampointer->x, mapcampointer->y);
|
||||
backceiling = P_GetSectorCeilingZAt(§ors[back->heightsec], mapcampointer->x, mapcampointer->y);
|
||||
}
|
||||
else
|
||||
{
|
||||
backfloor = P_CameraGetFloorZ(mapcampointer, back, tm.x, tm.y, linedef);
|
||||
backfloor = P_CameraGetFloorZ (mapcampointer, back, tm.x, tm.y, linedef);
|
||||
backceiling = P_CameraGetCeilingZ(mapcampointer, back, tm.x, tm.y, linedef);
|
||||
}
|
||||
|
||||
thingtop = mapcampointer->z + mapcampointer->height;
|
||||
|
||||
if (frontceiling < backceiling)
|
||||
{
|
||||
fixed_t thingtop = mapcampointer->z + mapcampointer->height;
|
||||
|
||||
if (frontceiling < backceiling)
|
||||
{
|
||||
opentop = frontceiling;
|
||||
highceiling = backceiling;
|
||||
}
|
||||
else
|
||||
{
|
||||
opentop = backceiling;
|
||||
highceiling = frontceiling;
|
||||
}
|
||||
|
||||
if (frontfloor > backfloor)
|
||||
{
|
||||
openbottom = frontfloor;
|
||||
lowfloor = backfloor;
|
||||
}
|
||||
else
|
||||
{
|
||||
openbottom = backfloor;
|
||||
lowfloor = frontfloor;
|
||||
}
|
||||
|
||||
// Check for fake floors in the sector.
|
||||
if (front->ffloors || back->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t delta1, delta2;
|
||||
|
||||
// Check for frontsector's fake floors
|
||||
if (front->ffloors)
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
if (bottomheight < opentop && delta1 >= delta2)
|
||||
opentop = bottomheight;
|
||||
else if (bottomheight < highceiling && delta1 >= delta2)
|
||||
highceiling = bottomheight;
|
||||
|
||||
if (topheight > openbottom && delta1 < delta2)
|
||||
openbottom = topheight;
|
||||
else if (topheight > lowfloor && delta1 < delta2)
|
||||
lowfloor = topheight;
|
||||
}
|
||||
|
||||
// Check for backsectors fake floors
|
||||
if (back->ffloors)
|
||||
for (rover = back->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
if (bottomheight < opentop && delta1 >= delta2)
|
||||
opentop = bottomheight;
|
||||
else if (bottomheight < highceiling && delta1 >= delta2)
|
||||
highceiling = bottomheight;
|
||||
|
||||
if (topheight > openbottom && delta1 < delta2)
|
||||
openbottom = topheight;
|
||||
else if (topheight > lowfloor && delta1 < delta2)
|
||||
lowfloor = topheight;
|
||||
}
|
||||
}
|
||||
openrange = opentop - openbottom;
|
||||
return;
|
||||
open->ceiling = frontceiling;
|
||||
open->highceiling = backceiling;
|
||||
}
|
||||
else
|
||||
{
|
||||
open->ceiling = backceiling;
|
||||
open->highceiling = frontceiling;
|
||||
}
|
||||
|
||||
if (frontfloor > backfloor)
|
||||
{
|
||||
open->floor = frontfloor;
|
||||
open->lowfloor = backfloor;
|
||||
}
|
||||
else
|
||||
{
|
||||
open->floor = backfloor;
|
||||
open->lowfloor = frontfloor;
|
||||
}
|
||||
|
||||
// Check for fake floors in the sector.
|
||||
if (front->ffloors || back->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t delta1, delta2;
|
||||
|
||||
// Check for frontsector's fake floors
|
||||
if (front->ffloors)
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
if (bottomheight < open->ceiling && delta1 >= delta2)
|
||||
open->ceiling = bottomheight;
|
||||
else if (bottomheight < open->highceiling && delta1 >= delta2)
|
||||
open->highceiling = bottomheight;
|
||||
|
||||
if (topheight > open->floor && delta1 < delta2)
|
||||
open->floor = topheight;
|
||||
else if (topheight > open->lowfloor && delta1 < delta2)
|
||||
open->lowfloor = topheight;
|
||||
}
|
||||
|
||||
// Check for backsectors fake floors
|
||||
if (back->ffloors)
|
||||
for (rover = back->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
if (!(rover->fofflags & FOF_BLOCKOTHERS) || !(rover->fofflags & FOF_RENDERALL) || !(rover->fofflags & FOF_EXISTS) || (rover->master->frontsector->flags & MSF_NOCLIPCAMERA))
|
||||
continue;
|
||||
|
||||
topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
if (bottomheight < open->ceiling && delta1 >= delta2)
|
||||
open->ceiling = bottomheight;
|
||||
else if (bottomheight < open->highceiling && delta1 >= delta2)
|
||||
open->highceiling = bottomheight;
|
||||
|
||||
if (topheight > open->floor && delta1 < delta2)
|
||||
open->floor = topheight;
|
||||
else if (topheight > open->lowfloor && delta1 < delta2)
|
||||
open->lowfloor = topheight;
|
||||
}
|
||||
}
|
||||
|
||||
open->range = (open->ceiling - open->floor);
|
||||
}
|
||||
|
||||
boolean
|
||||
|
|
@ -592,7 +586,7 @@ static boolean P_MidtextureIsSolid(line_t *linedef, mobj_t *mobj)
|
|||
return ((linedef->flags & ML_MIDSOLID) == ML_MIDSOLID);
|
||||
}
|
||||
|
||||
void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
||||
void P_LineOpening(line_t *linedef, mobj_t *mobj, opening_t *open)
|
||||
{
|
||||
enum { FRONT, BACK };
|
||||
|
||||
|
|
@ -607,10 +601,19 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
int hi = 0;
|
||||
int lo = 0;
|
||||
|
||||
// set these defaults so that polyobjects don't interfere with collision above or below them
|
||||
open->ceiling = open->highceiling = INT32_MAX;
|
||||
open->floor = open->lowfloor = INT32_MIN;
|
||||
open->range = 0;
|
||||
open->ceilingslope = open->floorslope = NULL;
|
||||
open->ceilingrover = open->floorrover = NULL;
|
||||
open->ceilingpic = open->floorpic = -1;
|
||||
open->ceilingstep = open->floorstep = 0;
|
||||
open->ceilingdrop = open->floordrop = 0;
|
||||
|
||||
if (linedef->sidenum[1] == 0xffff)
|
||||
{
|
||||
// single sided line
|
||||
openrange = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -636,23 +639,9 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
thingtop = mobj->z + mobj->height;
|
||||
}
|
||||
|
||||
openfloorrover = openceilingrover = NULL;
|
||||
if (linedef->polyobj)
|
||||
if (!linedef->polyobj)
|
||||
{
|
||||
// set these defaults so that polyobjects don't interfere with collision above or below them
|
||||
opentop = INT32_MAX;
|
||||
openbottom = INT32_MIN;
|
||||
highceiling = INT32_MIN;
|
||||
lowfloor = INT32_MAX;
|
||||
opentopslope = openbottomslope = NULL;
|
||||
opentoppic = openbottompic = -1;
|
||||
openceilingstep = 0;
|
||||
openceilingdrop = 0;
|
||||
openfloorstep = 0;
|
||||
openfloordrop = 0;
|
||||
}
|
||||
else
|
||||
{ // Set open and high/low values here
|
||||
// Set open and high/low values here
|
||||
fixed_t height[2];
|
||||
const sector_t * sector[2] = { front, back };
|
||||
|
||||
|
|
@ -662,18 +651,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
hi = ( height[0] < height[1] );
|
||||
lo = ! hi;
|
||||
|
||||
opentop = height[lo];
|
||||
highceiling = height[hi];
|
||||
opentopslope = sector[lo]->c_slope;
|
||||
opentoppic = sector[lo]->ceilingpic;
|
||||
open->ceiling = height[lo];
|
||||
open->highceiling = height[hi];
|
||||
open->ceilingslope = sector[lo]->c_slope;
|
||||
open->ceilingpic = sector[lo]->ceilingpic;
|
||||
|
||||
if (mobj)
|
||||
{
|
||||
topedge[FRONT] = P_GetSectorCeilingZAt(front, cross.x, cross.y);
|
||||
topedge[BACK] = P_GetSectorCeilingZAt(back, cross.x, cross.y);
|
||||
|
||||
openceilingstep = ( thingtop - topedge[lo] );
|
||||
openceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
open->ceilingstep = ( thingtop - topedge[lo] );
|
||||
open->ceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
}
|
||||
|
||||
height[FRONT] = P_GetFloorZ(mobj, front, tm.x, tm.y, linedef);
|
||||
|
|
@ -682,18 +671,18 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
hi = ( height[0] < height[1] );
|
||||
lo = ! hi;
|
||||
|
||||
openbottom = height[hi];
|
||||
lowfloor = height[lo];
|
||||
openbottomslope = sector[hi]->f_slope;
|
||||
openbottompic = sector[hi]->floorpic;
|
||||
open->floor = height[hi];
|
||||
open->lowfloor = height[lo];
|
||||
open->floorslope = sector[hi]->f_slope;
|
||||
open->floorpic = sector[hi]->floorpic;
|
||||
|
||||
if (mobj)
|
||||
{
|
||||
botedge[FRONT] = P_GetSectorFloorZAt(front, cross.x, cross.y);
|
||||
botedge[BACK] = P_GetSectorFloorZAt(back, cross.x, cross.y);
|
||||
|
||||
openfloorstep = ( botedge[hi] - mobj->z );
|
||||
openfloordrop = ( botedge[hi] - botedge[lo] );
|
||||
open->floorstep = ( botedge[hi] - mobj->z );
|
||||
open->floordrop = ( botedge[hi] - botedge[lo] );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -715,25 +704,25 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (delta1 > delta2)
|
||||
{
|
||||
// Below
|
||||
if (opentop > texbottom)
|
||||
if (open->ceiling > texbottom)
|
||||
{
|
||||
topedge[lo] -= ( opentop - texbottom );
|
||||
topedge[lo] -= ( open->ceiling - texbottom );
|
||||
|
||||
opentop = texbottom;
|
||||
openceilingstep = ( thingtop - topedge[lo] );
|
||||
openceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
open->ceiling = texbottom;
|
||||
open->ceilingstep = ( thingtop - topedge[lo] );
|
||||
open->ceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Above
|
||||
if (openbottom < textop)
|
||||
if (open->floor < textop)
|
||||
{
|
||||
botedge[hi] += ( textop - openbottom );
|
||||
botedge[hi] += ( textop - open->floor );
|
||||
|
||||
openbottom = textop;
|
||||
openfloorstep = ( botedge[hi] - mobj->z );
|
||||
openfloordrop = ( botedge[hi] - botedge[lo] );
|
||||
open->floor = textop;
|
||||
open->floorstep = ( botedge[hi] - mobj->z );
|
||||
open->floordrop = ( botedge[hi] - botedge[lo] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -745,7 +734,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (linedef->polyobj->flags & POF_TESTHEIGHT)
|
||||
{
|
||||
const sector_t *polysec = linedef->backsector;
|
||||
fixed_t polytop, polybottom;
|
||||
fixed_t polytop, polybottom, polymid;
|
||||
fixed_t delta1, delta2;
|
||||
|
||||
if (linedef->polyobj->flags & POF_CLIPPLANES)
|
||||
|
|
@ -759,25 +748,68 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
polybottom = INT32_MIN;
|
||||
}
|
||||
|
||||
delta1 = abs(mobj->z - (polybottom + ((polytop - polybottom)/2)));
|
||||
delta2 = abs(thingtop - (polybottom + ((polytop - polybottom)/2)));
|
||||
switch (open->fofType)
|
||||
{
|
||||
case LO_FOF_FLOORS:
|
||||
{
|
||||
if (mobj->z >= polytop)
|
||||
{
|
||||
if (polytop > open->floor)
|
||||
{
|
||||
open->floor = polytop;
|
||||
}
|
||||
else if (polytop > open->lowfloor)
|
||||
{
|
||||
open->lowfloor = polytop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LO_FOF_CEILINGS:
|
||||
{
|
||||
if (thingtop <= polybottom)
|
||||
{
|
||||
if (polybottom < open->ceiling)
|
||||
{
|
||||
open->ceiling = polybottom;
|
||||
}
|
||||
else if (polybottom < open->highceiling)
|
||||
{
|
||||
open->highceiling = polybottom;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
polymid = polybottom + (polytop - polybottom) / 2;
|
||||
delta1 = abs(mobj->z - polymid);
|
||||
delta2 = abs(thingtop - polymid);
|
||||
|
||||
if (polybottom < opentop && delta1 >= delta2)
|
||||
{
|
||||
opentop = polybottom;
|
||||
}
|
||||
else if (polybottom < highceiling && delta1 >= delta2)
|
||||
{
|
||||
highceiling = polybottom;
|
||||
}
|
||||
|
||||
if (polytop > openbottom && delta1 < delta2)
|
||||
{
|
||||
openbottom = polytop;
|
||||
}
|
||||
else if (polytop > lowfloor && delta1 < delta2)
|
||||
{
|
||||
lowfloor = polytop;
|
||||
if (delta1 > delta2)
|
||||
{
|
||||
if (polybottom < open->ceiling)
|
||||
{
|
||||
open->ceiling = polybottom;
|
||||
}
|
||||
else if (polybottom < open->highceiling)
|
||||
{
|
||||
open->highceiling = polybottom;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (polytop > open->floor)
|
||||
{
|
||||
open->floor = polytop;
|
||||
}
|
||||
else if (polytop > open->lowfloor)
|
||||
{
|
||||
open->lowfloor = polytop;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// otherwise don't do anything special, pretend there's nothing else there
|
||||
|
|
@ -793,22 +825,20 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
/* yuck */
|
||||
struct
|
||||
{
|
||||
fixed_t top;
|
||||
fixed_t bottom;
|
||||
fixed_t ceiling;
|
||||
fixed_t floor;
|
||||
ffloor_t * ceilingrover;
|
||||
ffloor_t * floorrover;
|
||||
} open[2] = {
|
||||
} fofopen[2] = {
|
||||
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
||||
{ INT32_MAX, INT32_MIN, NULL, NULL },
|
||||
};
|
||||
|
||||
const fixed_t oldopentop = opentop;
|
||||
const fixed_t oldopenbottom = openbottom;
|
||||
|
||||
// Check for frontsector's fake floors
|
||||
for (rover = front->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
continue;
|
||||
|
||||
|
|
@ -818,41 +848,89 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(mobj, front, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
|
||||
if (open->fofType != LO_FOF_ANY)
|
||||
{
|
||||
if (bottomheight < open[FRONT].top) {
|
||||
open[FRONT].top = bottomheight;
|
||||
opentopslope = *rover->b_slope;
|
||||
opentoppic = *rover->bottompic;
|
||||
open[FRONT].ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highceiling)
|
||||
highceiling = bottomheight;
|
||||
topheight = P_VeryTopOfFOF(rover);
|
||||
bottomheight = P_VeryBottomOfFOF(rover);
|
||||
}
|
||||
else
|
||||
{
|
||||
topheight = P_GetFOFTopZ(mobj, front, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, front, rover, tm.x, tm.y, linedef);
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
|
||||
switch (open->fofType)
|
||||
{
|
||||
if (topheight > open[FRONT].bottom) {
|
||||
open[FRONT].bottom = topheight;
|
||||
openbottomslope = *rover->t_slope;
|
||||
openbottompic = *rover->toppic;
|
||||
open[FRONT].floorrover = rover;
|
||||
case LO_FOF_FLOORS:
|
||||
{
|
||||
if (mobj->z >= topheight)
|
||||
{
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
|
||||
{
|
||||
if (topheight > fofopen[FRONT].floor)
|
||||
{
|
||||
fofopen[FRONT].floor = topheight;
|
||||
fofopen[FRONT].floorrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LO_FOF_CEILINGS:
|
||||
{
|
||||
if (thingtop <= bottomheight)
|
||||
{
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
|
||||
{
|
||||
if (bottomheight < fofopen[FRONT].ceiling)
|
||||
{
|
||||
fofopen[FRONT].ceiling = bottomheight;
|
||||
fofopen[FRONT].ceilingrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
midheight = bottomheight + (topheight - bottomheight) / 2;
|
||||
delta1 = abs(mobj->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (delta1 > delta2)
|
||||
{
|
||||
// thing is below FOF
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
|
||||
{
|
||||
if (bottomheight < fofopen[FRONT].ceiling)
|
||||
{
|
||||
fofopen[FRONT].ceiling = bottomheight;
|
||||
fofopen[FRONT].ceilingrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// thing is above FOF
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
|
||||
{
|
||||
if (topheight > fofopen[FRONT].floor)
|
||||
{
|
||||
fofopen[FRONT].floor = topheight;
|
||||
fofopen[FRONT].floorrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (topheight > lowfloor)
|
||||
lowfloor = topheight;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for backsectors fake floors
|
||||
for (rover = back->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
fixed_t topheight, bottomheight;
|
||||
fixed_t topheight, bottomheight, midheight;
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
continue;
|
||||
|
||||
|
|
@ -862,79 +940,146 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
|| (rover->fofflags & FOF_BLOCKOTHERS && !mobj->player)))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFOFTopZ(mobj, back, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tm.x, tm.y, linedef);
|
||||
|
||||
delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
|
||||
|
||||
if (delta1 >= delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM) // thing is below FOF
|
||||
if (open->fofType != LO_FOF_ANY)
|
||||
{
|
||||
if (bottomheight < open[BACK].top) {
|
||||
open[BACK].top = bottomheight;
|
||||
opentopslope = *rover->b_slope;
|
||||
opentoppic = *rover->bottompic;
|
||||
open[BACK].ceilingrover = rover;
|
||||
}
|
||||
else if (bottomheight < highceiling)
|
||||
highceiling = bottomheight;
|
||||
topheight = P_VeryTopOfFOF(rover);
|
||||
bottomheight = P_VeryBottomOfFOF(rover);
|
||||
}
|
||||
else
|
||||
{
|
||||
topheight = P_GetFOFTopZ(mobj, back, rover, tm.x, tm.y, linedef);
|
||||
bottomheight = P_GetFOFBottomZ(mobj, back, rover, tm.x, tm.y, linedef);
|
||||
}
|
||||
|
||||
if (delta1 < delta2 && (rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM) // thing is above FOF
|
||||
switch (open->fofType)
|
||||
{
|
||||
if (topheight > open[BACK].bottom) {
|
||||
open[BACK].bottom = topheight;
|
||||
openbottomslope = *rover->t_slope;
|
||||
openbottompic = *rover->toppic;
|
||||
open[BACK].floorrover = rover;
|
||||
case LO_FOF_FLOORS:
|
||||
{
|
||||
if (mobj->z >= topheight)
|
||||
{
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
|
||||
{
|
||||
if (topheight > fofopen[BACK].floor)
|
||||
{
|
||||
fofopen[BACK].floor = topheight;
|
||||
fofopen[BACK].floorrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LO_FOF_CEILINGS:
|
||||
{
|
||||
if (thingtop <= bottomheight)
|
||||
{
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
|
||||
{
|
||||
if (bottomheight < fofopen[BACK].ceiling)
|
||||
{
|
||||
fofopen[BACK].ceiling = bottomheight;
|
||||
fofopen[BACK].ceilingrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
midheight = bottomheight + (topheight - bottomheight) / 2;
|
||||
delta1 = abs(mobj->z - midheight);
|
||||
delta2 = abs(thingtop - midheight);
|
||||
|
||||
if (delta1 > delta2)
|
||||
{
|
||||
// thing is below FOF
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_PLATFORM)
|
||||
{
|
||||
if (bottomheight < fofopen[BACK].ceiling)
|
||||
{
|
||||
fofopen[BACK].ceiling = bottomheight;
|
||||
fofopen[BACK].ceilingrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// thing is above FOF
|
||||
if ((rover->fofflags & FOF_INTANGIBLEFLATS) != FOF_REVERSEPLATFORM)
|
||||
{
|
||||
if (topheight > fofopen[BACK].floor)
|
||||
{
|
||||
fofopen[BACK].floor = topheight;
|
||||
fofopen[BACK].floorrover = rover;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (topheight > lowfloor)
|
||||
lowfloor = topheight;
|
||||
}
|
||||
}
|
||||
|
||||
lo = ( open[0].top > open[1].top );
|
||||
hi = ( fofopen[0].ceiling < fofopen[1].ceiling );
|
||||
lo = ! hi;
|
||||
|
||||
if (open[lo].top <= oldopentop)
|
||||
if (fofopen[lo].ceiling <= open->ceiling)
|
||||
{
|
||||
hi = ! lo;
|
||||
topedge[lo] = P_GetFFloorBottomZAt(fofopen[lo].ceilingrover, cross.x, cross.y);
|
||||
|
||||
topedge[lo] = P_GetFFloorBottomZAt(open[lo].ceilingrover, cross.x, cross.y);
|
||||
|
||||
if (open[hi].top < oldopentop)
|
||||
if (fofopen[hi].ceiling < open->ceiling)
|
||||
{
|
||||
topedge[hi] = P_GetFFloorBottomZAt(open[hi].ceilingrover, cross.x, cross.y);
|
||||
topedge[hi] = P_GetFFloorBottomZAt(fofopen[hi].ceilingrover, cross.x, cross.y);
|
||||
}
|
||||
|
||||
opentop = open[lo].top;
|
||||
openceilingrover = open[lo].ceilingrover;
|
||||
openceilingstep = ( thingtop - topedge[lo] );
|
||||
openceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
open->ceiling = fofopen[lo].ceiling;
|
||||
open->ceilingrover = fofopen[lo].ceilingrover;
|
||||
open->ceilingslope = *fofopen[lo].ceilingrover->b_slope;
|
||||
open->ceilingpic = *fofopen[lo].ceilingrover->bottompic;
|
||||
open->ceilingstep = ( thingtop - topedge[lo] );
|
||||
open->ceilingdrop = ( topedge[hi] - topedge[lo] );
|
||||
|
||||
if (fofopen[hi].ceiling < open->highceiling)
|
||||
{
|
||||
open->highceiling = fofopen[hi].ceiling;
|
||||
}
|
||||
}
|
||||
else if (fofopen[lo].ceiling < open->highceiling)
|
||||
{
|
||||
open->highceiling = fofopen[lo].ceiling;
|
||||
}
|
||||
|
||||
hi = ( open[0].bottom < open[1].bottom );
|
||||
hi = ( fofopen[0].floor < fofopen[1].floor );
|
||||
lo = ! hi;
|
||||
|
||||
if (open[hi].bottom >= oldopenbottom)
|
||||
if (fofopen[hi].floor >= open->floor)
|
||||
{
|
||||
lo = ! hi;
|
||||
botedge[hi] = P_GetFFloorTopZAt(fofopen[hi].floorrover, cross.x, cross.y);
|
||||
|
||||
botedge[hi] = P_GetFFloorTopZAt(open[hi].floorrover, cross.x, cross.y);
|
||||
|
||||
if (open[lo].bottom > oldopenbottom)
|
||||
if (fofopen[lo].floor > open->floor)
|
||||
{
|
||||
botedge[lo] = P_GetFFloorTopZAt(open[lo].floorrover, cross.x, cross.y);
|
||||
botedge[lo] = P_GetFFloorTopZAt(fofopen[lo].floorrover, cross.x, cross.y);
|
||||
}
|
||||
|
||||
openbottom = open[hi].bottom;
|
||||
openfloorrover = open[hi].floorrover;
|
||||
openfloorstep = ( botedge[hi] - mobj->z );
|
||||
openfloordrop = ( botedge[hi] - botedge[lo] );
|
||||
open->floor = fofopen[hi].floor;
|
||||
open->floorrover = fofopen[hi].floorrover;
|
||||
open->floorslope = *fofopen[hi].floorrover->t_slope;
|
||||
open->floorpic = *fofopen[hi].floorrover->toppic;
|
||||
open->floorstep = ( botedge[hi] - mobj->z );
|
||||
open->floordrop = ( botedge[hi] - botedge[lo] );
|
||||
|
||||
if (fofopen[lo].floor > open->lowfloor)
|
||||
{
|
||||
open->lowfloor = fofopen[lo].floor;
|
||||
}
|
||||
}
|
||||
else if (fofopen[hi].floor > open->lowfloor)
|
||||
{
|
||||
open->lowfloor = fofopen[hi].floor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openrange = opentop - openbottom;
|
||||
open->range = (open->ceiling - open->floor);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result);
|
|||
void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result);
|
||||
INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line);
|
||||
void P_MakeDivline(line_t *li, divline_t *dl);
|
||||
void P_CameraLineOpening(line_t *plinedef);
|
||||
void P_CameraLineOpening(line_t *plinedef, opening_t *open);
|
||||
fixed_t P_InterceptVector(divline_t *v2, divline_t *v1);
|
||||
INT32 P_BoxOnLineSide(fixed_t *tmbox, line_t *ld);
|
||||
line_t * P_FindNearestLine(const fixed_t x, const fixed_t y, const sector_t *, const INT32 special);
|
||||
|
|
@ -61,16 +61,23 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_
|
|||
|
||||
boolean P_GetMidtextureTopBottom(line_t *linedef, fixed_t x, fixed_t y, fixed_t *return_top, fixed_t *return_bottom);
|
||||
|
||||
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
|
||||
extern pslope_t *opentopslope, *openbottomslope;
|
||||
extern ffloor_t *openfloorrover, *openceilingrover;
|
||||
extern fixed_t openceilingstep;
|
||||
extern fixed_t openceilingdrop;
|
||||
extern fixed_t openfloorstep;
|
||||
extern fixed_t openfloordrop;
|
||||
extern INT32 opentoppic, openbottompic;
|
||||
struct opening_t
|
||||
{
|
||||
fixed_t ceiling, floor, range;
|
||||
fixed_t lowfloor, highceiling;
|
||||
pslope_t *floorslope, *ceilingslope;
|
||||
ffloor_t *floorrover, *ceilingrover;
|
||||
fixed_t ceilingstep, ceilingdrop;
|
||||
fixed_t floorstep, floordrop;
|
||||
INT32 ceilingpic, floorpic;
|
||||
UINT8 fofType; // LO_FOF_ types for forcing FOF collide
|
||||
};
|
||||
|
||||
void P_LineOpening(line_t *plinedef, mobj_t *mobj);
|
||||
#define LO_FOF_ANY (0)
|
||||
#define LO_FOF_FLOORS (1)
|
||||
#define LO_FOF_CEILINGS (2)
|
||||
|
||||
void P_LineOpening(line_t *plinedef, mobj_t *mobj, opening_t *open);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
|||
127
src/p_sight.c
127
src/p_sight.c
|
|
@ -36,6 +36,7 @@ typedef struct
|
|||
|
||||
mobj_t *t1, *t2;
|
||||
boolean alreadyHates; // For bot traversal, for if the bot is already in a sector it doesn't want to be
|
||||
UINT8 traversed;
|
||||
} los_t;
|
||||
|
||||
typedef boolean (*los_init_t)(mobj_t *, mobj_t *, register los_t *);
|
||||
|
|
@ -51,6 +52,8 @@ typedef struct
|
|||
|
||||
static INT32 sightcounts[2];
|
||||
|
||||
#define TRAVERSE_MAX (2)
|
||||
|
||||
//
|
||||
// P_DivlineSide
|
||||
//
|
||||
|
|
@ -360,8 +363,12 @@ static boolean P_CanTraceBlockingLine(seg_t *seg, divline_t *divl, register los_
|
|||
|
||||
static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los)
|
||||
{
|
||||
const boolean flip = ((los->t1->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
||||
line_t *line = seg->linedef;
|
||||
fixed_t frac = 0;
|
||||
boolean canStepUp, canDropOff;
|
||||
fixed_t maxstep = 0;
|
||||
opening_t open = {0};
|
||||
|
||||
if (P_CanTraceBlockingLine(seg, divl, los) == false)
|
||||
{
|
||||
|
|
@ -369,45 +376,60 @@ static boolean P_CanBotTraverse(seg_t *seg, divline_t *divl, register los_t *los
|
|||
return false;
|
||||
}
|
||||
|
||||
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
|
||||
// calculate position at intercept
|
||||
tm.x = los->strace.x + FixedMul(los->strace.dx, frac);
|
||||
tm.y = los->strace.y + FixedMul(los->strace.dy, frac);
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
tm.x = los->t1->x;
|
||||
tm.y = los->t1->y;
|
||||
P_LineOpening(line, los->t1);
|
||||
open.fofType = (flip ? LO_FOF_CEILINGS : LO_FOF_FLOORS);
|
||||
P_LineOpening(line, los->t1, &open);
|
||||
maxstep = P_GetThingStepUp(los->t1, tm.x, tm.y);
|
||||
|
||||
if ((openrange < los->t1->height) // doesn't fit
|
||||
|| (opentop - los->t1->z < los->t1->height) // mobj is too high
|
||||
|| (openbottom - los->t1->z > maxstep)) // too big a step up
|
||||
if (open.range < los->t1->height)
|
||||
{
|
||||
// This line situationally blocks us
|
||||
// Can't fit
|
||||
return false;
|
||||
}
|
||||
|
||||
if (los->t1->player != NULL && los->alreadyHates == false)
|
||||
// If we can step up...
|
||||
canStepUp = ((flip ? (open.highceiling - open.ceiling) : (open.floor - open.lowfloor)) <= maxstep);
|
||||
|
||||
// Or if we're on the higher side...
|
||||
canDropOff = (flip ? (los->t1->z + los->t1->height <= open.ceiling) : (los->t1->z >= open.floor));
|
||||
|
||||
if (canStepUp || canDropOff)
|
||||
{
|
||||
// Treat damage sectors like walls, if you're not already in a bad sector.
|
||||
sector_t *front, *back;
|
||||
vertex_t pos;
|
||||
|
||||
P_ClosestPointOnLine(tm.x, tm.y, line, &pos);
|
||||
|
||||
front = seg->frontsector;
|
||||
back = seg->backsector;
|
||||
|
||||
if (K_BotHatesThisSector(los->t1->player, front, pos.x, pos.y)
|
||||
|| K_BotHatesThisSector(los->t1->player, back, pos.x, pos.y))
|
||||
if (los->t1->player != NULL && los->alreadyHates == false)
|
||||
{
|
||||
// This line does not block us, but we don't want to be in it.
|
||||
return false;
|
||||
// Treat damage / offroad sectors like walls.
|
||||
UINT8 side = P_DivlineSide(los->t2x, los->t2y, divl) & 1;
|
||||
sector_t *sector = (side == 1) ? seg->backsector : seg->frontsector;
|
||||
|
||||
if (K_BotHatesThisSector(los->t1->player, sector, tm.x, tm.y))
|
||||
{
|
||||
// This line does not block us, but we don't want to cross it regardless.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
los->traversed++;
|
||||
return (los->traversed < TRAVERSE_MAX);
|
||||
}
|
||||
|
||||
static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t *los)
|
||||
{
|
||||
const boolean flip = ((los->t1->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
|
||||
line_t *line = seg->linedef;
|
||||
fixed_t frac = 0;
|
||||
boolean canStepUp, canDropOff;
|
||||
fixed_t maxstep = 0;
|
||||
opening_t open = {0};
|
||||
|
||||
if (P_CanTraceBlockingLine(seg, divl, los) == false)
|
||||
{
|
||||
|
|
@ -422,7 +444,65 @@ static boolean P_CanWaypointTraverse(seg_t *seg, divline_t *divl, register los_t
|
|||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
// calculate fractional intercept (how far along we are divided by how far we are from t2)
|
||||
frac = P_InterceptVector2(&los->strace, divl);
|
||||
|
||||
// calculate position at intercept
|
||||
tm.x = los->strace.x + FixedMul(los->strace.dx, frac);
|
||||
tm.y = los->strace.y + FixedMul(los->strace.dy, frac);
|
||||
|
||||
// set openrange, opentop, openbottom
|
||||
open.fofType = (flip ? LO_FOF_CEILINGS : LO_FOF_FLOORS);
|
||||
P_LineOpening(line, los->t1, &open);
|
||||
maxstep = P_GetThingStepUp(los->t1, tm.x, tm.y);
|
||||
|
||||
#if 0
|
||||
if (los->t2->type == MT_WAYPOINT)
|
||||
{
|
||||
waypoint_t *wp = K_SearchWaypointHeapForMobj(los->t2);
|
||||
|
||||
if (wp != NULL)
|
||||
{
|
||||
CONS_Printf(
|
||||
"========\nID: %d\nrange: %.2f >= %.2f\n",
|
||||
K_GetWaypointID(wp),
|
||||
FIXED_TO_FLOAT(open.range),
|
||||
FIXED_TO_FLOAT(los->t1->height)
|
||||
);
|
||||
|
||||
if (open.range >= los->t1->height)
|
||||
{
|
||||
CONS_Printf(
|
||||
"floor: %.2f\nlowfloor: %.2f\nstep: %.2f <= %.2f\n",
|
||||
FIXED_TO_FLOAT(open.floor),
|
||||
FIXED_TO_FLOAT(open.lowfloor),
|
||||
FIXED_TO_FLOAT(open.floor - open.lowfloor),
|
||||
FIXED_TO_FLOAT(maxstep)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (open.range < los->t1->height)
|
||||
{
|
||||
// Can't fit
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we can step up...
|
||||
canStepUp = ((flip ? (open.highceiling - open.ceiling) : (open.floor - open.lowfloor)) <= maxstep);
|
||||
|
||||
// Or if we're on the higher side...
|
||||
canDropOff = (flip ? (los->t1->z + los->t1->height <= open.ceiling) : (los->t1->z >= open.floor));
|
||||
|
||||
if (canStepUp || canDropOff)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
los->traversed++;
|
||||
return (los->traversed < TRAVERSE_MAX);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -677,6 +757,7 @@ static boolean P_CompareMobjsAcrossLines(mobj_t *t1, mobj_t *t2, register los_fu
|
|||
los.t1 = t1;
|
||||
los.t2 = t2;
|
||||
los.alreadyHates = false;
|
||||
los.traversed = 0;
|
||||
|
||||
los.topslope =
|
||||
(los.bottomslope = t2->z - (los.sightzstart =
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ TYPEDEF (BasicFF_t);
|
|||
// p_maputl.h
|
||||
TYPEDEF (divline_t);
|
||||
TYPEDEF (intercept_t);
|
||||
TYPEDEF (opening_t);
|
||||
|
||||
// p_mobj.h
|
||||
TYPEDEF (mobj_t);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue