mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-20 18:42:26 +00:00
- adapted all hitscan calls in Duke/RR.
This commit is contained in:
parent
129ce0aea8
commit
10dce7dd2d
7 changed files with 253 additions and 316 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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? §or[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? §or[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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue