mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 00:41:55 +00:00
- pushmove rewritten.
This commit is contained in:
parent
830ded6e87
commit
2190499d63
5 changed files with 86 additions and 162 deletions
|
@ -639,8 +639,10 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
|
||||
if (enginecompatibility_mode == ENGINECOMPATIBILITY_NONE)
|
||||
{
|
||||
DVector2 v(vec.X* inttoworld, vec.Y* inttoworld);
|
||||
clipupdatesector(v, sectnum, rad * inttoworld, clipsectormap);
|
||||
DVector3 v(vec.X* inttoworld, vec.Y* inttoworld, 0);
|
||||
sectortype* sect = §or[*sectnum];
|
||||
updatesectorneighbor(v, §, rad * inttoworld);
|
||||
*sectnum = ::sectnum(sect);
|
||||
}
|
||||
|
||||
pos->X = vec.X;
|
||||
|
@ -697,93 +699,3 @@ CollisionBase clipmove_(vec3_t * const pos, int * const sectnum, int32_t xvect,
|
|||
}
|
||||
|
||||
|
||||
//
|
||||
// pushmove
|
||||
//
|
||||
int pushmove_(vec3_t *const vect, int *const sectnum,
|
||||
int32_t const walldist, int32_t const ceildist, int32_t const flordist, uint32_t const cliptype, bool clear /*= true*/)
|
||||
{
|
||||
int bad;
|
||||
|
||||
const int32_t dawalclipmask = (cliptype&65535);
|
||||
// const int32_t dasprclipmask = (cliptype >> 16);
|
||||
|
||||
if (*sectnum < 0)
|
||||
return -1;
|
||||
|
||||
int32_t k = 32;
|
||||
|
||||
int dir = 1;
|
||||
do
|
||||
{
|
||||
int32_t clipsectcnt = 0;
|
||||
|
||||
bad = 0;
|
||||
|
||||
if (clear)
|
||||
{
|
||||
if (enginecompatibility_mode != ENGINECOMPATIBILITY_NONE && *sectnum < 0)
|
||||
return 0;
|
||||
clipsectorlist[0] = *sectnum;
|
||||
clipsectnum = 1;
|
||||
|
||||
clipsectormap.Zero();
|
||||
clipsectormap.Set(*sectnum);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
const walltype* wal;
|
||||
int32_t startwall, endwall;
|
||||
|
||||
auto sec = §or[clipsectorlist[clipsectcnt]];
|
||||
if (dir > 0)
|
||||
startwall = sec->wallptr, endwall = startwall + sec->wallnum;
|
||||
else
|
||||
endwall = sec->wallptr, startwall = endwall + sec->wallnum - 1;
|
||||
|
||||
int i;
|
||||
|
||||
for (i=startwall, wal=&wall[startwall]; i!=endwall; i+=dir, wal+=dir)
|
||||
if (IsCloseToWall(DVector2(vect->X * inttoworld, vect->Y * inttoworld), &wall[i], (walldist-4) * inttoworld) == EClose::InFront)
|
||||
{
|
||||
int j = 0;
|
||||
if (wal->nextsector < 0 || wal->cstat & EWallFlags::FromInt(dawalclipmask)) j = 1;
|
||||
else
|
||||
{
|
||||
auto pvect = NearestPointOnWall(vect->X * inttoworld, vect->Y * inttoworld, wal);
|
||||
vec2_t closest = { int(pvect.X * worldtoint), int(pvect.Y * worldtoint) };
|
||||
|
||||
j = cliptestsector(clipsectorlist[clipsectcnt], wal->nextsector, flordist, ceildist, closest, vect->Z);
|
||||
}
|
||||
|
||||
if (j != 0)
|
||||
{
|
||||
DAngle jj = wal->delta().Angle();
|
||||
int32_t dx = -int(jj.Sin() * 8);
|
||||
int32_t dy = int(jj.Cos() * 8);
|
||||
int bad2 = 16;
|
||||
do
|
||||
{
|
||||
vect->X = (vect->X) + dx; vect->Y = (vect->Y) + dy;
|
||||
bad2--; if (bad2 == 0) break;
|
||||
} while (IsCloseToWall(DVector2(vect->X * inttoworld, vect->Y * inttoworld), &wall[i], (walldist - 4) * inttoworld) != EClose::Outside);
|
||||
bad = -1;
|
||||
k--; if (k <= 0) return bad;
|
||||
|
||||
DVector2 v(vect->vec2.X * inttoworld, vect->vec2.Y * inttoworld);
|
||||
clipupdatesector(v, sectnum, walldist * inttoworld, clipsectormap);
|
||||
|
||||
if (*sectnum < 0) return -1;
|
||||
}
|
||||
else if (!clipsectormap[wal->nextsector])
|
||||
addclipsect(wal->nextsector);
|
||||
}
|
||||
|
||||
clipsectcnt++;
|
||||
} while (clipsectcnt < clipsectnum);
|
||||
dir = -dir;
|
||||
} while (bad != 0);
|
||||
|
||||
return bad;
|
||||
}
|
||||
|
|
|
@ -447,19 +447,6 @@ inline int clipmove(DVector3& pos, sectortype** const sect, const DVector2& mvec
|
|||
return result.type;
|
||||
}
|
||||
|
||||
inline int pushmove(DVector3& pos, sectortype** const sect, double const walldist, double const ceildist, double const flordist,
|
||||
uint32_t const cliptype, bool clear = true)
|
||||
{
|
||||
auto vect = vec3_t(int(pos.X * worldtoint), int(pos.Y * worldtoint), int(pos.Z * zworldtoint));
|
||||
int sectno = *sect ? sector.IndexOf(*sect) : -1;
|
||||
int res = pushmove_(&vect, §no, int(walldist * worldtoint), int(ceildist * zworldtoint), int(flordist * zworldtoint), cliptype, clear);
|
||||
pos = { vect.X * inttoworld, vect.Y * inttoworld, vect.Z * zinttoworld };
|
||||
*sect = sectno == -1 ? nullptr : §or[sectno];
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor);
|
||||
|
||||
inline PClassActor* PClass::FindActor(FName name)
|
||||
{
|
||||
|
|
|
@ -1177,6 +1177,84 @@ void neartag(const DVector3& pos, sectortype* startsect, DAngle angle, HitInfoBa
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool checkOpening(const DVector3& pos, const sectortype* sec, const sectortype* nextsec, double ceilingdist, double floordist)
|
||||
{
|
||||
double c1, c2, f1, f2;
|
||||
calcSlope(sec, pos.X, pos.Y, &c1, &f1);
|
||||
calcSlope(nextsec, pos.X, pos.Y, &c2, &f2);
|
||||
|
||||
return ((f2 < f1 - 1 && (nextsec->floorstat & CSTAT_SECTOR_SKY) == 0 && pos.Z >= f2 - (floordist - zmaptoworld)) ||
|
||||
(c2 > c1 + 1 && (nextsec->ceilingstat & CSTAT_SECTOR_SKY) == 0 && pos.Z <= c2 + (ceilingdist - zmaptoworld)));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist, double floordist, unsigned cliptype)
|
||||
{
|
||||
auto wallflags = EWallFlags::FromInt(cliptype & 65535);
|
||||
int maxhitwalls = 0;
|
||||
bool pushed = true;
|
||||
|
||||
for(int direction = 1; pushed; direction = -direction)
|
||||
{
|
||||
pushed = false;
|
||||
|
||||
if (*pSect == nullptr)
|
||||
return -1;
|
||||
|
||||
BFSSectorSearch search(*pSect);
|
||||
|
||||
while (auto sec = search.GetNext())
|
||||
{
|
||||
// this must go both forward and backward so we cannot use wallsofsector. Pity
|
||||
for (int i = 0; i < sec->wallnum; i++)
|
||||
{
|
||||
auto wal = direction > 0 ? sec->firstWall() + i : sec->lastWall() - i;
|
||||
|
||||
if (IsCloseToWall(pos.XY(), wal, walldist - 0.25) == EClose::InFront)
|
||||
{
|
||||
bool blocked = false;
|
||||
if (!wal->twoSided() || wal->cstat & wallflags) blocked = true;
|
||||
else
|
||||
{
|
||||
auto pvect = NearestPointOnWall(pos.X, pos.Y, wal);
|
||||
blocked = checkOpening(DVector3(pvect, pos.Z), sec, wal->nextSector(), ceildist, floordist);
|
||||
}
|
||||
|
||||
if (blocked)
|
||||
{
|
||||
auto dv = wal->delta().Rotated90CCW().Unit() * 0.5;
|
||||
for (int t = 0; t < 16; t++)
|
||||
{
|
||||
pos += dv;
|
||||
if (IsCloseToWall(pos, wal, (walldist - 0.25)) == EClose::Outside) break;
|
||||
}
|
||||
pushed = true;
|
||||
|
||||
updatesector(pos, pSect);
|
||||
if (++maxhitwalls >= 32) return -1;
|
||||
if (*pSect == nullptr) return -1;
|
||||
}
|
||||
else
|
||||
search.Add(wal->nextSector());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pushed) return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -264,6 +264,9 @@ bool checkRangeOfWallSprite(DCoreActor* itActor, const DVector3& pos, double max
|
|||
bool checkRangeOfFloorSprite(DCoreActor* itActor, const DVector3& pos, double maxdist, double& theZ);
|
||||
void getzrange(const DVector3& pos, sectortype* sect, double* ceilz, CollisionBase& ceilhit, double* florz, CollisionBase& florhit, double walldist, uint32_t cliptype);
|
||||
|
||||
int pushmove(DVector3& pos, sectortype** pSect, double walldist, double ceildist, double flordist, unsigned cliptype);
|
||||
tspritetype* renderAddTsprite(tspriteArray& tsprites, DCoreActor* actor);
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ void DoUpdateSector(double x, double y, double z, int* sectnum, double maxDistan
|
|||
|
||||
for (auto& wal : wallsofsector(lsect))
|
||||
{
|
||||
if (wal.twoSided() && !search.Check(wal.nextsector) && (iter == 0 || SquareDistToSector(x, y, wal.nextSector()) <= maxDistSq))
|
||||
if (wal.twoSided() && !search.Check(wal.nextsector) && (iter == 0 || SquareDistToWall(x, y, &wal) <= maxDistSq))
|
||||
search.Add(wal.nextsector);
|
||||
}
|
||||
iter++;
|
||||
|
@ -118,59 +118,3 @@ inline void updatesector(int x_, int y_, int* sectnum)
|
|||
DoUpdateSector(x, y, 0, sectnum, MAXUPDATESECTORDIST, inside0);
|
||||
}
|
||||
|
||||
// clipmove uses this. It's really just two loops nearly identical to DoUpdateSector with different checking conditions.
|
||||
inline void clipupdatesector(const DVector2& pos, int* const sectnum, double walldist, BitArray& sectormap)
|
||||
{
|
||||
assert(*sectnum >= 0);
|
||||
sectortype* sect = §or[*sectnum];
|
||||
if (inside(pos.X, pos.Y, sect))
|
||||
return;
|
||||
|
||||
double sdist = SquareDistToSector(pos.X, pos.Y, sect);
|
||||
|
||||
double wd = (walldist + 8);
|
||||
wd *= wd;
|
||||
if (sdist > wd)
|
||||
{
|
||||
wd = 2048 * 2048;
|
||||
}
|
||||
|
||||
{
|
||||
BFSSearch search(sector.Size(), *sectnum);
|
||||
|
||||
for (unsigned secnum; (secnum = search.GetNext()) != BFSSearch::EOL;)
|
||||
{
|
||||
if (inside(pos.X, pos.Y, §or[secnum]))
|
||||
{
|
||||
*sectnum = secnum;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& wal : wallsofsector(secnum))
|
||||
{
|
||||
if (wal.twoSided() && sectormap[wal.nextsector])
|
||||
search.Add(wal.nextsector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
BFSSearch search(sector.Size(), *sectnum);
|
||||
|
||||
for (unsigned secnum; (secnum = search.GetNext()) != BFSSearch::EOL;)
|
||||
{
|
||||
if (inside(pos.X, pos.Y, §or[secnum]))
|
||||
{
|
||||
*sectnum = secnum;
|
||||
return;
|
||||
}
|
||||
for (auto& wal : wallsofsector(secnum))
|
||||
{
|
||||
if (wal.twoSided() && SquareDistToWall(pos.X, pos.Y, &wal) < wd)
|
||||
search.Add(wal.nextsector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*sectnum = -1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue