diff --git a/src/p_inter.c b/src/p_inter.c index eb2cabc66..da661c365 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2138,7 +2138,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da static void P_FlingBurst ( player_t *player, angle_t fa, - fixed_t z, mobjtype_t objType, tic_t objFuse, fixed_t objScale, @@ -2149,18 +2148,17 @@ static void P_FlingBurst fixed_t momxy = 5<> 1; - z = player->mo->z; - if (player->mo->eflags & MFE_VERTICALFLIP) - z += player->mo->height - mobjinfo[objType].height; - - mo = P_SpawnMobj(player->mo->x, player->mo->y, z, objType); + mo = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, objType); mo->threshold = 10; // not useful for spikes mo->fuse = objFuse; P_SetTarget(&mo->target, player->mo); - mo->destscale = objScale; - P_SetScale(mo, objScale); + if (objScale != FRACUNIT) + { + P_SetScale(mo, FixedMul(objScale, mo->scale)); + mo->destscale = mo->scale; + } /* 0: 0 @@ -2197,7 +2195,6 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) INT32 num_fling_rings; INT32 i; angle_t fa; - fixed_t z; // Rings shouldn't be in Battle! if (gametyperules & GTR_SPHERES) @@ -2223,19 +2220,13 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // determine first angle fa = player->mo->angle + ((P_RandomByte() & 1) ? -ANGLE_90 : ANGLE_90); - z = player->mo->z; - if (player->mo->eflags & MFE_VERTICALFLIP) - z += player->mo->height - mobjinfo[MT_RING].height; - for (i = 0; i < num_fling_rings; i++) { - P_FlingBurst(player, fa, z, - MT_FLINGRING, 60*TICRATE, player->mo->scale, i); + P_FlingBurst(player, fa, MT_FLINGRING, 60*TICRATE, FRACUNIT, i); } while (i < num_rings) { - P_FlingBurst(player, fa, z, - MT_DEBTSPIKE, 0, 3 * player->mo->scale / 2, i++); + P_FlingBurst(player, fa, MT_DEBTSPIKE, 0, 3 * FRACUNIT / 2, i++); } } diff --git a/src/p_local.h b/src/p_local.h index be4065466..5fc1ab956 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -158,6 +158,7 @@ boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart +#define P_IsObjectFlipped(o) ((o)->eflags & MFE_VERTICALFLIP) boolean P_InQuicksand(mobj_t *mo); boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff); @@ -521,5 +522,9 @@ void P_Thrust(mobj_t *mo, angle_t angle, fixed_t move); void P_ExplodeMissile(mobj_t *mo); void P_CheckGravity(mobj_t *mo, boolean affect); void P_SetPitchRollFromSlope(mobj_t *mo, pslope_t *slope); +fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale); +fixed_t P_GetMobjHead(const mobj_t *); +fixed_t P_GetMobjFeet(const mobj_t *); +fixed_t P_GetMobjGround(const mobj_t *); #endif // __P_LOCAL__ diff --git a/src/p_mobj.c b/src/p_mobj.c index 2bc6c620f..c31624787 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2296,11 +2296,6 @@ boolean P_ZMovement(mobj_t *mo) { mom.x = mom.y = 0; mom.z = -mom.z/2; - - if (mo->fuse == 0) - { - mo->fuse = 90; - } } else if (mo->flags & MF_MISSILE) { @@ -6267,6 +6262,12 @@ static boolean P_MobjRegularThink(mobj_t *mobj) else A_AttractChase(mobj); break; + case MT_DEBTSPIKE: + if (mobj->fuse == 0 && P_GetMobjFeet(mobj) == P_GetMobjGround(mobj)) + { + mobj->fuse = 90; + } + break; case MT_EMBLEM: if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); @@ -12748,6 +12749,15 @@ void P_FlashPal(player_t *pl, UINT16 type, UINT16 duration) pl->flashpal = type; } +// +// P_ScaleFromMap +// Scales a number relative to the mapobjectscale. +// +fixed_t P_ScaleFromMap(fixed_t n, fixed_t scale) +{ + return FixedMul(n, FixedDiv(scale, mapobjectscale)); +} + // // P_SpawnMobjFromMobj // Spawns an object with offsets relative to the position of another object. @@ -12765,16 +12775,40 @@ mobj_t *P_SpawnMobjFromMobj(mobj_t *mobj, fixed_t xofs, fixed_t yofs, fixed_t zo if (!newmobj) return NULL; + newmobj->destscale = P_ScaleFromMap(mobj->destscale, newmobj->destscale); + P_SetScale(newmobj, P_ScaleFromMap(mobj->scale, newmobj->scale)); + if (mobj->eflags & MFE_VERTICALFLIP) { - fixed_t elementheight = FixedMul(newmobj->info->height, mobj->scale); - newmobj->eflags |= MFE_VERTICALFLIP; newmobj->flags2 |= MF2_OBJECTFLIP; - newmobj->z = mobj->z + mobj->height - zofs - elementheight; + newmobj->z = mobj->z + mobj->height - zofs - newmobj->height; } - newmobj->destscale = mobj->destscale; - P_SetScale(newmobj, mobj->scale); return newmobj; } + +// +// P_GetMobjHead & P_GetMobjFeet +// Returns the top and bottom of an object, follows appearance, not physics, +// in reverse gravity. +// + +fixed_t P_GetMobjHead(const mobj_t *mobj) +{ + return P_IsObjectFlipped(mobj) ? mobj->z : mobj->z + mobj->height; +} + +fixed_t P_GetMobjFeet(const mobj_t *mobj) +{ + return P_IsObjectFlipped(mobj) ? mobj->z + mobj->height : mobj->z; +} + +// +// P_GetMobjGround +// Returns the object's floor, or ceiling in reverse gravity. +// +fixed_t P_GetMobjGround(const mobj_t *mobj) +{ + return P_IsObjectFlipped(mobj) ? mobj->ceilingz : mobj->floorz; +}