mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Adjust most player physics for Garden Top
- Auto accel - 800% acceleration - 110% top speed - Infinite tether like Lightning Shield - Resists going upward on slopes - Less friction - Can always turn your sprite - Turning speed does not get weaker at high speeds - Turning speed is normal underwater - Keeps moving in momentum direction, regardless of how you turn - Releasing a drift redirects all your momentum in that direction - Floats over bananas, damage sectors and offroad - No stair janking while floating - Hold drift for extra gravity. Not only does this fast fall (this stacks with true fast falling), it builds momentum down slopes too! - Parries Big Players (Grow), Invincibility, Flame Shield and, of course, other Tops -- all except if you're grinding - Wipes out anyone you touch - Infinite weight like Bubble Shield - Does not water skip - Does not water run while holding drift
This commit is contained in:
parent
5063a4acf1
commit
56a5432f41
6 changed files with 135 additions and 21 deletions
|
|
@ -66,17 +66,22 @@ boolean K_BananaBallhogCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t1->type == MT_BANANA && t1->health > 1)
|
||||
S_StartSound(t2, sfx_bsnipe);
|
||||
|
||||
damageitem = true;
|
||||
|
||||
if (t2->player->flamedash && t2->player->itemtype == KITEM_FLAMESHIELD)
|
||||
{
|
||||
// Melt item
|
||||
S_StartSound(t2, sfx_s3k43);
|
||||
}
|
||||
else if (K_IsRidingFloatingTop(t2->player))
|
||||
{
|
||||
// Float over silly banana
|
||||
damageitem = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
P_DamageMobj(t2, t1, t1->target, 1, DMG_NORMAL|DMG_WOMBO);
|
||||
}
|
||||
|
||||
damageitem = true;
|
||||
}
|
||||
else if (t2->type == MT_BANANA || t2->type == MT_BANANA_SHIELD
|
||||
|| t2->type == MT_ORBINAUT || t2->type == MT_ORBINAUT_SHIELD
|
||||
|
|
@ -774,11 +779,13 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
// Clash instead of damage if both parties have any of these conditions
|
||||
t1Condition = (K_IsBigger(t1, t2) == true)
|
||||
|| (t1->player->invincibilitytimer > 0)
|
||||
|| (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD);
|
||||
|| (t1->player->flamedash > 0 && t1->player->itemtype == KITEM_FLAMESHIELD)
|
||||
|| (t1->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t1->player));
|
||||
|
||||
t2Condition = (K_IsBigger(t2, t1) == true)
|
||||
|| (t2->player->invincibilitytimer > 0)
|
||||
|| (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD);
|
||||
|| (t2->player->flamedash > 0 && t2->player->itemtype == KITEM_FLAMESHIELD)
|
||||
|| (t2->player->curshield == KSHIELD_TOP && !K_IsHoldingDownTop(t2->player));
|
||||
|
||||
if (t1Condition == true && t2Condition == true)
|
||||
{
|
||||
|
|
|
|||
78
src/k_kart.c
78
src/k_kart.c
|
|
@ -1374,7 +1374,13 @@ static fixed_t K_PlayerWeight(mobj_t *mobj, mobj_t *against)
|
|||
if (!mobj->player)
|
||||
return weight;
|
||||
|
||||
if (against && !P_MobjWasRemoved(against) && against->player
|
||||
if (against && (against->type == MT_GARDENTOP || (against->player && against->player->curshield == KSHIELD_TOP)))
|
||||
{
|
||||
/* Players bumping into a Top get zero weight -- the
|
||||
Top rider is immovable. */
|
||||
weight = 0;
|
||||
}
|
||||
else if (against && !P_MobjWasRemoved(against) && against->player
|
||||
&& ((!P_PlayerInPain(against->player) && P_PlayerInPain(mobj->player)) // You're hurt
|
||||
|| (against->player->itemtype == KITEM_BUBBLESHIELD && mobj->player->itemtype != KITEM_BUBBLESHIELD))) // They have a Bubble Shield
|
||||
{
|
||||
|
|
@ -1962,6 +1968,18 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur
|
|||
#undef CHAOTIXBANDLEN
|
||||
}
|
||||
|
||||
static boolean K_HasInfiniteTether(player_t *player)
|
||||
{
|
||||
switch (player->curshield)
|
||||
{
|
||||
case KSHIELD_LIGHTNING:
|
||||
case KSHIELD_TOP:
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \brief Updates the player's drafting values once per frame
|
||||
|
||||
\param player player object passed from K_KartPlayerThink
|
||||
|
|
@ -1976,7 +1994,7 @@ static void K_UpdateDraft(player_t *player)
|
|||
UINT8 leniency;
|
||||
UINT8 i;
|
||||
|
||||
if (player->itemtype == KITEM_LIGHTNINGSHIELD)
|
||||
if (K_HasInfiniteTether(player))
|
||||
{
|
||||
// Lightning Shield gets infinite draft distance as its (other) passive effect.
|
||||
draftdistance = 0;
|
||||
|
|
@ -3267,6 +3285,8 @@ boolean K_ApplyOffroad(player_t *player)
|
|||
{
|
||||
if (player->invincibilitytimer || player->hyudorotimer || player->sneakertimer)
|
||||
return false;
|
||||
if (K_IsRidingFloatingTop(player))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3274,6 +3294,8 @@ boolean K_SlopeResistance(player_t *player)
|
|||
{
|
||||
if (player->invincibilitytimer || player->sneakertimer || player->tiregrease || player->flamedash)
|
||||
return true;
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -3320,6 +3342,9 @@ boolean K_WaterRun(player_t *player)
|
|||
|
||||
boolean K_WaterSkip(player_t *player)
|
||||
{
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
return false;
|
||||
|
||||
if (player->speed/3 > abs(player->mo->momz)) // Going more forward than horizontal, so you can skip across the water.
|
||||
return true;
|
||||
|
||||
|
|
@ -3531,7 +3556,7 @@ static void K_GetKartBoostPower(player_t *player)
|
|||
draftspeed *= 2;
|
||||
}
|
||||
|
||||
if (player->itemtype == KITEM_LIGHTNINGSHIELD)
|
||||
if (K_HasInfiniteTether(player))
|
||||
{
|
||||
// infinite tether
|
||||
draftspeed *= 2;
|
||||
|
|
@ -3653,6 +3678,10 @@ fixed_t K_GetKartAccel(player_t *player)
|
|||
if (gametype == GT_BATTLE && player->bumpers <= 0)
|
||||
k_accel *= 2;
|
||||
|
||||
// Marble Garden Top gets 800% accel
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
k_accel *= 8;
|
||||
|
||||
return FixedMul(k_accel, (FRACUNIT + player->accelboost) / 4);
|
||||
}
|
||||
|
||||
|
|
@ -3742,17 +3771,35 @@ SINT8 K_GetForwardMove(player_t *player)
|
|||
forwardmove = MAXPLMOVE;
|
||||
}
|
||||
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
{
|
||||
if (forwardmove < 0 ||
|
||||
(K_GetKartButtons(player) & BT_DRIFT))
|
||||
{
|
||||
forwardmove = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
forwardmove = MAXPLMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
return forwardmove;
|
||||
}
|
||||
|
||||
fixed_t K_GetNewSpeed(player_t *player)
|
||||
{
|
||||
const fixed_t accelmax = 4000;
|
||||
const fixed_t p_speed = K_GetKartSpeed(player, true, true);
|
||||
fixed_t p_speed = K_GetKartSpeed(player, true, true);
|
||||
fixed_t p_accel = K_GetKartAccel(player);
|
||||
|
||||
fixed_t newspeed, oldspeed, finalspeed;
|
||||
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
{
|
||||
p_speed = 11 * p_speed / 10;
|
||||
}
|
||||
|
||||
if (K_PlayerUsesBotMovement(player) == true && player->botvars.rubberband > 0)
|
||||
{
|
||||
// Acceleration is tied to top speed...
|
||||
|
|
@ -8964,13 +9011,25 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
|||
if ((currentSpeed <= 0) // Not moving
|
||||
&& ((K_GetKartButtons(player) & BT_EBRAKEMASK) != BT_EBRAKEMASK) // Not e-braking
|
||||
&& (player->respawn.state == RESPAWNST_NONE) // Not respawning
|
||||
&& (player->curshield != KSHIELD_TOP) // Not riding a Top
|
||||
&& (P_IsObjectOnGround(player->mo) == true)) // On the ground
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
p_maxspeed = K_GetKartSpeed(player, false, true);
|
||||
p_speed = min(currentSpeed, (p_maxspeed * 2));
|
||||
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
{
|
||||
// Do not downscale turning speed with faster
|
||||
// movement speed; behaves as if turning in place.
|
||||
p_speed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
p_speed = min(currentSpeed, (p_maxspeed * 2));
|
||||
}
|
||||
|
||||
weightadjust = FixedDiv((p_maxspeed * 3) - p_speed, (p_maxspeed * 3) + (player->kartweight * FRACUNIT));
|
||||
|
||||
if (K_PlayerUsesBotMovement(player))
|
||||
|
|
@ -8997,7 +9056,9 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
|||
turnfixed = FixedMul(turnfixed, FRACUNIT + player->handleboost);
|
||||
}
|
||||
|
||||
if ((player->mo->eflags & MFE_UNDERWATER) &&
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
;
|
||||
else if ((player->mo->eflags & MFE_UNDERWATER) &&
|
||||
player->speed > 11 * player->mo->scale)
|
||||
{
|
||||
turnfixed /= 2;
|
||||
|
|
@ -10013,6 +10074,11 @@ void K_AdjustPlayerFriction(player_t *player)
|
|||
player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->tiregrease;
|
||||
}
|
||||
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
{
|
||||
player->mo->friction += 1024;
|
||||
}
|
||||
|
||||
/*
|
||||
if (K_PlayerEBrake(player) == true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2850,6 +2850,11 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
|
|||
thing->terrain = NULL;
|
||||
}
|
||||
|
||||
if (thing->player && K_IsRidingFloatingTop(thing->player))
|
||||
{
|
||||
stairjank = false;
|
||||
}
|
||||
|
||||
/* FIXME: slope step down (even up) has some false
|
||||
positives, so just ignore them entirely. */
|
||||
if (stairjank && !oldslope && !thing->standingslope &&
|
||||
|
|
|
|||
33
src/p_mobj.c
33
src/p_mobj.c
|
|
@ -1133,7 +1133,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
gravityadd = FixedMul(TUMBLEGRAVITY, gravityadd);
|
||||
}
|
||||
|
||||
if (mo->player->fastfall != 0)
|
||||
if (K_IsHoldingDownTop(mo->player))
|
||||
{
|
||||
gravityadd = (5*gravityadd)/2;
|
||||
}
|
||||
else if (mo->player->fastfall != 0)
|
||||
{
|
||||
// Fast falling
|
||||
gravityadd *= 4;
|
||||
|
|
@ -3092,13 +3096,26 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
|||
fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight);
|
||||
fixed_t span = player->mo->watertop - player->mo->waterbottom;
|
||||
|
||||
return
|
||||
clip > -(player->mo->height / 2) &&
|
||||
span > player->mo->height &&
|
||||
player->speed / 5 > abs(player->mo->momz) &&
|
||||
player->speed > K_GetKartSpeed(player, false, false) &&
|
||||
K_WaterRun(player) &&
|
||||
(rover->flags & FF_SWIMMABLE);
|
||||
if (!(rover->flags & FF_SWIMMABLE) ||
|
||||
clip < -(player->mo->height / 2) ||
|
||||
span < player->mo->height)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player->curshield == KSHIELD_TOP)
|
||||
{
|
||||
return (K_GetKartButtons(player) & BT_DRIFT) != BT_DRIFT;
|
||||
}
|
||||
|
||||
if (K_WaterRun(player) &&
|
||||
player->speed / 5 > abs(player->mo->momz) &&
|
||||
player->speed > K_GetKartSpeed(player, false, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover)
|
||||
|
|
|
|||
|
|
@ -4426,7 +4426,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
switch (special)
|
||||
{
|
||||
case 1: // Damage (Generic)
|
||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||
if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector)))
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
||||
break;
|
||||
case 2: // Damage (Water) // SRB2kart - These three damage types are now offroad sectors
|
||||
|
|
@ -4434,7 +4434,7 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
|
|||
case 4: // Damage (Electrical)
|
||||
break;
|
||||
case 5: // Spikes
|
||||
if (roversector || P_MobjReadyToTrigger(player->mo, sector))
|
||||
if (!K_IsRidingFloatingTop(player) && (roversector || P_MobjReadyToTrigger(player->mo, sector)))
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_NORMAL);
|
||||
break;
|
||||
case 6: // Death Pit (Camera Mod)
|
||||
|
|
|
|||
21
src/p_user.c
21
src/p_user.c
|
|
@ -1801,7 +1801,7 @@ static void P_3dMovement(player_t *player)
|
|||
// Get the old momentum; this will be needed at the end of the function! -SH
|
||||
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
|
||||
|
||||
if (player->stairjank > 8 && leveltime & 3)
|
||||
if ((player->stairjank > 8 && leveltime & 3) || K_IsRidingFloatingTop(player))
|
||||
{
|
||||
movepushangle = K_MomentumAngle(player->mo);
|
||||
}
|
||||
|
|
@ -1884,6 +1884,7 @@ static void P_3dMovement(player_t *player)
|
|||
if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration...
|
||||
movepushforward = FixedMul(movepushforward, player->mo->movefactor);
|
||||
|
||||
if (player->curshield != KSHIELD_TOP)
|
||||
{
|
||||
INT32 a = K_GetUnderwaterTurnAdjust(player);
|
||||
INT32 adj = 0;
|
||||
|
|
@ -1967,6 +1968,24 @@ static void P_3dMovement(player_t *player)
|
|||
player->mo->momx += totalthrust.x;
|
||||
player->mo->momy += totalthrust.y;
|
||||
|
||||
// Releasing a drift while on the Top translates all your
|
||||
// momentum (and even then some) into whichever direction
|
||||
// you're facing
|
||||
if (onground && player->curshield == KSHIELD_TOP && (K_GetKartButtons(player) & BT_DRIFT) != BT_DRIFT && (player->oldcmd.buttons & BT_DRIFT))
|
||||
{
|
||||
const fixed_t gmin = FRACUNIT/4;
|
||||
const fixed_t gmax = 5*FRACUNIT/2;
|
||||
|
||||
const fixed_t grindfactor = (gmax - gmin) / GARDENTOP_MAXGRINDTIME;
|
||||
const fixed_t grindscale = gmin + (player->topdriftheld * grindfactor);
|
||||
|
||||
const fixed_t speed = R_PointToDist2(0, 0, player->mo->momx, player->mo->momy);
|
||||
|
||||
P_InstaThrust(player->mo, player->mo->angle, FixedMul(speed, grindscale));
|
||||
|
||||
player->topdriftheld = 0;/* reset after release */
|
||||
}
|
||||
|
||||
if (!onground)
|
||||
{
|
||||
const fixed_t airspeedcap = (50*mapobjectscale);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue