clipmove() improvements

This reverts some of the previous clipmove() changes in favor of implementing explicit rejection of movement in cases where clipping has somehow failed.

git-svn-id: https://svn.eduke32.com/eduke32@7457 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
terminx 2019-03-30 19:35:54 +00:00 committed by Christoph Oelckers
parent decce5bc70
commit ddd1d34973
1 changed files with 39 additions and 11 deletions

View File

@ -855,7 +855,7 @@ static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
const int32_t ox = ksgn(-dy), oy = ksgn(dx); const int32_t ox = ksgn(-dy), oy = ksgn(dx);
char first = (klabs(dx) <= klabs(dy)); char first = (klabs(dx) <= klabs(dy));
while (1) do
{ {
if (dx*(*y-y1) > (*x-x1)*dy) if (dx*(*y-y1) > (*x-x1)*dy)
return; return;
@ -867,6 +867,7 @@ static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
first ^= 1; first ^= 1;
} }
while (1);
} }
static int32_t get_floorspr_clipyou(int32_t x1, int32_t x2, int32_t x3, int32_t x4, static int32_t get_floorspr_clipyou(int32_t x1, int32_t x2, int32_t x3, int32_t x4,
@ -898,6 +899,23 @@ static int32_t get_floorspr_clipyou(int32_t x1, int32_t x2, int32_t x3, int32_t
return clipyou; return clipyou;
} }
static int sectoradjacent(int const sect1, int const sect2)
{
if (sector[sect1].wallnum < sector[sect2].wallnum)
{
for (int i = 0; i < sector[sect1].wallnum; i++)
if (wall[sector[sect1].wallptr+i].nextsector == sect2)
return 1;
}
else
{
for (int i = 0; i < sector[sect2].wallnum; i++)
if (wall[sector[sect2].wallptr+i].nextsector == sect1)
return 1;
}
return 0;
}
// //
// clipmove // clipmove
// //
@ -1066,7 +1084,9 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
} }
} }
if (clipyou) // We're not interested in any sector reached by portal traversal that we're "inside" of.
if (clipsectcnt != 1 && inside(pos->x, pos->y, dasect) == 1) break;
else if (clipyou)
{ {
int16_t objtype; int16_t objtype;
int32_t bsz; int32_t bsz;
@ -1088,12 +1108,9 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
day = walldist; if (dx < 0) day = -day; day = walldist; if (dx < 0) day = -day;
addclipline(x1+dax, y1+day, x2+dax, y2+day, objtype); addclipline(x1+dax, y1+day, x2+dax, y2+day, objtype);
} }
else if (wal->nextsector>=0)
if (wal->nextsector>=0)
{ {
// This fixes Duke3D E1L2. if (inside(pos->x, pos->y, wal->nextsector) == 1) continue;
// We're not interested in any sector reached by portal traversal that we're "inside" of.
if (inside(pos->x, pos->y, wal->nextsector)) break;
for (i=clipsectnum-1; i>=0; i--) for (i=clipsectnum-1; i>=0; i--)
if (wal->nextsector == clipsectorlist[i]) break; if (wal->nextsector == clipsectorlist[i]) break;
@ -1279,11 +1296,22 @@ int32_t clipmove(vec3_t *pos, int16_t *sectnum,
retval = (uint16_t) clipobjectval[hitwall]; retval = (uint16_t) clipobjectval[hitwall];
hitwalls[cnt] = hitwall; hitwalls[cnt] = hitwall;
} }
cnt--;
pos->x = intx; // this handles rejection of movement that managed to get past the clipping lines when it shouldn't have
pos->y = inty; int const osectnum = *sectnum;
updatesectorz(pos->x, pos->y, pos->z, sectnum);
updatesectorz(intx, inty, pos->z, sectnum);
if (*sectnum == osectnum ||
(!check_floor_curb(osectnum, *sectnum, flordist, pos->z, pos->x, pos->y) &&
(sectoradjacent(osectnum, *sectnum) || cansee(pos->x, pos->y, pos->z, osectnum, intx, inty, pos->z, *sectnum))))
{
pos->x = intx;
pos->y = inty;
cnt--;
}
else
*sectnum = osectnum;
} while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0); } while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0);
// I'm not a fan of these brute-force searches but this one should be OK // I'm not a fan of these brute-force searches but this one should be OK