From 8e89bc29e4a847133f11956b05e88c3ef82bfa56 Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@users.noreply.github.com>
Date: Thu, 20 Jan 2022 08:31:08 +0100
Subject: [PATCH] - new explosion flags

---
 source/games/duke/src/actors.cpp    |  4 ++--
 source/games/duke/src/actors_d.cpp  | 15 ++++-----------
 source/games/duke/src/actors_r.cpp  | 19 ++++---------------
 source/games/duke/src/constants.h   |  2 ++
 source/games/duke/src/flags_d.cpp   |  2 ++
 source/games/duke/src/flags_r.cpp   |  4 ++++
 source/games/duke/src/sectors_d.cpp | 24 +++++++-----------------
 source/games/duke/src/sectors_r.cpp | 27 +++++++--------------------
 8 files changed, 32 insertions(+), 65 deletions(-)

diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp
index 58b71658a..5edb5b758 100644
--- a/source/games/duke/src/actors.cpp
+++ b/source/games/duke/src/actors.cpp
@@ -985,7 +985,7 @@ void movemasterswitch(DDukeActor *actor)
 				}
 				else if (effector->spr.statnum == STAT_STANDABLE)
 				{
-					if (actorflag(effector, SFLAG2_BRIGHTEXPLODE)) // SEENINE and OOZFILTER
+					if (actorflag(effector, SFLAG2_BRIGHTEXPLODE)) // _SEENINE_ and _OOZFILTER_
 					{
 						effector->spr.shade = -31;
 					}
@@ -1186,7 +1186,7 @@ void moveooz(DDukeActor* actor, int seenine, int seeninedead, int ooz, int explo
 			DukeStatIterator it(STAT_STANDABLE);
 			while (auto act2 = it.Next())
 			{
-				if (actor->spr.hitag == act2->spr.hitag && (act2->spr.picnum == seenine || act2->spr.picnum == ooz))
+				if (actor->spr.hitag == act2->spr.hitag && actorflag(act2, SFLAG2_BRIGHTEXPLODE))
 					act2->spr.shade = -32;
 			}
 		}
diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp
index 008934489..a6327538f 100644
--- a/source/games/duke/src/actors_d.cpp
+++ b/source/games/duke/src/actors_d.cpp
@@ -632,22 +632,15 @@ int ifhitbyweapon_d(DDukeActor *actor)
 					}
 				}
 
-				switch(actor->attackertype)
+				if (attackerflag(actor, SFLAG2_DOUBLEDMGTHRUST))
 				{
-					case RADIUSEXPLOSION:
-					case RPG:
-					case HYDRENT:
-					case HEAVYHBOMB:
-					case SEENINE:
-					case OOZFILTER:
-					case EXPLODINGBARREL:
 						ps[p].vel.X += actor->hitextra * bcos(actor->hitang, 2);
 						ps[p].vel.Y += actor->hitextra * bsin(actor->hitang, 2);
-						break;
-					default:
+				}
+				else
+				{
 						ps[p].vel.X += actor->hitextra * bcos(actor->hitang, 1);
 						ps[p].vel.Y += actor->hitextra * bsin(actor->hitang, 1);
-						break;
 				}
 			}
 			else
diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp
index 5041a2a5b..ff4bf8a72 100644
--- a/source/games/duke/src/actors_r.cpp
+++ b/source/games/duke/src/actors_r.cpp
@@ -536,26 +536,15 @@ int ifhitbyweapon_r(DDukeActor *actor)
 					}
 				}
 
-				int pn = actor->attackertype;
-				if (pn == RPG2 && !isRRRA()) pn = 0; // avoid messing around with gotos.
-				switch (pn)
+				if (attackerflag(actor, SFLAG2_DOUBLEDMGTHRUST))
 				{
-				case RADIUSEXPLOSION:
-				case RPG:
-				case HYDRENT:
-				case HEAVYHBOMB:
-				case SEENINE:
-				case OOZFILTER:
-				case EXPLODINGBARREL:
-				case POWDERKEG:
-				case RPG2:
 					ps[p].vel.X += actor->hitextra * bcos(actor->hitang, 2);
 					ps[p].vel.Y += actor->hitextra * bsin(actor->hitang, 2);
-					break;
-				default:
+				}
+				else
+				{
 					ps[p].vel.X += actor->hitextra * bcos(actor->hitang, 1);
 					ps[p].vel.Y += actor->hitextra * bsin(actor->hitang, 1);
-					break;
 				}
 			}
 			else
diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h
index 674db35dc..be1b2d1e6 100644
--- a/source/games/duke/src/constants.h
+++ b/source/games/duke/src/constants.h
@@ -339,6 +339,8 @@ enum sflags2_t
 	SFLAG2_NOFLOORPAL			= 0x00000008,
 	SFLAG2_EXPLOSIVE			= 0x00000010,
 	SFLAG2_BRIGHTEXPLODE		= 0x00000020,
+	SFLAG2_DOUBLEDMGTHRUST		= 0x00000040,
+	SFLAG2_BREAKMIRRORS			= 0x00000080,
 };
 
 using EDukeFlags2 = TFlags<sflags2_t, uint32_t>;
diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp
index 97aac4a77..b388949b6 100644
--- a/source/games/duke/src/flags_d.cpp
+++ b/source/games/duke/src/flags_d.cpp
@@ -216,6 +216,8 @@ void initactorflags_d()
 	setflag(SFLAG2_NOFLOORPAL, { TRIPBOMB, LASERLINE });
 	setflag(SFLAG2_EXPLOSIVE, { FIREEXT, RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER });
 	setflag(SFLAG2_BRIGHTEXPLODE, { SEENINE, OOZFILTER });
+	setflag(SFLAG2_DOUBLEDMGTHRUST, { RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL });
+	setflag(SFLAG2_BREAKMIRRORS, { RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL });
 
 	if (isWorldTour())
 	{
diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp
index 1f0db3f98..51efc94bc 100644
--- a/source/games/duke/src/flags_r.cpp
+++ b/source/games/duke/src/flags_r.cpp
@@ -243,6 +243,10 @@ void initactorflags_r()
 	setflag(SFLAG2_EXPLOSIVE, {RPG, RADIUSEXPLOSION, SEENINE, OOZFILTER });
 	if (isRRRA()) setflag(SFLAG2_EXPLOSIVE, { RPG2 });
 	setflag(SFLAG2_BRIGHTEXPLODE, { SEENINE, OOZFILTER });
+	setflag(SFLAG2_DOUBLEDMGTHRUST, { RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL, POWDERKEG });
+	if (isRRRA()) setflag(SFLAG2_DOUBLEDMGTHRUST, { RPG2 });
+	setflag(SFLAG2_BREAKMIRRORS, { RADIUSEXPLOSION, RPG, HYDRENT, HEAVYHBOMB, SEENINE, OOZFILTER, EXPLODINGBARREL, POWDERKEG });
+	if (isRRRA()) setflag(SFLAG2_BREAKMIRRORS, { RPG2 });
 
 	// Animals were not supposed to have this, but due to a coding bug the logic was unconditional for everything in the game.
 	for (auto& ainf : gs.actorinfo)
diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp
index c7abb01e8..0a26bd210 100644
--- a/source/games/duke/src/sectors_d.cpp
+++ b/source/games/duke/src/sectors_d.cpp
@@ -644,24 +644,14 @@ void checkhitwall_d(DDukeActor* spr, walltype* wal, int x, int y, int z, int atw
 {
 	int j, sn = -1, darkestwall;
 
-	if (wal->overpicnum == MIRROR)
+	if (wal->overpicnum == MIRROR && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
 	{
-		switch (atwith)
-		{
-		case HEAVYHBOMB:
-		case RADIUSEXPLOSION:
-		case RPG:
-		case HYDRENT:
-		case SEENINE:
-		case OOZFILTER:
-		case EXPLODINGBARREL:
-			lotsofglass(spr, wal, 70);
-			wal->cstat &= ~CSTAT_WALL_MASKED;
-			wal->overpicnum = MIRRORBROKE;
-			wal->portalflags = 0;
-			S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-			return;
-		}
+		lotsofglass(spr, wal, 70);
+		wal->cstat &= ~CSTAT_WALL_MASKED;
+		wal->overpicnum = MIRRORBROKE;
+		wal->portalflags = 0;
+		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
+		return;
 	}
 
 	if (((wal->cstat & CSTAT_WALL_MASKED) || wal->overpicnum == BIGFORCE) && wal->twoSided())
diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp
index ee354dc6a..66de03619 100644
--- a/source/games/duke/src/sectors_r.cpp
+++ b/source/games/duke/src/sectors_r.cpp
@@ -985,27 +985,14 @@ void checkhitwall_r(DDukeActor* spr, walltype* wal, int x, int y, int z, int atw
 	int j;
 	int sn = -1, darkestwall;
 
-	if (wal->overpicnum == MIRROR)
+	if (wal->overpicnum == MIRROR && gs.actorinfo[atwith].flags2 & SFLAG2_BREAKMIRRORS)
 	{
-		switch (atwith)
-		{
-		case RPG2:
-			if (!isRRRA()) break;
-			[[fallthrough]];
-		case HEAVYHBOMB:
-		case RADIUSEXPLOSION:
-		case RPG:
-		case HYDRENT:
-		case SEENINE:
-		case OOZFILTER:
-		case EXPLODINGBARREL:
-			lotsofglass(spr, wal, 70);
-			wal->cstat &= ~CSTAT_WALL_MASKED;
-			wal->overpicnum = MIRRORBROKE;
-			wal->portalflags = 0;
-			S_PlayActorSound(GLASS_HEAVYBREAK, spr);
-			return;
-		}
+		lotsofglass(spr, wal, 70);
+		wal->cstat &= ~CSTAT_WALL_MASKED;
+		wal->overpicnum = MIRRORBROKE;
+		wal->portalflags = 0;
+		S_PlayActorSound(GLASS_HEAVYBREAK, spr);
+		return;
 	}
 
 	if (((wal->cstat & CSTAT_WALL_MASKED) || wal->overpicnum == BIGFORCE) && wal->twoSided())