diff --git a/docs/rh-log.txt b/docs/rh-log.txt index c229c8f27..0782bbecc 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,11 @@ +April 23, 2006 (Changes by Graf Zahl) +- Added MBF's logic to move monsters away from a dropoff but changed it + so that it doesn't require a general change in the movement code. +- Added: The Trace function needs a compatibility option to exclude + two-sided lines with both sides in the same sector from being checked. + Originally this wasn't done and some WADs (e.g. Alien Vendetta MAP15) + need the original behavior to work. + April 22, 2006 (Changes by Graf Zahl) - Removed ABossEye::Serialize because it didn't do anything. - Fixed the issues with .96x's railgun code and added it to the current diff --git a/src/actor.h b/src/actor.h index fe6ed95f7..48f898c8b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -278,6 +278,7 @@ enum MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. MF5_BOUNCEONACTORS = 0x00000008, // bouncing missile doesn't explode when it hits an actor MF5_EXPLODEONWATER = 0x00000010, // bouncing missile explpdes when hitting a water surface + MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away fro dropoffs // --- mobj.renderflags --- diff --git a/src/d_main.cpp b/src/d_main.cpp index 5486bdbf4..a35c9f7b9 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -392,6 +392,8 @@ CVAR (Flag, compat_nodoorlight, compatflags, COMPATF_NODOORLIGHT); CVAR (Flag, compat_ravenscroll, compatflags, COMPATF_RAVENSCROLL); CVAR (Flag, compat_soundtarget, compatflags, COMPATF_SOUNDTARGET); CVAR (Flag, compat_dehhealth, compatflags, COMPATF_DEHHEALTH); +CVAR (Flag, compat_trace, compatflags, COMPATF_TRACE); +CVAR (Flag, compat_dropoff, compatflags, COMPATF_DROPOFF); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 731a36ae5..e41845c9d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -264,6 +264,8 @@ enum COMPATF_RAVENSCROLL = 1 << 10, // Raven's scrollers use their original carrying speed COMPATF_SOUNDTARGET = 1 << 11, // Use sector based sound target code. COMPATF_DEHHEALTH = 1 << 12, // Limit deh.MaxHealth to the health bonus (as in Doom2.exe) + COMPATF_TRACE = 1 << 13, // Trace ignores lines with the same sector on both sides + COMPATF_DROPOFF = 1 << 14, // Monsters cannot move when hanging over a dropoff }; // phares 3/20/98: diff --git a/src/m_options.cpp b/src/m_options.cpp index d8b5a89c3..38956af36 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -956,6 +956,9 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "Raven scrollers use original speed", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_RAVENSCROLL} }, { bitflag, "Use original sound target handling", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SOUNDTARGET} }, { bitflag, "DEH health settings like Doom2.exe", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DEHHEALTH} }, + { bitflag, "Self ref. sectors don't block shots", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_TRACE} }, + { bitflag, "Monsters get stuck over dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DROPOFF} }, + { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, }; diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 7f7e1c341..204044c3e 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -144,6 +144,9 @@ void P_RecursiveSound (sector_t *sec, AActor *soundtarget, bool splash, int soun { continue; } + + // Early out for intra-sector lines + if (sides[check->sidenum[0]].sector==sides[check->sidenum[1]].sector) continue; if ( sides[ check->sidenum[0] ].sector == sec) other = sides[ check->sidenum[1] ].sector; @@ -277,9 +280,12 @@ bool P_CheckMeleeRange2 (AActor *actor) return true; } + +//============================================================================= // // P_CheckMissileRange // +//============================================================================= BOOL P_CheckMissileRange (AActor *actor) { fixed_t dist; @@ -529,6 +535,7 @@ BOOL P_Move (AActor *actor) } +//============================================================================= // // TryWalk // Attempts to move actor on @@ -540,6 +547,8 @@ BOOL P_Move (AActor *actor) // If a door is in the way, // an OpenDoor call is made to start it opening. // +//============================================================================= + BOOL P_TryWalk (AActor *actor) { if (!P_Move (actor)) @@ -550,18 +559,19 @@ BOOL P_TryWalk (AActor *actor) return true; } +//============================================================================= +// +// P_DoNewChaseDir +// +// killough 9/8/98: +// +// Most of P_NewChaseDir(), except for what +// determines the new direction to take +// +//============================================================================= -/* -================ -= -= P_NewChaseDir -= -================ -*/ - -void P_NewChaseDir (AActor *actor) +void P_DoNewChaseDir (AActor *actor, fixed_t deltax, fixed_t deltay) { - fixed_t deltax, deltay; dirtype_t d[3]; int tdir; dirtype_t olddir, turnaround; @@ -572,8 +582,6 @@ void P_NewChaseDir (AActor *actor) olddir = (dirtype_t)actor->movedir; turnaround = opposite[olddir]; - deltax = actor->target->x - actor->x; - deltay = actor->target->y - actor->y; // [RH] Make monsters run away from frightening players if ((actor->target->player != NULL && @@ -678,6 +686,132 @@ void P_NewChaseDir (AActor *actor) actor->movedir = DI_NODIR; // can not move } + +//============================================================================= +// +// killough 11/98: +// +// Monsters try to move away from tall dropoffs. +// +// In Doom, they were never allowed to hang over dropoffs, +// and would remain stuck if involuntarily forced over one. +// This logic, combined with p_map.c (P_TryMove), allows +// monsters to free themselves without making them tend to +// hang over dropoffs. +//============================================================================= + +struct avoiddropoff_t +{ + fixed_t deltax; + fixed_t deltay; + fixed_t floorx; + fixed_t floory; + fixed_t floorz; + fixed_t t_bbox[4]; +} a; + +static BOOL PIT_AvoidDropoff(line_t *line) +{ + if (line->backsector && // Ignore one-sided linedefs + a.t_bbox[BOXRIGHT] > line->bbox[BOXLEFT] && + a.t_bbox[BOXLEFT] < line->bbox[BOXRIGHT] && + a.t_bbox[BOXTOP] > line->bbox[BOXBOTTOM] && // Linedef must be contacted + a.t_bbox[BOXBOTTOM] < line->bbox[BOXTOP] && + P_BoxOnLineSide(a.t_bbox, line) == -1) + { + fixed_t front = line->frontsector->floorplane.ZatPoint(a.floorx,a.floory); + fixed_t back = line->backsector->floorplane.ZatPoint(a.floorx,a.floory); + angle_t angle; + + // The monster must contact one of the two floors, + // and the other must be a tall dropoff (more than 24). + + if (back == a.floorz && front < a.floorz - FRACUNIT*24) + { + angle = R_PointToAngle2(0,0,line->dx,line->dy); // front side dropoff + } + else if (front == a.floorz && back < a.floorz - FRACUNIT*24) + { + angle = R_PointToAngle2(line->dx,line->dy,0,0); // back side dropoff + } + else return true; + + // Move away from dropoff at a standard speed. + // Multiple contacted linedefs are cumulative (e.g. hanging over corner) + a.deltax -= finesine[angle >> ANGLETOFINESHIFT]*32; + a.deltay += finecosine[angle >> ANGLETOFINESHIFT]*32; + } + return true; +} + +//============================================================================= +// +// P_NewChaseDir +// +// killough 9/8/98: Split into two functions +// +//============================================================================= + +void P_NewChaseDir(AActor * actor) +{ + fixed_t deltax = actor->target->x - actor->x; + fixed_t deltay = actor->target->y - actor->y; + + // Try to move away from a dropoff + if (actor->floorz - actor->dropoffz > actor->MaxDropOffHeight && + actor->z <= actor->floorz && !(actor->flags & MF_DROPOFF) && + !(actor->flags2 & MF2_ONMOBJ) && + !(actor->flags & MF_FLOAT) && !(compatflags & COMPATF_DROPOFF)) + { + a.deltax = a.deltay = 0; + a.floorx = actor->x; + a.floory = actor->y; + a.floorz = actor->z; + + int yh=((a.t_bbox[BOXTOP] = actor->y+actor->radius)-bmaporgy)>>MAPBLOCKSHIFT; + int yl=((a.t_bbox[BOXBOTTOM]= actor->y-actor->radius)-bmaporgy)>>MAPBLOCKSHIFT; + int xh=((a.t_bbox[BOXRIGHT] = actor->x+actor->radius)-bmaporgx)>>MAPBLOCKSHIFT; + int xl=((a.t_bbox[BOXLEFT] = actor->x-actor->radius)-bmaporgx)>>MAPBLOCKSHIFT; + int bx, by; + + // check lines + + validcount++; + for (bx=xl ; bx<=xh ; bx++) + for (by=yl ; by<=yh ; by++) + P_BlockLinesIterator(bx, by, PIT_AvoidDropoff); // all contacted lines + + if (a.deltax || a.deltay) + { + // [Graf Zahl] I have changed P_TryMove to only apply this logic when + // being called from here. AVOIDINGDROPOFF activates the code that + // allows monsters to move away from a dropoff. This is different from + // MBF which requires unconditional use of the altered logic and therefore + // forcing a massive change in the monster behavior to use this. + + // use different dropoff movement logic in P_TryMove + actor->flags5|=MF5_AVOIDINGDROPOFF; + P_DoNewChaseDir(actor, a.deltax, a.deltay); + actor->flags5&=~MF5_AVOIDINGDROPOFF; + + // If moving away from dropoff, set movecount to 1 so that + // small steps are taken to get monster away from dropoff. + actor->movecount = 1; + return; + } + } + P_DoNewChaseDir(actor, deltax, deltay); +} + + + + +//============================================================================= +// +// P_RandomChaseDir +// +//============================================================================= + void P_RandomChaseDir (AActor *actor) { dirtype_t olddir, turnaround; @@ -1472,6 +1606,12 @@ void A_Look (AActor *actor) } } + +//========================================================================== +// +// A_Wander +// +//========================================================================== void A_Wander (AActor *self) { int delta; @@ -1511,6 +1651,12 @@ void A_Wander (AActor *self) } } + +//========================================================================== +// +// A_Look2 +// +//========================================================================== void A_Look2 (AActor *self) { AActor *targ; @@ -1856,7 +2002,7 @@ void A_DoChase (AActor *actor, bool fastchase, FState *meleestate, FState *missi // class bosses don't do this when strafing if (!fastchase || !actor->special2) { - // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions! + // CANTLEAVEFLOORPIC handling was completely missing in the non-serpent functions. fixed_t oldX = actor->x; fixed_t oldY = actor->y; int oldFloor = actor->floorpic; @@ -1902,10 +2048,11 @@ void A_FastChase (AActor *actor) A_DoChase (actor, true, actor->MeleeState, actor->MissileState, true, true); } - +//============================================================================= // // A_FaceTarget // +//============================================================================= void A_FaceTarget (AActor *actor) { if (!actor->target) @@ -1927,11 +2074,14 @@ void A_FaceTarget (AActor *actor) } } + +//=========================================================================== // // [RH] A_MonsterRail // // New function to let monsters shoot a railgun // +//=========================================================================== void A_MonsterRail (AActor *actor) { if (!actor->target) diff --git a/src/p_map.cpp b/src/p_map.cpp index 2a0f80a08..51d8bc351 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1670,11 +1670,19 @@ BOOL P_TryMove (AActor *thing, fixed_t x, fixed_t y, { floorz = MAX(thing->z, tmfloorz); } - if (floorz - tmdropoffz > thing->MaxDropOffHeight && - !(thing->flags2 & MF2_BLASTED)) - { // Can't move over a dropoff unless it's been blasted - thing->z = oldz; - return false; + if (!(thing->flags5&MF5_AVOIDINGDROPOFF)) + { + if (floorz - tmdropoffz > thing->MaxDropOffHeight && + !(thing->flags2 & MF2_BLASTED)) + { // Can't move over a dropoff unless it's been blasted + thing->z = oldz; + return false; + } + } + else + { + // special logic to move a monster off a dropoff + if (thing->dropoffz - tmdropoffz > thing->MaxDropOffHeight) return false; } } if (thing->flags2 & MF2_CANTLEAVEFLOORPIC diff --git a/src/p_trace.cpp b/src/p_trace.cpp index b1c1bb9da..69a0779cc 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -168,6 +168,13 @@ static BOOL PTR_TraceIterator (intercept_t *in) else { entersector = (lineside == 0) ? in->d.line->backsector : in->d.line->frontsector; + + // For backwards compatibility: Ignore lines with the same sector on both sides. + // This is the way Doom.exe did it and some WADs (e.g. Alien Vendetta MAP15 needs it. + if (compatflags & COMPATF_TRACE) + { + return true; + } } ff = CurSector->floorplane.ZatPoint (hitx, hity);