Don't forget about pushables!

This commit is contained in:
SSNTails 2024-02-15 15:18:26 -05:00
parent f5829451a3
commit d8723c4b7f
2 changed files with 35 additions and 98 deletions

View file

@ -393,17 +393,43 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
player = toucher->player;
I_Assert(player != NULL); // Only players can touch stuff!
if (player)
{
if (player->spectator)
return;
// Ignore multihits in "ouchie" mode
if (special->flags & (MF_ENEMY|MF_BOSS) && special->flags2 & MF2_FRET)
if (special->flags & (MF_ENEMY | MF_BOSS) && special->flags2 & MF2_FRET)
return;
if (LUA_HookTouchSpecial(special, toucher) || P_MobjWasRemoved(special))
return;
}
if (special->type == MT_STEAM && (player || (toucher->flags & MF_PUSHABLE)))
{
fixed_t speed = special->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust
SINT8 flipval = P_MobjFlip(special); // virtually everything here centers around the thruster's gravity, not the object's!
if (special->state != &states[S_STEAM1]) // Only when it bursts
return;
toucher->eflags |= MFE_SPRUNG;
toucher->momz = flipval * FixedMul(speed, FixedSqrt(FixedMul(special->scale, toucher->scale))); // scale the speed with both objects' scales, just like with springs!
if (player)
{
P_ResetPlayer(player);
if (player->panim != PA_FALL)
P_SetMobjState(toucher, S_PLAY_FALL);
}
return; // Don't collect it!
}
if (!player) // Only players can touch stuff!
return;
// 0 = none, 1 = elemental pierce, 2 = bubble bounce
elementalpierce = (((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL || (player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP) && (player->pflags & PF_SHIELDABILITY)
@ -1879,20 +1905,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
return;
case MT_STEAM: // Steam
fixed_t speed = special->info->mass; // conveniently, both fans and gas jets use this for the vertical thrust
SINT8 flipval = P_MobjFlip(special); // virtually everything here centers around the thruster's gravity, not the object's!
if (special->state != &states[S_STEAM1]) // Only when it bursts
break;
toucher->eflags |= MFE_SPRUNG;
toucher->momz = flipval * FixedMul(speed, FixedSqrt(FixedMul(special->scale, toucher->scale))); // scale the speed with both objects' scales, just like with springs!
P_ResetPlayer(player);
if (player->panim != PA_FALL)
P_SetMobjState(toucher, S_PLAY_FALL);
return;
default: // SOC or script pickup
if (player->bot && player->bot != BOT_MPAI)
return;

View file

@ -1468,13 +1468,13 @@ static unsigned PIT_DoCheckThing(mobj_t *thing)
}
// check for special pickup
if (thing->flags & MF_SPECIAL && tmthing->player)
if (thing->flags & MF_SPECIAL)
{
P_TouchSpecialThing(thing, tmthing, true); // can remove thing
return CHECKTHING_COLLIDE;
}
// check again for special pickup
if (tmthing->flags & MF_SPECIAL && thing->player)
if (tmthing->flags & MF_SPECIAL)
{
P_TouchSpecialThing(tmthing, thing, true); // can remove thing
return CHECKTHING_COLLIDE;
@ -4212,81 +4212,6 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist, UINT8 dama
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_RadiusAttack);
}
//
// PIT_SteamBurst
// Scan nearby players and MF2_PUSHABLEs for bursting with steam
// 'bombsource' is the steam object
//
static boolean PIT_SteamBurst(mobj_t *thing)
{
fixed_t dx, dy, dist;
if (thing == bombsource) // ignore the self
return true;
if (!((thing->player && thing->player->playerstate == PST_LIVE) || (thing->flags & MF_PUSHABLE)))
return true;
dx = abs(thing->x - bombspot->x);
dy = abs(thing->y - bombspot->y);
dist = P_AproxDistance(dx, dy);
if (dist > thing->radius + bombsource->radius)
return true; // out of XY range
fixed_t zdist;
if (bombsource->eflags & MFE_VERTICALFLIP)
{
if (thing->z > bombsource->z + bombsource->height)
return;
zdist = (bombsource->z + bombsource->height) - (thing->z + thing->height);
}
else
{
if (thing->z + thing->height < bombsource->z)
return;
zdist = thing->z - bombsource->z;
}
dist -= thing->radius;
if (dist < 0)
dist = 0;
if (dist >= bombdamage)
return true; // out of range
if (thing->floorz > bombspot->z && bombspot->ceilingz < thing->z)
return true;
if (thing->ceilingz < bombspot->z && bombspot->floorz > thing->z)
return true;
if (!bombsightcheck || P_CheckSight(thing, bombspot))
{ // must be in direct path
P_DamageMobj(thing, bombspot, bombsource, 1, bombdamagetype); // Tails 01-11-2001
}
return true;
}
void P_SteamBurst(mobj_t *source, fixed_t checkDist)
{
INT32 xl, xh, yl, yh;
fixed_t dist;
dist = FixedMul(source->radius, source->scale) + MAXRADIUS;
yh = (unsigned)(source->y + dist - bmaporgy) >> MAPBLOCKSHIFT;
yl = (unsigned)(source->y - dist - bmaporgy) >> MAPBLOCKSHIFT;
xh = (unsigned)(source->x + dist - bmaporgx) >> MAPBLOCKSHIFT;
xl = (unsigned)(source->x - dist - bmaporgx) >> MAPBLOCKSHIFT;
BMBOUNDFIX(xl, xh, yl, yh);
P_DoBlockThingsIterate(xl, yl, xh, yh, PIT_SteamBurst);
}
//
// SECTOR HEIGHT CHANGING
// After modifying a sectors floor or ceiling height,