mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-15 17:01:28 +00:00
- Blood: floatified VectorScan.
The texture checks in here definitely need some more verification, though. Doing a quick test looked ok, but I do not think this was enough.
This commit is contained in:
parent
3b76de7b7d
commit
e00eda6cb8
6 changed files with 57 additions and 61 deletions
|
@ -310,7 +310,7 @@ void render_drawrooms(DCoreActor* playersprite, const DVector3& position, sector
|
|||
checkRotatedWalls();
|
||||
|
||||
updatesector(position.XY(), §);
|
||||
if (sectnum == nullptr) return;
|
||||
if (sect == nullptr) return;
|
||||
|
||||
iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0;
|
||||
checkBenchActive();
|
||||
|
|
|
@ -6641,10 +6641,11 @@ bool actCanSplatWall(walltype* pWall)
|
|||
|
||||
void actFireVector(DBloodActor* shooter, int offset, int zoffset, int dx, int dy, int dz, VECTOR_TYPE vectorType)
|
||||
{
|
||||
DVector3 dv(dx * inttoworld, dy * inttoworld, dz * inttoworld);
|
||||
assert(vectorType >= 0 && vectorType < kVectorMax);
|
||||
const VECTORDATA* pVectorData = &gVectorData[vectorType];
|
||||
int nRange = pVectorData->maxDist;
|
||||
int hit = VectorScan(shooter, offset, zoffset, dx, dy, dz, nRange, 1);
|
||||
int hit = VectorScan(shooter, offset * inttoworld, zoffset * zinttoworld, dv, nRange * inttoworld, 1);
|
||||
if (hit == 3)
|
||||
{
|
||||
auto hitactor = gHitInfo.actor();
|
||||
|
@ -6825,7 +6826,7 @@ void actFireVector(DBloodActor* shooter, int offset, int zoffset, int dx, int dy
|
|||
{
|
||||
if (actor->xspr.physAttr & kPhysDebrisVector) {
|
||||
|
||||
int impulse = DivScale(pVectorData->impulse, ClipLow(actor->spriteMass.mass, 10), 6);
|
||||
int impulse = DivScale(pVectorData->impulse, max(actor->spriteMass.mass, 10), 6);
|
||||
actor->add_int_bvel_x(MulScale(dx, impulse, 16));
|
||||
actor->add_int_bvel_y(MulScale(dy, impulse, 16));
|
||||
actor->add_int_bvel_z(MulScale(dz, impulse, 16));
|
||||
|
|
|
@ -858,7 +858,7 @@ static void unicultThinkChase(DBloodActor* actor)
|
|||
else if (weaponType == kGenDudeWeaponHitscan && hscn)
|
||||
{
|
||||
if (genDudeAdjustSlope(actor, dist, weaponType)) break;
|
||||
VectorScan(actor, 0, 0, bcos(actor->int_ang()), bsin(actor->int_ang()), actor->dudeSlope, dist, 1);
|
||||
VectorScan(actor, 0, 0, DVector3(actor->spr.angle.ToVector() * 1024, actor->dudeSlope * inttoworld), dist * inttoworld, 1);
|
||||
if (actor == gHitInfo.actor()) break;
|
||||
|
||||
bool immune = nnExtIsImmune(hitactor, gVectorData[curWeapon].dmgType);
|
||||
|
@ -918,7 +918,7 @@ static void unicultThinkChase(DBloodActor* actor)
|
|||
if (hit == 4 && weaponType == kGenDudeWeaponHitscan && hscn)
|
||||
{
|
||||
bool masked = (pHWall->cstat & CSTAT_WALL_MASKED);
|
||||
if (masked) VectorScan(actor, 0, 0, bcos(actor->int_ang()), bsin(actor->int_ang()), actor->dudeSlope, dist, 1);
|
||||
if (masked) VectorScan(actor, 0, 0, DVector3(actor->spr.angle.ToVector() * 1024, actor->dudeSlope * inttoworld), dist * inttoworld, 1);
|
||||
|
||||
if ((actor != gHitInfo.actor()) && (pHWall->type != kWallGib || !masked || pXHWall == NULL || !pXHWall->triggerVector || pXHWall->locked))
|
||||
{
|
||||
|
|
|
@ -331,77 +331,80 @@ int HitScan(DBloodActor* actor, int z, int dx, int dy, int dz, unsigned int nMas
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int VectorScan(DBloodActor* actor, int nOffset, int nZOffset, int dx, int dy, int dz, int nRange, int ac)
|
||||
int VectorScan(DBloodActor* actor, double nOffset, double nZOffset, const DVector3& vel, double nRange, int ac)
|
||||
{
|
||||
assert(actor != nullptr);
|
||||
|
||||
int nNum = 256;
|
||||
gHitInfo.clearObj();
|
||||
int x1 = actor->int_pos().X + MulScale(nOffset, Cos(actor->int_ang() + 512), 30);
|
||||
int y1 = actor->int_pos().Y + MulScale(nOffset, Sin(actor->int_ang() + 512), 30);
|
||||
int z1 = actor->int_pos().Z + nZOffset;
|
||||
auto pos = actor->spr.pos.plusZ(nZOffset) + (actor->spr.angle + DAngle90).ToVector() * nOffset;
|
||||
auto bakCstat = actor->spr.cstat;
|
||||
actor->spr.cstat &= ~CSTAT_SPRITE_BLOCK_HITSCAN;
|
||||
if (nRange)
|
||||
{
|
||||
hitscangoal.X = x1 + MulScale(nRange << 4, Cos(actor->int_ang()), 30);
|
||||
hitscangoal.Y = y1 + MulScale(nRange << 4, Sin(actor->int_ang()), 30);
|
||||
auto goal = pos.XY() + actor->spr.angle.ToVector() * nRange;
|
||||
hitscangoal.X = goal.X * worldtoint;
|
||||
hitscangoal.Y = goal.Y * worldtoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
hitscangoal.X = hitscangoal.Y = 0x1fffffff;
|
||||
}
|
||||
vec3_t pos = { x1, y1, z1 };
|
||||
hitscan(pos, actor->sector(), { dx, dy, dz << 4 }, gHitInfo, CLIPMASK1);
|
||||
hitscan(pos, actor->sector(), vel, gHitInfo, CLIPMASK1);
|
||||
|
||||
hitscangoal.X = hitscangoal.Y = 0x1ffffff;
|
||||
actor->spr.cstat = bakCstat;
|
||||
while (nNum--)
|
||||
{
|
||||
if (nRange && approxDist(gHitInfo.hitpos.XY() - actor->spr.pos.XY()) > nRange)
|
||||
if (nRange && (gHitInfo.hitpos.XY() - actor->spr.pos.XY()).Length() > nRange)
|
||||
return -1;
|
||||
auto other = gHitInfo.actor();
|
||||
if (other != nullptr)
|
||||
{
|
||||
if ((other->spr.flags & 8) && !(ac & 1))
|
||||
return 3;
|
||||
return SS_SPRITE;
|
||||
if ((other->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) != 0)
|
||||
return 3;
|
||||
return SS_SPRITE;
|
||||
|
||||
int nPicnum = other->spr.picnum;
|
||||
if (tileWidth(nPicnum) == 0 || tileHeight(nPicnum) == 0)
|
||||
return 3;
|
||||
int height = (tileHeight(nPicnum) * other->spr.yrepeat) << 2;
|
||||
int otherZ = other->int_pos().Z;
|
||||
return SS_SPRITE;
|
||||
|
||||
double height = (tileHeight(nPicnum) * other->spr.yrepeat) * REPEAT_SCALE;
|
||||
double otherZ = other->spr.pos.Z;
|
||||
if (other->spr.cstat & CSTAT_SPRITE_YCENTER)
|
||||
otherZ += height / 2;
|
||||
|
||||
int nTopOfs = tileTopOffset(nPicnum);
|
||||
if (nTopOfs)
|
||||
otherZ -= (nTopOfs * other->spr.yrepeat) << 2;
|
||||
otherZ -= (nTopOfs * other->spr.yrepeat) * REPEAT_SCALE;
|
||||
assert(height > 0);
|
||||
int height2 = Scale(otherZ - gHitInfo.int_hitpos().Z, tileHeight(nPicnum), height);
|
||||
|
||||
double height2 = (otherZ - gHitInfo.hitpos.Z) * tileHeight(nPicnum) / height;
|
||||
if (!(other->spr.cstat & CSTAT_SPRITE_YFLIP))
|
||||
height2 = tileHeight(nPicnum) - height2;
|
||||
|
||||
if (height2 >= 0 && height2 < tileHeight(nPicnum))
|
||||
{
|
||||
int width = (tileWidth(nPicnum) * other->spr.xrepeat) >> 2;
|
||||
width = (width * 3) / 4;
|
||||
int check1 = ((y1 - other->int_pos().Y) * dx - (x1 - other->int_pos().X) * dy) / ksqrt(dx * dx + dy * dy);
|
||||
double width = (tileWidth(nPicnum) * other->spr.xrepeat) * REPEAT_SCALE * 0.75; // should actually be 0.8 to match the renderer!
|
||||
double check1 = ((pos.Y - other->spr.pos.Y) * vel.X - (pos.X - other->spr.pos.X) * vel.Y) / vel.XY().Length();
|
||||
assert(width > 0);
|
||||
int width2 = Scale(check1, tileWidth(nPicnum), width);
|
||||
|
||||
double width2 = check1 * tileWidth(nPicnum) / width;
|
||||
int nLeftOfs = tileLeftOffset(nPicnum);
|
||||
width2 += nLeftOfs + tileWidth(nPicnum) / 2;
|
||||
if (width2 >= 0 && width2 < tileWidth(nPicnum))
|
||||
{
|
||||
auto pData = tilePtr(nPicnum);
|
||||
if (pData[width2 * tileHeight(nPicnum) + height2] != TRANSPARENT_INDEX)
|
||||
return 3;
|
||||
if (pData[int(width2) * tileHeight(nPicnum) + int(height2)] != TRANSPARENT_INDEX)
|
||||
return SS_SPRITE;
|
||||
}
|
||||
}
|
||||
bakCstat = other->spr.cstat;
|
||||
other->spr.cstat &= ~CSTAT_SPRITE_BLOCK_HITSCAN;
|
||||
gHitInfo.clearObj();
|
||||
pos = gHitInfo.int_hitpos(); // must make a copy!
|
||||
hitscan(pos, other->sector(), { dx, dy, dz << 4 }, gHitInfo, CLIPMASK1);
|
||||
pos = gHitInfo.hitpos; // must make a copy!
|
||||
hitscan(pos, other->sector(), vel, gHitInfo, CLIPMASK1);
|
||||
other->spr.cstat = bakCstat;
|
||||
continue;
|
||||
}
|
||||
|
@ -424,12 +427,12 @@ int VectorScan(DBloodActor* actor, int nOffset, int nZOffset, int dx, int dy, in
|
|||
}
|
||||
if (!(pWall->cstat & (CSTAT_WALL_MASKED | CSTAT_WALL_1WAY)))
|
||||
return 0;
|
||||
int nOfs;
|
||||
double nOfs;
|
||||
if (pWall->cstat & CSTAT_WALL_ALIGN_BOTTOM)
|
||||
nOfs = ClipHigh(pSector->int_floorz(), pSectorNext->int_floorz());
|
||||
nOfs = min(pSector->floorz, pSectorNext->floorz);
|
||||
else
|
||||
nOfs = ClipLow(pSector->int_ceilingz(), pSectorNext->int_ceilingz());
|
||||
nOfs = (gHitInfo.int_hitpos().Z - nOfs) >> 8;
|
||||
nOfs = max(pSector->ceilingz, pSectorNext->ceilingz);
|
||||
nOfs = (gHitInfo.hitpos.Z - nOfs);
|
||||
if (pWall->cstat & CSTAT_WALL_YFLIP)
|
||||
nOfs = -nOfs;
|
||||
|
||||
|
@ -439,21 +442,19 @@ int VectorScan(DBloodActor* actor, int nOffset, int nZOffset, int dx, int dy, in
|
|||
if (!nSizX || !nSizY)
|
||||
return 0;
|
||||
|
||||
nOfs = (nOfs * pWall->yrepeat) / 8;
|
||||
nOfs += int((nSizY * pWall->ypan_) / 256);
|
||||
int nLength = approxDist(pWall->pos - pWall->point2Wall()->pos);
|
||||
int nHOffset;
|
||||
int nnOfs = int((nOfs * pWall->yrepeat) / 8);
|
||||
nnOfs += int((nSizY * pWall->ypan_) / 256);
|
||||
double nLength = (pWall->pos - pWall->point2Wall()->pos).Length();
|
||||
double fHOffset;
|
||||
if (pWall->cstat & CSTAT_WALL_XFLIP)
|
||||
nHOffset = approxDist(gHitInfo.hitpos.XY() - pWall->point2Wall()->pos);
|
||||
fHOffset = (gHitInfo.hitpos.XY() - pWall->point2Wall()->pos).Length();
|
||||
else
|
||||
nHOffset = approxDist(gHitInfo.hitpos.XY() - pWall->pos);
|
||||
fHOffset = (gHitInfo.hitpos.XY() - pWall->pos).Length();
|
||||
|
||||
nHOffset = pWall->xpan() + ((nHOffset * pWall->xrepeat) << 3) / nLength;
|
||||
nHOffset %= nSizX;
|
||||
nOfs %= nSizY;
|
||||
int nHOffset = int(pWall->xpan_ + ((fHOffset * pWall->xrepeat) * 8) / nLength) % nSizX;
|
||||
nnOfs %= nSizY;
|
||||
auto pData = tilePtr(nPicnum);
|
||||
int nPixel;
|
||||
nPixel = nHOffset * nSizY + nOfs;
|
||||
int nPixel = nHOffset * nSizY + nnOfs;
|
||||
|
||||
if (pData[nPixel] == TRANSPARENT_INDEX)
|
||||
{
|
||||
|
@ -462,8 +463,8 @@ int VectorScan(DBloodActor* actor, int nOffset, int nZOffset, int dx, int dy, in
|
|||
auto bakCstat2 = pWall->nextWall()->cstat;
|
||||
pWall->nextWall()->cstat &= ~CSTAT_WALL_BLOCK_HITSCAN;
|
||||
gHitInfo.clearObj();
|
||||
pos = gHitInfo.int_hitpos();
|
||||
hitscan(pos, pWall->nextSector(), { dx, dy, dz << 4 }, gHitInfo, CLIPMASK1);
|
||||
pos = gHitInfo.hitpos;
|
||||
hitscan(pos, pWall->nextSector(), vel, gHitInfo, CLIPMASK1);
|
||||
|
||||
pWall->cstat = bakCstat1;
|
||||
pWall->nextWall()->cstat = bakCstat2;
|
||||
|
@ -473,31 +474,25 @@ int VectorScan(DBloodActor* actor, int nOffset, int nZOffset, int dx, int dy, in
|
|||
}
|
||||
if (gHitInfo.hitSector != nullptr)
|
||||
{
|
||||
if (dz > 0)
|
||||
if (vel.Z > 0)
|
||||
{
|
||||
auto upper = barrier_cast<DBloodActor*>(gHitInfo.hitSector->upperLink);
|
||||
if (!upper) return 2;
|
||||
if (!upper) return SS_FLOOR;
|
||||
auto link = upper->GetOwner();
|
||||
gHitInfo.clearObj();
|
||||
x1 = gHitInfo.int_hitpos().X + link->int_pos().X - upper->int_pos().X;
|
||||
y1 = gHitInfo.int_hitpos().Y + link->int_pos().Y - upper->int_pos().Y;
|
||||
z1 = gHitInfo.int_hitpos().Z + link->int_pos().Z - upper->int_pos().Z;
|
||||
pos = { x1, y1, z1 };
|
||||
hitscan(pos, link->sector(), { dx, dy, dz << 4 }, gHitInfo, CLIPMASK1);
|
||||
pos = gHitInfo.hitpos + link->spr.pos - upper->spr.pos;
|
||||
hitscan(pos, link->sector(), vel, gHitInfo, CLIPMASK1);
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto lower = barrier_cast<DBloodActor*>(gHitInfo.hitSector->lowerLink);
|
||||
if (!lower) return 1;
|
||||
if (!lower) return SS_CEILING;
|
||||
auto link = lower->GetOwner();
|
||||
gHitInfo.clearObj();
|
||||
x1 = gHitInfo.int_hitpos().X + link->int_pos().X - lower->int_pos().X;
|
||||
y1 = gHitInfo.int_hitpos().Y + link->int_pos().Y - lower->int_pos().Y;
|
||||
z1 = gHitInfo.int_hitpos().Z + link->int_pos().Z - lower->int_pos().Z;
|
||||
pos = { x1, y1, z1 };
|
||||
hitscan(pos, link->sector(), { dx, dy, dz << 4 }, gHitInfo, CLIPMASK1);
|
||||
pos = gHitInfo.hitpos + link->spr.pos - lower->spr.pos;
|
||||
hitscan(pos, link->sector(), vel, gHitInfo, CLIPMASK1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,8 @@ inline int HitScan(DBloodActor* pSprite, double z, const DVector3& pos, unsigned
|
|||
{
|
||||
return HitScan(pSprite, int(z * zworldtoint), int(pos.X * worldtoint), int(pos.Y * worldtoint), int(pos.Z * worldtoint), nMask, a8);
|
||||
}
|
||||
int VectorScan(DBloodActor* pSprite, int nOffset, int nZOffset, int dx, int dy, int dz, int nRange, int ac);
|
||||
int VectorScan(DBloodActor* pSprite, double nOffset, double nZOffset, const DVector3& vel, double nRange, int ac);
|
||||
|
||||
void GetZRange(DBloodActor* pSprite, int* ceilZ, Collision* ceilHit, int* floorZ, Collision* floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0);
|
||||
void GetZRange(DBloodActor* pSprite, double* ceilZ, Collision* ceilHit, double* floorZ, Collision* floorHit, int nDist, unsigned int nMask, unsigned int nClipParallax = 0)
|
||||
{
|
||||
|
|
|
@ -380,7 +380,6 @@ void triggerTouchSprite(DBloodActor* pSprite, DBloodActor* nHSprite);
|
|||
void triggerTouchWall(DBloodActor* pSprite, walltype* nHWall);
|
||||
void killEvents(int nRx, int nCmd);
|
||||
void changeSpriteAngle(DBloodActor* pSpr, DAngle nAng);
|
||||
int getVelocityAngle(DBloodActor* pSpr);
|
||||
// ------------------------------------------------------------------------- //
|
||||
void aiPatrolSetMarker(DBloodActor* actor);
|
||||
void aiPatrolThink(DBloodActor* actor);
|
||||
|
|
Loading…
Reference in a new issue