- fixed some issues with P_FindFloorCeiling's coordinate processing.

- added a new compatmode CVAR which allows setting some generic compatibility 
  flag combinations:
  Doom: sets the options needed to make most Doom.exe compatible map play without
  errors.
  Doom (strict): Same as above but sets a few more options. Please note that this
  does not mean full Doom.exe behavior emulation.
  Boom: Sets all options that consider differences between ZDoom and Boom.
  ZDoom 2.0.63: Sets only the COMPATF_SOUNDTARGET option which is needed for
  many older ZDoom maps.
- added new COMPAT_CROSSDROPOFF option to block monsters from being pushed over
  dropoffs by damage kickback.
- fixed: AFastProjectile::Tick must call Effect only 8 times per tic, regardless
  of the amount of steps taken.
- fixed: momentum checks in AFastProjectile did not use absolute values.


SVN r1369 (trunk)
This commit is contained in:
Christoph Oelckers 2009-01-25 21:59:38 +00:00
parent 7f35a95942
commit f269af052c
8 changed files with 142 additions and 46 deletions

View file

@ -1,3 +1,8 @@
January 25, 2009 (Changes by Graf Zahl)
- fixed: AFastProjectile::Tick must call Effect only 8 times per tic, regardless
of the amount of steps taken.
- fixed: momentum checks in AFastProjectile did not use absolute values.
January 24, 2009 January 24, 2009
- Restored the rhythm section to fmopl.cpp and made some slight updates from - Restored the rhythm section to fmopl.cpp and made some slight updates from
version 0.72 of MAME's fmopl.c. Also refactored CalcVoice so that the version 0.72 of MAME's fmopl.c. Also refactored CalcVoice so that the

View file

@ -261,6 +261,7 @@ enum
MF4_LOOKALLAROUND = 0x00010000, // Monster has eyes in the back of its head MF4_LOOKALLAROUND = 0x00010000, // Monster has eyes in the back of its head
MF4_STANDSTILL = 0x00020000, // Monster should not chase targets unless attacked? MF4_STANDSTILL = 0x00020000, // Monster should not chase targets unless attacked?
MF4_SPECTRAL = 0x00040000, MF4_SPECTRAL = 0x00040000,
MF4_SCROLLMOVE = 0x00080000, // momentum has been applied by a scroller
MF4_NOSPLASHALERT = 0x00100000, // Splashes don't alert this monster MF4_NOSPLASHALERT = 0x00100000, // Splashes don't alert this monster
MF4_SYNCHRONIZED = 0x00200000, // For actors spawned at load-time only: Do not randomize tics MF4_SYNCHRONIZED = 0x00200000, // For actors spawned at load-time only: Do not randomize tics
MF4_NOTARGETSWITCH = 0x00400000, // monster never switches target until current one is dead MF4_NOTARGETSWITCH = 0x00400000, // monster never switches target until current one is dead

View file

@ -510,10 +510,50 @@ CVAR (Flag, sv_noautoaim, dmflags2, DF2_NOAUTOAIM);
int i_compatflags; // internal compatflags composed from the compatflags CVAR and MAPINFO settings int i_compatflags; // internal compatflags composed from the compatflags CVAR and MAPINFO settings
EXTERN_CVAR(Int, compatmode)
static int GetCompatibility(int mask)
{
if (level.info == NULL) return mask;
else return (mask & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask);
}
CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO) CUSTOM_CVAR (Int, compatflags, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
{ {
if (level.info == NULL) i_compatflags = self; i_compatflags = GetCompatibility(self);
else i_compatflags = (self & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask); }
CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_SERVERINFO)
{
int v;
switch (self)
{
default:
case 0:
v = 0;
break;
case 1: // Doom2.exe compatible with a few relaxed settings
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF;
break;
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set)
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY;
break;
case 3:
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL;
break;
case 4:
v = COMPATF_SOUNDTARGET;
break;
}
compatflags = v;
} }
CVAR (Flag, compat_shortTex, compatflags, COMPATF_SHORTTEX); CVAR (Flag, compat_shortTex, compatflags, COMPATF_SHORTTEX);
@ -536,6 +576,7 @@ CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY);
CVAR (Flag, compat_silentinstantfloors,compatflags, COMPATF_SILENT_INSTANT_FLOORS); CVAR (Flag, compat_silentinstantfloors,compatflags, COMPATF_SILENT_INSTANT_FLOORS);
CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS); CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS);
CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP); CVAR (Flag, compat_missileclip, compatflags, COMPATF_MISSILECLIP);
CVAR (Flag, compat_crossdropoff,compatflags, COMPATF_CROSSDROPOFF);
//========================================================================== //==========================================================================
// //

View file

@ -279,6 +279,7 @@ enum
COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent COMPATF_SILENT_INSTANT_FLOORS = 1<<17, // Instantly moving floors are not silent
COMPATF_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin. COMPATF_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin.
COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles COMPATF_MISSILECLIP = 1 << 19, // Use original Doom heights for clipping against projectiles
COMPATF_CROSSDROPOFF = 1 << 20, // monsters can't be pushed over dropoffs
}; };
// phares 3/20/98: // phares 3/20/98:

View file

@ -33,7 +33,7 @@ void AFastProjectile::Tick ()
int count = 8; int count = 8;
if (radius > 0) if (radius > 0)
{ {
while ( ((momx >> shift) > radius) || ((momy >> shift) > radius)) while ( ((abs(momx) >> shift) > radius) || ((abs(momy) >> shift) > radius))
{ {
// we need to take smaller steps. // we need to take smaller steps.
shift++; shift++;
@ -56,8 +56,8 @@ void AFastProjectile::Tick ()
if (--ripcount <= 0) if (--ripcount <= 0)
{ {
tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen tm.LastRipped = NULL; // [RH] Do rip damage each step, like Hexen
ripcount = count >> 3;
} }
if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm)) if (!P_TryMove (this, x + xfrac,y + yfrac, true, false, tm))
{ // Blocked move { // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj); P_ExplodeMissile (this, BlockingLine, BlockingMobj);
@ -78,7 +78,11 @@ void AFastProjectile::Tick ()
P_ExplodeMissile (this, NULL, NULL); P_ExplodeMissile (this, NULL, NULL);
return; return;
} }
if (changexy) Effect(); if (changexy && ripcount <= 0)
{
ripcount = count >> 3;
Effect();
}
} }
} }
// Advance the state // Advance the state

View file

@ -86,6 +86,7 @@
EXTERN_CVAR(Bool, nomonsterinterpolation) EXTERN_CVAR(Bool, nomonsterinterpolation)
EXTERN_CVAR(Int, showendoom) EXTERN_CVAR(Int, showendoom)
EXTERN_CVAR(Bool, hud_althud) EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, compatmode)
// //
// defaulted values // defaulted values
// //
@ -140,6 +141,14 @@ value_t OffOn[2] = {
{ 1.0, "Off" } { 1.0, "Off" }
}; };
value_t CompatModes[5] = {
{ 0.0, "Default" },
{ 1.0, "Doom" },
{ 2.0, "Doom (strict)" },
{ 3.0, "Boom" },
{ 4.0, "ZDoom 2.0.63" }
};
menu_t *CurrentMenu; menu_t *CurrentMenu;
int CurrentItem; int CurrentItem;
static const char *OldMessage; static const char *OldMessage;
@ -1092,6 +1101,8 @@ static menu_t DMFlagsMenu =
*=======================================*/ *=======================================*/
static menuitem_t CompatibilityItems[] = { static menuitem_t CompatibilityItems[] = {
{ discrete, "Compatibility mode", {&compatmode}, {5.0}, {0.0}, {0.0}, {CompatModes} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} }, { bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} },
{ bitflag, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} }, { bitflag, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} },
{ bitflag, "Limit Pain Elementals' Lost Souls", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_LIMITPAIN} }, { bitflag, "Limit Pain Elementals' Lost Souls", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_LIMITPAIN} },
@ -1107,6 +1118,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "DEH health settings like Doom2.exe", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DEHHEALTH} }, { 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, "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} }, { bitflag, "Monsters get stuck over dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_DROPOFF} },
{ bitflag, "Monsters cannot cross dropoffs", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_CROSSDROPOFF} },
{ bitflag, "Monsters see invisible players", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_INVISIBILITY} }, { bitflag, "Monsters see invisible players", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_INVISIBILITY} },
{ bitflag, "Boom scrollers are additive", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_BOOMSCROLL} }, { bitflag, "Boom scrollers are additive", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_BOOMSCROLL} },
{ bitflag, "Inst. moving floors are not silent", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SILENT_INSTANT_FLOORS} }, { bitflag, "Inst. moving floors are not silent", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SILENT_INSTANT_FLOORS} },

View file

@ -160,6 +160,45 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos
return true; return true;
} }
void P_GetFloorCeilingZ(FCheckPosition &tmf)
{
sector_t *sec = P_PointInSector (tmf.x, tmf.y);
tmf.floorsector = sec;
tmf.ceilingsector = sec;
tmf.floorz = tmf.dropoffz = sec->floorplane.ZatPoint (tmf.x, tmf.y);
tmf.ceilingz = sec->ceilingplane.ZatPoint (tmf.x, tmf.y);
tmf.floorpic = sec->GetTexture(sector_t::floor);
tmf.ceilingpic = sec->GetTexture(sector_t::ceiling);
#ifdef _3DFLOORS
for(unsigned int i=0;i<sec->e->XFloor.ffloors.Size();i++)
{
F3DFloor* rover = sec->e->XFloor.ffloors[i];
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
fixed_t ff_bottom = rover->bottom.plane->ZatPoint(tmf.x, tmf.y);
fixed_t ff_top = rover->top.plane->ZatPoint(tmf.x, tmf.y);
if (ff_top > tmf.floorz)
{
if (ff_top < tmf.z || (tmf.thing != NULL && ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight))
{
tmf.dropoffz = tmf.floorz = ff_top;
tmf.floorpic = *rover->top.texture;
}
}
if (ff_bottom < tmf.ceilingz && ff_bottom > tmf.z + tmf.thing->height)
{
tmf.ceilingz = ff_bottom;
tmf.ceilingpic = *rover->bottom.texture;
}
}
#endif
}
//========================================================================== //==========================================================================
// //
// P_FindFloorCeiling // P_FindFloorCeiling
@ -168,22 +207,24 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos
void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos) void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos)
{ {
sector_t *sec;
FCheckPosition tmf; FCheckPosition tmf;
tmf.thing = actor;
tmf.x = actor->x; tmf.x = actor->x;
tmf.y = actor->y; tmf.y = actor->y;
tmf.z = actor->z;
P_GetFloorCeilingZ(tmf);
actor->floorz = tmf.floorz;
actor->dropoffz = tmf.dropoffz;
actor->ceilingz = tmf.ceilingz;
actor->floorpic = tmf.floorpic;
actor->floorsector = tmf.floorsector;
actor->ceilingpic = tmf.ceilingpic;
actor->ceilingsector = tmf.ceilingsector;
FBoundingBox box(tmf.x, tmf.y, actor->radius); FBoundingBox box(tmf.x, tmf.y, actor->radius);
sec = P_PointInSector (tmf.x, tmf.y);
tmf.thing = actor;
tmf.floorz = tmf.dropoffz = sec->floorplane.ZatPoint (tmf.x, tmf.y);
tmf.ceilingz = sec->ceilingplane.ZatPoint (tmf.x, tmf.y);
tmf.floorpic = sec->GetTexture(sector_t::floor);
tmf.floorsector = sec;
tmf.ceilingpic = sec->GetTexture(sector_t::ceiling);
tmf.ceilingsector = sec;
tmf.touchmidtex = false; tmf.touchmidtex = false;
validcount++; validcount++;
@ -207,25 +248,6 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos)
actor->ceilingpic = tmf.ceilingpic; actor->ceilingpic = tmf.ceilingpic;
actor->ceilingsector = tmf.ceilingsector; actor->ceilingsector = tmf.ceilingsector;
} }
#ifdef _3DFLOORS
// also check 3D floors at the spawn position if the result from the block lines iterator cannot be used.
if (onlyspawnpos)
{
for(unsigned int i=0;i<actor->Sector->e->XFloor.ffloors.Size();i++)
{
F3DFloor* rover=actor->Sector->e->XFloor.ffloors[i];
if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;
fixed_t ff_bottom=rover->bottom.plane->ZatPoint(actor->x, actor->y);
fixed_t ff_top=rover->top.plane->ZatPoint(actor->x, actor->y);
if (ff_top > actor->floorz && ff_top < actor->z) actor->floorz = ff_top;
if (ff_bottom < actor->ceilingz && ff_bottom > actor->z + actor->height) actor->ceilingz = ff_bottom;
}
}
#endif
} }
// //
@ -244,11 +266,9 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos)
bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag) bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefrag)
{ {
FCheckPosition tmf; FCheckPosition tmf;
sector_t* newsec;
// kill anything occupying the position // kill anything occupying the position
newsec = P_PointInSector (x,y);
// The base floor/ceiling is from the subsector that contains the point. // The base floor/ceiling is from the subsector that contains the point.
// Any contacted lines the step closer together will adjust them. // Any contacted lines the step closer together will adjust them.
@ -256,12 +276,7 @@ bool P_TeleportMove (AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefr
tmf.x = x; tmf.x = x;
tmf.y = y; tmf.y = y;
tmf.z = z; tmf.z = z;
tmf.floorz = tmf.dropoffz = newsec->floorplane.ZatPoint (x, y); P_GetFloorCeilingZ(tmf);
tmf.ceilingz = newsec->ceilingplane.ZatPoint (x, y);
tmf.floorpic = newsec->GetTexture(sector_t::floor);
tmf.floorsector = newsec;
tmf.ceilingpic = newsec->GetTexture(sector_t::ceiling);
tmf.ceilingsector = newsec;
spechit.Clear (); spechit.Clear ();
@ -1540,6 +1555,13 @@ bool P_TryMove (AActor *thing, fixed_t x, fixed_t y,
} }
} }
// compatibility check: Doom originally did not allow monsters to cross dropoffs at all.
// If the compatibility flag is on, only allow this when the momentum comes from a scroller
if ((i_compatflags & COMPATF_CROSSDROPOFF) && !(thing->flags4 & MF4_SCROLLMOVE))
{
dropoff = false;
}
// killough 3/15/98: Allow certain objects to drop off // killough 3/15/98: Allow certain objects to drop off
if ((!dropoff && !(thing->flags & (MF_DROPOFF|MF_FLOAT|MF_MISSILE))) || (thing->flags5&MF5_NODROPOFF)) if ((!dropoff && !(thing->flags & (MF_DROPOFF|MF_FLOAT|MF_MISSILE))) || (thing->flags5&MF5_NODROPOFF))
{ {

View file

@ -1396,15 +1396,18 @@ void P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly)
// because BOOM relied on the speed being fast enough to accumulate // because BOOM relied on the speed being fast enough to accumulate
// despite friction. If the speed is too low, then its movement will get // despite friction. If the speed is too low, then its movement will get
// cancelled, and it won't accumulate to the desired speed. // cancelled, and it won't accumulate to the desired speed.
mo->flags4 &= ~MF4_SCROLLMOVE;
if (abs(scrollx) > CARRYSTOPSPEED) if (abs(scrollx) > CARRYSTOPSPEED)
{ {
scrollx = FixedMul (scrollx, CARRYFACTOR); scrollx = FixedMul (scrollx, CARRYFACTOR);
mo->momx += scrollx; mo->momx += scrollx;
mo->flags4 |= MF4_SCROLLMOVE;
} }
if (abs(scrolly) > CARRYSTOPSPEED) if (abs(scrolly) > CARRYSTOPSPEED)
{ {
scrolly = FixedMul (scrolly, CARRYFACTOR); scrolly = FixedMul (scrolly, CARRYFACTOR);
mo->momy += scrolly; mo->momy += scrolly;
mo->flags4 |= MF4_SCROLLMOVE;
} }
xmove += scrollx; xmove += scrollx;
ymove += scrolly; ymove += scrolly;
@ -1781,6 +1784,7 @@ explode:
} }
mo->momx = mo->momy = 0; mo->momx = mo->momy = 0;
mo->flags4 &= ~MF4_SCROLLMOVE;
// killough 10/98: kill any bobbing momentum too (except in voodoo dolls) // killough 10/98: kill any bobbing momentum too (except in voodoo dolls)
if (player && player->mo == mo) if (player && player->mo == mo)
@ -3235,14 +3239,20 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn))) if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn)))
{ {
actor->floorsector = actor->Sector;
actor->floorpic = actor->floorsector->GetTexture(sector_t::floor);
actor->ceilingsector = actor->Sector;
actor->ceilingpic = actor->ceilingsector->GetTexture(sector_t::ceiling);
// Check if there's something solid to stand on between the current position and the // Check if there's something solid to stand on between the current position and the
// current sector's floor. For map spawns this must be delayed until after setting the // current sector's floor. For map spawns this must be delayed until after setting the
// z-coordinate. // z-coordinate.
if (!SpawningMapThing) P_FindFloorCeiling(actor, true); if (!SpawningMapThing)
{
P_FindFloorCeiling(actor, true);
}
else
{
actor->floorsector = actor->Sector;
actor->floorpic = actor->floorsector->GetTexture(sector_t::floor);
actor->ceilingsector = actor->Sector;
actor->ceilingpic = actor->ceilingsector->GetTexture(sector_t::ceiling);
}
} }
else if (!(actor->flags5 & MF5_NOINTERACTION)) else if (!(actor->flags5 & MF5_NOINTERACTION))
{ {