Merge master

(We're still being haunted by whatever happened to make the entire k_kart.c file conflict every single time...)
This commit is contained in:
TehRealSalt 2019-09-25 10:04:27 -04:00
commit 93e844ecd2
10 changed files with 10352 additions and 10241 deletions

View file

@ -17,7 +17,7 @@ set(SRB2_ASSET_HASHED
gfx.pk3;\
textures.pk3;\
chars.pk3;\
maps.wad;\
maps.pk3;\
patch.pk3"
CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!"
)

View file

@ -15,7 +15,7 @@
#define ASSET_HASH_GFX_PK3 "${SRB2_ASSET_gfx.pk3_HASH}"
#define ASSET_HASH_TEXTURES_PK3 "${SRB2_ASSET_textures.pk3_HASH}"
#define ASSET_HASH_CHARS_PK3 "${SRB2_ASSET_chars.pk3_HASH}"
#define ASSET_HASH_MAPS_WAD "${SRB2_ASSET_maps.wad_HASH}"
#define ASSET_HASH_MAPS_PK3 "${SRB2_ASSET_maps.pk3_HASH}"
#ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}"
#endif
@ -36,7 +36,7 @@
#define ASSET_HASH_GFX_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_TEXTURES_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_CHARS_PK3 "00000000000000000000000000000000"
#define ASSET_HASH_MAPS_WAD "00000000000000000000000000000000"
#define ASSET_HASH_MAPS_PK3 "00000000000000000000000000000000"
#ifdef USE_PATCH_FILE
#define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000"
#endif

View file

@ -896,11 +896,18 @@ static void IdentifyVersion(void)
D_AddFile(va(pandf,srb2waddir,"gfx.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"textures.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"chars.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"maps.wad"), startupwadfiles); // TODO: make this a pk3 too!
D_AddFile(va(pandf,srb2waddir,"maps.pk3"), startupwadfiles);
#ifdef USE_PATCH_FILE
D_AddFile(va(pandf,srb2waddir,"patch.pk3"), startupwadfiles);
#endif
#if 0
// TODO: pk3 doesn't support music replacement IIRC
// music barely benefits from the compression anyway
// would be nice for the folders, though
D_AddFile(va(pandf,srb2waddir,"sounds.pk3"), startupwadfiles);
D_AddFile(va(pandf,srb2waddir,"music.pk3"), startupwadfiles);
#else
#if !defined (HAVE_SDL) || defined (HAVE_MIXER)
#define MUSICTEST(str) \
{\
@ -915,6 +922,7 @@ static void IdentifyVersion(void)
MUSICTEST("music.wad")
#undef MUSICTEST
#endif
#endif
}
/* ======================================================================== */
@ -1200,7 +1208,7 @@ void D_SRB2Main(void)
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_PK3); // gfx.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_PK3); // textures.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_WAD); // maps.wad -- 4 - If you touch this, make sure to touch up the majormods stuff below.
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_PK3); // maps.pk3 -- 4 - If you touch this, make sure to touch up the majormods stuff below.
#ifdef USE_PATCH_FILE
mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_PK3); // patch.pk3
#endif
@ -1208,7 +1216,7 @@ void D_SRB2Main(void)
mainwads++; // gfx.pk3
mainwads++; // textures.pk3
mainwads++; // chars.pk3
mainwads++; // maps.wad
mainwads++; // maps.pk3
#ifdef USE_PATCH_FILE
mainwads++; // patch.pk3
#endif

View file

@ -2322,6 +2322,9 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove
// ACCELCODE!!!1!11!
oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale);
// Don't calculate the acceleration as ever being above top speed
if (oldspeed > p_speed)
oldspeed = p_speed;
newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION);
if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust
@ -5412,6 +5415,282 @@ void K_KartPlayerAfterThink(player_t *player)
}
}
/*--------------------------------------------------
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
Gets the next waypoint of a player, by finding their closest waypoint, then checking which of itself and next or
previous waypoints are infront of the player.
Input Arguments:-
player - The player the next waypoint is being found for
Return:-
The waypoint that is the player's next waypoint
--------------------------------------------------*/
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{
waypoint_t *bestwaypoint = NULL;
if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false))
{
waypoint_t *waypoint = NULL;
waypoint = K_GetClosestWaypointToMobj(player->mo);
bestwaypoint = waypoint;
// 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.
// EXCEPTION: If our closest waypoint is the finishline AND we're facing towards it, don't do this.
// Otherwise it breaks the distance calculations.
if (waypoint != NULL)
{
boolean finishlinehack = false;
angle_t playerangle = player->mo->angle;
angle_t angletowaypoint =
R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y);
angle_t angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (bestwaypoint == K_GetFinishLineWaypoint())
{
// facing towards the finishline
if (angledelta <= ANGLE_90)
{
finishlinehack = true;
}
}
if ((angledelta > ANGLE_45) && (finishlinehack == false))
{
angle_t nextbestdelta = angledelta;
size_t i = 0U;
if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U))
{
for (i = 0U; i < waypoint->numnextwaypoints; i++)
{
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->nextwaypoints[i]->mobj->x, waypoint->nextwaypoints[i]->mobj->y);
angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (angledelta < nextbestdelta)
{
bestwaypoint = waypoint->nextwaypoints[i];
nextbestdelta = angledelta;
}
}
}
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U))
{
for (i = 0U; i < waypoint->numprevwaypoints; i++)
{
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->prevwaypoints[i]->mobj->x, waypoint->prevwaypoints[i]->mobj->y);
angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (angledelta < nextbestdelta)
{
bestwaypoint = waypoint->prevwaypoints[i];
nextbestdelta = angledelta;
}
}
}
}
}
}
return bestwaypoint;
}
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
{
boolean nextiscloser = true;
if ((waypoint != NULL) && (player != NULL) && (player->mo != NULL))
{
size_t i = 0U;
waypoint_t *currentwpcheck = NULL;
angle_t angletoplayer = ANGLE_MAX;
angle_t currentanglecheck = ANGLE_MAX;
angle_t bestangle = ANGLE_MAX;
angletoplayer = R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y,
player->mo->x, player->mo->y);
for (i = 0U; i < waypoint->numnextwaypoints; i++)
{
currentwpcheck = waypoint->nextwaypoints[i];
currentanglecheck = R_PointToAngle2(
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
// Get delta angle
currentanglecheck = currentanglecheck - angletoplayer;
if (currentanglecheck > ANGLE_180)
{
currentanglecheck = InvAngle(currentanglecheck);
}
if (currentanglecheck < bestangle)
{
bestangle = currentanglecheck;
}
}
for (i = 0U; i < waypoint->numprevwaypoints; i++)
{
currentwpcheck = waypoint->prevwaypoints[i];
currentanglecheck = R_PointToAngle2(
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
// Get delta angle
currentanglecheck = currentanglecheck - angletoplayer;
if (currentanglecheck > ANGLE_180)
{
currentanglecheck = InvAngle(currentanglecheck);
}
if (currentanglecheck < bestangle)
{
bestangle = currentanglecheck;
nextiscloser = false;
break;
}
}
}
return nextiscloser;
}
/*--------------------------------------------------
static void K_UpdateDistanceFromFinishLine(player_t *const player)
Updates the distance a player has to the finish line.
Input Arguments:-
player - The player the distance is being updated for
Return:-
None
--------------------------------------------------*/
static void K_UpdateDistanceFromFinishLine(player_t *const player)
{
if ((player != NULL) && (player->mo != NULL))
{
if (player->exiting)
{
player->nextwaypoint = K_GetFinishLineWaypoint();
player->distancetofinish = 0U;
}
else
{
waypoint_t *finishline = K_GetFinishLineWaypoint();
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player);
if ((nextwaypoint != player->nextwaypoint) &&
(K_GetWaypointIsShortcut(nextwaypoint) == false) && (K_GetWaypointIsEnabled(nextwaypoint) == true))
{
size_t i = 0U;
waypoint_t *aimwaypoint = NULL;
player->starpostx = nextwaypoint->mobj->x >> FRACBITS;
player->starposty = nextwaypoint->mobj->y >> FRACBITS;
player->starpostz = nextwaypoint->mobj->z >> FRACBITS;
// player gravflip determines which way to respawn
player->kartstuff[k_starpostflip] = player->mo->flags2 & MF2_OBJECTFLIP;
// starpostangle is to the first valid nextwaypoint for simplicity
// if we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix
// their map!
for (i = 0U; i < nextwaypoint->numnextwaypoints; i++)
{
aimwaypoint = nextwaypoint->nextwaypoints[i];
if ((i == nextwaypoint->numnextwaypoints - 1U)
|| ((K_GetWaypointIsEnabled(aimwaypoint) == true)
&& (K_GetWaypointIsSpawnpoint(aimwaypoint) == true)))
{
player->starpostangle = R_PointToAngle2(
nextwaypoint->mobj->x, nextwaypoint->mobj->y, aimwaypoint->mobj->x, aimwaypoint->mobj->y);
break;
}
}
}
player->nextwaypoint = nextwaypoint;
// nextwaypoint is now the waypoint that is in front of us
if ((player->nextwaypoint != NULL) && (finishline != NULL))
{
const boolean useshortcuts = false;
const boolean huntbackwards = false;
boolean pathfindsuccess = false;
path_t pathtofinish = {};
pathfindsuccess =
K_PathfindToWaypoint(player->nextwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
// Update the player's distance to the finish line if a path was found.
// Using shortcuts won't find a path, so distance won't be updated until the player gets back on track
if (pathfindsuccess == true)
{
// Add euclidean distance to the next waypoint to the distancetofinish
UINT32 adddist;
fixed_t disttowaypoint =
P_AproxDistance(
player->mo->x - player->nextwaypoint->mobj->x,
player->mo->y - player->nextwaypoint->mobj->y);
disttowaypoint = P_AproxDistance(disttowaypoint, player->mo->z - player->nextwaypoint->mobj->z);
adddist = ((UINT32)disttowaypoint) >> FRACBITS;
player->distancetofinish = pathtofinish.totaldist + adddist;
Z_Free(pathtofinish.array);
// distancetofinish is currently a flat distance to the finish line, but in order to be fully
// correct we need to add to it the length of the entire circuit multiplied by the number of laps
// left after this one. This will give us the total distance to the finish line, and allow item
// distance calculation to work easily
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
{
const UINT8 numfulllapsleft = ((UINT8)cv_numlaps.value - player->laps);
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
// An additional HACK, to fix looking backwards towards the finish line
// If the player's next waypoint is the finishline and the angle distance from player to
// connectin waypoints implies they're closer to a next waypoint, add a full track distance
if (player->nextwaypoint == finishline)
{
if (K_PlayerCloserToNextWaypoints(player->nextwaypoint, player) == true)
{
player->distancetofinish += K_GetCircuitLength();
}
}
}
}
}
}
}
}
// Returns false if this player being placed here causes them to collide with any other player
// Used in g_game.c for match etc. respawning
// This does not check along the z because the z is not correctly set for the spawnee at this point
@ -5671,284 +5950,6 @@ static void K_KartDrift(player_t *player, boolean onground)
else
player->kartstuff[k_brakedrift] = 0;
}
/*--------------------------------------------------
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
Gets the next waypoint of a player, by finding their closest waypoint, then checking which of itself and next or
previous waypoints are infront of the player.
Input Arguments:-
player - The player the next waypoint is being found for
Return:-
The waypoint that is the player's next waypoint
--------------------------------------------------*/
static waypoint_t *K_GetPlayerNextWaypoint(player_t *player)
{
waypoint_t *bestwaypoint = NULL;
if ((player != NULL) && (player->mo != NULL) && (P_MobjWasRemoved(player->mo) == false))
{
waypoint_t *waypoint = NULL;
waypoint = K_GetClosestWaypointToMobj(player->mo);
bestwaypoint = waypoint;
// 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.
// EXCEPTION: If our closest waypoint is the finishline AND we're facing towards it, don't do this.
// Otherwise it breaks the distance calculations.
if (waypoint != NULL)
{
boolean finishlinehack = false;
angle_t playerangle = player->mo->angle;
angle_t angletowaypoint =
R_PointToAngle2(player->mo->x, player->mo->y, waypoint->mobj->x, waypoint->mobj->y);
angle_t angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (bestwaypoint == K_GetFinishLineWaypoint())
{
// facing towards the finishline
if (angledelta <= ANGLE_90)
{
finishlinehack = true;
}
}
if ((angledelta > ANGLE_45) && (finishlinehack == false))
{
angle_t nextbestdelta = angledelta;
size_t i = 0U;
if ((waypoint->nextwaypoints != NULL) && (waypoint->numnextwaypoints > 0U))
{
for (i = 0U; i < waypoint->numnextwaypoints; i++)
{
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->nextwaypoints[i]->mobj->x, waypoint->nextwaypoints[i]->mobj->y);
angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (angledelta < nextbestdelta)
{
bestwaypoint = waypoint->nextwaypoints[i];
nextbestdelta = angledelta;
}
}
}
if ((waypoint->prevwaypoints != NULL) && (waypoint->numprevwaypoints > 0U))
{
for (i = 0U; i < waypoint->numprevwaypoints; i++)
{
angletowaypoint = R_PointToAngle2(
player->mo->x, player->mo->y,
waypoint->prevwaypoints[i]->mobj->x, waypoint->prevwaypoints[i]->mobj->y);
angledelta = playerangle - angletowaypoint;
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
}
if (angledelta < nextbestdelta)
{
bestwaypoint = waypoint->prevwaypoints[i];
nextbestdelta = angledelta;
}
}
}
}
}
}
return bestwaypoint;
}
static boolean K_PlayerCloserToNextWaypoints(waypoint_t *const waypoint, player_t *const player)
{
boolean nextiscloser = true;
if ((waypoint != NULL) && (player != NULL) && (player->mo != NULL))
{
size_t i = 0U;
waypoint_t *currentwpcheck = NULL;
angle_t angletoplayer = ANGLE_MAX;
angle_t currentanglecheck = ANGLE_MAX;
angle_t bestangle = ANGLE_MAX;
angletoplayer = R_PointToAngle2(waypoint->mobj->x, waypoint->mobj->y,
player->mo->x, player->mo->y);
for (i = 0U; i < waypoint->numnextwaypoints; i++)
{
currentwpcheck = waypoint->nextwaypoints[i];
currentanglecheck = R_PointToAngle2(
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
// Get delta angle
currentanglecheck = currentanglecheck - angletoplayer;
if (currentanglecheck > ANGLE_180)
{
currentanglecheck = InvAngle(currentanglecheck);
}
if (currentanglecheck < bestangle)
{
bestangle = currentanglecheck;
}
}
for (i = 0U; i < waypoint->numprevwaypoints; i++)
{
currentwpcheck = waypoint->prevwaypoints[i];
currentanglecheck = R_PointToAngle2(
waypoint->mobj->x, waypoint->mobj->y, currentwpcheck->mobj->x, currentwpcheck->mobj->y);
// Get delta angle
currentanglecheck = currentanglecheck - angletoplayer;
if (currentanglecheck > ANGLE_180)
{
currentanglecheck = InvAngle(currentanglecheck);
}
if (currentanglecheck < bestangle)
{
bestangle = currentanglecheck;
nextiscloser = false;
break;
}
}
}
return nextiscloser;
}
/*--------------------------------------------------
static void K_UpdateDistanceFromFinishLine(player_t *const player)
Updates the distance a player has to the finish line.
Input Arguments:-
player - The player the distance is being updated for
Return:-
None
--------------------------------------------------*/
static void K_UpdateDistanceFromFinishLine(player_t *const player)
{
if ((player != NULL) && (player->mo != NULL))
{
if (player->exiting)
{
player->nextwaypoint = K_GetFinishLineWaypoint();
player->distancetofinish = 0U;
}
else
{
waypoint_t *finishline = K_GetFinishLineWaypoint();
waypoint_t *nextwaypoint = K_GetPlayerNextWaypoint(player);
if ((nextwaypoint != player->nextwaypoint) &&
(K_GetWaypointIsShortcut(nextwaypoint) == false) && (K_GetWaypointIsEnabled(nextwaypoint) == true))
{
size_t i = 0U;
waypoint_t *aimwaypoint = NULL;
player->starpostx = nextwaypoint->mobj->x >> FRACBITS;
player->starposty = nextwaypoint->mobj->y >> FRACBITS;
player->starpostz = nextwaypoint->mobj->z >> FRACBITS;
// player gravflip determines which way to respawn
player->kartstuff[k_starpostflip] = player->mo->flags2 & MF2_OBJECTFLIP;
// starpostangle is to the first valid nextwaypoint for simplicity
// if we reach the last waypoint and it's still not valid, just use it anyway. Someone needs to fix
// their map!
for (i = 0U; i < nextwaypoint->numnextwaypoints; i++)
{
aimwaypoint = nextwaypoint->nextwaypoints[i];
if ((i == nextwaypoint->numnextwaypoints - 1U)
|| ((K_GetWaypointIsEnabled(aimwaypoint) == true)
&& (K_GetWaypointIsSpawnpoint(aimwaypoint) == true)))
{
player->starpostangle = R_PointToAngle2(
nextwaypoint->mobj->x, nextwaypoint->mobj->y, aimwaypoint->mobj->x, aimwaypoint->mobj->y);
break;
}
}
}
player->nextwaypoint = nextwaypoint;
// nextwaypoint is now the waypoint that is in front of us
if ((player->nextwaypoint != NULL) && (finishline != NULL))
{
const boolean useshortcuts = false;
const boolean huntbackwards = false;
boolean pathfindsuccess = false;
path_t pathtofinish = {};
pathfindsuccess =
K_PathfindToWaypoint(player->nextwaypoint, finishline, &pathtofinish, useshortcuts, huntbackwards);
// Update the player's distance to the finish line if a path was found.
// Using shortcuts won't find a path, so distance won't be updated until the player gets back on track
if (pathfindsuccess == true)
{
// Add euclidean distance to the next waypoint to the distancetofinish
UINT32 adddist;
fixed_t disttowaypoint =
P_AproxDistance(
player->mo->x - player->nextwaypoint->mobj->x,
player->mo->y - player->nextwaypoint->mobj->y);
disttowaypoint = P_AproxDistance(disttowaypoint, player->mo->z - player->nextwaypoint->mobj->z);
adddist = ((UINT32)disttowaypoint) >> FRACBITS;
player->distancetofinish = pathtofinish.totaldist + adddist;
Z_Free(pathtofinish.array);
// distancetofinish is currently a flat distance to the finish line, but in order to be fully
// correct we need to add to it the length of the entire circuit multiplied by the number of laps
// left after this one. This will give us the total distance to the finish line, and allow item
// distance calculation to work easily
if ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) == 0U)
{
const UINT8 numfulllapsleft = ((UINT8)cv_numlaps.value - player->laps);
player->distancetofinish += numfulllapsleft * K_GetCircuitLength();
// An additional HACK, to fix looking backwards towards the finish line
// If the player's next waypoint is the finishline and the angle distance from player to
// connectin waypoints implies they're closer to a next waypoint, add a full track distance
if (player->nextwaypoint == finishline)
{
if (K_PlayerCloserToNextWaypoints(player->nextwaypoint, player) == true)
{
player->distancetofinish += K_GetCircuitLength();
}
}
}
}
}
}
}
}
//
// K_KartUpdatePosition
//
@ -9784,7 +9785,7 @@ void K_drawKartFreePlay(UINT32 flashtime)
return;
V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy
LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY");
LAPS_Y+3, V_HUDTRANS|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY");
}
static void K_drawDistributionDebugger(void)

View file

@ -8322,7 +8322,11 @@ void A_ItemPop(mobj_t *actor)
void A_JawzChase(mobj_t *actor)
{
const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy);
player_t *player;
fixed_t thrustamount = 0;
fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction;
fixed_t topspeed = actor->movefactor;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_JawzChase", actor))
return;
@ -8335,20 +8339,100 @@ void A_JawzChase(mobj_t *actor)
if (actor->tracer->health)
{
const angle_t targetangle = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
mobj_t *ret;
angle_t angledelta = actor->angle - targetangle;
boolean turnclockwise = true;
if (G_RaceGametype())
{
const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4)));
const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y);
if (distaway < distbarrier)
{
if (actor->tracer->player)
{
fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false)));
topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier));
}
}
}
if (angledelta != 0)
{
angle_t MAX_JAWZ_TURN = ANGLE_90/15; // We can turn a maximum of 6 degrees per frame at regular max speed
// MAX_JAWZ_TURN gets stronger the slower the top speed of jawz
if (topspeed < actor->movefactor)
{
if (topspeed == 0)
{
MAX_JAWZ_TURN = ANGLE_180;
}
else
{
fixed_t anglemultiplier = FixedDiv(actor->movefactor, topspeed);
MAX_JAWZ_TURN += FixedAngle(FixedMul(AngleFixed(MAX_JAWZ_TURN), anglemultiplier));
}
}
if (angledelta > ANGLE_180)
{
angledelta = InvAngle(angledelta);
turnclockwise = false;
}
if (angledelta > MAX_JAWZ_TURN)
{
angledelta = MAX_JAWZ_TURN;
}
if (turnclockwise)
{
actor->angle -= angledelta;
}
else
{
actor->angle += angledelta;
}
}
ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE);
P_SetTarget(&ret->target, actor->tracer);
ret->frame |= ((leveltime % 10) / 2) + 5;
ret->color = actor->cvmem;
P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), (7*actor->movefactor)/64);
return;
}
else
P_SetTarget(&actor->tracer, NULL);
}
if (!P_IsObjectOnGround(actor))
{
// No friction in the air
frictionsafety = FRACUNIT;
}
if (currentspeed >= topspeed)
{
// Thrust as if you were at top speed, slow down naturally
thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed;
}
else
{
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
// Thrust to immediately get to top speed
thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety);
}
if (!actor->tracer)
{
actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy);
}
P_Thrust(actor, actor->angle, thrustamount);
if ((actor->tracer != NULL) && (actor->tracer->health > 0))
return;
if (actor->extravalue1) // Disable looking by setting this
return;

View file

@ -1937,7 +1937,7 @@ void P_XYMovement(mobj_t *mo)
#endif
//{ SRB2kart stuff
if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer))
if (mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer))
return;
if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2)
@ -7935,9 +7935,18 @@ void P_MobjThinker(mobj_t *mobj)
else
{
fixed_t finalspeed = mobj->movefactor;
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
fixed_t thrustamount = 0;
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
mobj_t *ghost = P_SpawnGhostMobj(mobj);
ghost->colorized = true; // already has color!
if (!grounded)
{
// No friction in the air
frictionsafety = FRACUNIT;
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
if (mobj->health <= 5)
{
@ -7946,7 +7955,19 @@ void P_MobjThinker(mobj_t *mobj)
finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4);
}
P_InstaThrust(mobj, mobj->angle, finalspeed);
if (currentspeed >= finalspeed)
{
// Thrust as if you were at top speed, slow down naturally
thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed;
}
else
{
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
// Thrust to immediately get to top speed
thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety);
}
P_Thrust(mobj, mobj->angle, thrustamount);
if (grounded)
{
@ -7968,9 +7989,6 @@ void P_MobjThinker(mobj_t *mobj)
case MT_JAWZ:
{
sector_t *sec2;
fixed_t topspeed = mobj->movefactor;
fixed_t distbarrier = 512*mapobjectscale;
fixed_t distaway;
mobj_t *ghost = P_SpawnGhostMobj(mobj);
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player)
@ -7984,37 +8002,7 @@ void P_MobjThinker(mobj_t *mobj)
if (leveltime % TICRATE == 0)
S_StartSound(mobj, mobj->info->activesound);
distbarrier = FixedMul(distbarrier, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4)));
if (G_RaceGametype() && mobj->tracer)
{
distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y);
if (distaway < distbarrier)
{
if (mobj->tracer->player)
{
fixed_t speeddifference = abs(topspeed - min(mobj->tracer->player->speed, K_GetKartSpeed(mobj->tracer->player, false)));
topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier));
}
}
}
if (G_BattleGametype())
{
mobj->friction -= 1228;
if (mobj->friction > FRACUNIT)
mobj->friction = FRACUNIT;
if (mobj->friction < 0)
mobj->friction = 0;
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, topspeed);
if (mobj->tracer)
mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y);
else
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
// Movement handling has ALL been moved to A_JawzChase
K_DriftDustHandling(mobj);
@ -8042,6 +8030,9 @@ void P_MobjThinker(mobj_t *mobj)
else
{
mobj_t *ghost = P_SpawnGhostMobj(mobj);
const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy);
fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction;
fixed_t thrustamount = 0;
if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player)
{
@ -8049,8 +8040,26 @@ void P_MobjThinker(mobj_t *mobj)
ghost->colorized = true;
}
if (!grounded)
{
// No friction in the air
frictionsafety = FRACUNIT;
}
if (currentspeed >= mobj->movefactor)
{
// Thrust as if you were at top speed, slow down naturally
thrustamount = FixedDiv(mobj->movefactor, frictionsafety) - mobj->movefactor;
}
else
{
const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed;
// Thrust to immediately get to top speed
thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety);
}
mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy);
P_InstaThrust(mobj, mobj->angle, mobj->movefactor);
P_Thrust(mobj, mobj->angle, thrustamount);
if (grounded)
{
@ -9447,7 +9456,9 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
|| mobj->type == MT_BIGTUMBLEWEED
|| mobj->type == MT_LITTLETUMBLEWEED
|| mobj->type == MT_CANNONBALLDECOR
|| mobj->type == MT_FALLINGROCK) {
|| mobj->type == MT_FALLINGROCK
|| mobj->type == MT_ORBINAUT
|| mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD) {
P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly
//if (mobj->standingslope) CONS_Printf("slope physics on mobj\n");
P_ButteredSlope(mobj);

View file

@ -871,33 +871,31 @@ void P_ButteredSlope(mobj_t *mo)
return; // don't slide down slopes if you can't touch them or you're not affected by gravity
if (mo->player) {
if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING))
// Changed in kart to only not apply physics on very slight slopes (I think about 4 degree angles)
if (abs(mo->standingslope->zdelta) < FRACUNIT/21 && !(mo->player->pflags & PF_SPINNING))
return; // Don't slide on non-steep slopes unless spinning
// This only means you can be stopped on slopes that aren't steeper than 45 degrees
if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy))
return; // Allow the player to stand still on slopes below a certain steepness
}
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 15 / 16 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 4 / 5 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1);
if (mo->player && (mo->player->pflags & PF_SPINNING)) {
fixed_t mult = 0;
if (mo->player) {
fixed_t mult = FRACUNIT;
if (mo->momx || mo->momy) {
angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection;
if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0)
angle ^= ANGLE_180;
mult = FINECOSINE(angle >> ANGLETOFINESHIFT);
mult = FRACUNIT + (FRACUNIT + FINECOSINE(angle>>ANGLETOFINESHIFT))*3/2;
}
thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8);
thrust = FixedMul(thrust, mult);
}
if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed
thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16);
// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
// Let's get the gravity strength for the object...
thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo)));

View file

@ -4186,6 +4186,11 @@ static void P_3dMovement(player_t *player)
// If "no" to 2, normalize to topspeed, so we can't suddenly run faster than it of our own accord.
// If "no" to 1, we're not reaching any limits yet, so ignore this entirely!
// -Shadow Hog
// Only do this forced cap of speed when in midair, the kart acceleration code takes into account friction, and
// doesn't let you accelerate past top speed, so this is unnecessary on the ground, but in the air is needed to
// allow for being able to change direction on spring jumps without being accelerated into the void - Sryder
if (!P_IsObjectOnGround(player->mo))
{
newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed)
{
@ -4210,6 +4215,7 @@ static void P_3dMovement(player_t *player)
}
}
}
}
//
// P_SpectatorMovement

View file

@ -427,13 +427,13 @@ void SCR_DisplayTicRate(void)
ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/
// draw "FPS"
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
// draw total frame:
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, TICRATE, ticcntcolor);
V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, TICRATE, ticcntcolor);
// draw "/"
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, frameslash, ticcntcolor);
V_DrawFixedPatch(306<<FRACBITS, 190<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, frameslash, ticcntcolor);
// draw our actual framerate
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT, totaltics, ticcntcolor);
V_DrawPingNum(306, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, totaltics, ticcntcolor);
lasttic = ontic;
@ -448,6 +448,6 @@ void SCR_DisplayLocalPing(void)
if (cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping)) // only show 2 (warning) if our ping is at a bad level
{
INT32 dispy = cv_ticrate.value ? 160 : 181;
HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM);
HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS);
}
}

View file

@ -1377,11 +1377,14 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
if (st_overlay)
{
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && consoleplayer != serverplayer)
SCR_DisplayLocalPing();
}
if (rendermode == render_soft && screens[0])
{