- 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
- 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

View file

@ -261,6 +261,7 @@ enum
MF4_LOOKALLAROUND = 0x00010000, // Monster has eyes in the back of its head
MF4_STANDSTILL = 0x00020000, // Monster should not chase targets unless attacked?
MF4_SPECTRAL = 0x00040000,
MF4_SCROLLMOVE = 0x00080000, // momentum has been applied by a scroller
MF4_NOSPLASHALERT = 0x00100000, // Splashes don't alert this monster
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

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
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)
{
if (level.info == NULL) i_compatflags = self;
else i_compatflags = (self & ~level.info->compatmask) | (level.info->compatflags & level.info->compatmask);
i_compatflags = GetCompatibility(self);
}
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);
@ -536,6 +576,7 @@ CVAR (Flag, compat_invisibility,compatflags, COMPATF_INVISIBILITY);
CVAR (Flag, compat_silentinstantfloors,compatflags, COMPATF_SILENT_INSTANT_FLOORS);
CVAR (Flag, compat_sectorsounds,compatflags, COMPATF_SECTORSOUNDS);
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_SECTORSOUNDS = 1 << 18, // Sector sounds use original method for sound origin.
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:

View file

@ -33,7 +33,7 @@ void AFastProjectile::Tick ()
int count = 8;
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.
shift++;
@ -56,8 +56,8 @@ void AFastProjectile::Tick ()
if (--ripcount <= 0)
{
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))
{ // Blocked move
P_ExplodeMissile (this, BlockingLine, BlockingMobj);
@ -78,7 +78,11 @@ void AFastProjectile::Tick ()
P_ExplodeMissile (this, NULL, NULL);
return;
}
if (changexy) Effect();
if (changexy && ripcount <= 0)
{
ripcount = count >> 3;
Effect();
}
}
}
// Advance the state

View file

@ -86,6 +86,7 @@
EXTERN_CVAR(Bool, nomonsterinterpolation)
EXTERN_CVAR(Int, showendoom)
EXTERN_CVAR(Bool, hud_althud)
EXTERN_CVAR(Int, compatmode)
//
// defaulted values
//
@ -140,6 +141,14 @@ value_t OffOn[2] = {
{ 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;
int CurrentItem;
static const char *OldMessage;
@ -1092,6 +1101,8 @@ static menu_t DMFlagsMenu =
*=======================================*/
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, "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} },
@ -1107,6 +1118,7 @@ static menuitem_t CompatibilityItems[] = {
{ 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} },
{ 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, "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} },

View file

@ -160,6 +160,45 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos
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
@ -168,22 +207,24 @@ static bool PIT_FindFloorCeiling (line_t *ld, const FBoundingBox &box, FCheckPos
void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos)
{
sector_t *sec;
FCheckPosition tmf;
tmf.thing = actor;
tmf.x = actor->x;
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);
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;
validcount++;
@ -207,25 +248,6 @@ void P_FindFloorCeiling (AActor *actor, bool onlyspawnpos)
actor->ceilingpic = tmf.ceilingpic;
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)
{
FCheckPosition tmf;
sector_t* newsec;
// kill anything occupying the position
newsec = P_PointInSector (x,y);
// The base floor/ceiling is from the subsector that contains the point.
// 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.y = y;
tmf.z = z;
tmf.floorz = tmf.dropoffz = newsec->floorplane.ZatPoint (x, y);
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;
P_GetFloorCeilingZ(tmf);
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
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
// despite friction. If the speed is too low, then its movement will get
// cancelled, and it won't accumulate to the desired speed.
mo->flags4 &= ~MF4_SCROLLMOVE;
if (abs(scrollx) > CARRYSTOPSPEED)
{
scrollx = FixedMul (scrollx, CARRYFACTOR);
mo->momx += scrollx;
mo->flags4 |= MF4_SCROLLMOVE;
}
if (abs(scrolly) > CARRYSTOPSPEED)
{
scrolly = FixedMul (scrolly, CARRYFACTOR);
mo->momy += scrolly;
mo->flags4 |= MF4_SCROLLMOVE;
}
xmove += scrollx;
ymove += scrolly;
@ -1781,6 +1784,7 @@ explode:
}
mo->momx = mo->momy = 0;
mo->flags4 &= ~MF4_SCROLLMOVE;
// killough 10/98: kill any bobbing momentum too (except in voodoo dolls)
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)))
{
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
// current sector's floor. For map spawns this must be delayed until after setting the
// 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))
{