- floatified large parts of SO movement code.

This commit is contained in:
Christoph Oelckers 2022-09-03 21:36:47 +02:00
parent 212be963d9
commit 0b642dc631
7 changed files with 53 additions and 77 deletions

View file

@ -1487,9 +1487,8 @@ struct SECTOR_OBJECT
morph_z_min, // morphing point z min
morph_z_max;
int16_t xorig[MAX_SO_POINTS], // save the original x & y location of each wall so it can be
yorig[MAX_SO_POINTS], // refreshed
max_damage, // max damage
DVector2 orig[MAX_SO_POINTS]; // save the original x & y location of each wall so it can be
int16_t max_damage, // max damage
ram_damage, // damage taken by ramming
wait_tics, //
num_sectors, // number of sectors

View file

@ -154,7 +154,7 @@ short MultiClipTurn(PLAYER* pp, short new_ang, int z, int floor_dist)
return true;
}
int testquadinsect(int *point_num, vec2_t const * q, sectortype* sect)
int testquadinsect(int *point_num, DVector2 const * qp, sectortype* sect)
{
int i,next_i;
@ -162,7 +162,7 @@ int testquadinsect(int *point_num, vec2_t const * q, sectortype* sect)
for (i=0; i < 4; i++)
{
if (!inside(q[i].X, q[i].Y, sect))
if (!inside(qp[i].X, qp[i].Y, sect))
{
*point_num = i;
@ -173,8 +173,7 @@ int testquadinsect(int *point_num, vec2_t const * q, sectortype* sect)
for (i=0; i<4; i++)
{
next_i = (i+1) & 3;
if (!cansee(q[i].X, q[i].Y,0x3fffffff, sect,
q[next_i].X, q[next_i].Y,0x3fffffff, sect))
if (!cansee(DVector3(qp[i], 0x3fffff), sect, DVector3(qp[next_i], 0x3fffff), sect))
{
return false;
}
@ -185,22 +184,22 @@ int testquadinsect(int *point_num, vec2_t const * q, sectortype* sect)
//Ken gives the tank clippin' a try...
int RectClipMove(PLAYER* pp, int *qx, int *qy)
int RectClipMove(PLAYER* pp, DVector2* qpos)
{
int i;
vec2_t xy[4];
DVector2 xy[4];
int point_num;
DVector2 pvect((pp->vect.X >> 14) * inttoworld, (pp->vect.Y >> 14) * inttoworld);
for (i = 0; i < 4; i++)
{
xy[i].X = qx[i] + (pp->vect.X>>14);
xy[i].Y = qy[i] + (pp->vect.Y>>14);
xy[i] = qpos[i] + pvect;
}
//Given the 4 points: x[4], y[4]
if (testquadinsect(&point_num, xy, pp->cursector))
{
pp->add_int_ppos_XY({ (pp->vect.X >> 14), (pp->vect.Y >> 14) });
pp->pos += pvect;
return true;
}
@ -211,12 +210,12 @@ int RectClipMove(PLAYER* pp, int *qx, int *qy)
{
for (i = 0; i < 4; i++)
{
xy[i].X = qx[i] - (pp->vect.Y>>15);
xy[i].Y = qy[i] + (pp->vect.X>>15);
xy[i].X = qpos[i].X - pvect.Y * 0.5;
xy[i].Y = qpos[i].Y + pvect.X * 0.5;
}
if (testquadinsect(&point_num, xy, pp->cursector))
{
pp->add_int_ppos_XY({ -(pp->vect.Y >> 15), (pp->vect.X >> 15) });
pp->pos.XY() += { -pvect.X * 0.5, pvect.X * 0.5 };
}
return false;
@ -226,12 +225,12 @@ int RectClipMove(PLAYER* pp, int *qx, int *qy)
{
for (i = 0; i < 4; i++)
{
xy[i].X = qx[i] + (pp->vect.Y>>15);
xy[i].Y = qy[i] - (pp->vect.X>>15);
xy[i].X = qpos[i].X + pvect.Y * 0.5;
xy[i].Y = qpos[i].Y - pvect.X * 0.5;
}
if (testquadinsect(&point_num, xy, pp->cursector))
{
pp->add_int_ppos_XY({ (pp->vect.Y >> 15), -(pp->vect.X >> 15) });
pp->pos.XY() += { pvect.X * 0.5, -pvect.X * 0.5 };
}
return false;
@ -240,42 +239,29 @@ int RectClipMove(PLAYER* pp, int *qx, int *qy)
return false;
}
int testpointinquad(int x, int y, int *qx, int *qy)
int testpointinquad(const DVector2& pt, const DVector2* quad)
{
int i, cnt, x1, y1, x2, y2;
cnt = 0;
for (i=0; i<4; i++)
for (int i = 0; i < 4; i++)
{
y1 = qy[i]-y;
y2 = qy[(i+1)&3]-y;
if ((y1^y2) >= 0) continue;
x1 = qx[i]-x;
x2 = qx[(i+1)&3]-x;
if ((x1^x2) >= 0)
cnt ^= x1;
else
cnt ^= (x1*y2-x2*y1)^y2;
double dist = PointOnLineSide(pt.X, pt.Y, quad[i].X, quad[i].Y, quad[(i + 1) & 3].X - quad[i].X, quad[(i + 1) & 3].Y - quad[i].Y);
if (dist > 0) return false;
}
return cnt>>31;
return true;
}
short RectClipTurn(PLAYER* pp, short new_ang, int *qx, int *qy, int *ox, int *oy)
short RectClipTurn(PLAYER* pp, DAngle new_angl, DVector2* qpos, DVector2* opos)
{
int i;
vec2_t xy[4];
DVector2 xy[4];
SECTOR_OBJECT* sop = pp->sop;
short rot_ang;
DAngle rot_angl;
int point_num;
rot_ang = NORM_ANGLE(new_ang + sop->spin_ang - sop->ang_orig);
rot_angl = new_angl + DAngle::fromBuild(sop->spin_ang - sop->ang_orig);
for (i = 0; i < 4; i++)
{
vec2_t const p = { ox[i], oy[i] };
rotatepoint(pp->int_ppos().vec2, p, rot_ang, &xy[i]);
xy[i] = rotatepoint(pp->pos.XY(), opos[i], rot_angl);
// cannot use sop->xmid and ymid because the SO is off the map at this point
//rotatepoint(&sop->xmid, p, rot_ang, &xy[i]);
}
//Given the 4 points: x[4], y[4]
@ -284,8 +270,7 @@ short RectClipTurn(PLAYER* pp, short new_ang, int *qx, int *qy, int *ox, int *oy
// move to new pos
for (i = 0; i < 4; i++)
{
qx[i] = xy[i].X;
qy[i] = xy[i].Y;
qpos[i] = xy[i];
}
return true;
}

View file

@ -29,8 +29,8 @@ BEGIN_SW_NS
Collision MultiClipMove(PLAYER* pp, int z, int floor_dist);
short MultiClipTurn(PLAYER* pp, short new_ang, int z, int floor_dist);
int RectClipMove(PLAYER* pp, int *qx, int *qy);
int testpointinquad(int x, int y, int *qx, int *qy);
int RectClipMove(PLAYER* pp, DVector2* qpos);
int testpointinquad(const DVector2& pt, const DVector2* quad);
//short RectClipTurn(PLAYER* pp, short new_ang, int z, int floor_dist, int *qx, int *qy);
short RectClipTurn(PLAYER* pp, short new_ang, int *qx, int *qy, int *ox, int *oy);
END_SW_NS

View file

@ -1477,7 +1477,7 @@ void DoPlayerTurnVehicle(PLAYER* pp, float avel, int z, int floor_dist)
}
}
void DoPlayerTurnVehicleRect(PLAYER* pp, int *x, int *y, int *ox, int *oy)
void DoPlayerTurnVehicleRect(PLAYER* pp, DVector2* pos, DVector2* opos)
{
float avel;
SECTOR_OBJECT* sop = pp->sop;
@ -1497,10 +1497,10 @@ void DoPlayerTurnVehicleRect(PLAYER* pp, int *x, int *y, int *ox, int *oy)
if (avel != 0)
{
auto sum = pp->angle.ang + DAngle::fromDeg(avel);
if (RectClipTurn(pp, NORM_ANGLE(sum.Buildang()), x, y, ox, oy))
if (RectClipTurn(pp, sum, pos, opos))
{
pp->angle.ang = sum;
pp->actor->set_int_ang(pp->angle.ang.Buildang());
pp->actor->spr.angle = pp->angle.ang;
}
}
}
@ -2301,10 +2301,8 @@ void SetupDriveCrush(PLAYER* pp, int *x, int *y)
y[3] = pp->int_ppos().Y + radius;
}
void DriveCrush(PLAYER* pp, int *x, int *y)
void DriveCrush(PLAYER* pp, DVector2* quad)
{
int testpointinquad(int x, int y, int *qx, int *qy);
SECTOR_OBJECT* sop = pp->sop_control;
short stat;
sectortype* *sectp;
@ -2320,7 +2318,7 @@ void DriveCrush(PLAYER* pp, int *x, int *y)
SWSectIterator it(sop->op_main_sector);
while (auto actor = it.Next())
{
if (testpointinquad(actor->int_pos().X, actor->int_pos().Y, x, y))
if (testpointinquad(actor->spr.pos, quad))
{
if ((actor->spr.extra & SPRX_BREAKABLE) && HitBreakSprite(actor, 0))
continue;
@ -2355,7 +2353,7 @@ void DriveCrush(PLAYER* pp, int *x, int *y)
SWStatIterator it2(STAT_ENEMY);
while (auto actor = it.Next())
{
if (testpointinquad(actor->int_pos().X, actor->int_pos().Y, x, y))
if (testpointinquad(actor->spr.pos, quad))
{
//if (actor->spr.z < pp->posz)
if (actor->int_pos().Z < sop->crush_z)
@ -2382,7 +2380,7 @@ void DriveCrush(PLAYER* pp, int *x, int *y)
it2.Reset(STAT_DEAD_ACTOR);
while (auto actor = it.Next())
{
if (testpointinquad(actor->int_pos().X, actor->int_pos().Y, x, y))
if (testpointinquad(actor->spr.pos, quad))
{
if (actor->int_pos().Z < sop->crush_z)
continue;
@ -2404,7 +2402,7 @@ void DriveCrush(PLAYER* pp, int *x, int *y)
if (actor->user.PlayerP == pp)
continue;
if (testpointinquad(actor->int_pos().X, actor->int_pos().Y, x, y))
if (testpointinquad(actor->spr.pos, quad))
{
int damage;
@ -2451,7 +2449,6 @@ void DoPlayerMoveVehicle(PLAYER* pp)
DSWActor* actor = pp->sop->sp_child;
if (!actor) return;
DSWActor* plActor = pp->actor;
int x[4], y[4], ox[4], oy[4];
int wallcount;
int count=0;
@ -2512,6 +2509,8 @@ void DoPlayerMoveVehicle(PLAYER* pp)
pp->lastcursector = pp->cursector;
z = pp->int_ppos().Z + Z(10);
DVector2 pos[4], opos[4];
if (RectClip)
{
for (sectp = sop->sectp, wallcount = 0, j = 0; *sectp; sectp++, j++)
@ -2520,12 +2519,8 @@ void DoPlayerMoveVehicle(PLAYER* pp)
{
if (wal.extra && (wal.extra & (WALLFX_LOOP_OUTER|WALLFX_LOOP_OUTER_SECONDARY)) == WALLFX_LOOP_OUTER)
{
x[count] = wal.wall_int_pos().X;
y[count] = wal.wall_int_pos().Y;
ox[count] = sop->int_pmid().X - sop->xorig[wallcount];
oy[count] = sop->int_pmid().Y - sop->yorig[wallcount];
pos[count] = wal.pos;
opos[count] = sop->pmid - sop->orig[wallcount];
count++;
}
@ -2551,10 +2546,10 @@ void DoPlayerMoveVehicle(PLAYER* pp)
auto save_cstat = plActor->spr.cstat;
plActor->spr.cstat &= ~(CSTAT_SPRITE_BLOCK);
DoPlayerTurnVehicleRect(pp, x, y, ox, oy);
DoPlayerTurnVehicleRect(pp, pos, opos);
ret = RectClipMove(pp, x, y);
DriveCrush(pp, x, y);
ret = RectClipMove(pp, pos);
DriveCrush(pp, pos);
plActor->spr.cstat = save_cstat;
if (!ret)
@ -2563,14 +2558,13 @@ void DoPlayerMoveVehicle(PLAYER* pp)
if (vel > 13000)
{
vec3_t hit_pos = { (x[0] + x[1]) >> 1, (y[0] + y[1]) >> 1, pp->cursector->int_floorz() - Z(10) };
DVector3 hitpos(hit_pos.X * inttoworld, hit_pos.Y * inttoworld, pp->cursector->floorz - 10);
DVector3 hitpos((pos[0] + pos[1]) * 0.5, pp->cursector->floorz - 10);
hitscan(hitpos, pp->cursector,
DVector3(MOVEx(256, pp->angle.ang), MOVEy(256, pp->angle.ang), 0),
hit, CLIPMASK_PLAYER);
if (FindDistance2D(hit.int_hitpos().vec2 - hit_pos.vec2) < 800)
if ((hit.hitpos.XY() - hitpos.XY()).LengthSquared() < 50 * 50)
{
if (hit.hitWall)
actor->user.coll.setWall(wallnum(hit.hitWall));

View file

@ -624,8 +624,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, SECTOR_OBJECT& w,
.Array("sectp", w.sectp, def->sectp, w.num_sectors)
.Array("zorig_floor", w.zorig_floor, def->zorig_floor, w.num_sectors)
.Array("sp_num", w.so_actors, def->so_actors, countof(w.so_actors))
.Array("xorig", w.xorig, def->xorig, w.num_walls)
.Array("yorig", w.yorig, def->yorig, w.num_walls)
.Array("orig", w.orig, def->orig, w.num_walls)
("controller", w.controller, def->controller)
("child", w.sp_child, def->sp_child)
("xmid", w.pmid.X, def->pmid.X)

View file

@ -1348,13 +1348,12 @@ void PlaceSectorObjectsOnTracks(void)
// move all walls in sectors
for (auto& wal : wallsofsector(sop->sectp[j]))
{
sop->xorig[sop->num_walls] = sop->int_pmid().X - wal.wall_int_pos().X;
sop->yorig[sop->num_walls] = sop->int_pmid().Y - wal.wall_int_pos().Y;
sop->orig[sop->num_walls] = sop->pmid - wal.pos;
sop->num_walls++;
}
}
ASSERT((uint16_t)sop->num_walls < SIZ(sop->xorig));
ASSERT((uint16_t)sop->num_walls < SIZ(sop->orig));
if (sop->track <= -1)
continue;
@ -1782,8 +1781,8 @@ void RefreshPoints(SECTOR_OBJECT* sop, int nx, int ny, bool dynamic)
{
if (!(wal.extra && (wal.extra & WALLFX_DONT_MOVE)))
{
dx = x = sop->int_pmid().X - sop->xorig[wallcount];
dy = y = sop->int_pmid().Y - sop->yorig[wallcount];
dx = x = sop->int_pmid().X - sop->orig[wallcount].X * worldtoint;
dy = y = sop->int_pmid().Y - sop->orig[wallcount].Y * worldtoint;
if (dynamic && sop->scale_type)
{

View file

@ -64,8 +64,8 @@ void SOwallmove(SECTOR_OBJECT* sop, DSWActor* actor, walltype* find_wallp, int d
*nx = dist * ang.Cos();
*ny = dist * ang.Sin();
sop->xorig[wallcount] -= *nx;
sop->yorig[wallcount] -= *ny;
sop->orig[wallcount].X -= *nx * inttoworld;
sop->orig[wallcount].Y -= *ny * inttoworld;
sop->flags |= (SOBJ_UPDATE_ONCE);
return;