mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-01-09 16:32:33 +00:00
Merge branch 'water-skip-conditions' into 'master'
Fun times at the pool See merge request KartKrew/Kart!710
This commit is contained in:
commit
ff05234783
13 changed files with 458 additions and 184 deletions
|
|
@ -446,7 +446,6 @@ typedef struct player_s
|
|||
INT32 underwatertilt;
|
||||
|
||||
fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
|
||||
UINT8 waterskip; // Water skipping counter
|
||||
|
||||
UINT16 tiregrease; // Reduced friction timer after hitting a spring
|
||||
UINT16 springstars; // Spawn stars around a player when they hit a spring
|
||||
|
|
|
|||
271
src/k_kart.c
271
src/k_kart.c
|
|
@ -3231,7 +3231,7 @@ tripwirepass_t K_TripwirePassConditions(player_t *player)
|
|||
|
||||
if (
|
||||
player->flamedash ||
|
||||
player->speed > 2 * K_GetKartSpeed(player, false, true)
|
||||
player->speed > 2 * K_GetKartSpeed(player, false, false)
|
||||
)
|
||||
return TRIPWIRE_BOOST;
|
||||
|
||||
|
|
@ -3249,17 +3249,241 @@ boolean K_TripwirePass(player_t *player)
|
|||
return (player->tripwirePass != TRIPWIRE_NONE);
|
||||
}
|
||||
|
||||
boolean K_WaterRun(player_t *player)
|
||||
boolean K_MovingHorizontally(mobj_t *mobj)
|
||||
{
|
||||
if (
|
||||
player->invincibilitytimer ||
|
||||
player->sneakertimer ||
|
||||
player->tiregrease ||
|
||||
player->flamedash ||
|
||||
player->speed > 2 * K_GetKartSpeed(player, false, true)
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
return (P_AproxDistance(mobj->momx, mobj->momy) / 5 > abs(mobj->momz));
|
||||
}
|
||||
|
||||
boolean K_WaterRun(mobj_t *mobj)
|
||||
{
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_JAWZ:
|
||||
{
|
||||
if (mobj->tracer != NULL && P_MobjWasRemoved(mobj->tracer) == false)
|
||||
{
|
||||
fixed_t jawzFeet = P_GetMobjFeet(mobj);
|
||||
fixed_t chaseFeet = P_GetMobjFeet(mobj->tracer);
|
||||
fixed_t footDiff = (chaseFeet - jawzFeet) * P_MobjFlip(mobj);
|
||||
|
||||
// Water run if the player we're chasing is above/equal to us.
|
||||
// Start water skipping if they're underneath the water.
|
||||
return (footDiff > -mobj->tracer->height);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case MT_PLAYER:
|
||||
{
|
||||
if (mobj->player == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mobj->player->invincibilitytimer
|
||||
|| mobj->player->sneakertimer
|
||||
|| mobj->player->tiregrease
|
||||
|| mobj->player->flamedash
|
||||
|| mobj->player->speed > 2 * K_GetKartSpeed(mobj->player, false, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean K_WaterSkip(mobj_t *mobj)
|
||||
{
|
||||
if (mobj->waterskip >= 2)
|
||||
{
|
||||
// Already finished waterskipping.
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (mobj->type)
|
||||
{
|
||||
case MT_PLAYER:
|
||||
case MT_ORBINAUT:
|
||||
case MT_JAWZ:
|
||||
case MT_BALLHOG:
|
||||
{
|
||||
// Allow
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
// Don't allow
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->waterskip > 0)
|
||||
{
|
||||
// Already waterskipping.
|
||||
// Simply make sure you haven't slowed down drastically.
|
||||
return (P_AproxDistance(mobj->momx, mobj->momy) > 20 * mapobjectscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Need to be moving horizontally and not vertically
|
||||
// to be able to start a water skip.
|
||||
return K_MovingHorizontally(mobj);
|
||||
}
|
||||
}
|
||||
|
||||
void K_SpawnWaterRunParticles(mobj_t *mobj)
|
||||
{
|
||||
fixed_t runSpeed = 14 * mobj->scale;
|
||||
fixed_t curSpeed = INT32_MAX;
|
||||
fixed_t topSpeed = INT32_MAX;
|
||||
fixed_t trailScale = FRACUNIT;
|
||||
|
||||
if (mobj->momz != 0)
|
||||
{
|
||||
// Only while touching ground.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mobj->watertop == INT32_MAX || mobj->waterbottom == INT32_MIN)
|
||||
{
|
||||
// Invalid water plane.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mobj->player != NULL)
|
||||
{
|
||||
if (mobj->player->spectator)
|
||||
{
|
||||
// Not as spectator.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mobj->player->carry == CR_SLIDING)
|
||||
{
|
||||
// Not in water slides.
|
||||
return;
|
||||
}
|
||||
|
||||
topSpeed = K_GetKartSpeed(mobj->player, false, false);
|
||||
runSpeed = FixedMul(runSpeed, mobj->movefactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
topSpeed = FixedMul(mobj->scale, K_GetKartSpeedFromStat(5));
|
||||
}
|
||||
|
||||
curSpeed = P_AproxDistance(mobj->momx, mobj->momy);
|
||||
|
||||
if (curSpeed <= runSpeed)
|
||||
{
|
||||
// Not fast enough.
|
||||
return;
|
||||
}
|
||||
|
||||
// Near the water plane.
|
||||
if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->watertop && mobj->z <= mobj->watertop)
|
||||
|| (mobj->eflags & MFE_VERTICALFLIP && mobj->z + mobj->height >= mobj->waterbottom && mobj->z <= mobj->waterbottom))
|
||||
{
|
||||
if (topSpeed > runSpeed)
|
||||
{
|
||||
trailScale = FixedMul(FixedDiv(curSpeed - runSpeed, topSpeed - runSpeed), mapobjectscale);
|
||||
}
|
||||
else
|
||||
{
|
||||
trailScale = mapobjectscale; // Scaling is based off difference between runspeed and top speed
|
||||
}
|
||||
|
||||
if (trailScale > 0)
|
||||
{
|
||||
const angle_t forwardangle = K_MomentumAngle(mobj);
|
||||
const fixed_t playerVisualRadius = mobj->radius + (8 * mobj->scale);
|
||||
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
|
||||
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
|
||||
const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames);
|
||||
fixed_t x1, x2, y1, y2;
|
||||
mobj_t *water;
|
||||
|
||||
x1 = mobj->x + mobj->momx + P_ReturnThrustX(mobj, forwardangle + ANGLE_90, playerVisualRadius);
|
||||
y1 = mobj->y + mobj->momy + P_ReturnThrustY(mobj, forwardangle + ANGLE_90, playerVisualRadius);
|
||||
x1 = x1 + P_ReturnThrustX(mobj, forwardangle, playerVisualRadius);
|
||||
y1 = y1 + P_ReturnThrustY(mobj, forwardangle, playerVisualRadius);
|
||||
|
||||
x2 = mobj->x + mobj->momx + P_ReturnThrustX(mobj, forwardangle - ANGLE_90, playerVisualRadius);
|
||||
y2 = mobj->y + mobj->momy + P_ReturnThrustY(mobj, forwardangle - ANGLE_90, playerVisualRadius);
|
||||
x2 = x2 + P_ReturnThrustX(mobj, forwardangle, playerVisualRadius);
|
||||
y2 = y2 + P_ReturnThrustY(mobj, forwardangle, playerVisualRadius);
|
||||
|
||||
// Left
|
||||
// underlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = mobj->momx;
|
||||
water->momy = mobj->momy;
|
||||
water->momz = mobj->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
// overlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = mobj->momx;
|
||||
water->momy = mobj->momy;
|
||||
water->momz = mobj->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
// Right
|
||||
// Underlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, mobj->scale) : mobj->watertop), MT_WATERTRAILUNDERLAY);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = mobj->momx;
|
||||
water->momy = mobj->momy;
|
||||
water->momz = mobj->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
// Overlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((mobj->eflags & MFE_VERTICALFLIP) ? mobj->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, mobj->scale) : mobj->watertop), MT_WATERTRAIL);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = mobj->momx;
|
||||
water->momy = mobj->momy;
|
||||
water->momz = mobj->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
if (!S_SoundPlaying(mobj, sfx_s3kdbs))
|
||||
{
|
||||
const INT32 volume = (min(trailScale, FRACUNIT) * 255) / FRACUNIT;
|
||||
S_StartSoundAtVolume(mobj, sfx_s3kdbs, volume);
|
||||
}
|
||||
}
|
||||
|
||||
// Little water sound while touching water - just a nicety.
|
||||
if ((mobj->eflags & MFE_TOUCHWATER) && !(mobj->eflags & MFE_UNDERWATER))
|
||||
{
|
||||
if (P_RandomChance(PR_BUBBLE, FRACUNIT/2) && leveltime % TICRATE == 0)
|
||||
{
|
||||
S_StartSound(mobj, sfx_floush);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static fixed_t K_FlameShieldDashVar(INT32 val)
|
||||
|
|
@ -7956,9 +8180,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(player->mo))
|
||||
player->waterskip = 0;
|
||||
|
||||
if (player->instashield)
|
||||
player->instashield--;
|
||||
|
||||
|
|
@ -8752,6 +8973,16 @@ INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering)
|
|||
return outputSteering;
|
||||
}
|
||||
|
||||
static fixed_t K_GetUnderwaterStrafeMul(player_t *player)
|
||||
{
|
||||
const fixed_t minSpeed = 11 * player->mo->scale;
|
||||
fixed_t baseline = INT32_MAX;
|
||||
|
||||
baseline = 2 * K_GetKartSpeed(player, false, true) / 3;
|
||||
|
||||
return max(0, FixedDiv(player->speed - minSpeed, baseline - minSpeed));
|
||||
}
|
||||
|
||||
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
||||
{
|
||||
fixed_t turnfixed = turnvalue * FRACUNIT;
|
||||
|
|
@ -8829,10 +9060,10 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
|||
turnfixed = FixedMul(turnfixed, FRACUNIT + player->handleboost);
|
||||
}
|
||||
|
||||
if ((player->mo->eflags & MFE_UNDERWATER) &&
|
||||
player->speed > 11 * player->mo->scale)
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
turnfixed /= 2;
|
||||
fixed_t div = min(FRACUNIT + K_GetUnderwaterStrafeMul(player), 2*FRACUNIT);
|
||||
turnfixed = FixedDiv(turnfixed, div);
|
||||
}
|
||||
|
||||
// Weight has a small effect on turning
|
||||
|
|
@ -8843,8 +9074,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
|
|||
|
||||
INT32 K_GetUnderwaterTurnAdjust(player_t *player)
|
||||
{
|
||||
if ((player->mo->eflags & MFE_UNDERWATER) &&
|
||||
player->speed > 11 * player->mo->scale)
|
||||
if (player->mo->eflags & MFE_UNDERWATER)
|
||||
{
|
||||
INT32 steer = (K_GetKartTurnValue(player,
|
||||
player->steering) << TICCMD_REDUCE);
|
||||
|
|
@ -8852,8 +9082,7 @@ INT32 K_GetUnderwaterTurnAdjust(player_t *player)
|
|||
if (!player->drift)
|
||||
steer = 9 * steer / 5;
|
||||
|
||||
return FixedMul(steer, 8 * FixedDiv(player->speed,
|
||||
2 * K_GetKartSpeed(player, false, true) / 3));
|
||||
return FixedMul(steer, 8 * K_GetUnderwaterStrafeMul(player));
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -142,7 +142,10 @@ boolean K_ApplyOffroad(player_t *player);
|
|||
boolean K_SlopeResistance(player_t *player);
|
||||
tripwirepass_t K_TripwirePassConditions(player_t *player);
|
||||
boolean K_TripwirePass(player_t *player);
|
||||
boolean K_WaterRun(player_t *player);
|
||||
boolean K_MovingHorizontally(mobj_t *mobj);
|
||||
boolean K_WaterRun(mobj_t *mobj);
|
||||
boolean K_WaterSkip(mobj_t *mobj);
|
||||
void K_SpawnWaterRunParticles(mobj_t *mobj);
|
||||
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
|
||||
INT16 K_GetSpindashChargeTime(player_t *player);
|
||||
fixed_t K_GetSpindashChargeSpeed(player_t *player);
|
||||
|
|
|
|||
|
|
@ -954,12 +954,15 @@ static int lib_pCheckDeathPitCollide(lua_State *L)
|
|||
|
||||
static int lib_pCheckSolidLava(lua_State *L)
|
||||
{
|
||||
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||
ffloor_t *rover = *((ffloor_t **)luaL_checkudata(L, 2, META_FFLOOR));
|
||||
//HUDSAFE
|
||||
INLEVEL
|
||||
if (!mo)
|
||||
return LUA_ErrInvalid(L, "mobj_t");
|
||||
if (!rover)
|
||||
return LUA_ErrInvalid(L, "ffloor_t");
|
||||
lua_pushboolean(L, P_CheckSolidLava(rover));
|
||||
lua_pushboolean(L, P_CheckSolidLava(mo, rover));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ enum mobj_e {
|
|||
mobj_spryoff,
|
||||
mobj_sprzoff,
|
||||
mobj_hitlag,
|
||||
mobj_waterskip,
|
||||
mobj_dispoffset
|
||||
};
|
||||
|
||||
|
|
@ -181,6 +182,7 @@ static const char *const mobj_opt[] = {
|
|||
"spryoff",
|
||||
"sprzoff",
|
||||
"hitlag",
|
||||
"waterskip",
|
||||
"dispoffset",
|
||||
NULL};
|
||||
|
||||
|
|
@ -460,6 +462,9 @@ static int mobj_get(lua_State *L)
|
|||
case mobj_hitlag:
|
||||
lua_pushinteger(L, mo->hitlag);
|
||||
break;
|
||||
case mobj_waterskip:
|
||||
lua_pushinteger(L, mo->waterskip);
|
||||
break;
|
||||
case mobj_dispoffset:
|
||||
lua_pushinteger(L, mo->dispoffset);
|
||||
break;
|
||||
|
|
@ -835,6 +840,9 @@ static int mobj_set(lua_State *L)
|
|||
case mobj_hitlag:
|
||||
mo->hitlag = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_waterskip:
|
||||
mo->waterskip = (UINT8)luaL_checkinteger(L, 3);
|
||||
break;
|
||||
case mobj_dispoffset:
|
||||
mo->dispoffset = luaL_checkinteger(L, 3);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -264,8 +264,6 @@ static int player_get(lua_State *L)
|
|||
lua_pushinteger(L, plr->aizdriftturn);
|
||||
else if (fastcmp(field,"offroad"))
|
||||
lua_pushinteger(L, plr->offroad);
|
||||
else if (fastcmp(field,"waterskip"))
|
||||
lua_pushinteger(L, plr->waterskip);
|
||||
else if (fastcmp(field,"tiregrease"))
|
||||
lua_pushinteger(L, plr->tiregrease);
|
||||
else if (fastcmp(field,"springstars"))
|
||||
|
|
@ -634,8 +632,6 @@ static int player_set(lua_State *L)
|
|||
plr->aizdriftturn = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"offroad"))
|
||||
plr->offroad = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"waterskip"))
|
||||
plr->waterskip = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"tiregrease"))
|
||||
plr->tiregrease = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"springstars"))
|
||||
|
|
|
|||
|
|
@ -315,7 +315,7 @@ fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, f
|
|||
|
||||
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
|
||||
boolean P_CheckDeathPitCollide(mobj_t *mo);
|
||||
boolean P_CheckSolidLava(ffloor_t *rover);
|
||||
boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover);
|
||||
void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype);
|
||||
|
||||
mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zofs, mobjtype_t type);
|
||||
|
|
@ -337,8 +337,8 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
|
|||
void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab);
|
||||
mobj_t *P_GetClosestAxis(mobj_t *source);
|
||||
|
||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover);
|
||||
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover);
|
||||
boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover);
|
||||
boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover);
|
||||
|
||||
void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot);
|
||||
|
||||
|
|
|
|||
|
|
@ -1940,7 +1940,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (thing->player && P_CheckSolidFFloorSurface(thing->player, rover))
|
||||
if (P_CheckSolidFFloorSurface(thing, rover))
|
||||
;
|
||||
else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))
|
||||
;
|
||||
|
|
@ -2524,9 +2524,7 @@ static boolean P_WaterRunning(mobj_t *thing)
|
|||
|
||||
static boolean P_WaterStepUp(mobj_t *thing)
|
||||
{
|
||||
player_t *player = thing->player;
|
||||
return (player && player->waterskip) ||
|
||||
P_WaterRunning(thing);
|
||||
return (thing->waterskip > 0 || P_WaterRunning(thing));
|
||||
}
|
||||
|
||||
fixed_t P_BaseStepUp(void)
|
||||
|
|
|
|||
|
|
@ -777,7 +777,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover))
|
||||
if (P_CheckSolidFFloorSurface(mobj, rover))
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
|
@ -821,7 +821,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
|
|||
if (!(rover->flags & FF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover))
|
||||
if (P_CheckSolidFFloorSurface(mobj, rover))
|
||||
;
|
||||
else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|
||||
|| (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
|
||||
|
|
|
|||
224
src/p_mobj.c
224
src/p_mobj.c
|
|
@ -1105,6 +1105,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
}
|
||||
}
|
||||
|
||||
if (mo->waterskip > 0)
|
||||
{
|
||||
gravityadd = (4*gravityadd)/3;
|
||||
}
|
||||
|
||||
if (mo->player)
|
||||
{
|
||||
if (mo->flags2 & MF2_OBJECTFLIP)
|
||||
|
|
@ -1118,11 +1123,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
|
|||
P_PlayerFlip(mo);
|
||||
}
|
||||
|
||||
if (mo->player->waterskip)
|
||||
{
|
||||
gravityadd = (4*gravityadd)/3;
|
||||
}
|
||||
|
||||
if (mo->player->trickpanel >= 2)
|
||||
{
|
||||
gravityadd = (5*gravityadd)/2;
|
||||
|
|
@ -1938,7 +1938,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype)
|
|||
topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL);
|
||||
|
||||
if (mo->player && P_CheckSolidFFloorSurface(mo->player, rover)) // only the player should stand on lava or run on water
|
||||
if (P_CheckSolidFFloorSurface(mo, rover)) // only the player should stand on lava or run on water
|
||||
;
|
||||
else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only
|
||||
continue;
|
||||
|
|
@ -2097,11 +2097,18 @@ boolean P_CheckDeathPitCollide(mobj_t *mo)
|
|||
return false;
|
||||
}
|
||||
|
||||
boolean P_CheckSolidLava(ffloor_t *rover)
|
||||
boolean P_CheckSolidLava(mobj_t *mobj, ffloor_t *rover)
|
||||
{
|
||||
if (mobj->player == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
|
||||
&& !(rover->master->flags & ML_BLOCKPLAYERS))
|
||||
return true;
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3079,31 +3086,115 @@ boolean P_SceneryZMovement(mobj_t *mo)
|
|||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// P_CanRunOnWater
|
||||
//
|
||||
// Returns true if player can waterrun on the 3D floor
|
||||
// Returns true if player can water run on a 3D floor
|
||||
//
|
||||
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
|
||||
boolean P_CanRunOnWater(mobj_t *mobj, ffloor_t *rover)
|
||||
{
|
||||
boolean flip = player->mo->eflags & MFE_VERTICALFLIP;
|
||||
fixed_t surfaceheight = flip ? player->mo->waterbottom : player->mo->watertop;
|
||||
fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z;
|
||||
fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight);
|
||||
fixed_t span = player->mo->watertop - player->mo->waterbottom;
|
||||
const boolean flip = (mobj->eflags & MFE_VERTICALFLIP);
|
||||
player_t *player = mobj->player;
|
||||
|
||||
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);
|
||||
fixed_t surfaceheight = INT32_MAX;
|
||||
fixed_t surfDiff = INT32_MAX;
|
||||
|
||||
fixed_t floorheight = INT32_MAX;
|
||||
fixed_t floorDiff = INT32_MAX;
|
||||
|
||||
fixed_t mobjbottom = INT32_MAX;
|
||||
fixed_t maxStep = INT32_MAX;
|
||||
boolean doifit = false;
|
||||
|
||||
pslope_t *waterSlope = NULL;
|
||||
angle_t ourZAng = 0;
|
||||
angle_t waterZAng = 0;
|
||||
|
||||
if (rover == NULL)
|
||||
{
|
||||
// No rover.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(rover->flags & FF_SWIMMABLE))
|
||||
{
|
||||
// It's not even a water FOF.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player != NULL
|
||||
&& player->carry != CR_NONE) // Special carry state.
|
||||
{
|
||||
// No good player state.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (P_IsObjectOnGround(mobj) == false)
|
||||
{
|
||||
// Don't allow jumping onto water to start a water run.
|
||||
// (Already water running still counts as being on the ground.)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (K_WaterRun(mobj) == false)
|
||||
{
|
||||
// Basic conditions for enabling water run.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mobj->standingslope != NULL)
|
||||
{
|
||||
ourZAng = mobj->standingslope->zangle;
|
||||
}
|
||||
|
||||
waterSlope = (flip ? *rover->b_slope : *rover->t_slope);
|
||||
if (waterSlope != NULL)
|
||||
{
|
||||
waterZAng = waterSlope->zangle;
|
||||
}
|
||||
|
||||
if (ourZAng != waterZAng)
|
||||
{
|
||||
// The surface slopes are different.
|
||||
return false;
|
||||
}
|
||||
|
||||
surfaceheight = flip ? P_GetFFloorBottomZAt(rover, mobj->x, mobj->y) : P_GetFFloorTopZAt(rover, mobj->x, mobj->y);
|
||||
mobjbottom = flip ? (mobj->z + mobj->height) : mobj->z;
|
||||
|
||||
doifit = flip ? (surfaceheight - mobj->floorz >= mobj->height) : (mobj->ceilingz - surfaceheight >= mobj->height);
|
||||
|
||||
if (!doifit)
|
||||
{
|
||||
// Object can't fit in this space.
|
||||
return false;
|
||||
}
|
||||
|
||||
maxStep = P_GetThingStepUp(mobj);
|
||||
|
||||
surfDiff = flip ? (surfaceheight - mobjbottom) : (mobjbottom - surfaceheight);
|
||||
if (surfDiff <= maxStep && surfDiff >= 0)
|
||||
{
|
||||
// We start water run IF we can step-down!
|
||||
floorheight = flip ? P_GetSectorCeilingZAt(mobj->subsector->sector, mobj->x, mobj->y) : P_GetSectorFloorZAt(mobj->subsector->sector, mobj->x, mobj->y);
|
||||
floorDiff = flip ? (floorheight - mobjbottom) : (mobjbottom - floorheight);
|
||||
if (floorDiff <= maxStep && floorDiff >= 0)
|
||||
{
|
||||
// ... but NOT if real floor is in range.
|
||||
// FIXME: Count solid FOFs in this check
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover)
|
||||
boolean P_CheckSolidFFloorSurface(mobj_t *mobj, ffloor_t *rover)
|
||||
{
|
||||
return P_CheckSolidLava(rover) ||
|
||||
P_CanRunOnWater(player, rover);
|
||||
return P_CheckSolidLava(mobj, rover) ||
|
||||
P_CanRunOnWater(mobj, rover);
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -3125,6 +3216,8 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
boolean wasgroundpounding = false;
|
||||
fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y);
|
||||
fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y);
|
||||
pslope_t *topslope = NULL;
|
||||
pslope_t *bottomslope = NULL;
|
||||
|
||||
// Default if no water exists.
|
||||
mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT;
|
||||
|
|
@ -3167,6 +3260,9 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
mobj->watertop = topheight;
|
||||
mobj->waterbottom = bottomheight;
|
||||
|
||||
topslope = *rover->t_slope;
|
||||
bottomslope = *rover->b_slope;
|
||||
|
||||
// Just touching the water?
|
||||
if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - height < bottomheight)
|
||||
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + height > topheight))
|
||||
|
|
@ -3204,13 +3300,28 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
mobj->watertop = mobj->z;
|
||||
mobj->waterbottom = mobj->z - height;
|
||||
}
|
||||
|
||||
topslope = bottomslope = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Spectators and dead players don't get to do any of the things after this.
|
||||
if (p && (p->spectator || p->playerstate != PST_LIVE))
|
||||
if (P_IsObjectOnGround(mobj) == true)
|
||||
{
|
||||
return;
|
||||
mobj->waterskip = 0;
|
||||
}
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
// Spectators and dead players don't get to do any of the things after this.
|
||||
if (p->spectator || p->playerstate != PST_LIVE)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (mobj->flags & MF_APPLYTERRAIN)
|
||||
{
|
||||
K_SpawnWaterRunParticles(mobj);
|
||||
}
|
||||
|
||||
// The rest of this code only executes on a water state change.
|
||||
|
|
@ -3219,20 +3330,21 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
return;
|
||||
}
|
||||
|
||||
if (p && !p->waterskip &&
|
||||
p->curshield != KSHIELD_BUBBLE && wasinwater)
|
||||
if (p != NULL
|
||||
&& p->curshield != KSHIELD_BUBBLE
|
||||
&& mobj->waterskip == 0
|
||||
&& wasinwater)
|
||||
{
|
||||
// Play the gasp sound
|
||||
S_StartSound(mobj, sfx_s3k38);
|
||||
}
|
||||
|
||||
if ((p) // Players
|
||||
|| (mobj->flags & MF_PUSHABLE) // Pushables
|
||||
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
|
||||
)
|
||||
if (mobj->flags & MF_APPLYTERRAIN)
|
||||
{
|
||||
fixed_t waterZ = INT32_MAX;
|
||||
fixed_t solidZ = INT32_MAX;
|
||||
fixed_t diff = INT32_MAX;
|
||||
INT32 waterDelta = 0;
|
||||
|
||||
fixed_t thingZ = INT32_MAX;
|
||||
boolean splashValid = false;
|
||||
|
|
@ -3241,11 +3353,19 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
{
|
||||
waterZ = mobj->waterbottom;
|
||||
solidZ = mobj->ceilingz;
|
||||
if (bottomslope)
|
||||
{
|
||||
waterDelta = bottomslope->zdelta;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
waterZ = mobj->watertop;
|
||||
solidZ = mobj->floorz;
|
||||
if (topslope)
|
||||
{
|
||||
waterDelta = topslope->zdelta;
|
||||
}
|
||||
}
|
||||
|
||||
diff = waterZ - solidZ;
|
||||
|
|
@ -3314,25 +3434,22 @@ void P_MobjCheckWater(mobj_t *mobj)
|
|||
|
||||
splish->destscale = mobj->scale;
|
||||
P_SetScale(splish, mobj->scale);
|
||||
|
||||
// skipping stone!
|
||||
if (K_WaterSkip(mobj) == true
|
||||
&& abs(waterDelta) < FRACUNIT/21) // Only on flat water
|
||||
{
|
||||
const fixed_t hop = 5 * mapobjectscale;
|
||||
|
||||
mobj->momx = (4*mobj->momx)/5;
|
||||
mobj->momy = (4*mobj->momy)/5;
|
||||
mobj->momz = hop * P_MobjFlip(mobj);
|
||||
|
||||
mobj->waterskip++;
|
||||
}
|
||||
}
|
||||
|
||||
// skipping stone!
|
||||
if (p && p->waterskip < 2
|
||||
&& ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water.
|
||||
|| (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
|
||||
&& (splashValid == true))
|
||||
{
|
||||
const fixed_t hop = 5 * mobj->scale;
|
||||
|
||||
mobj->momx = (4*mobj->momx)/5;
|
||||
mobj->momy = (4*mobj->momy)/5;
|
||||
mobj->momz = hop * P_MobjFlip(mobj);
|
||||
|
||||
p->waterskip++;
|
||||
}
|
||||
|
||||
}
|
||||
else if (P_MobjFlip(mobj) * mobj->momz > 0)
|
||||
else
|
||||
{
|
||||
if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|
||||
{
|
||||
|
|
@ -6717,11 +6834,13 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
case MT_ORBINAUT:
|
||||
{
|
||||
Obj_OrbinautThink(mobj);
|
||||
P_MobjCheckWater(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_JAWZ:
|
||||
{
|
||||
Obj_JawzThink(mobj);
|
||||
P_MobjCheckWater(mobj);
|
||||
break;
|
||||
}
|
||||
case MT_EGGMANITEM:
|
||||
|
|
@ -6785,6 +6904,8 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
|
|||
|
||||
if (mobj->threshold > 0)
|
||||
mobj->threshold--;
|
||||
|
||||
P_MobjCheckWater(mobj);
|
||||
}
|
||||
break;
|
||||
case MT_SINK:
|
||||
|
|
@ -9872,6 +9993,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
|
|||
mobj->colorized = false;
|
||||
|
||||
mobj->hitlag = 0;
|
||||
mobj->waterskip = 0;
|
||||
|
||||
// Set shadowscale here, before spawn hook so that Lua can change it
|
||||
P_DefaultMobjShadowScale(mobj);
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ typedef struct mobj_s
|
|||
struct mobj_s *terrainOverlay; // Overlay sprite object for terrain
|
||||
|
||||
INT32 hitlag; // Sal-style hit lag, straight from Captain Fetch's jowls
|
||||
UINT8 waterskip; // Water skipping counter
|
||||
|
||||
INT32 dispoffset;
|
||||
|
||||
|
|
|
|||
|
|
@ -280,7 +280,6 @@ static void P_NetArchivePlayers(void)
|
|||
WRITEINT32(save_p, players[i].underwatertilt);
|
||||
|
||||
WRITEFIXED(save_p, players[i].offroad);
|
||||
WRITEUINT8(save_p, players[i].waterskip);
|
||||
|
||||
WRITEUINT16(save_p, players[i].tiregrease);
|
||||
WRITEUINT16(save_p, players[i].springstars);
|
||||
|
|
@ -577,7 +576,6 @@ static void P_NetUnArchivePlayers(void)
|
|||
players[i].underwatertilt = READINT32(save_p);
|
||||
|
||||
players[i].offroad = READFIXED(save_p);
|
||||
players[i].waterskip = READUINT8(save_p);
|
||||
|
||||
players[i].tiregrease = READUINT16(save_p);
|
||||
players[i].springstars = READUINT16(save_p);
|
||||
|
|
@ -1638,6 +1636,7 @@ typedef enum
|
|||
MD2_ITNEXT = 1<<27,
|
||||
MD2_LASTMOMZ = 1<<28,
|
||||
MD2_TERRAIN = 1<<29,
|
||||
MD2_WATERSKIP = 1<<30,
|
||||
} mobj_diff2_t;
|
||||
|
||||
typedef enum
|
||||
|
|
@ -1872,6 +1871,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
}
|
||||
if (mobj->hitlag)
|
||||
diff2 |= MD2_HITLAG;
|
||||
if (mobj->waterskip)
|
||||
diff2 |= MD2_WATERSKIP;
|
||||
if (mobj->dispoffset)
|
||||
diff2 |= MD2_DISPOFFSET;
|
||||
if (mobj == waypointcap)
|
||||
|
|
@ -2082,6 +2083,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
|
|||
{
|
||||
WRITEINT32(save_p, mobj->hitlag);
|
||||
}
|
||||
if (diff2 & MD2_WATERSKIP)
|
||||
{
|
||||
WRITEUINT8(save_p, mobj->waterskip);
|
||||
}
|
||||
if (diff2 & MD2_DISPOFFSET)
|
||||
{
|
||||
WRITEINT32(save_p, mobj->dispoffset);
|
||||
|
|
@ -3191,6 +3196,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
|
|||
{
|
||||
mobj->hitlag = READINT32(save_p);
|
||||
}
|
||||
if (diff2 & MD2_WATERSKIP)
|
||||
{
|
||||
mobj->waterskip = READUINT8(save_p);
|
||||
}
|
||||
if (diff2 & MD2_DISPOFFSET)
|
||||
{
|
||||
mobj->dispoffset = READINT32(save_p);
|
||||
|
|
|
|||
94
src/p_user.c
94
src/p_user.c
|
|
@ -2292,100 +2292,6 @@ void P_MovePlayer(player_t *player)
|
|||
//GAMEPLAY STUFF//
|
||||
//////////////////
|
||||
|
||||
if (((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height >= player->mo->watertop && player->mo->z <= player->mo->watertop)
|
||||
|| (player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height >= player->mo->waterbottom && player->mo->z <= player->mo->waterbottom))
|
||||
&& (player->speed > runspd)
|
||||
&& player->mo->momz == 0 && player->carry != CR_SLIDING && !player->spectator)
|
||||
{
|
||||
fixed_t playerTopSpeed = K_GetKartSpeed(player, false, false);
|
||||
fixed_t trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);
|
||||
|
||||
if (playerTopSpeed > runspd)
|
||||
trailScale = FixedMul(FixedDiv(player->speed - runspd, playerTopSpeed - runspd), mapobjectscale);
|
||||
else
|
||||
trailScale = mapobjectscale; // Scaling is based off difference between runspeed and top speed
|
||||
|
||||
if (trailScale > 0)
|
||||
{
|
||||
const angle_t forwardangle = K_MomentumAngle(player->mo);
|
||||
const fixed_t playerVisualRadius = player->mo->radius + (8 * player->mo->scale);
|
||||
const size_t numFrames = S_WATERTRAIL8 - S_WATERTRAIL1;
|
||||
const statenum_t curOverlayFrame = S_WATERTRAIL1 + (leveltime % numFrames);
|
||||
const statenum_t curUnderlayFrame = S_WATERTRAILUNDERLAY1 + (leveltime % numFrames);
|
||||
fixed_t x1, x2, y1, y2;
|
||||
mobj_t *water;
|
||||
|
||||
x1 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle + ANGLE_90, playerVisualRadius);
|
||||
y1 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle + ANGLE_90, playerVisualRadius);
|
||||
x1 = x1 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius);
|
||||
y1 = y1 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius);
|
||||
|
||||
x2 = player->mo->x + player->mo->momx + P_ReturnThrustX(player->mo, forwardangle - ANGLE_90, playerVisualRadius);
|
||||
y2 = player->mo->y + player->mo->momy + P_ReturnThrustY(player->mo, forwardangle - ANGLE_90, playerVisualRadius);
|
||||
x2 = x2 + P_ReturnThrustX(player->mo, forwardangle, playerVisualRadius);
|
||||
y2 = y2 + P_ReturnThrustY(player->mo, forwardangle, playerVisualRadius);
|
||||
|
||||
// Left
|
||||
// underlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
// overlay
|
||||
water = P_SpawnMobj(x1, y1,
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 - ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
// Right
|
||||
// Underlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curUnderlayFrame);
|
||||
|
||||
// Overlay
|
||||
water = P_SpawnMobj(x2, y2,
|
||||
((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL);
|
||||
P_InitAngle(water, forwardangle - ANGLE_180 + ANGLE_22h);
|
||||
water->destscale = trailScale;
|
||||
water->momx = player->mo->momx;
|
||||
water->momy = player->mo->momy;
|
||||
water->momz = player->mo->momz;
|
||||
P_SetScale(water, trailScale);
|
||||
P_SetMobjState(water, curOverlayFrame);
|
||||
|
||||
if (!S_SoundPlaying(player->mo, sfx_s3kdbs))
|
||||
{
|
||||
const INT32 volume = (min(trailScale, FRACUNIT) * 255) / FRACUNIT;
|
||||
S_StartSoundAtVolume(player->mo, sfx_s3kdbs, volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Little water sound while touching water - just a nicety.
|
||||
if ((player->mo->eflags & MFE_TOUCHWATER) && !(player->mo->eflags & MFE_UNDERWATER) && !player->spectator)
|
||||
{
|
||||
if (P_RandomChance(PR_BUBBLE, FRACUNIT/2) && leveltime % TICRATE == 0)
|
||||
S_StartSound(player->mo, sfx_floush);
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
//SPINNING AND SPINDASHING//
|
||||
////////////////////////////
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue