mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- 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:
parent
7f35a95942
commit
f269af052c
8 changed files with 142 additions and 46 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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} },
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
@ -3234,15 +3238,21 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
|
|||
}
|
||||
|
||||
if (SpawningMapThing || !type->IsDescendantOf (RUNTIME_CLASS(APlayerPawn)))
|
||||
{
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
else if (!(actor->flags5 & MF5_NOINTERACTION))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue