From 66d59efddcf8070270bce0603e11853c6ca1500d Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 17 Jul 2017 23:58:54 +0100 Subject: [PATCH 1/9] Sorry, MI. More info in forthcoming merge request. --- src/info.c | 10 +++++----- src/p_mobj.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/info.c b/src/info.c index 4f1a76c73..30f6c082d 100644 --- a/src/info.c +++ b/src/info.c @@ -5992,7 +5992,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_WALLSPIKE 522, // doomednum - S_WALLSPIKE1, // spawnstate + S_WALLSPIKE1, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -6005,9 +6005,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate - sfx_None, // deathsound + sfx_None, // deathsound 2*TICRATE, // speed - 32*FRACUNIT, // radius + 16*FRACUNIT, // radius 14*FRACUNIT, // height 0, // display offset 4, // mass @@ -6019,7 +6019,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_WALLSPIKEBASE -1, // doomednum - S_WALLSPIKEBASE, // spawnstate + S_WALLSPIKEBASE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound @@ -6034,7 +6034,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 7*FRACUNIT, // radius + FRACUNIT/4, // radius 14*FRACUNIT, // height 0, // display offset 4, // mass diff --git a/src/p_mobj.c b/src/p_mobj.c index 2bb370f50..c6847df30 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10146,7 +10146,7 @@ ML_NOCLIMB : Direction not controllable // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so... - const fixed_t baseradius = mobj->radius/2 - FixedMul(FRACUNIT, mobj->scale); + const fixed_t baseradius = mobj->radius - FixedMul(mobjinfo[MT_WALLSPIKEBASE].radius, mobj->scale); mobj_t *base = P_SpawnMobj( mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), From 6d43fad0986b72a5df3c63bcf434e6b03cbe250b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 12:56:39 +0100 Subject: [PATCH 2/9] Correct the baseradius stuff. (Still doing some other work, though - will let you know when the branch is safe to review.) --- src/info.c | 2 +- src/p_mobj.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index 30f6c082d..66e1b64cf 100644 --- a/src/info.c +++ b/src/info.c @@ -6034,7 +6034,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - FRACUNIT/4, // radius + 7*FRACUNIT, // radius 14*FRACUNIT, // height 0, // display offset 4, // mass diff --git a/src/p_mobj.c b/src/p_mobj.c index c6847df30..ddb36afa5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7379,16 +7379,18 @@ void P_MobjThinker(mobj_t *mobj) return; } mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); +#if 0 if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle { mobj_t *target = mobj->target; // shortcut - const fixed_t baseradius = target->radius/2 - FixedMul(FRACUNIT, target->scale); + const fixed_t baseradius = target->radius - (target->scale/4); //FixedMul(FRACUNIT/4, target->scale); P_UnsetThingPosition(mobj); mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); P_SetThingPosition(mobj); mobj->angle = target->angle + ANGLE_90; } +#endif break; case MT_FALLINGROCK: // Despawn rocks here in case zmovement code can't do so (blame slopes) @@ -10146,7 +10148,7 @@ ML_NOCLIMB : Direction not controllable // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so... - const fixed_t baseradius = mobj->radius - FixedMul(mobjinfo[MT_WALLSPIKEBASE].radius, mobj->scale); + const fixed_t baseradius = mobj->radius - (mobj->scale/4); //FixedMul(FRACUNIT/4, mobj->scale); mobj_t *base = P_SpawnMobj( mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), From a5477737d79dce77c3f04eb75cfd27e6710730d6 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 14:17:10 +0100 Subject: [PATCH 3/9] Whooh boy. Probably requires re-review. * Support for MF_PAPERCOLLISION tmhitthing in P_SlideMove. * Knockback for wallspikes is much more consistent. * Optimised away a FixedDiv call when determining the slopetype of a line. * Changed the position of the wallspike base slightly. * Made it so NOTHING can step up onto the player outside of other players, essentially killing a bunch of springs-launch-with-players style bugs. (I was able to recreate that issue with the wallspikes until I added this, which is why I did it in this branch.) --- src/p_map.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++--- src/p_mobj.c | 4 +-- src/p_polyobj.c | 2 +- src/p_setup.c | 2 +- src/p_user.c | 5 ++- 5 files changed, 91 insertions(+), 10 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index e1f204a8c..b4fecd614 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -971,15 +971,15 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > bottomz // above bottom && thing->z < topz) // below top - { // don't check angle, the player was clearly in the way in this case + // don't check angle, the player was clearly in the way in this case P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); - } } else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player) { fixed_t bottomz, topz; bottomz = thing->z; topz = thing->z + thing->height; + if (thing->eflags & MFE_VERTICALFLIP) bottomz -= FixedMul(FRACUNIT, thing->scale); else @@ -1151,12 +1151,14 @@ static boolean PIT_CheckThing(mobj_t *thing) } } - if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)) + if (!(tmthing->player) && (thing->player)) + ; // no solid thing should ever be able to step up onto a player + else if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)) { if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now... return false; // "cancel" P_TryMove via blocking so you keep your current position } - else if (tmthing->flags & MF_SPRING && (thing->player || thing->flags & MF_PUSHABLE)) + else if (tmthing->flags & MF_SPRING && (thing->flags & MF_PUSHABLE)) ; // Fix a few nasty spring-jumping bugs that happen sometimes. // Monitors are not treated as solid to players who are jumping, spinning or gliding, // unless it's a CTF team monitor and you're on the wrong team @@ -3092,6 +3094,7 @@ void P_SlideMove(mobj_t *mo) fixed_t leadx, leady, trailx, traily, newx, newy; INT16 hitcount = 0; boolean success = false; + boolean papercol = false; if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) { @@ -3099,6 +3102,80 @@ void P_SlideMove(mobj_t *mo) if (tmhitthing->flags & MF_PUSHABLE) return; + if (tmhitthing->flags & MF_PAPERCOLLISION) + { + fixed_t cosradius, sinradius; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef - does this need to be static? toast does not know + + fixed_t num, den; + + // trace along the three leading corners + if (mo->momx > 0) + { + leadx = mo->x + mo->radius; + trailx = mo->x - mo->radius; + } + else + { + leadx = mo->x - mo->radius; + trailx = mo->x + mo->radius; + } + + if (mo->momy > 0) + { + leady = mo->y + mo->radius; + traily = mo->y - mo->radius; + } + else + { + leady = mo->y - mo->radius; + traily = mo->y + mo->radius; + } + + papercol = true; + slidemo = mo; + bestslideline = &junk; + + cosradius = FixedMul(tmhitthing->radius, FINECOSINE(tmhitthing->angle>>ANGLETOFINESHIFT)); + sinradius = FixedMul(tmhitthing->radius, FINESINE(tmhitthing->angle>>ANGLETOFINESHIFT)); + + v1.x = tmhitthing->x - cosradius; + v1.y = tmhitthing->y - sinradius; + v2.x = tmhitthing->x + cosradius; + v2.y = tmhitthing->y + sinradius; + + junk.v1 = &v1; + junk.v2 = &v2; + junk.dx = 2*cosradius; // v2.x - v1.x; + junk.dy = 2*sinradius; // v2.y - v1.y; + + junk.slopetype = !cosradius ? ST_VERTICAL : !sinradius ? ST_HORIZONTAL : + ((sinradius > 0) == (cosradius > 0)) ? ST_POSITIVE : ST_NEGATIVE; + + bestslidefrac = FRACUNIT+1; + + den = FixedMul(junk.dy>>8, mo->momx) - FixedMul(junk.dx>>8, mo->momy); + + if (!den) + bestslidefrac = 0; + else + { + fixed_t frac; +#define P_PaperTraverse(startx, starty) \ + num = FixedMul((v1.x - leadx)>>8, junk.dy) + FixedMul((leady - v1.y)>>8, junk.dx); \ + frac = FixedDiv(num, den); \ + if (frac < bestslidefrac) \ + bestslidefrac = frac + P_PaperTraverse(leadx, leady); + P_PaperTraverse(trailx, leady); + P_PaperTraverse(leadx, traily); +#undef dowork + } + + goto papercollision; + } + // Thankfully box collisions are a lot simpler than arbitrary lines. There's only four possible cases. if (mo->y + mo->radius <= tmhitthing->y - tmhitthing->radius) { @@ -3129,7 +3206,7 @@ void P_SlideMove(mobj_t *mo) bestslideline = NULL; retry: - if (++hitcount == 3) + if ((++hitcount == 3) || papercol) goto stairstep; // don't loop forever // trace along the three leading corners @@ -3171,6 +3248,7 @@ retry: return; } +papercollision: // move up to the wall if (bestslidefrac == FRACUNIT+1) { diff --git a/src/p_mobj.c b/src/p_mobj.c index ddb36afa5..1bb6a2f01 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7383,7 +7383,7 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle { mobj_t *target = mobj->target; // shortcut - const fixed_t baseradius = target->radius - (target->scale/4); //FixedMul(FRACUNIT/4, target->scale); + const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); P_UnsetThingPosition(mobj); mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); @@ -10148,7 +10148,7 @@ ML_NOCLIMB : Direction not controllable // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so... - const fixed_t baseradius = mobj->radius - (mobj->scale/4); //FixedMul(FRACUNIT/4, mobj->scale); + const fixed_t baseradius = mobj->radius - (mobj->scale/2); //FixedMul(FRACUNIT/2, mobj->scale); mobj_t *base = P_SpawnMobj( mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), diff --git a/src/p_polyobj.c b/src/p_polyobj.c index 7776ab19a..fd3237c9d 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1237,7 +1237,7 @@ static void Polyobj_rotateLine(line_t *ld) // determine slopetype ld->slopetype = !ld->dx ? ST_VERTICAL : !ld->dy ? ST_HORIZONTAL : - FixedDiv(ld->dy, ld->dx) > 0 ? ST_POSITIVE : ST_NEGATIVE; + ((ld->dy > 0) == (ld->dx > 0)) ? ST_POSITIVE : ST_NEGATIVE; // update bounding box if (v1->x < v2->x) diff --git a/src/p_setup.c b/src/p_setup.c index 4f11c10d0..217f087cd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1212,7 +1212,7 @@ static void P_LoadLineDefs(lumpnum_t lumpnum) ld->slopetype = ST_VERTICAL; else if (!ld->dy) ld->slopetype = ST_HORIZONTAL; - else if (FixedDiv(ld->dy, ld->dx) > 0) + else if ((ld->dy > 0) == (ld->dx > 0)) ld->slopetype = ST_POSITIVE; else ld->slopetype = ST_NEGATIVE; diff --git a/src/p_user.c b/src/p_user.c index 9ae79e5e2..58593eca1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -821,7 +821,10 @@ void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor) if (inflictor) { - ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); + if (inflictor->type == MT_WALLSPIKE) + ang = inflictor->angle; + else + ang = R_PointToAngle2(inflictor->x-inflictor->momx, inflictor->y - inflictor->momy, player->mo->x - player->mo->momx, player->mo->y - player->mo->momy); // explosion and rail rings send you farther back, making it more difficult // to recover From d1be22ccf5b6aeabb0acf9a5de67309f6d58d166 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 14:17:10 +0100 Subject: [PATCH 4/9] * Scope tweakin's to prevent having to make some stuff static. * Make wallspikes intangible if you're being thrust away from them in pain. --- src/p_map.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index b4fecd614..20b36fea6 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -990,10 +990,15 @@ static boolean PIT_CheckThing(mobj_t *thing) && !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer { // use base as a reference point to determine what angle you touched the spike at angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); - angle_t diffangle = thing->angle - touchangle; - if (diffangle > ANGLE_180) - diffangle = InvAngle(diffangle); - if (diffangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked! + + if (P_PlayerInPain(tmthing->player) + && (R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle) > ANGLE_180) + return true; + + touchangle = thing->angle - touchangle; + if (touchangle > ANGLE_180) + touchangle = InvAngle(touchangle); + if (touchangle <= ANGLE_22h) // if you touched it at this close an angle, you get poked! P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } } @@ -3094,7 +3099,10 @@ void P_SlideMove(mobj_t *mo) fixed_t leadx, leady, trailx, traily, newx, newy; INT16 hitcount = 0; boolean success = false; + boolean papercol = false; + vertex_t v1, v2; // fake vertexes + line_t junk; // fake linedef if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) { @@ -3104,11 +3112,7 @@ void P_SlideMove(mobj_t *mo) if (tmhitthing->flags & MF_PAPERCOLLISION) { - fixed_t cosradius, sinradius; - vertex_t v1, v2; // fake vertexes - line_t junk; // fake linedef - does this need to be static? toast does not know - - fixed_t num, den; + fixed_t cosradius, sinradius, num, den; // trace along the three leading corners if (mo->momx > 0) From 2330f1a9c9eddd24af3c72e6796221ebb3668e4b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 14:17:10 +0100 Subject: [PATCH 5/9] Account for the fact that pointtoangle2 points due weast if there's no dy OR dx, so that's taken care of. --- src/p_map.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_map.c b/src/p_map.c index 20b36fea6..7ea19a249 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -992,6 +992,7 @@ static boolean PIT_CheckThing(mobj_t *thing) angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); if (P_PlayerInPain(tmthing->player) + && (tmthing->momx || tmthing->momy) && (R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle) > ANGLE_180) return true; From ef4dc42c7cba52ce8eac5eec52a90e2377b1e5e5 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 14:17:10 +0100 Subject: [PATCH 6/9] * Bustable wallspikes. * Improve the code for busting vertical spikes. * Improve the frame arrangement for vertical spikes' spriteset. (Requires new patch.dta) * Make all spikes consistently do damage with DMG_SPIKE. * (unrelated) renamed "flame stomp" to "elemental stomp" in P_HitDeathMessages --- src/dehacked.c | 2 + src/info.c | 20 +++-- src/info.h | 2 + src/p_inter.c | 230 ++++++++++++++++++++++++++++++++----------------- src/p_map.c | 31 ++++--- src/p_mobj.c | 5 +- 6 files changed, 188 insertions(+), 102 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 1279d7bd0..3db12d4c0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4681,6 +4681,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_WALLSPIKE5", "S_WALLSPIKE6", "S_WALLSPIKEBASE", + "S_WALLSPIKED1", + "S_WALLSPIKED2", // Starpost "S_STARPOST_IDLE", diff --git a/src/info.c b/src/info.c index 66e1b64cf..191c8ae91 100644 --- a/src/info.c +++ b/src/info.c @@ -1563,13 +1563,13 @@ state_t states[NUMSTATES] = // Floor Spike {SPR_USPK, 0,-1, {A_SpikeRetract}, 1, 0, S_SPIKE2}, // S_SPIKE1 -- Fully extended - {SPR_USPK, 5, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 - {SPR_USPK, 4, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 + {SPR_USPK, 1, 2, {A_Pain}, 0, 0, S_SPIKE3}, // S_SPIKE2 + {SPR_USPK, 2, 2, {NULL}, 0, 0, S_SPIKE4}, // S_SPIKE3 {SPR_USPK, 3,-1, {A_SpikeRetract}, 0, 0, S_SPIKE5}, // S_SPIKE4 -- Fully retracted - {SPR_USPK, 4, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 - {SPR_USPK, 5, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 - {SPR_USPK, 1,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles - {SPR_USPK, 2,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 + {SPR_USPK, 2, 2, {A_Pain}, 0, 0, S_SPIKE6}, // S_SPIKE5 + {SPR_USPK, 1, 2, {NULL}, 0, 0, S_SPIKE1}, // S_SPIKE6 + {SPR_USPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED1 -- Busted spike particles + {SPR_USPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_SPIKED2 // Wall Spike {SPR_WSPK, 0|FF_PAPERSPRITE,-1, {A_SpikeRetract}, 1, 0, S_WALLSPIKE2}, // S_WALLSPIKE1 -- Fully extended @@ -1579,6 +1579,8 @@ state_t states[NUMSTATES] = {SPR_WSPK, 2|FF_PAPERSPRITE, 2, {A_Pain}, 0, 0, S_WALLSPIKE6}, // S_WALLSPIKE5 {SPR_WSPK, 1|FF_PAPERSPRITE, 2, {NULL}, 0, 0, S_WALLSPIKE1}, // S_WALLSPIKE6 {SPR_WSPB, 0|FF_PAPERSPRITE,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKEBASE -- Base + {SPR_WSPK, 4,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED1 -- Busted spike particles + {SPR_WSPK, 5,-1, {NULL}, 0, 0, S_NULL}, // S_WALLSPIKED2 // Starpost {SPR_STPT, 0 , -1, {NULL}, 0, 0, S_NULL}, // S_STARPOST_IDLE @@ -6003,9 +6005,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_s3k64, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound + S_WALLSPIKED1, // deathstate + S_WALLSPIKED2, // xdeathstate + sfx_mspogo, // deathsound 2*TICRATE, // speed 16*FRACUNIT, // radius 14*FRACUNIT, // height diff --git a/src/info.h b/src/info.h index 42fd63dff..735530667 100644 --- a/src/info.h +++ b/src/info.h @@ -1784,6 +1784,8 @@ typedef enum state S_WALLSPIKE5, S_WALLSPIKE6, S_WALLSPIKEBASE, + S_WALLSPIKED1, + S_WALLSPIKED2, // Starpost S_STARPOST_IDLE, diff --git a/src/p_inter.c b/src/p_inter.c index 33ca1eeb5..730fd207b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1665,7 +1665,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour if (damagetype == DMG_NUKE) // SH_ARMAGEDDON, armageddon shield str = M_GetText("%s%s's armageddon blast %s %s.\n"); else if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL && (inflictor->player->pflags & PF_SHIELDABILITY)) - str = M_GetText("%s%s's flame stomp %s %s.\n"); + str = M_GetText("%s%s's elemental stomp %s %s.\n"); else if (inflictor->player->powers[pw_invulnerability]) str = M_GetText("%s%s's invincibility aura %s %s.\n"); else if (inflictor->player->powers[pw_super]) @@ -1719,6 +1719,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n"); break; case MT_SPIKE: + case MT_WALLSPIKE: str = M_GetText("%s was %s by spikes.\n"); break; default: @@ -2395,7 +2396,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget else { P_SetObjectMomZ(target, 14*FRACUNIT, false); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes + if (damagetype == DMG_SPIKE) // Spikes S_StartSound(target, sfx_spkdth); else P_PlayDeathSound(target); @@ -2457,90 +2458,159 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } - if (target->type == MT_SPIKE && inflictor && target->info->deathstate != S_NULL) + if (target->type == MT_SPIKE && target->info->deathstate != S_NULL) { - const fixed_t x=target->x,y=target->y,z=target->z; - const fixed_t scale=target->scale; - const boolean flip=(target->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP; - S_StartSound(target,target->info->deathsound); + const angle_t ang = ((inflictor) ? inflictor->angle : 0) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + fixed_t momz; - P_SetMobjState(target, target->info->deathstate); - target->health = 0; - target->angle = inflictor->angle + ANGLE_90; - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - if (flip) - target->z -= FixedMul(12*FRACUNIT, target->scale); - else - target->z += FixedMul(12*FRACUNIT, target->scale); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; - - if (flip) - { - target = P_SpawnMobj(x,y,z-FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); - target->eflags |= MFE_VERTICALFLIP; - } - else - target = P_SpawnMobj(x,y,z+FixedMul(12*FRACUNIT, target->scale),MT_SPIKE); - P_SetMobjState(target, target->info->deathstate); - target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(2*FRACUNIT, target->scale)); - target->momz = FixedMul(7*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + S_StartSound(target, target->info->deathsound); if (target->info->xdeathstate != S_NULL) { - target = P_SpawnMobj(x,y,z,MT_SPIKE); + momz = 6*scale; if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle + ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + momz *= -1; +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = angtweak;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov;\ + chunk->y += ymov;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk,chunk->angle, 4*scale);\ + chunk->momz = momz - target = P_SpawnMobj(x,y,z,MT_SPIKE); - if (flip) - target->eflags |= MFE_VERTICALFLIP; - P_SetMobjState(target, target->info->xdeathstate); - target->health = 0; - target->angle = inflictor->angle - ANGLE_90; - target->destscale = scale; - P_SetScale(target, scale); - P_UnsetThingPosition(target); - target->flags = MF_NOCLIP; - target->x += P_ReturnThrustX(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - target->y += P_ReturnThrustY(target, target->angle, FixedMul(8*FRACUNIT, target->scale)); - P_SetThingPosition(target); - P_InstaThrust(target,target->angle,FixedMul(4*FRACUNIT, target->scale)); - target->momz = FixedMul(6*FRACUNIT, target->scale); - if (flip) - target->momz = -target->momz; + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + makechunk(ang, xoffs, yoffs); + +#undef makechunk } + + momz = 7*scale; + if (flip) + momz *= -1; + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_SPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = ang + ANGLE_180; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x -= xoffs; + chunk->y -= yoffs; + if (flip) + chunk->z -= 12*scale; + else + chunk->z += 12*scale; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, chunk->angle, 2*scale); + chunk->momz = momz; + + P_SetMobjState(target, target->info->deathstate); + target->health = 0; + target->angle = ang; + P_UnsetThingPosition(target); + target->flags = MF_NOCLIP; + target->x += xoffs; + target->y += yoffs; + target->z = chunk->z; + P_SetThingPosition(target); + P_InstaThrust(target, target->angle, 2*scale); + target->momz = momz; + } + else if (target->type == MT_WALLSPIKE && target->info->deathstate != S_NULL) + { + const angle_t ang = (/*(inflictor) ? inflictor->angle : */target->angle) + ANGLE_90; + const fixed_t scale = target->scale; + const fixed_t xoffs = P_ReturnThrustX(target, ang, 8*scale), yoffs = P_ReturnThrustY(target, ang, 8*scale), forwardxoffs = P_ReturnThrustX(target, target->angle, 7*scale), forwardyoffs = P_ReturnThrustY(target, target->angle, 7*scale); + const UINT16 flip = (target->eflags & MFE_VERTICALFLIP); + mobj_t *chunk; + boolean sprflip; + + S_StartSound(target, target->info->deathsound); + if (!P_MobjWasRemoved(target->tracer)) + P_RemoveMobj(target->tracer); + + if (target->info->xdeathstate != S_NULL) + { + sprflip = P_RandomChance(FRACUNIT/2); + +#define makechunk(angtweak, xmov, ymov) \ + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE);\ + chunk->eflags |= flip;\ + P_SetMobjState(chunk, target->info->xdeathstate);\ + chunk->health = 0;\ + chunk->angle = target->angle;\ + chunk->destscale = scale;\ + P_SetScale(chunk, scale);\ + P_UnsetThingPosition(chunk);\ + chunk->flags = MF_NOCLIP;\ + chunk->x += xmov - forwardxoffs;\ + chunk->y += ymov - forwardyoffs;\ + P_SetThingPosition(chunk);\ + P_InstaThrust(chunk, angtweak, 4*scale);\ + chunk->momz = P_RandomRange(5, 7)*scale;\ + if (flip)\ + chunk->momz *= -1;\ + if (sprflip)\ + chunk->frame |= FF_VERTICALFLIP + + makechunk(ang + ANGLE_180, -xoffs, -yoffs); + sprflip = !sprflip; + makechunk(ang, xoffs, yoffs); + +#undef makechunk + } + + sprflip = P_RandomChance(FRACUNIT/2); + + chunk = P_SpawnMobj(target->x, target->y, target->z, MT_WALLSPIKE); + chunk->eflags |= flip; + + P_SetMobjState(chunk, target->info->deathstate); + chunk->health = 0; + chunk->angle = target->angle; + chunk->destscale = scale; + P_SetScale(chunk, scale); + P_UnsetThingPosition(chunk); + chunk->flags = MF_NOCLIP; + chunk->x += forwardxoffs - xoffs; + chunk->y += forwardyoffs - yoffs; + P_SetThingPosition(chunk); + P_InstaThrust(chunk, ang + ANGLE_180, 2*scale); + chunk->momz = P_RandomRange(5, 7)*scale; + if (flip) + chunk->momz *= -1; + if (sprflip) + chunk->frame |= FF_VERTICALFLIP; + + P_SetMobjState(target, target->info->deathstate); + target->health = 0; + P_UnsetThingPosition(target); + target->flags = MF_NOCLIP; + target->x += forwardxoffs + xoffs; + target->y += forwardyoffs + yoffs; + P_SetThingPosition(target); + P_InstaThrust(target, ang, 2*scale); + target->momz = P_RandomRange(5, 7)*scale; + if (flip) + target->momz *= -1; + if (!sprflip) + target->frame |= FF_VERTICALFLIP; } else if (target->player) { @@ -2876,7 +2946,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + if (damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. @@ -2905,7 +2975,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); - if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // spikes + if (damagetype == DMG_SPIKE) // spikes S_StartSound(player->mo, sfx_spkdth); if (source && source->player && !player->powers[pw_super]) //don't score points against super players diff --git a/src/p_map.c b/src/p_map.c index 7ea19a249..665ebd204 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -439,7 +439,9 @@ static boolean PIT_CheckThing(mobj_t *thing) // Metal Sonic destroys tiny baby objects. if (tmthing->type == MT_METALSONIC_RACE - && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) || thing->type == MT_SPIKE)) + && (thing->flags & (MF_MISSILE|MF_ENEMY|MF_BOSS) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) { if ((thing->flags & (MF_ENEMY|MF_BOSS)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; @@ -451,12 +453,14 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->type == MT_SPIKE) + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) { + mobjtype_t type = thing->type; if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) - if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); } else @@ -470,10 +474,13 @@ static boolean PIT_CheckThing(mobj_t *thing) // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. if ((tmthing->player) && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) - && (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE)) + && (thing->flags & (MF_MONITOR) + || (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE))) || ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY)) || (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)) - && (thing->type == MT_SPIKE)))) + && (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE)))) { if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE))) return true; @@ -485,12 +492,14 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->type == MT_SPIKE) + if (thing->type == MT_SPIKE + || thing->type == MT_WALLSPIKE) { + mobjtype_t type = thing->type; if (thing->flags & MF_SOLID) S_StartSound(tmthing, thing->info->deathsound); for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) - if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) + if (thing->type == type && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y), thing->z - tmthing->z) < 56*thing->scale)//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(thing, tmthing, tmthing, 0); } else @@ -937,12 +946,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height <= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) && thing->z + thing->height + thing->momz >= tmthing->z + FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && thing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->z >= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) && thing->z + thing->momz <= tmthing->z + tmthing->height - FixedMul(FRACUNIT, tmthing->scale) + tmthing->momz && !(thing->player->charability == CA_BOUNCE && thing->player->panim == PA_ABILITY && !(thing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(thing, tmthing, tmthing, 1, 0); + P_DamageMobj(thing, tmthing, tmthing, 1, DMG_SPIKE); } else if (thing->type == MT_SPIKE && thing->flags & MF_SOLID && tmthing->player) // unfortunate player falls into spike?! { @@ -951,12 +960,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height <= thing->z - FixedMul(FRACUNIT, thing->scale) && tmthing->z + tmthing->height + tmthing->momz >= thing->z - FixedMul(FRACUNIT, thing->scale) && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && tmthing->eflags & MFE_VERTICALFLIP)) - P_DamageMobj(tmthing, thing, thing, 1, 0); + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } else if (tmthing->z >= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) && tmthing->z + tmthing->momz <= thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) && !(tmthing->player->charability == CA_BOUNCE && tmthing->player->panim == PA_ABILITY && !(tmthing->eflags & MFE_VERTICALFLIP))) - P_DamageMobj(tmthing, thing, thing, 1, 0); + P_DamageMobj(tmthing, thing, thing, 1, DMG_SPIKE); } if (tmthing->type == MT_WALLSPIKE && tmthing->flags & MF_SOLID && thing->player) // wall spike impales player diff --git a/src/p_mobj.c b/src/p_mobj.c index 1bb6a2f01..f01cd4383 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2739,8 +2739,9 @@ static boolean P_ZMovement(mobj_t *mo) return true; break; case MT_SPIKE: + case MT_WALLSPIKE: // Dead spike particles disappear upon ground contact - if ((mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz) && mo->health <= 0) + if (!mo->health && (mo->z <= mo->floorz || mo->z + mo->height >= mo->ceilingz)) { P_RemoveMobj(mo); return false; @@ -10148,7 +10149,7 @@ ML_NOCLIMB : Direction not controllable // spawn base { const angle_t mobjangle = FixedAngle(mthing->angle*FRACUNIT); // the mobj's own angle hasn't been set quite yet so... - const fixed_t baseradius = mobj->radius - (mobj->scale/2); //FixedMul(FRACUNIT/2, mobj->scale); + const fixed_t baseradius = mobj->radius - mobj->scale; mobj_t *base = P_SpawnMobj( mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), From b2e92e7a099b741e9a4270d8753cca878d2270e4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Tue, 18 Jul 2017 14:17:10 +0100 Subject: [PATCH 7/9] * Invert solidity flag for vertical spikes and wallspikes. * (unrelated) Per a request by sphere, make the ambush flag stop sounds being made by the gas jet. --- src/p_enemy.c | 19 +++++++++++-------- src/p_mobj.c | 8 ++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 4b8d14170..08c6eb306 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4110,15 +4110,18 @@ void A_SetSolidSteam(mobj_t *actor) #endif actor->flags &= ~MF_NOCLIP; actor->flags |= MF_SOLID; - if (P_RandomChance(FRACUNIT/8)) + if (!(actor->flags2 & MF2_AMBUSH)) { - if (actor->info->deathsound) - S_StartSound(actor, actor->info->deathsound); // Hiss! - } - else - { - if (actor->info->painsound) - S_StartSound(actor, actor->info->painsound); + if (P_RandomChance(FRACUNIT/8)) + { + if (actor->info->deathsound) + S_StartSound(actor, actor->info->deathsound); // Hiss! + } + else + { + if (actor->info->painsound) + S_StartSound(actor, actor->info->painsound); + } } P_SetObjectMomZ (actor, 1, true); diff --git a/src/p_mobj.c b/src/p_mobj.c index f01cd4383..f8d1a4239 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10120,8 +10120,8 @@ ML_NOCLIMB : Direction not controllable mobj->flags &= ~MF_SCENERY; mobj->fuse = mthing->angle + mobj->info->speed; } - // Use per-thing collision for spikes if the deaf flag is checked. - if (mthing->options & MTF_AMBUSH && !metalrecording) + // Use per-thing collision for spikes if the deaf flag isn't checked. + if (!(mthing->options & MTF_AMBUSH) && !metalrecording) { P_UnsetThingPosition(mobj); mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIPHEIGHT); @@ -10137,8 +10137,8 @@ ML_NOCLIMB : Direction not controllable mobj->flags &= ~MF_SCENERY; mobj->fuse = mobj->info->speed; } - // Use per-thing collision for spikes if the deaf flag is checked. - if (mthing->options & MTF_AMBUSH && !metalrecording) + // Use per-thing collision for spikes if the deaf flag isn't checked. + if (!(mthing->options & MTF_AMBUSH) && !metalrecording) { P_UnsetThingPosition(mobj); mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT); From 1e1d191a757c5703e4c6a3f9a890c1e7c7b65ff9 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 30 Jul 2017 16:52:39 +0100 Subject: [PATCH 8/9] Make it so you can't even STAND on spikes if you're flashing and moving away from them. --- src/p_map.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 665ebd204..209df088c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -986,6 +986,13 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (thing->type == MT_WALLSPIKE && thing->flags & MF_SOLID && tmthing->player) { fixed_t bottomz, topz; + angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); + + if (P_PlayerInPain(tmthing->player) + && (tmthing->momx || tmthing->momy) + && (R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle) > ANGLE_180) + return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. + bottomz = thing->z; topz = thing->z + thing->height; @@ -998,13 +1005,6 @@ static boolean PIT_CheckThing(mobj_t *thing) && tmthing->z < topz // below top && !P_MobjWasRemoved(thing->tracer)) // this probably wouldn't work if we didn't have a tracer { // use base as a reference point to determine what angle you touched the spike at - angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); - - if (P_PlayerInPain(tmthing->player) - && (tmthing->momx || tmthing->momy) - && (R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle) > ANGLE_180) - return true; - touchangle = thing->angle - touchangle; if (touchangle > ANGLE_180) touchangle = InvAngle(touchangle); From 021e7ed1f0b0eb94420554fb6ec7243eadc32cf4 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 30 Jul 2017 17:45:27 +0100 Subject: [PATCH 9/9] Okay, actually fixed. Thanks, MI, for understanding the maths a little better than I :p --- src/p_map.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 209df088c..d4d8796a2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -988,10 +988,14 @@ static boolean PIT_CheckThing(mobj_t *thing) fixed_t bottomz, topz; angle_t touchangle = R_PointToAngle2(thing->tracer->x, thing->tracer->y, tmthing->x, tmthing->y); - if (P_PlayerInPain(tmthing->player) - && (tmthing->momx || tmthing->momy) - && (R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle) > ANGLE_180) - return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. + if (P_PlayerInPain(tmthing->player) && (tmthing->momx || tmthing->momy)) + { + angle_t playerangle = R_PointToAngle2(0, 0, tmthing->momx, tmthing->momy) - touchangle; + if (playerangle > ANGLE_180) + playerangle = InvAngle(playerangle); + if (playerangle < ANGLE_90) + return true; // Yes, this is intentionally outside the z-height check. No standing on spikes whilst moving away from them. + } bottomz = thing->z; topz = thing->z + thing->height;