diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 73389dcd8..b80213e9f 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -763,7 +763,7 @@ void detonate(DDukeActor *actor, PClassActor* explosion) { int x = actor->spr.extra; spawn(actor, explosion); - fi.hitradius(actor, gs.seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); + hitradius(actor, gs.seenineblastradius, x >> 2, x - (x >> 1), x - (x >> 2), x); S_PlayActorSound(PIPEBOMB_EXPLODE, actor); } @@ -852,6 +852,132 @@ void blastceiling(DDukeActor* actor, double radius) } } } + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void hitradius(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4) +{ + double radius = r * inttoworld; + static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; + + if (!(actor->flags3 & SFLAG3_NOCEILINGBLAST)) + { + blastceiling(actor, radius); + } + + double q = zrand(32) - (isRR() ? 24 : 16); + + auto Owner = actor->GetOwner(); + for (int x = 0; x < 7; x++) + { + DukeStatIterator itj(statlist[x]); + while (auto act2 = itj.Next()) + { + if (Owner) + { + if (Owner->isPlayer() && act2->isPlayer() && ud.coop != 0 && ud.ffire == 0 && Owner != act2 /* && (dmflags & NOFRIENDLYRADIUSDMG)*/) + { + continue; + } + + if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSPECIES && !Owner->isPlayer() && Owner->GetClass() == act2->GetClass()) + { + continue; + } + } + + if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY)) + { + if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)) + if ((actor->spr.pos - act2->spr.pos).Length() < radius) + { + if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector())) + continue; + checkhitsprite(act2, actor); + } + } + else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL))) + { + // this is a damage type check, not a projectile type check. + // It's also quite broken because it doesn't check for being shrunk but tries to guess it from the size. + // Unfortunately, with CON there is no way to retrieve proper shrunk state in any way. + if (actor->GetClass() == DukeShrinkSparkClass && (act2->spr.scale.X < 0.375)) + { + continue; + } + if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner) + { + continue; + } + if (actor->flags3 & SFLAG3_HITRADIUS_NOEFFECT) + { + continue; + } + + double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length(); + + if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector())) + { + act2->hitang = (act2->spr.pos - actor->spr.pos).Angle(); + act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra); + + if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE)) + { + if (dist < radius / 3) + { + if (hp4 == hp3) hp4++; + act2->hitextra = hp3 + (krand() % (hp4 - hp3)); + } + else if (dist < 2 * radius / 3) + { + if (hp3 == hp2) hp3++; + act2->hitextra = hp2 + (krand() % (hp3 - hp2)); + } + else if (dist < radius) + { + if (hp2 == hp1) hp2++; + act2->hitextra = hp1 + (krand() % (hp2 - hp1)); + } + + if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2)) + { + if (act2->vel.X < 0) act2->vel.X = 0; + act2->vel.X += ((actor->spr.extra / 4.)); + } + + if ((act2->flags1 & SFLAG_HITRADIUSCHECK)) + checkhitsprite(act2, actor); + } + else if (actor->spr.extra == 0) act2->hitextra = 0; + + if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS) + { + if (act2->isPlayer()) + { + int p = act2->PlayerIndex(); + + if (act2->attackertype == DukeFlamethrowerFlameClass && Owner->isPlayer()) + { + ps[p].numloogs = -1 - actor->spr.yint; + } + + if (ps[p].newOwner != nullptr) + { + clearcamera(&ps[p]); + } + } + act2->SetHitOwner(actor->GetOwner()); + } + } + } + } + } +} + //--------------------------------------------------------------------------- // // Rotating sector diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 135b8ad58..9ab5d01a6 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -147,120 +147,6 @@ int ifsquished(DDukeActor* actor, int p) // //--------------------------------------------------------------------------- -void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4) -{ - double radius = r * inttoworld; - static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; - - if(!(actor->flags3 & SFLAG3_NOCEILINGBLAST)) - { - blastceiling(actor, radius); - } - - double q = zrand(32) - 16; - - auto Owner = actor->GetOwner(); - for (int x = 0; x < 7; x++) - { - DukeStatIterator itj(statlist[x]); - while (auto act2 = itj.Next()) - { - if (Owner) - { - if (Owner->isPlayer() && act2->isPlayer() && ud.coop != 0 && ud.ffire == 0 && Owner != act2 /* && (dmflags & NOFRIENDLYRADIUSDMG)*/) - { - continue; - } - - if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSPECIES && !Owner->isPlayer() && Owner->GetClass() == act2->GetClass()) - { - continue; - } - } - - if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY)) - { - if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL)) - if ((actor->spr.pos - act2->spr.pos).Length() < radius) - { - if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector())) - continue; - checkhitsprite(act2, actor); - } - } - else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL))) - { - if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner) - { - continue; - } - - double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length(); - - if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector())) - { - act2->hitang = (act2->spr.pos - actor->spr.pos).Angle(); - act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra); - - if (!(actor->flags3 & SFLAG3_HITRADIUS_NODAMAGE)) - { - if (dist < radius / 3) - { - if (hp4 == hp3) hp4++; - act2->hitextra = hp3 + (krand() % (hp4 - hp3)); - } - else if (dist < 2 * radius / 3) - { - if (hp3 == hp2) hp3++; - act2->hitextra = hp2 + (krand() % (hp3 - hp2)); - } - else if (dist < radius) - { - if (hp2 == hp1) hp2++; - act2->hitextra = hp1 + (krand() % (hp2 - hp1)); - } - - if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2)) - { - if (act2->vel.X < 0) act2->vel.X = 0; - act2->vel.X += ( (actor->spr.extra / 4.)); - } - - if ((act2->flags1 & SFLAG_HITRADIUSCHECK)) - checkhitsprite(act2, actor); - } - else if (actor->spr.extra == 0) act2->hitextra = 0; - - if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS) - { - if (act2->isPlayer()) - { - int p = act2->PlayerIndex(); - - if (act2->attackertype == DukeFlamethrowerFlameClass && Owner->isPlayer()) - { - ps[p].numloogs = -1 - actor->spr.yint; - } - - if (ps[p].newOwner != nullptr) - { - clearcamera(&ps[p]); - } - } - act2->SetHitOwner(actor->GetOwner()); - } - } - } - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - int movesprite_ex_d(DDukeActor* actor, const DVector3& change, unsigned int cliptype, Collision &result) { diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 03011354f..a6dbd630d 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -146,102 +146,6 @@ void addweapon_r(player_struct* p, int weapon, bool wswitch) // //--------------------------------------------------------------------------- -void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4) -{ - double radius = r * inttoworld; - static const uint8_t statlist[] = { STAT_DEFAULT, STAT_ACTOR, STAT_STANDABLE, STAT_PLAYER, STAT_FALLER, STAT_ZOMBIEACTOR, STAT_MISC }; - - if (!(actor->flags3 & SFLAG3_NOCEILINGBLAST)) - { - blastceiling(actor, radius); - } - - double q = zrand(32) - 24; - - auto Owner = actor->GetOwner(); - for (int x = 0; x < 7; x++) - { - DukeStatIterator it1(statlist[x]); - while (auto act2 = it1.Next()) - { - if (x == 0 || x >= 5 || (act2->flags1 & SFLAG_HITRADIUS_CHECKHITONLY)) - { - if ((actor->spr.pos - act2->spr.pos).Length() < radius) - { - if (badguy(act2) && !cansee(act2->spr.pos.plusZ(q), act2->sector(), actor->spr.pos.plusZ(q), actor->sector())) - continue; - - checkhitsprite(act2, actor); - } - } - else if (act2->spr.extra >= 0 && act2 != actor && ((act2->flags1 & SFLAG_HITRADIUS_FORCEEFFECT) || badguy(act2) || (act2->spr.cstat & CSTAT_SPRITE_BLOCK_ALL))) - { - if (actor->flags3 & SFLAG3_HITRADIUS_DONTHURTSHOOTER && act2 == Owner) - { - continue; - } - if (actor->flags3 & SFLAG3_HITRADIUS_NOEFFECT) - { - continue; - } - - double dist = (act2->getPosWithOffsetZ() - actor->spr.pos).Length(); - - if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector())) - { - - act2->hitang = (act2->spr.pos - actor->spr.pos).Angle(); - act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra); - - if (dist < radius / 3) - { - if (hp4 == hp3) hp4++; - act2->hitextra = hp3 + (krand() % (hp4 - hp3)); - } - else if (dist < 2 * radius / 3) - { - if (hp3 == hp2) hp3++; - act2->hitextra = hp2 + (krand() % (hp3 - hp2)); - } - else if (dist < radius) - { - if (hp2 == hp1) hp2++; - act2->hitextra = hp1 + (krand() % (hp2 - hp1)); - } - - if (!(act2->flags2 & SFLAG2_NORADIUSPUSH) && !bossguy(act2)) - { - if (act2->vel.X < 0) act2->vel.X = 0; - act2->vel.X += ((actor->spr.extra / 4.)); - } - - if ((act2->flags1 & SFLAG_HITRADIUSCHECK)) - checkhitsprite(act2, actor); - - if (act2->GetClass() != DukeRadiusExplosionClass && Owner && Owner->spr.statnum < MAXSTATUS) - { - if (act2->isPlayer()) - { - int p = act2->PlayerIndex(); - if (ps[p].newOwner != nullptr) - { - clearcamera(&ps[p]); - } - } - act2->SetHitOwner(actor->GetOwner()); - } - } - } - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - int movesprite_ex_r(DDukeActor* actor, const DVector3& change, unsigned int cliptype, Collision &result) { int bg = badguy(actor); diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 62362b2c9..160b72fd1 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -46,8 +46,6 @@ void checksectors_r(int snum); void addweapon_d(player_struct* p, int weapon, bool wswitch); void addweapon_r(player_struct* p, int weapon, bool wswitch); -void hitradius_d(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); -void hitradius_r(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); void lotsofmoney_d(DDukeActor* s, int n); void lotsofmail_d(DDukeActor* s, int n); void lotsofpaper_d(DDukeActor* s, int n); @@ -97,7 +95,6 @@ void SetDispatcher() checksectors_d, addweapon_d, - hitradius_d, lotsofmoney_d, lotsofmail_d, lotsofpaper_d, @@ -128,7 +125,6 @@ void SetDispatcher() checksectors_r, addweapon_r, - hitradius_r, lotsoffeathers_r, lotsoffeathers_r, lotsoffeathers_r, diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index e42d6028a..0a41abec9 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -81,7 +81,6 @@ struct Dispatcher void (*checksectors)(int low); void (*addweapon)(player_struct *p, int weapon, bool wswitch); - void (*hitradius)(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); void (*lotsofmoney)(DDukeActor *s, int n); void (*lotsofmail)(DDukeActor *s, int n); void (*lotsofpaper)(DDukeActor *s, int n); diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 39234bcbb..fe9668e4a 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -40,7 +40,7 @@ void movefta(); void clearcameras(player_struct* p); void RANDOMSCRAP(DDukeActor* i); void detonate(DDukeActor* i, PClassActor* explosion); -void blastceiling(DDukeActor* actor, double radius); +void hitradius(DDukeActor* i, int r, int hp1, int hp2, int hp3, int hp4); void lotsofstuff(DDukeActor* s, int n, PClassActor* spawntype); void watersplash2(DDukeActor* i); bool money(DDukeActor* i, int BLOODPOOL); diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 6fe576fa6..10d708f4d 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -2017,7 +2017,7 @@ int ParseState::parse(void) insptr += 2; break; case concmd_hitradius: - fi.hitradius(g_ac, *(insptr + 1), *(insptr + 2), *(insptr + 3), *(insptr + 4), *(insptr + 5)); + hitradius(g_ac, *(insptr + 1), *(insptr + 2), *(insptr + 3), *(insptr + 4), *(insptr + 5)); insptr+=6; break; case concmd_ifp: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 9cee600da..ae3d177a8 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -549,12 +549,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, RandomScrap, RANDOMSCRAP) return 0; } -void DukeActor_hitradius(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int hp4) -{ - fi.hitradius(actor, r, hp1, hp2, hp3, hp4); -} - -DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, DukeActor_hitradius) +DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, hitradius) { PARAM_SELF_PROLOGUE(DDukeActor); PARAM_INT(r); @@ -562,7 +557,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, hitradius, DukeActor_hitradius) PARAM_INT(h2); PARAM_INT(h3); PARAM_INT(h4); - DukeActor_hitradius(self, r, h1, h2, h3, h4); + hitradius(self, r, h1, h2, h3, h4); return 0; }