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