- hitscan in player_r.cpp

This commit is contained in:
Christoph Oelckers 2021-11-18 00:01:29 +01:00
parent 1a11e445c3
commit d45ab528e6

View file

@ -88,9 +88,10 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
spritetype* const s = actor->s; spritetype* const s = actor->s;
int sect = s->sectnum; int sect = s->sectnum;
int zvel; int zvel;
int hitsect, hitwall;
int hitx, hity, hitz; int hitx, hity, hitz;
DDukeActor* hitsprt; DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
if (p >= 0) if (p >= 0)
{ {
@ -106,25 +107,24 @@ 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); sa = getangle(pspr->s->x - sx, pspr->s->y - sy);
} }
hitscanw(sx, sy, sz, sect, hitscan(sx, sy, sz, sect,
bcos(sa), bcos(sa),
bsin(sa), zvel << 6, bsin(sa), zvel << 6,
&hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
if (isRRRA() && hitsect >= 0 && ((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) if (isRRRA() && hitsectp != nullptr && ((hitsectp->lotag == 160 && zvel > 0) || (hitsectp->lotag == 161 && zvel < 0))
&& hitsprt == nullptr && hitwall == -1) && hitsprt == nullptr && wal == nullptr)
{ {
DukeLinearSpriteIterator its; DukeStatIterator its(STAT_EFFECTOR);
while (auto effector = its.Next()) while (auto effector = its.Next())
{ {
// shouldn't this only check STAT_EFFECTOR? if (effector->s->sector() == hitsectp && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
if (effector->s->sectnum == hitsect && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner() && effector->s->lotag == SE_7_TELEPORT)
&& effector->s->lotag == 7)
{ {
int nx, ny, nz; int nx, ny, nz;
nx = hitx + (effector->GetOwner()->s->x - effector->s->x); nx = hitx + (effector->GetOwner()->s->x - effector->s->x);
ny = hity + (effector->GetOwner()->s->y - effector->s->y); ny = hity + (effector->GetOwner()->s->y - effector->s->y);
if (sector[hitsect].lotag == 161) if (hitsectp->lotag == 161)
{ {
nz = effector->GetOwner()->getSector()->floorz; nz = effector->GetOwner()->getSector()->floorz;
} }
@ -132,28 +132,28 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
{ {
nz = effector->GetOwner()->getSector()->ceilingz; nz = effector->GetOwner()->getSector()->ceilingz;
} }
hitscanw(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6, hitscan(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6,
&hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
break; break;
} }
} }
} }
if (hitsect < 0) return; if (hitsectp == nullptr) return;
if ((abs(sx - hitx) + abs(sy - hity)) < 1024) if ((abs(sx - hitx) + abs(sy - hity)) < 1024)
{ {
if (hitwall >= 0 || hitsprt) if (wal != nullptr || hitsprt)
{ {
DDukeActor* wpn; DDukeActor* wpn;
if (isRRRA() && atwith == SLINGBLADE) if (isRRRA() && atwith == SLINGBLADE)
{ {
wpn = EGS(hitsect, hitx, hity, hitz, SLINGBLADE, -15, 0, 0, sa, 32, 0, actor, 4); wpn = EGS(sectnum(hitsectp), hitx, hity, hitz, SLINGBLADE, -15, 0, 0, sa, 32, 0, actor, 4);
wpn->s->extra += 50; wpn->s->extra += 50;
} }
else else
{ {
wpn = EGS(hitsect, hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, actor, 4); wpn = EGS(sectnum(hitsectp), hitx, hity, hitz, KNEE, -15, 0, 0, sa, 32, 0, actor, 4);
wpn->s->extra += (krand() & 7); wpn->s->extra += (krand() & 7);
} }
if (p >= 0) if (p >= 0)
@ -172,22 +172,21 @@ static void shootmelee(DDukeActor *actor, int p, int sx, int sy, int sz, int sa,
fi.checkhitsprite(hitsprt, wpn); fi.checkhitsprite(hitsprt, wpn);
if (p >= 0) fi.checkhitswitch(p, -1, hitsprt); if (p >= 0) fi.checkhitswitch(p, -1, hitsprt);
} }
else if (hitwall >= 0) else if (wal)
{ {
auto wal = &wall[hitwall];
if (wal->cstat & 2) if (wal->cstat & 2)
if (wal->nextsector >= 0) if (wal->nextsector >= 0)
if (hitz >= (wal->nextSector()->floorz)) if (hitz >= (wal->nextSector()->floorz))
wal = wal->nextWall(); wal = wal->nextWall();
if (/*hitwall >= 0 &&*/ wal->picnum != ACCESSSWITCH && wal->picnum != ACCESSSWITCH2) if (wal->picnum != ACCESSSWITCH && wal->picnum != ACCESSSWITCH2)
{ {
fi.checkhitwall(wpn, wal, hitx, hity, hitz, atwith); fi.checkhitwall(wpn, wal, hitx, hity, hitz, atwith);
if (p >= 0) fi.checkhitswitch(p, wallnum(wal), nullptr); if (p >= 0) fi.checkhitswitch(p, wallnum(wal), nullptr);
} }
} }
} }
else if (p >= 0 && zvel > 0 && sector[hitsect].lotag == 1) else if (p >= 0 && zvel > 0 && hitsectp->lotag == 1)
{ {
auto splash = spawn(ps[p].GetActor(), WATERSPLASH2); auto splash = spawn(ps[p].GetActor(), WATERSPLASH2);
splash->s->x = hitx; splash->s->x = hitx;
@ -211,9 +210,10 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
auto s = actor->s; auto s = actor->s;
int sect = s->sectnum; int sect = s->sectnum;
int zvel = 0; int zvel = 0;
int hitsect, hitwall;
int hitx, hity, hitz; int hitx, hity, hitz;
DDukeActor* hitsprt; DDukeActor* hitsprt;
sectortype* hitsectp;
walltype* wal;
if (s->extra >= 0) s->shade = -96; if (s->extra >= 0) s->shade = -96;
@ -266,23 +266,22 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
} }
s->cstat &= ~257; s->cstat &= ~257;
hitscanw(sx, sy, sz, sect, bcos(sa), bsin(sa), hitscan(sx, sy, sz, sect, bcos(sa), bsin(sa),
zvel << 6, &hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); zvel << 6, &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
if (isRRRA() && hitsect >= 0 && (((sector[hitsect].lotag == 160 && zvel > 0) || (sector[hitsect].lotag == 161 && zvel < 0)) if (isRRRA() && hitsectp != nullptr && (((hitsectp->lotag == 160 && zvel > 0) || (hitsectp->lotag == 161 && zvel < 0))
&& hitsprt == nullptr && hitwall == -1)) && hitsprt == nullptr && wal == nullptr))
{ {
DukeLinearSpriteIterator its; DukeStatIterator its(STAT_EFFECTOR);
while (auto effector = its.Next()) while (auto effector = its.Next())
{ {
// shouldn't this only check STAT_EFFECTOR? if (effector->s->sector() == hitsectp && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner()
if (effector->s->sectnum == hitsect && effector->s->picnum == SECTOREFFECTOR && effector->GetOwner() && effector->s->lotag == SE_7_TELEPORT)
&& effector->s->lotag == 7)
{ {
int nx, ny, nz; int nx, ny, nz;
nx = hitx + (effector->GetOwner()->s->x - effector->s->x); nx = hitx + (effector->GetOwner()->s->x - effector->s->x);
ny = hity + (effector->GetOwner()->s->y - effector->s->y); ny = hity + (effector->GetOwner()->s->y - effector->s->y);
if (sector[hitsect].lotag == 161) if (hitsectp->lotag == 161)
{ {
nz = effector->GetOwner()->getSector()->floorz; nz = effector->GetOwner()->getSector()->floorz;
} }
@ -290,8 +289,8 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
{ {
nz = effector->GetOwner()->getSector()->ceilingz; nz = effector->GetOwner()->getSector()->ceilingz;
} }
hitscanw(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6, hitscan(nx, ny, nz, effector->GetOwner()->s->sectnum, bcos(sa), bsin(sa), zvel << 6,
&hitsect, &hitwall, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1); &hitsectp, &wal, &hitsprt, &hitx, &hity, &hitz, CLIPMASK1);
break; break;
} }
} }
@ -299,37 +298,37 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
s->cstat |= 257; s->cstat |= 257;
if (hitsect < 0) return; if (hitsectp == nullptr) return;
if (atwith == SHOTGUN) if (atwith == SHOTGUN)
if (sector[hitsect].lotag == 1) if (hitsectp->lotag == 1)
if (krand() & 1) if (krand() & 1)
return; return;
if ((krand() & 15) == 0 && sector[hitsect].lotag == 2) if ((krand() & 15) == 0 && hitsectp->lotag == 2)
tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1)); tracers(hitx, hity, hitz, sx, sy, sz, 8 - (ud.multimode >> 1));
DDukeActor* spark; DDukeActor* spark;
if (p >= 0) if (p >= 0)
{ {
spark = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4); spark = EGS(sectnum(hitsectp), hitx, hity, hitz, SHOTSPARK1, -15, 10, 10, sa, 0, 0, actor, 4);
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress]; spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
spark->s->extra += (krand() % 6); spark->s->extra += (krand() % 6);
if (hitwall == -1 && hitsprt == nullptr) if (wal == nullptr && hitsprt == nullptr)
{ {
if (zvel < 0) if (zvel < 0)
{ {
if (sector[hitsect].ceilingstat & 1) if (hitsectp->ceilingstat & 1)
{ {
spark->s->xrepeat = 0; spark->s->xrepeat = 0;
spark->s->yrepeat = 0; spark->s->yrepeat = 0;
return; return;
} }
else else
fi.checkhitceiling(hitsect); fi.checkhitceiling(sectnum(hitsectp));
} }
if (sector[hitsect].lotag != 1) if (hitsectp->lotag != 1)
spawn(spark, SMALLSMOKE); spawn(spark, SMALLSMOKE);
} }
@ -364,10 +363,9 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
return; return;
} }
} }
else if (hitwall >= 0) else if (wal != nullptr)
{ {
spawn(spark, SMALLSMOKE); spawn(spark, SMALLSMOKE);
auto wal = &wall[hitwall];
if (fi.isadoorwall(wal->picnum) == 1) if (fi.isadoorwall(wal->picnum) == 1)
goto SKIPBULLETHOLE; goto SKIPBULLETHOLE;
@ -384,17 +382,17 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
wal->picnum == HANDSWITCH || wal->picnum == HANDSWITCH ||
wal->picnum == HANDSWITCH + 1)) wal->picnum == HANDSWITCH + 1))
{ {
fi.checkhitswitch(p, hitwall, nullptr); fi.checkhitswitch(p, wallnum(wal), nullptr);
return; return;
} }
if (wal->hitag != 0 || (wal->nextwall >= 0 && wal->nextWall()->hitag != 0)) if (wal->hitag != 0 || (wal->nextwall >= 0 && wal->nextWall()->hitag != 0))
goto SKIPBULLETHOLE; goto SKIPBULLETHOLE;
if (hitsect >= 0 && sector[hitsect].lotag == 0) if (hitsectp != nullptr && hitsectp->lotag == 0)
if (wal->overpicnum != BIGFORCE) if (wal->overpicnum != BIGFORCE)
if ((wal->nextsector >= 0 && wal->nextSector()->lotag == 0) || if ((wal->nextsector >= 0 && wal->nextSector()->lotag == 0) ||
(wal->nextsector == -1 && sector[hitsect].lotag == 0)) (wal->nextsector == -1 && hitsectp->lotag == 0))
if ((wal->cstat & 16) == 0) if ((wal->cstat & 16) == 0)
{ {
if (wal->nextsector >= 0) if (wal->nextsector >= 0)
@ -433,7 +431,7 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
} }
else else
{ {
spark = EGS(hitsect, hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4); spark = EGS(sectnum(hitsectp), hitx, hity, hitz, SHOTSPARK1, -15, 24, 24, sa, 0, 0, actor, 4);
spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress]; spark->s->extra = ScriptCode[gs.actorinfo[atwith].scriptaddress];
if (hitsprt) if (hitsprt)
@ -443,8 +441,8 @@ static void shootweapon(DDukeActor* actor, int p, int sx, int sy, int sz, int sa
spawn(spark, SMALLSMOKE); spawn(spark, SMALLSMOKE);
else spark->s->xrepeat = spark->s->yrepeat = 0; else spark->s->xrepeat = spark->s->yrepeat = 0;
} }
else if (hitwall >= 0) else if (wal != nullptr)
fi.checkhitwall(spark, &wall[hitwall], hitx, hity, hitz, SHOTSPARK1); fi.checkhitwall(spark, wal, hitx, hity, hitz, SHOTSPARK1);
} }
if ((krand() & 255) < 10) if ((krand() & 255) < 10)