From 19f4e4ff63cb47ddc7cfcc47dbac4ae20fa816a9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 29 Dec 2022 15:19:22 +0100 Subject: [PATCH] - added a new flag and split out the geometry destruction part from the hitradius functions ... which suddenly look a lot less menacing... --- source/core/thingdef_data.cpp | 1 + source/games/duke/src/actors.cpp | 45 +++++++++++++++++++ source/games/duke/src/actors_d.cpp | 39 +--------------- source/games/duke/src/actors_r.cpp | 39 +--------------- source/games/duke/src/constants.h | 1 + source/games/duke/src/funct.h | 1 + .../games/duke/actors/dukeweapons/rpg.zs | 20 +++++---- .../games/duke/actors/dukeweapons/shrinker.zs | 1 + 8 files changed, 64 insertions(+), 83 deletions(-) diff --git a/source/core/thingdef_data.cpp b/source/core/thingdef_data.cpp index 258cd5bcb..ae5c76627 100644 --- a/source/core/thingdef_data.cpp +++ b/source/core/thingdef_data.cpp @@ -178,6 +178,7 @@ static FFlagDef DukeActorFlagDefs[] = DEFINE_FLAG(SFLAG3, SPECIALINIT, DDukeActor, flags3), DEFINE_FLAG(SFLAG3, DONTLIGHTSHOOTER, DDukeActor, flags3), DEFINE_FLAG(SFLAG3, SHOOTCENTERED, DDukeActor, flags3), + DEFINE_FLAG(SFLAG3, NOCEILINGBLAST, DDukeActor, flags3), }; diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 4aed368d0..73389dcd8 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -807,6 +807,51 @@ void gutsdir(DDukeActor* actor, PClassActor* gtype, int n, int p) } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void blastceiling(DDukeActor* actor, double radius) +{ + BFSSectorSearch search(actor->sector()); + + while (auto dasectp = search.GetNext()) + { + if ((dasectp->ceilingz - actor->spr.pos.Z) < radius * 16) // what value range is this supposed to be? The check that was here did not multiply correctly + { + auto wal = dasectp->walls.Data(); + double d = (wal->pos - actor->spr.pos.XY()).Sum(); + if (d < radius) + checkhitceiling(dasectp); + else + { + auto thirdpoint = wal->point2Wall()->point2Wall(); + d = (thirdpoint->pos - actor->spr.pos.XY()).Sum(); + if (d < radius) + checkhitceiling(dasectp); + } + } + + for (auto& wal : dasectp->walls) + { + if ((wal.pos - actor->spr.pos.XY()).Sum() < radius) + { + if (wal.twoSided()) + { + search.Add(wal.nextSector()); + } + DVector3 w1(((wal.pos + wal.point2Wall()->pos) * 0.5 + actor->spr.pos) * 0.5, actor->spr.pos.Z); // half way between the actor and the wall's center. + sectortype* sect = wal.sectorp(); + updatesector(w1, §); + + if (sect && cansee(w1, sect, actor->spr.pos, actor->sector())) + checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z)); + } + } + } +} //--------------------------------------------------------------------------- // // Rotating sector diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index beb184373..a7625dc4a 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -152,44 +152,9 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h 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->spr.picnum != DTILE_SHRINKSPARK && !(actor->spr.picnum == DTILE_RPG && actor->spr.scale.X < 0.171875)) + if(!(actor->flags3 & SFLAG3_NOCEILINGBLAST)) { - BFSSectorSearch search(actor->sector()); - - while (auto dasectp = search.GetNext()) - { - if ((dasectp->ceilingz- actor->spr.pos.Z) < radius * 16) // what value range is this supposed to be? The check that was here did not multiply correctly - { - auto wal = dasectp->walls.Data(); - double d = (wal->pos - actor->spr.pos.XY()).Sum(); - if (d < radius) - checkhitceiling(dasectp); - else - { - auto thirdpoint = wal->point2Wall()->point2Wall(); - d = (thirdpoint->pos - actor->spr.pos.XY()).Sum(); - if (d < radius) - checkhitceiling(dasectp); - } - } - - for (auto& wal : dasectp->walls) - { - if ((wal.pos - actor->spr.pos.XY()).Sum() < radius) - { - if (wal.twoSided()) - { - search.Add(wal.nextSector()); - } - DVector3 w1(((wal.pos + wal.point2Wall()->pos) * 0.5 + actor->spr.pos) * 0.5, actor->spr.pos.Z); // half way between the actor and the wall's center. - sectortype* sect = wal.sectorp(); - updatesector(w1, §); - - if (sect && cansee(w1, sect, actor->spr.pos, actor->sector())) - checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z)); - } - } - } + blastceiling(actor, radius); } double q = zrand(32) - 16; diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 428af1ccf..746116561 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -151,44 +151,9 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h 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->spr.scale.X >= 0.17675 || !(actor->spr.picnum == RTILE_RPG || ((isRRRA()) && actor->spr.picnum == RTILE_RPG2))) + if (!(actor->flags3 & SFLAG3_NOCEILINGBLAST)) { - BFSSectorSearch search(actor->sector()); - - while (auto dasectp = search.GetNext()) - { - if ((dasectp->ceilingz- actor->spr.pos.Z) < radius * 16) // what value range is this supposed to be? The check that was here did not multiply correctly - { - auto wal = dasectp->walls.Data(); - double d = (wal->pos - actor->spr.pos.XY()).Sum(); - if (d < radius) - checkhitceiling(dasectp); - else - { - auto thirdpoint = wal->point2Wall()->point2Wall(); - d = (thirdpoint->pos - actor->spr.pos.XY()).Sum(); - if (d < radius) - checkhitceiling(dasectp); - } - } - - for (auto& wal : dasectp->walls) - { - if ((wal.pos - actor->spr.pos.XY()).Sum() < radius) - { - if (wal.twoSided()) - { - search.Add(wal.nextSector()); - } - DVector3 w1(((wal.pos + wal.point2Wall()->pos) * 0.5 + actor->spr.pos) * 0.5, actor->spr.pos.Z); // half way between the actor and the wall's center. - sectortype* sect = wal.sectorp(); - updatesector(w1, §); - - if (sect && cansee(w1, sect, actor->spr.pos, actor->sector())) - checkhitwall(actor, &wal, DVector3(wal.pos, actor->spr.pos.Z)); - } - } - } + blastceiling(actor, radius); } double q = zrand(32) - 24; diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index eb826bf14..ebd8d93ba 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -411,6 +411,7 @@ enum sflags3_t SFLAG3_SPECIALINIT = 0x00000200, // special aiming case for Duke's BOSS2 SFLAG3_DONTLIGHTSHOOTER = 0x00000400, SFLAG3_SHOOTCENTERED = 0x00000800, // enemies default to right hand shooting. This disables it. + SFLAG3_NOCEILINGBLAST = 0x00001000, // do not damage ceilings when exploding }; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 69018bf86..39234bcbb 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -40,6 +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 lotsofstuff(DDukeActor* s, int n, PClassActor* spawntype); void watersplash2(DDukeActor* i); bool money(DDukeActor* i, int BLOODPOOL); diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs index 138e0be75..c0534d22b 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs @@ -126,14 +126,14 @@ class DukeRPG : DukeProjectile else act90 = aimed; } - double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5) + 8; - double dist = (p.actor.pos.XY - aimed.pos.XY).Length(); - zvel = ((aimed.pos.Z - pos.Z - dal) * vel) / dist; - if (!(aimed.bSPECIALAUTOAIM)) - ang = (aimed.pos.XY - pos.XY).Angle(); - } - else - [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 40.5); + double dal = ((aimed.scale.X * aimed.spriteHeight()) * 0.5) + 8; + double dist = (p.actor.pos.XY - aimed.pos.XY).Length(); + zvel = ((aimed.pos.Z - pos.Z - dal) * vel) / dist; + if (!(aimed.bSPECIALAUTOAIM)) + ang = (aimed.pos.XY - pos.XY).Angle(); + } + else + [vel, zvel] = Raze.setFreeAimVelocity(vel, zvel, p.getPitchWithView(), 40.5); } else { @@ -186,6 +186,7 @@ class DukeRPG : DukeProjectile if (actor is 'RedneckHulk') { spawned.scale = (0.125, 0.125); + spawned.bNoCeilingBlast = true; } else if (actor is 'DukeBoss3') { @@ -233,11 +234,12 @@ class DukeRPG : DukeProjectile spawned.extra >>= 2; } } - else if (p.curr_weapon == DukeWpn.DEVISTATOR_WEAPON) + else if (p.curr_weapon == DukeWpn.DEVISTATOR_WEAPON && !Raze.isRR()) { spawned.extra >>= 2; spawned.Angle += frandom(-22.5 / 8, 22.5 / 8); spawned.vel.Z += frandom(-1, 1); + spawned.bNoCeilingBlast = true; if (p.hbomb_hold_delay) { diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs index aa290fbd4..de21221c6 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs @@ -67,6 +67,7 @@ class DukeShrinkSpark : DukeProjectile +FULLBRIGHT; +MIRRORREFLECT; +NOFLOORPAL; + +NOCEILINGBLAST; } override void posthiteffect(CollisionData coll)