- adapted all hitscan calls in Duke/RR.

This commit is contained in:
Christoph Oelckers 2021-11-26 00:08:59 +01:00
parent 129ce0aea8
commit 10dce7dd2d
7 changed files with 253 additions and 316 deletions

View file

@ -243,7 +243,7 @@ extern DBloodActor bloodActors[kMaxSprites];
inline DBloodActor* DBloodActor::base() { return bloodActors; }
// subclasses to add a game specific actor() method
// subclassed to add a game specific actor() method
struct HitInfo : public HitInfoBase
{
DBloodActor* actor() const

View file

@ -5074,7 +5074,8 @@ int furthestangle(DDukeActor *actor, int angs)
{
auto s = actor->s;
int j, furthest_angle = 0, angincs;
int hx, hy, hz, d, greatestd;
int d, greatestd;
HitInfo hit;
greatestd = -(1 << 30);
angincs = 2048 / angs;
@ -5084,9 +5085,9 @@ int furthestangle(DDukeActor *actor, int angs)
for (j = s->ang; j < (2048 + s->ang); j += angincs)
{
hitscan(s->x, s->y, s->z - (8 << 8), s->sector(), bcos(j), bsin(j), 0, nullptr, nullptr, nullptr, &hx, &hy, &hz, CLIPMASK1);
hitscan({ s->x, s->y, s->z - (8 << 8) }, s->sector(), { bcos(j), bsin(j), 0 }, hit, CLIPMASK1);
d = abs(hx - s->x) + abs(hy - s->y);
d = abs(hit.hitpos.x - s->x) + abs(hit.hitpos.y - s->y);
if (d > greatestd)
{
@ -5107,9 +5108,8 @@ int furthestcanseepoint(DDukeActor *actor, DDukeActor* tosee, int* dax, int* day
{
auto s = actor->s;
int j, angincs;
int hx, hy, hz, d, da;//, d, cd, ca,tempx,tempy,cx,cy;
DDukeActor* dd;
sectortype* hitsect;
int d, da;//, d, cd, ca,tempx,tempy,cx,cy;
HitInfo hit;
if ((actor->temp_data[0] & 63)) return -1;
@ -5120,17 +5120,16 @@ int furthestcanseepoint(DDukeActor *actor, DDukeActor* tosee, int* dax, int* day
auto ts = tosee->s;
for (j = ts->ang; j < (2048 + ts->ang); j += (angincs - (krand() & 511)))
{
hitscan(ts->x, ts->y, ts->z - (16 << 8), ts->sector(), bcos(j), bsin(j), 16384 - (krand() & 32767),
&hitsect, nullptr, &dd, &hx, &hy, &hz, CLIPMASK1);
hitscan({ ts->x, ts->y, ts->z - (16 << 8) }, ts->sector(), { bcos(j), bsin(j), 16384 - (krand() & 32767) }, hit, CLIPMASK1);
d = abs(hx - ts->x) + abs(hy - ts->y);
da = abs(hx - s->x) + abs(hy - s->y);
d = abs(hit.hitpos.x - ts->x) + abs(hit.hitpos.y - ts->y);
da = abs(hit.hitpos.x - s->x) + abs(hit.hitpos.y - s->y);
if (d < da && hitsect)
if (cansee(hx, hy, hz, hitsect, s->x, s->y, s->z - (16 << 8), s->sector()))
if (d < da && hit.hitSector)
if (cansee(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, hit.hitSector, s->x, s->y, s->z - (16 << 8), s->sector()))
{
*dax = hx;
*day = hy;
*dax = hit.hitpos.x;
*day = hit.hitpos.y;
return 1;
}
}

View file

@ -211,28 +211,6 @@ inline void getzrange_ex(int x, int y, int z, sectortype* sect, int32_t* ceilz,
florhit.setFromEngine(fh);
}
inline int hitscan(int x, int y, int z, int sectnum, int32_t vx, int32_t vy, int32_t vz,
sectortype** hitsect, walltype** hitwall, DDukeActor** hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype)
{
short hitsprt, hitsct, hitwal;
int res = ::hitscan(x, y, z, sectnum, vx, vy, vz, &hitsct, &hitwal, &hitsprt, hitx, hity, hitz, cliptype);
if (hitspr) *hitspr = hitsprt == -1 ? nullptr : &hittype[hitsprt];
if (hitsect) *hitsect = hitsct >= 0? &sector[hitsct] : nullptr;
if (hitwall) *hitwall = hitwal >= 0? &wall[hitwal] : nullptr;
return res;
}
inline int hitscan(int x, int y, int z, sectortype* sect, int32_t vx, int32_t vy, int32_t vz,
sectortype** hitsect, walltype** hitwall, DDukeActor** hitspr, int* hitx, int* hity, int* hitz, uint32_t cliptype)
{
short hitsprt, hitsct, hitwal;
int res = ::hitscan(x, y, z, sectnum(sect), vx, vy, vz, &hitsct, &hitwal, &hitsprt, hitx, hity, hitz, cliptype);
if (hitspr) *hitspr = hitsprt == -1 ? nullptr : &hittype[hitsprt];
if (hitsect) *hitsect = hitsct >= 0? &sector[hitsct] : nullptr;
if (hitwall) *hitwall = hitwal >= 0? &wall[hitwal] : nullptr;
return res;
}
inline void neartag(int32_t xs, int32_t ys, int32_t zs, int sectnum, int ange,
sectortype** neartagsector, walltype** neartagwall, DDukeActor** neartagsprite,
int32_t* neartaghitdist, int32_t neartagrange, uint8_t tagsearch)

View file

@ -169,15 +169,14 @@ void tracers(int x1, int y1, int z1, int x2, int y2, int z2, int n)
int hits(DDukeActor* actor)
{
auto sp = actor->s;
int sx, sy, sz;
int zoff;
HitInfo hit;
if (sp->picnum == TILE_APLAYER) zoff = isRR() ? PHEIGHT_RR : PHEIGHT_DUKE;
else zoff = 0;
hitscan(sp->x, sp->y, sp->z - zoff, sp->sector(), bcos(sp->ang), bsin(sp->ang), 0, nullptr, nullptr, nullptr, &sx, &sy, &sz, CLIPMASK1);
return (FindDistance2D(sx - sp->x, sy - sp->y));
hitscan(sp->pos, sp->sector(), { bcos(sp->ang), bsin(sp->ang), 0 }, hit, CLIPMASK1);
return (FindDistance2D(hit.hitpos.x - sp->x, hit.hitpos.y - sp->y));
}
//---------------------------------------------------------------------------
@ -189,20 +188,21 @@ int hits(DDukeActor* actor)
int hitasprite(DDukeActor* actor, DDukeActor** hitsp)
{
auto sp = actor->s;
int sx, sy, sz, zoff;
walltype* wal;
int zoff;
HitInfo hit;
if (badguy(actor))
zoff = (42 << 8);
else if (sp->picnum == TILE_APLAYER) zoff = (39 << 8);
else zoff = 0;
hitscan(sp->x, sp->y, sp->z - zoff, sp->sector(), bcos(sp->ang), bsin(sp->ang), 0, nullptr, &wal, hitsp, &sx, &sy, &sz, CLIPMASK1);
hitscan({ sp->x, sp->y, sp->z - zoff }, sp->sector(), { bcos(sp->ang), bsin(sp->ang), 0 }, hit, CLIPMASK1);
if (hitsp) *hitsp = hit.actor();
if (wal != nullptr && (wal->cstat & 16) && badguy(actor))
if (hit.hitWall != nullptr && (hit.hitWall->cstat & 16) && badguy(actor))
return((1 << 30));
return (FindDistance2D(sx - sp->x, sy - sp->y));
return (FindDistance2D(hit.hitpos.x - sp->x, hit.hitpos.y - sp->y));
}
//---------------------------------------------------------------------------
@ -213,12 +213,12 @@ int hitasprite(DDukeActor* actor, DDukeActor** hitsp)
int hitawall(struct player_struct* p, walltype** hitw)
{
int sx, sy, sz;
HitInfo hit;
hitscan(p->pos.x, p->pos.y, p->pos.z, p->cursector,
p->angle.ang.bcos(), p->angle.ang.bsin(), 0, nullptr, hitw, nullptr, &sx, &sy, &sz, CLIPMASK0);
hitscan(p->pos, p->cursector, { p->angle.ang.bcos(), p->angle.ang.bsin(), 0 }, hit, CLIPMASK0);
if (hitw) *hitw = hit.hitWall;
return (FindDistance2D(sx - p->pos.x, sy - p->pos.y));
return (FindDistance2D(hit.hitpos.x - p->pos.x, hit.hitpos.y - p->pos.y));
}
@ -993,10 +993,7 @@ void shootbloodsplat(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i
spritetype* const s = actor->s;
auto sectp = s->sector();
int zvel;
int hitx, hity, hitz;
sectortype* hitsectp;
walltype* wal;
DDukeActor* d;
HitInfo hit;
if (p >= 0)
sa += 64 - (krand() & 127);
@ -1004,25 +1001,22 @@ void shootbloodsplat(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i
zvel = 1024 - (krand() & 2047);
hitscan(sx, sy, sz, sectp,
bcos(sa),
bsin(sa), zvel << 6,
&hitsectp, &wal, &d, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sectp, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
// oh my...
if (FindDistance2D(sx - hitx, sy - hity) < 1024 &&
(wal != nullptr && wal->overpicnum != BIGFORCE) &&
((wal->twoSided() && hitsectp != nullptr &&
wal->nextSector()->lotag == 0 &&
hitsectp->lotag == 0 &&
(hitsectp->floorz - wal->nextSector()->floorz) > (16 << 8)) ||
(!wal->twoSided() && hitsectp->lotag == 0)))
if (FindDistance2D(sx - hit.hitpos.x, sy - hit.hitpos.y) < 1024 &&
(hit.hitWall != nullptr && hit.hitWall->overpicnum != BIGFORCE) &&
((hit.hitWall->twoSided() && hit.hitSector != nullptr &&
hit.hitWall->nextSector()->lotag == 0 &&
hit.hitSector->lotag == 0 &&
(hit.hitSector->floorz - hit.hitWall->nextSector()->floorz) > (16 << 8)) ||
(!hit.hitWall->twoSided() && hit.hitSector->lotag == 0)))
{
if ((wal->cstat & 16) == 0)
if ((hit.hitWall->cstat & 16) == 0)
{
if (wal->twoSided())
if (hit.hitWall->twoSided())
{
DukeSectIterator it(wal->nextSector());
DukeSectIterator it(hit.hitWall->nextSector());
while (auto act2 = it.Next())
{
if (act2->s->statnum == STAT_EFFECTOR && act2->s->lotag == SE_13_EXPLOSIVE)
@ -1030,21 +1024,21 @@ void shootbloodsplat(DDukeActor* actor, int p, int sx, int sy, int sz, int sa, i
}
}
if (wal->twoSided() &&
wal->nextWall()->hitag != 0)
if (hit.hitWall->twoSided() &&
hit.hitWall->nextWall()->hitag != 0)
return;
if (wal->hitag == 0)
if (hit.hitWall->hitag == 0)
{
auto spawned = spawn(actor, atwith);
if (spawned)
{
spawned->s->xvel = -12;
auto delta = wal->delta();
auto delta = hit.hitWall->delta();
spawned->s->ang = getangle(-delta.x, -delta.y) + 512; // note the '-' sign here!
spawned->s->x = hitx;
spawned->s->y = hity;
spawned->s->z = hitz;
spawned->s->x = hit.hitpos.x;
spawned->s->y = hit.hitpos.y;
spawned->s->z = hit.hitpos.z;
spawned->s->cstat |= (krand() & 4);
ssp(spawned, CLIPMASK0);
setsprite(spawned, spawned->s->pos);

View file

@ -236,10 +236,7 @@ static void shootknee(DDukeActor* actor, int p, int sx, int sy, int sz, int sa)
auto s = actor->s;
auto sectp = s->sector();
int zvel;
int hitx, hity, hitz;
DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* hitwallp;
HitInfo hit;
if (p >= 0)
{
@ -255,19 +252,16 @@ static void shootknee(DDukeActor* actor, int p, int sx, int sy, int sz, int sa)
sa = getangle(pactor->s->x - sx, pactor->s->y - sy);
}
hitscan(sx, sy, sz, sectp,
bcos(sa),
bsin(sa), zvel << 6,
&hitsectp, &hitwallp, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sectp, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
if (hitsectp == nullptr) return;
if (hit.hitSector == nullptr) return;
if ((abs(sx - hitx) + abs(sy - hity)) < 1024)
if ((abs(sx - hit.hitpos.x) + abs(sy - hit.hitpos.y)) < 1024)
{
if (hitwallp || hitsprt)
if (hit.hitWall || hit.actor())
{
auto knee = EGS(hitsectp, hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, actor, 4);
auto knee = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, KNEE, -15, 0, 0, sa, 32, 0, actor, 4);
if (knee)
{
knee->s->extra += (krand() & 7);
@ -281,34 +275,33 @@ static void shootknee(DDukeActor* actor, int p, int sx, int sy, int sz, int sa)
if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400)
knee->s->extra += (gs.max_player_health >> 2);
}
if (hitsprt && hitsprt->s->picnum != ACCESSSWITCH && hitsprt->s->picnum != ACCESSSWITCH2)
if (hit.actor() && hit.actor()->s->picnum != ACCESSSWITCH && hit.actor()->s->picnum != ACCESSSWITCH2)
{
fi.checkhitsprite(hitsprt, knee);
if (p >= 0) fi.checkhitswitch(p, nullptr, hitsprt);
fi.checkhitsprite(hit.actor(), knee);
if (p >= 0) fi.checkhitswitch(p, nullptr, hit.actor());
}
else if (hitwallp)
else if (hit.hitWall)
{
auto wal = hitwallp;
if (wal->cstat & 2)
if (wal->twoSided())
if (hitz >= (wal->nextSector()->floorz))
wal =wal->nextWall();
if (hit.hitWall->cstat & 2)
if (hit.hitWall->twoSided())
if (hit.hitpos.z >= (hit.hitWall->nextSector()->floorz))
hit.hitWall =hit.hitWall->nextWall();
if (wal->picnum != ACCESSSWITCH && wal->picnum != ACCESSSWITCH2)
if (hit.hitWall->picnum != ACCESSSWITCH && hit.hitWall->picnum != ACCESSSWITCH2)
{
fi.checkhitwall(knee, wal, hitx, hity, hitz, KNEE);
if (p >= 0) fi.checkhitswitch(p, wal, nullptr);
fi.checkhitwall(knee, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, KNEE);
if (p >= 0) fi.checkhitswitch(p, hit.hitWall, nullptr);
}
}
}
else if (p >= 0 && zvel > 0 && hitsectp->lotag == 1)
else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1)
{
auto splash = spawn(ps[p].GetActor(), WATERSPLASH2);
if (splash)
{
splash->s->x = hitx;
splash->s->y = hity;
splash->s->x = hit.hitpos.x;
splash->s->y = hit.hitpos.y;
splash->s->ang = ps[p].angle.ang.asbuild(); // Total tweek
splash->s->xvel = 32;
ssp(actor, CLIPMASK0);
@ -330,10 +323,7 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa
auto s = actor->s;
auto sectp = s->sector();
int zvel = 0;
int hitx, hity, hitz;
DDukeActor* hitact;
sectortype* hitsectp;
walltype* hitwallp;
HitInfo hit;
if (s->extra >= 0) s->shade = -96;
@ -415,47 +405,44 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa
}
s->cstat &= ~257;
hitscan(sx, sy, sz, sectp,
bcos(sa),
bsin(sa),
zvel << 6, &hitsectp, &hitwallp, &hitact, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sectp, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
s->cstat |= 257;
if (hitsectp == nullptr) return;
if (hit.hitSector == nullptr) return;
if ((krand() & 15) == 0 && hitsectp->lotag == 2)
tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1));
if ((krand() & 15) == 0 && hit.hitSector->lotag == 2)
tracers(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, sx, sy, sz, 8 - (ud.multimode >> 1));
DDukeActor* spark;
if (p >= 0)
{
spark = EGS(hitsectp, hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4);
spark = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4);
if (!spark) return;
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
spark->s->extra += (krand() % 6);
if (hitwallp == nullptr && hitact == nullptr)
if (hit.hitWall == nullptr && hit.actor() == nullptr)
{
if (zvel < 0)
{
if (hitsectp->ceilingstat & 1)
if (hit.hitSector->ceilingstat & 1)
{
spark->s->xrepeat = 0;
spark->s->yrepeat = 0;
return;
}
else
fi.checkhitceiling(hitsectp);
fi.checkhitceiling(hit.hitSector);
}
spawn(spark, SMALLSMOKE);
}
if (hitact)
if (hit.actor())
{
fi.checkhitsprite(hitact, spark);
if (hitact->s->picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1))
fi.checkhitsprite(hit.actor(), spark);
if (hit.actor()->s->picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1))
{
spark->s->xrepeat = spark->s->yrepeat = 0;
auto jib = spawn(spark, JIBS6);
@ -470,52 +457,51 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa
else spawn(spark, SMALLSMOKE);
if (p >= 0 && (
hitact->s->picnum == DIPSWITCH ||
hitact->s->picnum == DIPSWITCH + 1 ||
hitact->s->picnum == DIPSWITCH2 ||
hitact->s->picnum == DIPSWITCH2 + 1 ||
hitact->s->picnum == DIPSWITCH3 ||
hitact->s->picnum == DIPSWITCH3 + 1 ||
hitact->s->picnum == HANDSWITCH ||
hitact->s->picnum == HANDSWITCH + 1))
hit.actor()->s->picnum == DIPSWITCH ||
hit.actor()->s->picnum == DIPSWITCH + 1 ||
hit.actor()->s->picnum == DIPSWITCH2 ||
hit.actor()->s->picnum == DIPSWITCH2 + 1 ||
hit.actor()->s->picnum == DIPSWITCH3 ||
hit.actor()->s->picnum == DIPSWITCH3 + 1 ||
hit.actor()->s->picnum == HANDSWITCH ||
hit.actor()->s->picnum == HANDSWITCH + 1))
{
fi.checkhitswitch(p, nullptr, hitact);
fi.checkhitswitch(p, nullptr, hit.actor());
return;
}
}
else if (hitwallp)
else if (hit.hitWall)
{
spawn(spark, SMALLSMOKE);
auto wal = hitwallp;
if (fi.isadoorwall(wal->picnum) == 1)
if (fi.isadoorwall(hit.hitWall->picnum) == 1)
goto SKIPBULLETHOLE;
if (p >= 0 && (
wal->picnum == DIPSWITCH ||
wal->picnum == DIPSWITCH + 1 ||
wal->picnum == DIPSWITCH2 ||
wal->picnum == DIPSWITCH2 + 1 ||
wal->picnum == DIPSWITCH3 ||
wal->picnum == DIPSWITCH3 + 1 ||
wal->picnum == HANDSWITCH ||
wal->picnum == HANDSWITCH + 1))
hit.hitWall->picnum == DIPSWITCH ||
hit.hitWall->picnum == DIPSWITCH + 1 ||
hit.hitWall->picnum == DIPSWITCH2 ||
hit.hitWall->picnum == DIPSWITCH2 + 1 ||
hit.hitWall->picnum == DIPSWITCH3 ||
hit.hitWall->picnum == DIPSWITCH3 + 1 ||
hit.hitWall->picnum == HANDSWITCH ||
hit.hitWall->picnum == HANDSWITCH + 1))
{
fi.checkhitswitch(p, wal, nullptr);
fi.checkhitswitch(p, hit.hitWall, nullptr);
return;
}
if (wal->hitag != 0 || (wal->twoSided() && wal->nextWall()->hitag != 0))
if (hit.hitWall->hitag != 0 || (hit.hitWall->twoSided() && hit.hitWall->nextWall()->hitag != 0))
goto SKIPBULLETHOLE;
if (hitsectp && hitsectp->lotag == 0)
if (wal->overpicnum != BIGFORCE)
if ((wal->twoSided() && wal->nextSector()->lotag == 0) ||
(!wal->twoSided() && hitsectp->lotag == 0))
if ((wal->cstat & 16) == 0)
if (hit.hitSector && hit.hitSector->lotag == 0)
if (hit.hitWall->overpicnum != BIGFORCE)
if ((hit.hitWall->twoSided() && hit.hitWall->nextSector()->lotag == 0) ||
(!hit.hitWall->twoSided() && hit.hitSector->lotag == 0))
if ((hit.hitWall->cstat & 16) == 0)
{
if (wal->twoSided())
if (hit.hitWall->twoSided())
{
DukeSectIterator it(wal->nextSector());
DukeSectIterator it(hit.hitWall->nextSector());
while (auto l = it.Next())
{
if (l->s->statnum == 3 && l->s->lotag == 13)
@ -534,7 +520,7 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa
if (hole)
{
hole->s->xvel = -1;
auto delta = wal->delta();
auto delta = hit.hitWall->delta();
hole->s->ang = getangle(-delta.x, -delta.y) + 512;
ssp(hole, CLIPMASK0);
}
@ -542,36 +528,36 @@ static void shootweapon(DDukeActor *actor, int p, int sx, int sy, int sz, int sa
SKIPBULLETHOLE:
if (wal->cstat & 2)
if (wal->twoSided())
if (hitz >= (wal->nextSector()->floorz))
wal = wal->nextWall();
if (hit.hitWall->cstat & 2)
if (hit.hitWall->twoSided())
if (hit.hitpos.z >= (hit.hitWall->nextSector()->floorz))
hit.hitWall = hit.hitWall->nextWall();
fi.checkhitwall(spark, wal, hitx, hity, hitz, SHOTSPARK1);
fi.checkhitwall(spark, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1);
}
}
else
{
spark = EGS(hitsectp, hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4);
spark = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4);
if (spark)
{
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
if (hitact)
if (hit.actor())
{
fi.checkhitsprite(hitact, spark);
if (hitact->s->picnum != TILE_APLAYER)
fi.checkhitsprite(hit.actor(), spark);
if (hit.actor()->s->picnum != TILE_APLAYER)
spawn(spark, SMALLSMOKE);
else spark->s->xrepeat = spark->s->yrepeat = 0;
}
else if (hitwallp)
fi.checkhitwall(spark, hitwallp, hitx, hity, hitz, SHOTSPARK1);
else if (hit.hitWall)
fi.checkhitwall(spark, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1);
}
}
if ((krand() & 255) < 4)
{
vec3_t v{ hitx, hity, hitz };
vec3_t v{ hit.hitpos.x, hit.hitpos.y, hit.hitpos.z };
S_PlaySound3D(PISTOL_RICOCHET, spark, &v);
}
}
@ -868,39 +854,33 @@ static void shootlaser(DDukeActor* actor, int p, int sx, int sy, int sz, int sa)
auto sectp = s->sector();
int zvel;
int j;
int hitx, hity, hitz;
DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
HitInfo hit;
if (p >= 0)
zvel = -ps[p].horizon.sum().asq16() >> 11;
else zvel = 0;
hitscan(sx, sy, sz - ps[p].pyoff, sectp,
bcos(sa),
bsin(sa),
zvel << 6, &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz - ps[p].pyoff }, sectp, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
j = 0;
if (hitsprt) return;
if (hit.actor()) return;
if (wal && hitsectp)
if (hit.hitWall && hit.hitSector)
{
if (((hitx - sx) * (hitx - sx) + (hity - sy) * (hity - sy)) < (290 * 290))
if (((hit.hitpos.x - sx) * (hit.hitpos.x - sx) + (hit.hitpos.y - sy) * (hit.hitpos.y - sy)) < (290 * 290))
{
if (wal->twoSided())
if (hit.hitWall->twoSided())
{
if (wal->nextSector()->lotag <= 2 && hitsectp->lotag <= 2)
if (hit.hitWall->nextSector()->lotag <= 2 && hit.hitSector->lotag <= 2)
j = 1;
}
else if (hitsectp->lotag <= 2)
else if (hit.hitSector->lotag <= 2)
j = 1;
}
if (j == 1)
{
auto bomb = EGS(hitsectp, hitx, hity, hitz, TRIPBOMB, -16, 4, 5, sa, 0, 0, actor, 6);
auto bomb = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, TRIPBOMB, -16, 4, 5, sa, 0, 0, actor, 6);
if (!bomb) return;
if (isWW2GI())
{
@ -924,7 +904,7 @@ static void shootlaser(DDukeActor* actor, int p, int sx, int sy, int sz, int sa)
bomb->s->xvel = -20;
ssp(bomb, CLIPMASK0);
bomb->s->cstat = 16;
auto delta = wal->delta();
auto delta = hit.hitWall->delta();
bomb->temp_data[5] = bomb->s->ang = getangle(-delta.x, -delta.y) - 512;
if (p >= 0)
@ -945,10 +925,7 @@ static void shootgrowspark(DDukeActor* actor, int p, int sx, int sy, int sz, int
auto sect = s->sector();
int zvel;
int k;
int hitx, hity, hitz;
DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
HitInfo hit;
if (p >= 0)
{
@ -997,29 +974,28 @@ static void shootgrowspark(DDukeActor* actor, int p, int sx, int sy, int sz, int
//RESHOOTGROW:
s->cstat &= ~257;
hitscan(sx, sy, sz, sect, bcos(sa), bsin(sa),
zvel << 6, &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sect, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
s->cstat |= 257;
auto spark = EGS(sect, hitx, hity, hitz, GROWSPARK, -16, 28, 28, sa, 0, 0, actor, 1);
auto spark = EGS(sect, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, GROWSPARK, -16, 28, 28, sa, 0, 0, actor, 1);
if (!spark) return;
spark->s->pal = 2;
spark->s->cstat |= 130;
spark->s->xrepeat = spark->s->yrepeat = 1;
if (wal == nullptr && hitsprt == nullptr && hitsectp != nullptr)
if (hit.hitWall == nullptr && hit.actor() == nullptr && hit.hitSector != nullptr)
{
if (zvel < 0 && (hitsectp->ceilingstat & 1) == 0)
fi.checkhitceiling(hitsectp);
if (zvel < 0 && (hit.hitSector->ceilingstat & 1) == 0)
fi.checkhitceiling(hit.hitSector);
}
else if (hitsprt != nullptr) fi.checkhitsprite(hitsprt, spark);
else if (wal != nullptr)
else if (hit.actor() != nullptr) fi.checkhitsprite(hit.actor(), spark);
else if (hit.hitWall != nullptr)
{
if (wal->picnum != ACCESSSWITCH && wal->picnum != ACCESSSWITCH2)
if (hit.hitWall->picnum != ACCESSSWITCH && hit.hitWall->picnum != ACCESSSWITCH2)
{
fi.checkhitwall(spark, wal, hitx, hity, hitz, GROWSPARK);
fi.checkhitwall(spark, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, GROWSPARK);
}
}
}
@ -2048,40 +2024,33 @@ static void underwater(int snum, ESyncBits actions, int fz, int cz)
int operateTripbomb(int snum)
{
auto p = &ps[snum];
HitInfo hit;
int sx, sy, sz;
DDukeActor* hitsprt;
sectortype *hitsectp;
walltype* wal;
hitscan(p->pos, p->cursector, { p->angle.ang.bcos(), p->angle.ang.bsin(), -p->horizon.sum().asq16() >> 11 }, hit, CLIPMASK1);
hitscan(p->pos.x, p->pos.y, p->pos.z,
p->cursector, p->angle.ang.bcos(),
p->angle.ang.bsin(), -p->horizon.sum().asq16() >> 11,
&hitsectp, &wal, &hitsprt, &sx, &sy, &sz, CLIPMASK1);
if (hitsectp == nullptr || hitsprt)
if (hit.hitSector == nullptr || hit.actor())
return 0;
if (wal != nullptr && hitsectp->lotag > 2)
if (hit.hitWall != nullptr && hit.hitSector->lotag > 2)
return 0;
if (wal != nullptr && wal->overpicnum >= 0)
if (wal->overpicnum == BIGFORCE)
if (hit.hitWall != nullptr && hit.hitWall->overpicnum >= 0)
if (hit.hitWall->overpicnum == BIGFORCE)
return 0;
DDukeActor* j;
DukeSectIterator it(hitsectp);
DukeSectIterator it(hit.hitSector);
while ((j = it.Next()))
{
auto sj = j->s;
if (sj->picnum == TRIPBOMB &&
abs(sj->z - sz) < (12 << 8) && ((sj->x - sx) * (sj->x - sx) + (sj->y - sy) * (sj->y - sy)) < (290 * 290))
abs(sj->z - hit.hitpos.z) < (12 << 8) && ((sj->x - hit.hitpos.x) * (sj->x - hit.hitpos.x) + (sj->y - hit.hitpos.y) * (sj->y - hit.hitpos.y)) < (290 * 290))
return 0;
}
if (j == nullptr && wal != nullptr && (wal->cstat & 16) == 0)
if ((wal->twoSided() && wal->nextSector()->lotag <= 2) || (!wal->twoSided() && hitsectp->lotag <= 2))
if (((sx - p->pos.x) * (sx - p->pos.x) + (sy - p->pos.y) * (sy - p->pos.y)) < (290 * 290))
if (j == nullptr && hit.hitWall != nullptr && (hit.hitWall->cstat & 16) == 0)
if ((hit.hitWall->twoSided() && hit.hitWall->nextSector()->lotag <= 2) || (!hit.hitWall->twoSided() && hit.hitSector->lotag <= 2))
if (((hit.hitpos.x - p->pos.x) * (hit.hitpos.x - p->pos.x) + (hit.hitpos.y - p->pos.y) * (hit.hitpos.y - p->pos.y)) < (290 * 290))
{
p->pos.z = p->oposz;
p->poszv = 0;

View file

@ -88,10 +88,7 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
spritetype* const s = actor->s;
auto sectp = s->sector();
int zvel;
int hitx, hity, hitz;
DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
HitInfo hit;
if (p >= 0)
{
@ -107,24 +104,21 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
sa = getangle(pspr->s->x - sx, pspr->s->y - sy);
}
hitscan(sx, sy, sz, sectp,
bcos(sa),
bsin(sa), zvel << 6,
&hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sectp, { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
if (isRRRA() && hitsectp != nullptr && ((hitsectp->lotag == 160 && zvel > 0) || (hitsectp->lotag == 161 && zvel < 0))
&& hitsprt == nullptr && wal == nullptr)
if (isRRRA() && hit.hitSector != nullptr && ((hit.hitSector->lotag == 160 && zvel > 0) || (hit.hitSector->lotag == 161 && zvel < 0))
&& hit.actor() == nullptr && hit.hitWall == nullptr)
{
DukeStatIterator its(STAT_EFFECTOR);
while (auto effector = its.Next())
{
if (effector->s->sector() == hitsectp && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
if (effector->s->sector() == hit.hitSector && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
&& effector->s->lotag == SE_7_TELEPORT)
{
int nx, ny, nz;
nx = hitx + (effector->GetOwner()->s->x - effector->s->x);
ny = hity + (effector->GetOwner()->s->y - effector->s->y);
if (hitsectp->lotag == 161)
nx = hit.hitpos.x + (effector->GetOwner()->s->x - effector->s->x);
ny = hit.hitpos.y + (effector->GetOwner()->s->y - effector->s->y);
if (hit.hitSector->lotag == 161)
{
nz = effector->GetOwner()->sector()->floorz;
}
@ -132,29 +126,28 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
{
nz = effector->GetOwner()->sector()->ceilingz;
}
hitscan(nx, ny, nz, effector->GetOwner()->s->sector(), bcos(sa), bsin(sa), zvel << 6,
&hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ nx, ny, nz }, effector->GetOwner()->s->sector(), { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
break;
}
}
}
if (hitsectp == nullptr) return;
if (hit.hitSector == nullptr) return;
if ((abs(sx - hitx) + abs(sy - hity)) < 1024)
if ((abs(sx - hit.hitpos.x) + abs(sy - hit.hitpos.y)) < 1024)
{
if (wal != nullptr || hitsprt)
if (hit.hitWall != nullptr || hit.actor())
{
DDukeActor* wpn;
if (isRRRA() && atwith == SLINGBLADE)
{
wpn = EGS(hitsectp, hitx, hity, hitz, SLINGBLADE, -15, 0, 0, sa, 32, 0, actor, 4);
wpn = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SLINGBLADE, -15, 0, 0, sa, 32, 0, actor, 4);
if (!wpn) return;
wpn->s->extra += 50;
}
else
{
wpn = EGS(hitsectp, hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, actor, 4);
wpn = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, KNEE, -15, 0, 0, sa, 32, 0, actor, 4);
if (!wpn) return;
wpn->s->extra += (krand() & 7);
}
@ -169,32 +162,32 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
if (p >= 0 && ps[p].steroids_amount > 0 && ps[p].steroids_amount < 400)
wpn->s->extra += (gs.max_player_health >> 2);
if (hitsprt && hitsprt->s->picnum != ACCESSSWITCH && hitsprt->s->picnum != ACCESSSWITCH2)
if (hit.actor() && hit.actor()->s->picnum != ACCESSSWITCH && hit.actor()->s->picnum != ACCESSSWITCH2)
{
fi.checkhitsprite(hitsprt, wpn);
if (p >= 0) fi.checkhitswitch(p, nullptr, hitsprt);
fi.checkhitsprite(hit.actor(), wpn);
if (p >= 0) fi.checkhitswitch(p, nullptr, hit.actor());
}
else if (wal)
else if (hit.hitWall)
{
if (wal->cstat & 2)
if (wal->twoSided())
if (hitz >= (wal->nextSector()->floorz))
wal = wal->nextWall();
if (hit.hitWall->cstat & 2)
if (hit.hitWall->twoSided())
if (hit.hitpos.z >= (hit.hitWall->nextSector()->floorz))
hit.hitWall = hit.hitWall->nextWall();
if (wal->picnum != ACCESSSWITCH && wal->picnum != ACCESSSWITCH2)
if (hit.hitWall->picnum != ACCESSSWITCH && hit.hitWall->picnum != ACCESSSWITCH2)
{
fi.checkhitwall(wpn, wal, hitx, hity, hitz, atwith);
if (p >= 0) fi.checkhitswitch(p, wal, nullptr);
fi.checkhitwall(wpn, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, atwith);
if (p >= 0) fi.checkhitswitch(p, hit.hitWall, nullptr);
}
}
}
else if (p >= 0 && zvel > 0 && hitsectp->lotag == 1)
else if (p >= 0 && zvel > 0 && hit.hitSector->lotag == 1)
{
auto splash = spawn(ps[p].GetActor(), WATERSPLASH2);
if (splash)
{
splash->s->x = hitx;
splash->s->y = hity;
splash->s->x = hit.hitpos.x;
splash->s->y = hit.hitpos.y;
splash->s->ang = ps[p].angle.ang.asbuild(); // Total tweek
splash->s->xvel = 32;
ssp(actor, 0);
@ -215,10 +208,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
auto s = actor->s;
auto sectp = s->sector();
int zvel = 0;
int hitx, hity, hitz;
DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
HitInfo hit;
if (s->extra >= 0) s->shade = -96;
@ -271,22 +261,21 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
}
s->cstat &= ~257;
hitscan(sx, sy, sz, sectp, bcos(sa), bsin(sa),
zvel << 6, &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ sx, sy, sz }, sectp, { bcos(sa), bsin(sa),zvel << 6 }, hit, CLIPMASK1);
if (isRRRA() && hitsectp != nullptr && (((hitsectp->lotag == 160 && zvel > 0) || (hitsectp->lotag == 161 && zvel < 0))
&& hitsprt == nullptr && wal == nullptr))
if (isRRRA() && hit.hitSector != nullptr && (((hit.hitSector->lotag == 160 && zvel > 0) || (hit.hitSector->lotag == 161 && zvel < 0))
&& hit.actor() == nullptr && hit.hitWall == nullptr))
{
DukeStatIterator its(STAT_EFFECTOR);
while (auto effector = its.Next())
{
if (effector->s->sector() == hitsectp && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
if (effector->s->sector() == hit.hitSector && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
&& effector->s->lotag == SE_7_TELEPORT)
{
int nx, ny, nz;
nx = hitx + (effector->GetOwner()->s->x - effector->s->x);
ny = hity + (effector->GetOwner()->s->y - effector->s->y);
if (hitsectp->lotag == 161)
nx = hit.hitpos.x + (effector->GetOwner()->s->x - effector->s->x);
ny = hit.hitpos.y + (effector->GetOwner()->s->y - effector->s->y);
if (hit.hitSector->lotag == 161)
{
nz = effector->GetOwner()->sector()->floorz;
}
@ -294,8 +283,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
{
nz = effector->GetOwner()->sector()->ceilingz;
}
hitscan(nx, ny, nz, effector->GetOwner()->s->sector(), bcos(sa), bsin(sa), zvel << 6,
&hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
hitscan({ nx, ny, nz }, effector->GetOwner()->s->sector(), { bcos(sa), bsin(sa), zvel << 6 }, hit, CLIPMASK1);
break;
}
}
@ -303,47 +291,47 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
s->cstat |= 257;
if (hitsectp == nullptr) return;
if (hit.hitSector == nullptr) return;
if (atwith == SHOTGUN)
if (hitsectp->lotag == 1)
if (hit.hitSector->lotag == 1)
if (krand() & 1)
return;
if ((krand() & 15) == 0 && hitsectp->lotag == 2)
tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1));
if ((krand() & 15) == 0 && hit.hitSector->lotag == 2)
tracers(hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, sx, sy, sz, 8 - (ud.multimode >> 1));
DDukeActor* spark;
if (p >= 0)
{
spark = EGS(hitsectp, hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4);
spark = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4);
if (!spark) return;
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
spark->s->extra += (krand() % 6);
if (wal == nullptr && hitsprt == nullptr)
if (hit.hitWall == nullptr && hit.actor() == nullptr)
{
if (zvel < 0)
{
if (hitsectp->ceilingstat & 1)
if (hit.hitSector->ceilingstat & 1)
{
spark->s->xrepeat = 0;
spark->s->yrepeat = 0;
return;
}
else
fi.checkhitceiling(hitsectp);
fi.checkhitceiling(hit.hitSector);
}
if (hitsectp->lotag != 1)
if (hit.hitSector->lotag != 1)
spawn(spark, SMALLSMOKE);
}
if (hitsprt)
if (hit.actor())
{
if (hitsprt->s->picnum == 1930)
if (hit.actor()->s->picnum == 1930)
return;
fi.checkhitsprite(hitsprt, spark);
if (hitsprt->s->picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1))
fi.checkhitsprite(hit.actor(), spark);
if (hit.actor()->s->picnum == TILE_APLAYER && (ud.coop != 1 || ud.ffire == 1))
{
auto l = spawn(spark, JIBS6);
spark->s->xrepeat = spark->s->yrepeat = 0;
@ -358,55 +346,55 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
else spawn(spark, SMALLSMOKE);
if (p >= 0 && (
hitsprt->s->picnum == DIPSWITCH ||
hitsprt->s->picnum == DIPSWITCH + 1 ||
hitsprt->s->picnum == DIPSWITCH2 ||
hitsprt->s->picnum == DIPSWITCH2 + 1 ||
hitsprt->s->picnum == DIPSWITCH3 ||
hitsprt->s->picnum == DIPSWITCH3 + 1 ||
(isRRRA() && hitsprt->s->picnum == RRTILE8660) ||
hitsprt->s->picnum == HANDSWITCH ||
hitsprt->s->picnum == HANDSWITCH + 1))
hit.actor()->s->picnum == DIPSWITCH ||
hit.actor()->s->picnum == DIPSWITCH + 1 ||
hit.actor()->s->picnum == DIPSWITCH2 ||
hit.actor()->s->picnum == DIPSWITCH2 + 1 ||
hit.actor()->s->picnum == DIPSWITCH3 ||
hit.actor()->s->picnum == DIPSWITCH3 + 1 ||
(isRRRA() && hit.actor()->s->picnum == RRTILE8660) ||
hit.actor()->s->picnum == HANDSWITCH ||
hit.actor()->s->picnum == HANDSWITCH + 1))
{
fi.checkhitswitch(p, nullptr, hitsprt);
fi.checkhitswitch(p, nullptr, hit.actor());
return;
}
}
else if (wal != nullptr)
else if (hit.hitWall != nullptr)
{
spawn(spark, SMALLSMOKE);
if (fi.isadoorwall(wal->picnum) == 1)
if (fi.isadoorwall(hit.hitWall->picnum) == 1)
goto SKIPBULLETHOLE;
if (isablockdoor(wal->picnum) == 1)
if (isablockdoor(hit.hitWall->picnum) == 1)
goto SKIPBULLETHOLE;
if (p >= 0 && (
wal->picnum == DIPSWITCH ||
wal->picnum == DIPSWITCH + 1 ||
wal->picnum == DIPSWITCH2 ||
wal->picnum == DIPSWITCH2 + 1 ||
wal->picnum == DIPSWITCH3 ||
wal->picnum == DIPSWITCH3 + 1 ||
(isRRRA() && wal->picnum == RRTILE8660) ||
wal->picnum == HANDSWITCH ||
wal->picnum == HANDSWITCH + 1))
hit.hitWall->picnum == DIPSWITCH ||
hit.hitWall->picnum == DIPSWITCH + 1 ||
hit.hitWall->picnum == DIPSWITCH2 ||
hit.hitWall->picnum == DIPSWITCH2 + 1 ||
hit.hitWall->picnum == DIPSWITCH3 ||
hit.hitWall->picnum == DIPSWITCH3 + 1 ||
(isRRRA() && hit.hitWall->picnum == RRTILE8660) ||
hit.hitWall->picnum == HANDSWITCH ||
hit.hitWall->picnum == HANDSWITCH + 1))
{
fi.checkhitswitch(p, wal, nullptr);
fi.checkhitswitch(p, hit.hitWall, nullptr);
return;
}
if (wal->hitag != 0 || (wal->twoSided() && wal->nextWall()->hitag != 0))
if (hit.hitWall->hitag != 0 || (hit.hitWall->twoSided() && hit.hitWall->nextWall()->hitag != 0))
goto SKIPBULLETHOLE;
if (hitsectp != nullptr && hitsectp->lotag == 0)
if (wal->overpicnum != BIGFORCE)
if ((wal->twoSided() && wal->nextSector()->lotag == 0) ||
(!wal->twoSided() && hitsectp->lotag == 0))
if ((wal->cstat & 16) == 0)
if (hit.hitSector != nullptr && hit.hitSector->lotag == 0)
if (hit.hitWall->overpicnum != BIGFORCE)
if ((hit.hitWall->twoSided() && hit.hitWall->nextSector()->lotag == 0) ||
(!hit.hitWall->twoSided() && hit.hitSector->lotag == 0))
if ((hit.hitWall->cstat & 16) == 0)
{
if (wal->twoSided())
if (hit.hitWall->twoSided())
{
DukeSectIterator it(wal->nextSector());
DukeSectIterator it(hit.hitWall->nextSector());
while (auto l = it.Next())
{
if (l->s->statnum == 3 && l->s->lotag == 13)
@ -425,7 +413,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
if (l)
{
l->s->xvel = -1;
auto delta = wal->delta();
auto delta = hit.hitWall->delta();
l->s->ang = getangle(-delta.x, -delta.y) + 512;
ssp(l, CLIPMASK0);
}
@ -433,34 +421,34 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
SKIPBULLETHOLE:
if (wal->cstat & 2)
if (wal->twoSided())
if (hitz >= (wal->nextSector()->floorz))
wal = wal->nextWall();
if (hit.hitWall->cstat & 2)
if (hit.hitWall->twoSided())
if (hit.hitpos.z >= (hit.hitWall->nextSector()->floorz))
hit.hitWall = hit.hitWall->nextWall();
fi.checkhitwall(spark, wal, hitx, hity, hitz, SHOTSPARK1);
fi.checkhitwall(spark, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1);
}
}
else
{
spark = EGS(hitsectp, hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4);
spark = EGS(hit.hitSector, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4);
if (!spark) return;
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
if (hitsprt)
if (hit.actor())
{
fi.checkhitsprite(hitsprt, spark);
if (hitsprt->s->picnum != TILE_APLAYER)
fi.checkhitsprite(hit.actor(), spark);
if (hit.actor()->s->picnum != TILE_APLAYER)
spawn(spark, SMALLSMOKE);
else spark->s->xrepeat = spark->s->yrepeat = 0;
}
else if (wal != nullptr)
fi.checkhitwall(spark, wal, hitx, hity, hitz, SHOTSPARK1);
else if (hit.hitWall != nullptr)
fi.checkhitwall(spark, hit.hitWall, hit.hitpos.x, hit.hitpos.y, hit.hitpos.z, SHOTSPARK1);
}
if ((krand() & 255) < 10)
{
vec3_t v{ hitx, hity, hitz };
vec3_t v{ hit.hitpos.x, hit.hitpos.y, hit.hitpos.z };
S_PlaySound3D(PISTOL_RICOCHET, spark, &v);
}
}

View file

@ -102,6 +102,15 @@ struct DDukeActor : public DCoreActor
extern DDukeActor hittype[MAXSPRITES + 1];
inline DDukeActor* DDukeActor::array() { return hittype; }
// subclassed to add a game specific actor() method
struct HitInfo : public HitInfoBase
{
DDukeActor* actor() const
{
return static_cast<DDukeActor*>(hitActor);
}
};
struct animwalltype
{
walltype* wall;