mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 15:02:01 +00:00
- refactoring of PIT_CheckThing.
This commit is contained in:
parent
98c7fabb89
commit
ca2fc47fa3
2 changed files with 57 additions and 51 deletions
|
@ -290,6 +290,7 @@ enum
|
||||||
FFCF_NOPORTALS = 16, // ignore portals (considers them impassable.)
|
FFCF_NOPORTALS = 16, // ignore portals (considers them impassable.)
|
||||||
FFCF_NOFLOOR = 32,
|
FFCF_NOFLOOR = 32,
|
||||||
FFCF_NOCEILING = 64,
|
FFCF_NOCEILING = 64,
|
||||||
|
FFCF_RESTRICTEDPORTAL = 128, // current values in the iterator's return are through a restricted portal type (i.e. some features are blocked.)
|
||||||
};
|
};
|
||||||
void P_FindFloorCeiling (AActor *actor, int flags=0);
|
void P_FindFloorCeiling (AActor *actor, int flags=0);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,7 @@ static FRandom pr_crunch("DoCrunch");
|
||||||
// keep track of special lines as they are hit,
|
// keep track of special lines as they are hit,
|
||||||
// but don't process them until the move is proven valid
|
// but don't process them until the move is proven valid
|
||||||
TArray<line_t *> spechit;
|
TArray<line_t *> spechit;
|
||||||
|
TArray<line_t *> portalhit;
|
||||||
|
|
||||||
// Temporary holder for thing_sectorlist threads
|
// Temporary holder for thing_sectorlist threads
|
||||||
msecnode_t* sector_list = NULL; // phares 3/16/98
|
msecnode_t* sector_list = NULL; // phares 3/16/98
|
||||||
|
@ -415,8 +416,6 @@ bool P_TeleportMove(AActor *thing, fixed_t x, fixed_t y, fixed_t z, bool telefra
|
||||||
tmf.abovemidtex = false;
|
tmf.abovemidtex = false;
|
||||||
P_GetFloorCeilingZ(tmf, 0);
|
P_GetFloorCeilingZ(tmf, 0);
|
||||||
|
|
||||||
spechit.Clear();
|
|
||||||
|
|
||||||
bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP);
|
bool StompAlwaysFrags = ((thing->flags2 & MF2_TELESTOMP) || (level.flags & LEVEL_MONSTERSTELEFRAG) || telefrag) && !(thing->flags7 & MF7_NOTELESTOMP);
|
||||||
|
|
||||||
// P_LineOpening requires the thing's z to be the destination z in order to work.
|
// P_LineOpening requires the thing's z to be the destination z in order to work.
|
||||||
|
@ -839,7 +838,6 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
if (!(tm.thing->flags & MF_DROPOFF) &&
|
if (!(tm.thing->flags & MF_DROPOFF) &&
|
||||||
!(tm.thing->flags & (MF_NOGRAVITY | MF_NOCLIP)))
|
!(tm.thing->flags & (MF_NOGRAVITY | MF_NOCLIP)))
|
||||||
{
|
{
|
||||||
// Check 3D floors as well
|
|
||||||
if ((open.frontfloorplane.c < STEEPSLOPE) != (open.backfloorplane.c < STEEPSLOPE))
|
if ((open.frontfloorplane.c < STEEPSLOPE) != (open.backfloorplane.c < STEEPSLOPE))
|
||||||
{
|
{
|
||||||
// on the boundary of a steep slope
|
// on the boundary of a steep slope
|
||||||
|
@ -847,7 +845,7 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the floor planes on both sides we should recalculate open.bottom at the actual position we are checking
|
// If the floor planes on both sides match we should recalculate open.bottom at the actual position we are checking
|
||||||
// This is to avoid bumpy movement when crossing a linedef with the same slope on both sides.
|
// This is to avoid bumpy movement when crossing a linedef with the same slope on both sides.
|
||||||
if (open.frontfloorplane == open.backfloorplane)
|
if (open.frontfloorplane == open.backfloorplane)
|
||||||
{
|
{
|
||||||
|
@ -902,6 +900,10 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
||||||
{
|
{
|
||||||
spechit.Push(ld);
|
spechit.Push(ld);
|
||||||
}
|
}
|
||||||
|
if (ld->portalindex >= 0)
|
||||||
|
{
|
||||||
|
portalhit.Push(ld);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1013,9 +1015,8 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY))
|
if (!((thing->flags & (MF_SOLID | MF_SPECIAL | MF_SHOOTABLE)) || thing->flags6 & MF6_TOUCHY))
|
||||||
return true; // can't hit thing
|
return true; // can't hit thing
|
||||||
|
|
||||||
fixedvec3 thingpos = thing->PosRelative(tm.thing);
|
|
||||||
fixed_t blockdist = thing->radius + tm.thing->radius;
|
fixed_t blockdist = thing->radius + tm.thing->radius;
|
||||||
if (abs(thingpos.x - tm.x) >= blockdist || abs(thingpos.y - tm.y) >= blockdist)
|
if (abs(thing->X() - cres.position.x) >= blockdist || abs(thing->Y() - cres.position.y) >= blockdist)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS)
|
if ((thing->flags2 | tm.thing->flags2) & MF2_THRUACTORS)
|
||||||
|
@ -1026,12 +1027,19 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
|
|
||||||
tm.thing->BlockingMobj = thing;
|
tm.thing->BlockingMobj = thing;
|
||||||
topz = thing->Top();
|
topz = thing->Top();
|
||||||
|
|
||||||
|
// Both things overlap in x or y direction
|
||||||
|
bool unblocking = false;
|
||||||
|
|
||||||
|
// walking on other actors and unblocking is too messy through restricted portal types so disable it.
|
||||||
|
if (!(cres.portalflags & FFCF_RESTRICTEDPORTAL))
|
||||||
|
{
|
||||||
if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) &&
|
if (!(i_compatflags & COMPATF_NO_PASSMOBJ) && !(tm.thing->flags & (MF_FLOAT | MF_MISSILE | MF_SKULLFLY | MF_NOGRAVITY)) &&
|
||||||
(thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE))
|
(thing->flags & MF_SOLID) && (thing->flags4 & MF4_ACTLIKEBRIDGE))
|
||||||
{
|
{
|
||||||
// [RH] Let monsters walk on actors as well as floors
|
// [RH] Let monsters walk on actors as well as floors
|
||||||
if ((tm.thing->flags3 & MF3_ISMONSTER) &&
|
if (cres.zdiff != 0 && (tm.thing->flags3 & MF3_ISMONSTER) &&
|
||||||
topz >= tm.floorz && topz <= tm.thing->Z() + tm.thing->MaxStepHeight)
|
topz >= tm.floorz && topz <= cres.position.z + tm.thing->MaxStepHeight)
|
||||||
{
|
{
|
||||||
// The commented-out if is an attempt to prevent monsters from walking off a
|
// The commented-out if is an attempt to prevent monsters from walking off a
|
||||||
// thing further than they would walk off a ledge. I can't think of an easy
|
// thing further than they would walk off a ledge. I can't think of an easy
|
||||||
|
@ -1047,29 +1055,27 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both things overlap in x or y direction
|
if (((tm.FromPMove || tm.thing->player != NULL) && thing->flags&MF_SOLID))
|
||||||
bool unblocking = false;
|
|
||||||
|
|
||||||
if ((tm.FromPMove || tm.thing->player != NULL) && thing->flags&MF_SOLID)
|
|
||||||
{
|
{
|
||||||
|
fixedvec3 oldpos = tm.thing->PosRelative(thing);
|
||||||
// Both actors already overlap. To prevent them from remaining stuck allow the move if it
|
// Both actors already overlap. To prevent them from remaining stuck allow the move if it
|
||||||
// takes them further apart or the move does not change the position (when called from P_ChangeSector.)
|
// takes them further apart or the move does not change the position (when called from P_ChangeSector.)
|
||||||
if (tm.x == tm.thing->X() && tm.y == tm.thing->Y())
|
if (oldpos.x == thing->X() && oldpos.y == thing->Y())
|
||||||
{
|
{
|
||||||
unblocking = true;
|
unblocking = true;
|
||||||
}
|
}
|
||||||
else if (abs(thingpos.x - tm.thing->X()) < (thing->radius+tm.thing->radius) &&
|
else if (abs(thing->X() - oldpos.x) < (thing->radius + tm.thing->radius) &&
|
||||||
abs(thingpos.y - tm.thing->Y()) < (thing->radius+tm.thing->radius))
|
abs(thing->Y() - oldpos.y) < (thing->radius + tm.thing->radius))
|
||||||
|
|
||||||
{
|
{
|
||||||
fixed_t newdist = thing->AproxDistance(tm.x, tm.y, tm.thing);
|
fixed_t newdist = thing->AproxDistance(cres.position.x, cres.position.y);
|
||||||
fixed_t olddist = thing->AproxDistance(tm.thing);
|
fixed_t olddist = thing->AproxDistance(oldpos.x, oldpos.y);
|
||||||
|
|
||||||
if (newdist > olddist)
|
if (newdist > olddist)
|
||||||
{
|
{
|
||||||
// ... but not if they did not overlap in z-direction before but would after the move.
|
// unblock only if there's already a vertical overlap (or both actors are flagged not to overlap)
|
||||||
unblocking = !((tm.thing->Z() >= topz && tm.z < topz) ||
|
unblocking = (cres.position.z + tm.thing->height > thing->Z() && cres.position.z < topz) || (tm.thing->flags3 & thing->flags3 & MF3_DONTOVERLAP);
|
||||||
(tm.thing->Top() <= thingpos.z && tm.thing->Top() > thingpos.z));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1087,7 +1093,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
{ // Some things prefer not to overlap each other, if possible
|
{ // Some things prefer not to overlap each other, if possible
|
||||||
return unblocking;
|
return unblocking;
|
||||||
}
|
}
|
||||||
if ((tm.thing->Z() >= topz) || (tm.thing->Top() <= thing->Z()))
|
if ((cres.position.z >= topz) || (cres.position.z + tm.thing->height <= thing->Z()))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1103,7 +1109,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
// or different species if DONTHARMSPECIES
|
// or different species if DONTHARMSPECIES
|
||||||
(!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) &&
|
(!(thing->flags6 & MF6_DONTHARMSPECIES) || thing->GetSpecies() != tm.thing->GetSpecies()) &&
|
||||||
// touches vertically
|
// touches vertically
|
||||||
topz >= tm.thing->Z() && tm.thing->Z() + tm.thing->height >= thingpos.z &&
|
topz >= cres.position.z && cres.position.z + tm.thing->height >= thing->Z() &&
|
||||||
// prevents lost souls from exploding when fired by pain elementals
|
// prevents lost souls from exploding when fired by pain elementals
|
||||||
(thing->master != tm.thing && tm.thing->master != thing))
|
(thing->master != tm.thing && tm.thing->master != thing))
|
||||||
// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
|
// Difference with MBF: MBF hardcodes the LS/PE check and lets actors of the same species
|
||||||
|
@ -1206,11 +1212,11 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it went over / under
|
// Check if it went over / under
|
||||||
if (tm.thing->Z() > thingpos.z + clipheight)
|
if (cres.position.z > thing->Z() + clipheight)
|
||||||
{ // Over thing
|
{ // Over thing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (tm.thing->Top() < thingpos.z)
|
if (cres.position.z + tm.thing->height < thing->Z())
|
||||||
{ // Under thing
|
{ // Under thing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1361,7 +1367,7 @@ bool PIT_CheckThing(FMultiBlockThingsIterator &it, FMultiBlockThingsIterator::Ch
|
||||||
// [RH] The next condition is to compensate for the extra height
|
// [RH] The next condition is to compensate for the extra height
|
||||||
// that gets added by P_CheckPosition() so that you cannot pick
|
// that gets added by P_CheckPosition() so that you cannot pick
|
||||||
// up things that are above your true height.
|
// up things that are above your true height.
|
||||||
&& thingpos.z < tm.thing->Top() - tm.thing->MaxStepHeight)
|
&& thing->Z() < cres.position.z + tm.thing->height - tm.thing->MaxStepHeight)
|
||||||
{ // Can be picked up by tmthing
|
{ // Can be picked up by tmthing
|
||||||
P_TouchSpecialThing(thing, tm.thing); // can remove thing
|
P_TouchSpecialThing(thing, tm.thing); // can remove thing
|
||||||
}
|
}
|
||||||
|
@ -1476,8 +1482,8 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo
|
||||||
// could end up stuck inside a wall.
|
// could end up stuck inside a wall.
|
||||||
AActor *BlockingMobj = thing->BlockingMobj;
|
AActor *BlockingMobj = thing->BlockingMobj;
|
||||||
|
|
||||||
// If this blocks through a line portal with a vertical displacement, it will always completely block. There is no way to step up onto such an actor.
|
// If this blocks through a restricted line portal, it will always completely block.
|
||||||
if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ) || tcres.zdiff != 0)
|
if (BlockingMobj == NULL || (i_compatflags & COMPATF_NO_PASSMOBJ) || (tcres.portalflags & FFCF_RESTRICTEDPORTAL))
|
||||||
{ // Thing slammed into something; don't let it move now.
|
{ // Thing slammed into something; don't let it move now.
|
||||||
thing->height = realheight;
|
thing->height = realheight;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1533,7 +1539,6 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, FCheckPosition &tm, bo
|
||||||
|
|
||||||
FMultiBlockLinesIterator it(pcheck, thing);
|
FMultiBlockLinesIterator it(pcheck, thing);
|
||||||
FMultiBlockLinesIterator::CheckResult lcres;
|
FMultiBlockLinesIterator::CheckResult lcres;
|
||||||
line_t *ld;
|
|
||||||
|
|
||||||
fixed_t thingdropoffz = tm.floorz;
|
fixed_t thingdropoffz = tm.floorz;
|
||||||
//bool onthing = (thingdropoffz != tmdropoffz);
|
//bool onthing = (thingdropoffz != tmdropoffz);
|
||||||
|
|
Loading…
Reference in a new issue