Liquid terrain functions

This commit is contained in:
Sally Coolatta 2021-12-09 02:37:44 -05:00
parent f7834054a5
commit d7a8ec9fbd

View file

@ -3042,27 +3042,78 @@ void P_MobjCheckWater(mobj_t *mobj)
} }
} }
if (mobj->terrain != NULL)
{
if (mobj->terrain->flags & TRF_LIQUID)
{
// This floor is water.
mobj->eflags |= MFE_TOUCHWATER;
if (mobj->eflags & MFE_VERTICALFLIP)
{
mobj->watertop = thingtop + height;
mobj->waterbottom = thingtop;
}
else
{
mobj->watertop = mobj->z;
mobj->waterbottom = mobj->z - height;
}
}
}
// Spectators and dead players don't get to do any of the things after this. // 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 && (p->spectator || p->playerstate != PST_LIVE))
{
return; return;
}
// The rest of this code only executes on a water state change. // The rest of this code only executes on a water state change.
if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater) if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater)
{
return; return;
}
if ((p) // Players if ((p) // Players
|| (mobj->flags & MF_PUSHABLE) // Pushables || (mobj->flags & MF_PUSHABLE) // Pushables
|| ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still || ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still
) )
{ {
fixed_t waterZ = INT32_MAX;
fixed_t solidZ = INT32_MAX;
fixed_t diff = INT32_MAX;
fixed_t thingZ = INT32_MAX;
boolean splashValid = false;
if (mobj->eflags & MFE_VERTICALFLIP)
{
waterZ = mobj->waterbottom;
solidZ = mobj->ceilingz;
}
else
{
waterZ = mobj->watertop;
solidZ = mobj->floorz;
}
diff = waterZ - solidZ;
if (mobj->eflags & MFE_VERTICALFLIP)
{
diff = -diff;
}
// Check to make sure you didn't just cross into a sector to jump out of // Check to make sure you didn't just cross into a sector to jump out of
// that has shallower water than the block you were originally in. // that has shallower water than the block you were originally in.
if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1) if (diff <= (height >> 1))
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->ceilingz-mobj->waterbottom <= height>>1)) {
return; return;
}
if (mobj->eflags & MFE_GOOWATER || wasingoo) { // Decide what happens to your momentum when you enter/leave goopy water. if (mobj->eflags & MFE_GOOWATER || wasingoo)
if (P_MobjFlip(mobj)*mobj->momz > 0) {
// Decide what happens to your momentum when you enter/leave goopy water.
if (P_MobjFlip(mobj) * mobj->momz > 0)
{ {
mobj->momz -= (mobj->momz/8); // cut momentum a little bit to prevent multiple bobs mobj->momz -= (mobj->momz/8); // cut momentum a little bit to prevent multiple bobs
//CONS_Printf("leaving\n"); //CONS_Printf("leaving\n");
@ -3074,25 +3125,42 @@ void P_MobjCheckWater(mobj_t *mobj)
//CONS_Printf("entering\n"); //CONS_Printf("entering\n");
} }
} }
else if (wasinwater && P_MobjFlip(mobj)*mobj->momz > 0) else if (wasinwater && P_MobjFlip(mobj) * mobj->momz > 0)
mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT)); // Give the mobj a little out-of-water boost.
if (P_MobjFlip(mobj)*mobj->momz < 0)
{ {
if ((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz <= mobj->waterbottom) // Give the mobj a little out-of-water boost.
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz >= mobj->watertop)) mobj->momz = FixedMul(mobj->momz, FixedDiv(780*FRACUNIT, 457*FRACUNIT));
}
if (mobj->eflags & MFE_VERTICALFLIP)
{
thingZ = thingtop - (height >> 1);
splashValid = (thingZ - mobj->momz <= waterZ);
}
else
{
thingZ = mobj->z + (height >> 1);
splashValid = (thingZ - mobj->momz >= waterZ);
}
if (P_MobjFlip(mobj) * mobj->momz <= 0)
{
if (splashValid == true)
{ {
// Spawn a splash // Spawn a splash
mobj_t *splish; mobj_t *splish;
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH; mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype); splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish->flags2 |= MF2_OBJECTFLIP; splish->flags2 |= MF2_OBJECTFLIP;
splish->eflags |= MFE_VERTICALFLIP; splish->eflags |= MFE_VERTICALFLIP;
} }
else else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); {
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
}
splish->destscale = mobj->scale; splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale); P_SetScale(splish, mobj->scale);
} }
@ -3101,40 +3169,37 @@ void P_MobjCheckWater(mobj_t *mobj)
if (p && p->waterskip < 2 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/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! || (p->speed > 20*mapobjectscale && p->waterskip)) // Already skipped once, so you can skip once more!
&& ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) && (splashValid == true))
|| ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom)))
{ {
const fixed_t hop = 5<<FRACBITS; const fixed_t hop = 5 * mobj->scale;
mobj->momx = (4*mobj->momx)/5; mobj->momx = (4*mobj->momx)/5;
mobj->momy = (4*mobj->momy)/5; mobj->momy = (4*mobj->momy)/5;
mobj->momz = hop * P_MobjFlip(mobj);
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->momz = FixedMul(-hop, mobj->scale);
else
mobj->momz = FixedMul(hop, mobj->scale);
p->waterskip++; p->waterskip++;
} }
} }
else if (P_MobjFlip(mobj)*mobj->momz > 0) else if (P_MobjFlip(mobj) * mobj->momz > 0)
{ {
if (((mobj->eflags & MFE_VERTICALFLIP && thingtop-(height>>1)-mobj->momz > mobj->waterbottom) if (splashValid == true && !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
|| (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z+(height>>1)-mobj->momz < mobj->watertop))
&& !(mobj->eflags & MFE_UNDERWATER)) // underwater check to prevent splashes on opposite side
{ {
// Spawn a splash // Spawn a splash
mobj_t *splish; mobj_t *splish;
mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH; mobjtype_t splishtype = (mobj->eflags & MFE_TOUCHLAVA) ? MT_LAVASPLISH : MT_SPLISH;
if (mobj->eflags & MFE_VERTICALFLIP) if (mobj->eflags & MFE_VERTICALFLIP)
{ {
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->waterbottom-FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype); splish = P_SpawnMobj(mobj->x, mobj->y, waterZ - FixedMul(mobjinfo[splishtype].height, mobj->scale), splishtype);
splish->flags2 |= MF2_OBJECTFLIP; splish->flags2 |= MF2_OBJECTFLIP;
splish->eflags |= MFE_VERTICALFLIP; splish->eflags |= MFE_VERTICALFLIP;
} }
else else
splish = P_SpawnMobj(mobj->x, mobj->y, mobj->watertop, splishtype); {
splish = P_SpawnMobj(mobj->x, mobj->y, waterZ, splishtype);
}
splish->destscale = mobj->scale; splish->destscale = mobj->scale;
P_SetScale(splish, mobj->scale); P_SetScale(splish, mobj->scale);
} }
@ -3155,7 +3220,7 @@ void P_MobjCheckWater(mobj_t *mobj)
else else
S_StartSound(mobj, sfx_splish); // And make a sound! S_StartSound(mobj, sfx_splish); // And make a sound!
bubblecount = FixedDiv(abs(mobj->momz), mobj->scale)>>(FRACBITS-1); bubblecount = FixedDiv(abs(mobj->momz), mobj->scale) >> (FRACBITS-1);
// Max bubble count // Max bubble count
if (bubblecount > 128) if (bubblecount > 128)
bubblecount = 128; bubblecount = 128;