From eb233f44c1105b1377dbd921fafedce83f8edf7b Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 28 Oct 2013 14:11:20 +0000 Subject: [PATCH] libcommon: Fix mobj-nofit-crunch behavior regression; cleanup --- doomsday/plugins/common/include/p_actor.h | 12 ++ doomsday/plugins/common/include/p_map.h | 3 - doomsday/plugins/common/src/p_actor.cpp | 23 +++ doomsday/plugins/common/src/p_map.cpp | 192 ++++++++++------------ 4 files changed, 120 insertions(+), 110 deletions(-) diff --git a/doomsday/plugins/common/include/p_actor.h b/doomsday/plugins/common/include/p_actor.h index 7c3fccf085..871524e033 100644 --- a/doomsday/plugins/common/include/p_actor.h +++ b/doomsday/plugins/common/include/p_actor.h @@ -80,6 +80,18 @@ void P_MobjAngleSRVOTicker(mobj_t *mo); boolean P_MobjIsCamera(mobj_t const *mo); +/** + * Returns @c true iff @a mobj is currently "crunchable", i.e., it can be turned + * into a pile of giblets if it no longer fits in the opening between floor and + * ceiling planes. + */ +boolean Mobj_IsCrunchable(mobj_t *mobj); + +/** + * Returns @c true iff @a mobj is a dropped item. + */ +boolean Mobj_IsDroppedItem(mobj_t *mobj); + /** * Returns the terraintype_t of the floor plane at the mobj's origin. * diff --git a/doomsday/plugins/common/include/p_map.h b/doomsday/plugins/common/include/p_map.h index 537a4a2b15..b63c262110 100644 --- a/doomsday/plugins/common/include/p_map.h +++ b/doomsday/plugins/common/include/p_map.h @@ -36,9 +36,6 @@ DENG_EXTERN_C mobj_t *tmBlockingMobj; #endif DENG_EXTERN_C mobj_t *lineTarget; // Who got hit (or NULL). -#if __JDOOM__ || __JDOOM64__ -DENG_EXTERN_C boolean PuffNoSpark; -#endif #if __JHEXEN__ DENG_EXTERN_C mobj_t *PuffSpawned; #endif diff --git a/doomsday/plugins/common/src/p_actor.cpp b/doomsday/plugins/common/src/p_actor.cpp index 2bf62b3267..c944a2bc59 100644 --- a/doomsday/plugins/common/src/p_actor.cpp +++ b/doomsday/plugins/common/src/p_actor.cpp @@ -212,6 +212,29 @@ boolean P_MobjIsCamera(mobj_t const *mo) (mo->player->plr->flags & DDPF_CAMERA)); } +boolean Mobj_IsCrunchable(mobj_t *mobj) +{ + DENG_ASSERT(mobj != 0); + +#if __JDOOM__ || __JDOOM64__ + return mobj->health <= 0 && (cfg.gibCrushedNonBleeders || !(mobj->flags & MF_NOBLOOD)); +#elif __JHEXEN__ + return mobj->health <= 0 && (mobj->flags & MF_CORPSE) != 0; +#else + return mobj->health <= 0; +#endif +} + +boolean Mobj_IsDroppedItem(mobj_t *mobj) +{ + DENG_ASSERT(mobj != 0); +#if __JHEXEN__ + return (mobj->flags2 & MF2_DROPPED) != 0; +#else + return (mobj->flags & MF_DROPPED) != 0; +#endif +} + terraintype_t const *P_MobjFloorTerrain(mobj_t *mobj) { return P_PlaneMaterialTerrainType(Mobj_Sector(mobj), PLN_FLOOR); diff --git a/doomsday/plugins/common/src/p_map.cpp b/doomsday/plugins/common/src/p_map.cpp index 55e61b81c4..94a990e647 100644 --- a/doomsday/plugins/common/src/p_map.cpp +++ b/doomsday/plugins/common/src/p_map.cpp @@ -1670,7 +1670,7 @@ struct ptr_shoottraverse_params_t int damage; ///< Damage to inflict. coord_t range; ///< Maximum effective range from the trace origin. mobjtype_t puffType; ///< Type of puff to spawn. - bool puffNoSpark; ///< Advance the puff to the first non-spark state. + bool puffNoSpark; ///< @c true= Advance the puff to the first non-spark state. }; /** @@ -2402,72 +2402,6 @@ void P_UseLines(player_t *player) P_PathTraverse2(mo->origin, pos, PTF_LINE, PTR_UseTraverse, mo); } -/** - * Takes a valid thing and adjusts the thing->floorZ, thing->ceilingZ, - * and possibly thing->origin[VZ]. - * - * This is called for all nearby monsters whenever a sector changes height - * If the thing doesn't fit, the z will be set to the lowest value and - * false will be returned - * - * @param thing The mobj whoose position to adjust. - * - * @return @c true iff the thing did fit. - */ -static boolean heightClip(mobj_t *thing) -{ - // Don't height clip cameras. - if(P_MobjIsCamera(thing)) - { - return false; - } - - bool const onfloor = (thing->origin[VZ] == thing->floorZ); - - P_CheckPosition(thing, thing->origin); - thing->floorZ = tmFloorZ; - thing->ceilingZ = tmCeilingZ; -#if !__JHEXEN__ - thing->dropOffZ = tmDropoffZ; // $dropoff_fix: remember dropoffs. -#endif - - if(onfloor) - { -#if __JHEXEN__ - if((thing->origin[VZ] - thing->floorZ < 9) || - (thing->flags & MF_NOGRAVITY)) - { - thing->origin[VZ] = thing->floorZ; - } -#else - // Update view offset of real players. - if(Mobj_IsPlayer(thing) && !Mobj_IsVoodooDoll(thing)) - { - thing->player->viewZ += thing->floorZ - thing->origin[VZ]; - } - - // Walking monsters rise and fall with the floor. - thing->origin[VZ] = thing->floorZ; - - // $dropoff_fix: Possibly upset balance of objects hanging off ledges. - if((thing->intFlags & MIF_FALLING) && thing->gear >= MAXGEAR) - { - thing->gear = 0; - } -#endif - } - else - { - // Don't adjust a floating monster unless forced to. - if(thing->origin[VZ] + thing->height > thing->ceilingZ) - { - thing->origin[VZ] = thing->ceilingZ - thing->height; - } - } - - return (thing->ceilingZ - thing->floorZ) >= thing->height; -} - /** * Allows the player to slide along any angled walls by adjusting the * xmove / ymove so that the NEXT move will slide along the wall. @@ -2697,76 +2631,120 @@ struct pit_changesector_params_t bool noFit; }; +/// @return Always @c false for use as an interation callback. static int PIT_ChangeSector(mobj_t *thing, void *context) { pit_changesector_params_t &parm = *static_cast(context); DENG_ASSERT(thing->info != 0); - // Don't check things that aren't blocklinked (supposedly immaterial). + // Skip mobjs that aren't blocklinked (supposedly immaterial). if(thing->info->flags & MF_NOBLOCKMAP) { return false; } - if(heightClip(thing)) + // Update the Z position of the mobj and determine whether it physically + // fits in the opening between floor and ceiling. + if(!P_MobjIsCamera(thing)) { - return false; // Keep checking... - } + bool const onfloor = (thing->origin[VZ] == thing->floorZ); - // Crunch bodies to giblets. -#if __JDOOM__ || __JDOOM64__ - if(thing->health <= 0 && (cfg.gibCrushedNonBleeders || !(thing->flags & MF_NOBLOOD))) -#elif __JHEXEN__ - if(thing->health <= 0 && (thing->flags & MF_CORPSE)) + P_CheckPosition(thing, thing->origin); + thing->floorZ = tmFloorZ; + thing->ceilingZ = tmCeilingZ; +#if !__JHEXEN__ + thing->dropOffZ = tmDropoffZ; // $dropoff_fix: remember dropoffs. +#endif + + if(onfloor) + { +#if __JHEXEN__ + if((thing->origin[VZ] - thing->floorZ < 9) || + (thing->flags & MF_NOGRAVITY)) + { + thing->origin[VZ] = thing->floorZ; + } #else - if(thing->health <= 0) + // Update view offset of real players. + if(Mobj_IsPlayer(thing) && !Mobj_IsVoodooDoll(thing)) + { + thing->player->viewZ += thing->floorZ - thing->origin[VZ]; + } + + // Walking monsters rise and fall with the floor. + thing->origin[VZ] = thing->floorZ; + + // $dropoff_fix: Possibly upset balance of objects hanging off ledges. + if((thing->intFlags & MIF_FALLING) && thing->gear >= MAXGEAR) + { + thing->gear = 0; + } #endif + } + else + { + // Don't adjust a floating monster unless forced to do so. + if(thing->origin[VZ] + thing->height > thing->ceilingZ) + { + thing->origin[VZ] = thing->ceilingZ - thing->height; + } + } + + // Does this mobj fit in the open space? + if((thing->ceilingZ - thing->floorZ) >= thing->height) + { + return false; + } + } + + // Crunch bodies to giblets. + if(Mobj_IsCrunchable(thing)) { #if __JHEXEN__ if(thing->flags & MF_NOBLOOD) { P_MobjRemove(thing, false); + return false; } - else +#endif + +#if __JHEXEN__ + if(thing->state != &STATES[S_GIBS1]) +#endif { - if(thing->state != &STATES[S_GIBS1]) - { - P_MobjChangeState(thing, S_GIBS1); - thing->height = 0; - thing->radius = 0; - S_StartSound(SFX_PLAYER_FALLING_SPLAT, thing); - } - } -#else -# if __JDOOM64__ - S_StartSound(SFX_SLOP, thing); -# endif +#if __JHEXEN__ + P_MobjChangeState(thing, S_GIBS1); +#elif __JDOOM__ || __JDOOM64__ + P_MobjChangeState(thing, S_GIBS); +#endif -# if __JDOOM__ || __JDOOM64__ - P_MobjChangeState(thing, S_GIBS); -# endif - thing->flags &= ~MF_SOLID; - thing->height = 0; - thing->radius = 0; +#if !__JHEXEN__ + thing->flags &= ~MF_SOLID; #endif - return false; // Keep checking... - } + thing->height = 0; + thing->radius = 0; - // Crunch dropped items. #if __JHEXEN__ - if(thing->flags2 & MF2_DROPPED) -#else - if(thing->flags & MF_DROPPED) + S_StartSound(SFX_PLAYER_FALLING_SPLAT, thing); +#elif __JDOOM64__ + S_StartSound(SFX_SLOP, thing); #endif + } + + return false; + } + + // Remove dropped items. + if(Mobj_IsDroppedItem(thing)) { P_MobjRemove(thing, false); - return false; // Keep checking... + return false; } if(!(thing->flags & MF_SHOOTABLE)) { - return false; // Keep checking... + return false; } parm.noFit = true; @@ -2793,7 +2771,7 @@ static int PIT_ChangeSector(mobj_t *thing, void *context) } } - return false; // Keep checking (crush other things)... + return false; } boolean P_ChangeSector(Sector *sector, int crush) @@ -2801,9 +2779,9 @@ boolean P_ChangeSector(Sector *sector, int crush) pit_changesector_params_t parm; parm.noFit = false; #if __JHEXEN__ - parm.crushDamage = int(crush); + parm.crushDamage = crush; #else - parm.crushDamage = 10; + parm.crushDamage = crush > 0? 10 : 0; #endif VALIDCOUNT++;