mirror of
https://github.com/ZDoom/Raze.git
synced 2025-01-31 04:20:42 +00:00
- floatified MoveSector
This commit is contained in:
parent
a3fadff0e6
commit
9d8f06612f
5 changed files with 77 additions and 95 deletions
|
@ -18,7 +18,7 @@ __forceinline constexpr int64_t DivScaleL(int64_t a, int64_t b, int shift) { ret
|
|||
template<int b = 16>
|
||||
inline fixed_t FloatToFixed(double f)
|
||||
{
|
||||
return xs_Fix<b>::ToFix(f);
|
||||
return int(f * (1 << b));
|
||||
}
|
||||
|
||||
template<int b = 16>
|
||||
|
|
|
@ -196,9 +196,8 @@ void FuncLion(int, int, int, int);
|
|||
struct BlockInfo
|
||||
{
|
||||
TObjPtr<DExhumedActor*> pActor;
|
||||
int x;
|
||||
int y;
|
||||
int field_8;
|
||||
DVector2 pos;
|
||||
double mindist;
|
||||
};
|
||||
extern BlockInfo sBlockInfo[];
|
||||
|
||||
|
@ -231,7 +230,7 @@ int PlotCourseToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2);
|
|||
void CheckSectorFloor(sectortype* pSector, double z, DVector2& xy);
|
||||
int GetAngleToSprite(DExhumedActor* nSprite1, DExhumedActor* nSprite2);
|
||||
int GetWallNormal(walltype* nWall);
|
||||
void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel);
|
||||
void MoveSector(sectortype* pSector, DAngle nAngle, int *nXVel, int *nYVel);
|
||||
Collision AngleChase(DExhumedActor* nSprite, DExhumedActor* nSprite2, int ebx, int ecx, int push1);
|
||||
void SetQuake(DExhumedActor* nSprite, int nVal);
|
||||
|
||||
|
|
|
@ -66,10 +66,9 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, BlockInfo& w, Bloc
|
|||
{
|
||||
if (arc.BeginObject(keyname))
|
||||
{
|
||||
arc("at8", w.field_8)
|
||||
arc("mindist", w.mindist)
|
||||
("sprite", w.pActor)
|
||||
("x", w.x)
|
||||
("y", w.y)
|
||||
("pos", w.pos)
|
||||
.EndObject();
|
||||
}
|
||||
return arc;
|
||||
|
@ -651,163 +650,149 @@ int GrabPushBlock()
|
|||
void CreatePushBlock(sectortype* pSector)
|
||||
{
|
||||
int nBlock = GrabPushBlock();
|
||||
|
||||
double xSumm = 0;
|
||||
double ySumm = 0;
|
||||
DVector2 sum(0, 0);
|
||||
|
||||
for (auto& wal : wallsofsector(pSector))
|
||||
{
|
||||
xSumm += wal.pos.X;
|
||||
ySumm += wal.pos.Y;
|
||||
sum += wal.pos;
|
||||
}
|
||||
|
||||
double xAvgg = xSumm / pSector->wallnum;
|
||||
double yAvgg = ySumm / pSector->wallnum;
|
||||
DVector2 avg = sum / pSector->wallnum;
|
||||
|
||||
sBlockInfo[nBlock].x = xAvgg * worldtoint;
|
||||
sBlockInfo[nBlock].y = yAvgg * worldtoint;
|
||||
sBlockInfo[nBlock].pos = avg;
|
||||
|
||||
auto pActor = insertActor(pSector, 0);
|
||||
|
||||
sBlockInfo[nBlock].pActor = pActor;
|
||||
|
||||
pActor->spr.pos = { xAvgg, yAvgg, pSector->floorz- 1 };
|
||||
pActor->spr.pos = { avg, pSector->floorz- 1 };
|
||||
pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
|
||||
|
||||
double mindist = 0;
|
||||
|
||||
for (auto& wal : wallsofsector(pSector))
|
||||
{
|
||||
double xDiff = abs(xAvgg - wal.pos.X);
|
||||
double yDiff = abs(yAvgg - wal.pos.Y);
|
||||
double length = (avg - wal.pos).Length();
|
||||
|
||||
double nSqrt = g_sqrt(xDiff * xDiff + yDiff * yDiff);
|
||||
|
||||
if (nSqrt > mindist) {
|
||||
mindist = nSqrt;
|
||||
if (length > mindist) {
|
||||
mindist = length;
|
||||
}
|
||||
}
|
||||
|
||||
sBlockInfo[nBlock].field_8 = mindist * worldtoint;
|
||||
sBlockInfo[nBlock].mindist = mindist;
|
||||
|
||||
pActor->set_native_clipdist( (int(mindist * worldtoint) & 0xFF) << 2);
|
||||
pSector->extra = nBlock;
|
||||
}
|
||||
|
||||
void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
|
||||
|
||||
void MoveSector(sectortype* pSector, DAngle nAngle, int *nXVel, int *nYVel)
|
||||
{
|
||||
if (pSector == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
int nXVect, nYVect;
|
||||
DVector2 nVect;
|
||||
|
||||
if (nAngle < 0)
|
||||
if (nAngle < nullAngle)
|
||||
{
|
||||
nXVect = *nXVel;
|
||||
nYVect = *nYVel;
|
||||
nAngle = getangle(nXVect, nYVect);
|
||||
nVect = { FixedToFloat<18>(*nXVel), FixedToFloat<18>(*nYVel) };
|
||||
nAngle = VecToAngle(nVect);
|
||||
}
|
||||
else
|
||||
{
|
||||
nXVect = bcos(nAngle, 6);
|
||||
nYVect = bsin(nAngle, 6);
|
||||
nVect = nAngle.ToVector() * 4;
|
||||
}
|
||||
|
||||
int nBlock = pSector->extra;
|
||||
int nSectFlag = pSector->Flag;
|
||||
|
||||
int nFloorZ = pSector->int_floorz();
|
||||
double nFloorZ = pSector->floorz;
|
||||
|
||||
walltype *pStartWall = pSector->firstWall();
|
||||
sectortype* pNextSector = pStartWall->nextSector();
|
||||
|
||||
BlockInfo *pBlockInfo = &sBlockInfo[nBlock];
|
||||
|
||||
vec3_t pos;
|
||||
DVector3 pos;
|
||||
|
||||
pos.X = sBlockInfo[nBlock].x;
|
||||
int x_b = sBlockInfo[nBlock].x;
|
||||
pos.XY() = sBlockInfo[nBlock].pos;
|
||||
auto b_pos = pos.XY();
|
||||
|
||||
pos.Y = sBlockInfo[nBlock].y;
|
||||
int y_b = sBlockInfo[nBlock].y;
|
||||
|
||||
|
||||
int nZVal;
|
||||
double nZVal;
|
||||
|
||||
int bUnderwater = nSectFlag & kSectUnderwater;
|
||||
|
||||
if (nSectFlag & kSectUnderwater)
|
||||
{
|
||||
nZVal = pSector->int_ceilingz();
|
||||
pos.Z = pNextSector->int_ceilingz() + 256;
|
||||
nZVal = pSector->ceilingz;
|
||||
pos.Z = pNextSector->ceilingz + 1;
|
||||
|
||||
pSector->setceilingz(pNextSector->ceilingz);
|
||||
}
|
||||
else
|
||||
{
|
||||
nZVal = pSector->int_floorz();
|
||||
pos.Z = pNextSector->int_floorz() - 256;
|
||||
nZVal = pSector->floorz;
|
||||
pos.Z = pNextSector->floorz - 1;
|
||||
|
||||
pSector->setfloorz(pNextSector->floorz);
|
||||
}
|
||||
|
||||
auto pSectorB = pSector;
|
||||
Collision scratch;
|
||||
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
|
||||
clipmove(pos, &pSectorB, FloatToFixed<18>(nVect.X), FloatToFixed<18>(nVect.Y), pBlockInfo->mindist, 0, 0, CLIPMASK1, scratch);
|
||||
|
||||
int yvect = pos.Y - y_b;
|
||||
int xvect = pos.X - x_b;
|
||||
auto vect = pos.XY() - b_pos;
|
||||
|
||||
if (pSectorB != pNextSector && pSectorB != pSector)
|
||||
{
|
||||
yvect = 0;
|
||||
xvect = 0;
|
||||
vect.Zero();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bUnderwater)
|
||||
{
|
||||
pos = { x_b, y_b, nZVal };
|
||||
pos.XY() = b_pos;
|
||||
pos.Z = nZVal;
|
||||
|
||||
clipmove(pos, &pSectorB, nXVect, nYVect, pBlockInfo->field_8, 0, 0, CLIPMASK1, scratch);
|
||||
clipmove(pos, &pSectorB, FloatToFixed<18>(nVect.X), FloatToFixed<18>(nVect.Y), pBlockInfo->mindist, 0, 0, CLIPMASK1, scratch);
|
||||
|
||||
int deltax = pos.X - x_b;
|
||||
int deltay = pos.Y - y_b;
|
||||
auto delta = pos.XY() - b_pos;
|
||||
|
||||
if (abs(xvect) > abs(deltax))
|
||||
if (abs(vect.X) > abs(delta.X))
|
||||
{
|
||||
xvect = deltax;
|
||||
vect.X = delta.X;
|
||||
}
|
||||
|
||||
if (abs(yvect) > abs(deltay))
|
||||
if (abs(vect.Y) > abs(delta.Y))
|
||||
{
|
||||
yvect = deltay;
|
||||
vect.Y = delta.Y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GREEN
|
||||
if (yvect || xvect)
|
||||
if (!vect.isZero())
|
||||
{
|
||||
ExhumedSectIterator it(pSector);
|
||||
while (auto pActor = it.Next())
|
||||
{
|
||||
if (pActor->spr.statnum < 99)
|
||||
{
|
||||
pActor->add_int_pos({ xvect, yvect, 0 });
|
||||
pActor->spr.pos += vect;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos.Z = pActor->int_pos().Z;
|
||||
pos.Z = pActor->spr.pos.Z;
|
||||
|
||||
if ((nSectFlag & kSectUnderwater) || pos.Z != nZVal || pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE)
|
||||
{
|
||||
pos.X = pActor->int_pos().X;
|
||||
pos.Y = pActor->int_pos().Y;
|
||||
pos.XY() = pActor->spr.pos.XY();
|
||||
pSectorB = pSector;
|
||||
|
||||
clipmove(pos, &pSectorB, -xvect, -yvect, 4 * pActor->native_clipdist(), 0, 0, CLIPMASK0, scratch);
|
||||
// The vector that got passed in here originally was Q28.4, while clipmove expects Q14.18, effectively resulting in actual zero movement
|
||||
// because the resulting offset would be far below the coordinate's precision.
|
||||
clipmove(pos, &pSectorB, FloatToFixed<18>(-vect.X / 16384.), FloatToFixed<18>(-vect.Y / 16384), pActor->int_clipdist(), 0, 0, CLIPMASK0, scratch);
|
||||
|
||||
if (pSectorB) {
|
||||
ChangeActorSect(pActor, pSectorB);
|
||||
|
@ -820,18 +805,19 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
|
|||
{
|
||||
if (pActor->spr.statnum >= 99)
|
||||
{
|
||||
pos = pActor->int_pos();
|
||||
pos = pActor->spr.pos;
|
||||
pSectorB = pNextSector;
|
||||
|
||||
clipmove(pos, &pSectorB,
|
||||
-xvect - (bcos(nAngle) * (4 * pActor->native_clipdist())),
|
||||
-yvect - (bsin(nAngle) * (4 * pActor->native_clipdist())),
|
||||
4 * pActor->native_clipdist(), 0, 0, CLIPMASK0, scratch);
|
||||
// Original used 14 bits of scale from the sine table and 4 bits from clipdist.
|
||||
// vect was added unscaled, essentially nullifying its effect entirely.
|
||||
auto vect2 = -nAngle.ToVector() * pActor->fClipdist()/* - vect*/;
|
||||
|
||||
clipmove(pos, &pSectorB, FloatToFixed<18>(vect2.X), FloatToFixed<18>(vect2.Y), pActor->int_clipdist(), 0, 0, CLIPMASK0, scratch);
|
||||
|
||||
|
||||
if (pSectorB != pNextSector && (pSectorB == pSector || pNextSector == pSector))
|
||||
{
|
||||
if (pSectorB != pSector || nFloorZ >= pActor->int_pos().Z)
|
||||
if (pSectorB != pSector || nFloorZ >= pActor->spr.pos.Z)
|
||||
{
|
||||
if (pSectorB) {
|
||||
ChangeActorSect(pActor, pSectorB);
|
||||
|
@ -839,10 +825,9 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
|
|||
}
|
||||
else
|
||||
{
|
||||
movesprite(pActor,
|
||||
(xvect << 14) + bcos(nAngle) * pActor->native_clipdist(),
|
||||
(yvect << 14) + bsin(nAngle) * pActor->native_clipdist(),
|
||||
0, 0, 0, CLIPMASK0);
|
||||
// Unlike the above, this one *did* scale vect
|
||||
vect2 = nAngle.ToVector() * pActor->fClipdist() * 0.25 + vect;
|
||||
movesprite(pActor, FloatToFixed<18>(vect2.X), FloatToFixed<18>(vect2.Y), 0, 0, 0, CLIPMASK0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -850,39 +835,36 @@ void MoveSector(sectortype* pSector, int nAngle, int *nXVel, int *nYVel)
|
|||
|
||||
for(auto& wal : wallsofsector(pSector))
|
||||
{
|
||||
dragpoint(&wal, xvect + wal.wall_int_pos().X, yvect + wal.wall_int_pos().Y);
|
||||
dragpoint(&wal, vect + wal.pos);
|
||||
}
|
||||
|
||||
pBlockInfo->x += xvect;
|
||||
pBlockInfo->y += yvect;
|
||||
pBlockInfo->pos += vect;
|
||||
}
|
||||
|
||||
// loc_163DD
|
||||
xvect <<= 14;
|
||||
yvect <<= 14;
|
||||
|
||||
if (!(nSectFlag & kSectUnderwater))
|
||||
{
|
||||
ExhumedSectIterator it(pSector);
|
||||
while (auto pActor = it.Next())
|
||||
{
|
||||
if (pActor->spr.statnum >= 99 && nZVal == pActor->int_pos().Z && !(pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE))
|
||||
if (pActor->spr.statnum >= 99 && nZVal == pActor->spr.pos.Z && !(pActor->spr.cstat & CSTAT_SPRITE_INVISIBLE))
|
||||
{
|
||||
pSectorB = pSector;
|
||||
clipmove(pActor->spr.pos, &pSectorB, xvect, yvect, 4 * pActor->native_clipdist(), 5120, -5120, CLIPMASK0, scratch);
|
||||
clipmove(pActor->spr.pos, &pSectorB, FloatToFixed<18>(vect.X), FloatToFixed<18>(vect.Y), pActor->int_clipdist(), 5120, -5120, CLIPMASK0, scratch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nSectFlag & kSectUnderwater) {
|
||||
pSector->set_int_ceilingz(nZVal);
|
||||
pSector->setceilingz(nZVal);
|
||||
}
|
||||
else {
|
||||
pSector->set_int_floorz(nZVal);
|
||||
pSector->setfloorz(nZVal);
|
||||
}
|
||||
|
||||
*nXVel = xvect;
|
||||
*nYVel = yvect;
|
||||
*nXVel = FloatToFixed<18>(vect.X);
|
||||
*nYVel = FloatToFixed<18>(vect.Y);
|
||||
|
||||
/*
|
||||
Update player position variables, in case the player sprite was moved by a sector,
|
||||
|
|
|
@ -2332,12 +2332,12 @@ void DoMovingSects()
|
|||
// TrailPoint *pTrail = &sTrailPoint[nTrail];
|
||||
|
||||
// loc_23872:
|
||||
int nAngle = getangle(sTrailPoint[nTrail].x - pBlockInfo->x, sTrailPoint[nTrail].y - pBlockInfo->y);
|
||||
int nAngle = getangle(sTrailPoint[nTrail].x - pBlockInfo->pos.X * worldtoint, sTrailPoint[nTrail].y - pBlockInfo->pos.Y * worldtoint);
|
||||
|
||||
int nXVel = bcos(nAngle, 4) * sMoveSect[i].field_10;
|
||||
int nYVel = bsin(nAngle, 4) * sMoveSect[i].field_10;
|
||||
|
||||
int ebx = (sTrailPoint[nTrail].x - pBlockInfo->x) << 14;
|
||||
int ebx = (sTrailPoint[nTrail].x - int(pBlockInfo->pos.X * worldtoint)) << 14;
|
||||
|
||||
int eax = nXVel;
|
||||
if (eax < 0) {
|
||||
|
@ -2347,7 +2347,7 @@ void DoMovingSects()
|
|||
int edx = eax;
|
||||
eax = ebx;
|
||||
|
||||
int ecx = (sTrailPoint[nTrail].y - pBlockInfo->y) << 14;
|
||||
int ecx = (sTrailPoint[nTrail].y - int(pBlockInfo->pos.Y * worldtoint)) << 14;
|
||||
|
||||
if (eax < 0) {
|
||||
eax = -eax;
|
||||
|
@ -2403,18 +2403,18 @@ void DoMovingSects()
|
|||
// loc_2393A:
|
||||
if (sMoveSect[i].pCurSector != nullptr)
|
||||
{
|
||||
MoveSector(sMoveSect[i].pCurSector, -1, &nXVel, &nYVel);
|
||||
MoveSector(sMoveSect[i].pCurSector, -minAngle, &nXVel, &nYVel);
|
||||
}
|
||||
|
||||
int var_2C = nXVel;
|
||||
int var_30 = nYVel;
|
||||
|
||||
MoveSector(pSector, -1, &nXVel, &nYVel);
|
||||
MoveSector(pSector, -minAngle, &nXVel, &nYVel);
|
||||
|
||||
if (nXVel != var_2C || nYVel != var_30)
|
||||
{
|
||||
MoveSector(sMoveSect[i].pCurSector, -1, &var_2C, &var_30);
|
||||
MoveSector(sMoveSect[i].pCurSector, -1, &nXVel, &nYVel);
|
||||
MoveSector(sMoveSect[i].pCurSector, -minAngle, &var_2C, &var_30);
|
||||
MoveSector(sMoveSect[i].pCurSector, -minAngle, &nXVel, &nYVel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -991,6 +991,7 @@ void AIPlayer::Tick(RunListEvent* ev)
|
|||
nNormal = GetWallNormal(nMove.hitWall);
|
||||
}
|
||||
|
||||
// moving blocks - move this to a separate function!
|
||||
if (sect != nullptr)
|
||||
{
|
||||
if ((sect->hitag == 45) && bTouchFloor)
|
||||
|
@ -1007,10 +1008,10 @@ void AIPlayer::Tick(RunListEvent* ev)
|
|||
|
||||
int xvel = sPlayerInput[nPlayer].xVel;
|
||||
int yvel = sPlayerInput[nPlayer].yVel;
|
||||
int nMyAngle = getangle(xvel, yvel);
|
||||
int nMyAngle = getangle(xvel, yvel) & 2047; // note: must be positive!
|
||||
|
||||
setsectinterpolate(sect);
|
||||
MoveSector(sect, nMyAngle, &xvel, &yvel);
|
||||
MoveSector(sect, DAngle::fromBuild(nMyAngle), &xvel, &yvel);
|
||||
|
||||
if (PlayerList[nPlayer].nPlayerPushSound <= -1)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue