From b418ac0acba5bec043a6612d7e43df4e4106ca18 Mon Sep 17 00:00:00 2001
From: TehRealSalt <tehrealsalt@gmail.com>
Date: Wed, 22 Mar 2017 12:59:16 -0400
Subject: [PATCH 1/4] Level completion emblems

Simple port of something I made for a 2.1 exe mod that Mystic mentioned
needed doing on the 2.2 Priorities topic
(http://mb.srb2.org/showpost.php?p=790613&postcount=4). Adds emblem type
"map", which gives you an emblem upon beating the map it's for. Var sets
more specific conditions; 1 for all emeralds completion, 2 for Ultimate
mode completion, 3 for Perfect Bonus completion. (These can be easily
removed if requested; these were added simply because it was easy to
implement for modders.)

Criticism on the way it's coded and/or how it is implemented is highly
encouraged. Test wad is <root>/TehRealSalt/levelemblems.wad,
pre-compiled exe is <root>/TehRealSalt/levelemblems.exe.
---
 src/dehacked.c |  2 ++
 src/m_cond.c   | 41 ++++++++++++++++++++++++++++++++++++++++-
 src/m_cond.h   |  2 ++
 src/m_menu.c   |  2 ++
 src/y_inter.c  | 11 +++++++++++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/src/dehacked.c b/src/dehacked.c
index 5ba5d75d4..cfc711fb2 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -2277,6 +2277,8 @@ static void reademblemdata(MYFILE *f, INT32 num)
 					emblemlocations[num-1].type = ET_NGRADE;
 				else if (fastcmp(word2, "NTIME"))
 					emblemlocations[num-1].type = ET_NTIME;
+				else if (fastcmp(word2, "MAP"))
+					emblemlocations[num-1].type = ET_MAP;
 				else
 					emblemlocations[num-1].type = (UINT8)value;
 			}
diff --git a/src/m_cond.c b/src/m_cond.c
index 5e23d4080..0955f9506 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -929,7 +929,7 @@ UINT8 M_CheckLevelEmblems(void)
 	// Update Score, Time, Rings emblems
 	for (i = 0; i < numemblems; ++i)
 	{
-		if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].collected)
+		if (emblemlocations[i].type <= ET_SKIN || emblemlocations[i].type == ET_MAP || emblemlocations[i].collected)
 			continue;
 
 		levelnum = emblemlocations[i].level;
@@ -963,6 +963,45 @@ UINT8 M_CheckLevelEmblems(void)
 	return somethingUnlocked;
 }
 
+UINT8 M_CompletionEmblems(void) // Bah! Duplication! :/
+{
+	INT32 i;
+	INT32 embtype;
+	INT16 levelnum;
+	UINT8 res;
+	UINT8 somethingUnlocked = 0;
+
+	for (i = 0; i < numemblems; ++i)
+	{
+		if (emblemlocations[i].type != ET_MAP || emblemlocations[i].collected)
+			continue;
+
+		levelnum = emblemlocations[i].level;
+		embtype = emblemlocations[i].var;
+
+		switch (embtype)
+		{
+			case 1: // Requires map to be beaten with all emeralds
+				res = ((mapvisited[levelnum - 1] & MV_ALLEMERALDS) == MV_ALLEMERALDS);
+				break;
+			case 2: // Requires map to be beaten in Ultimate mode
+				res = ((mapvisited[levelnum - 1] & MV_ULTIMATE) == MV_ULTIMATE);
+				break;
+			case 3: // Requires map to be beaten with a perfect bonus
+				res = ((mapvisited[levelnum - 1] & MV_PERFECT) == MV_PERFECT);
+				break;
+			default: // Requires map to be beaten, no special requirements
+				res = ((mapvisited[levelnum - 1] & MV_BEATEN) == MV_BEATEN);
+				break;
+		}
+
+		emblemlocations[i].collected = res;
+		if (res)
+			++somethingUnlocked;
+	}
+	return somethingUnlocked;
+}
+
 // -------------------
 // Quick unlock checks
 // -------------------
diff --git a/src/m_cond.h b/src/m_cond.h
index e61ff1f79..521e1d1f4 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -73,6 +73,7 @@ typedef struct
 #define ET_RINGS  4
 #define ET_NGRADE 5
 #define ET_NTIME  6
+#define ET_MAP    7
 
 typedef struct
 {
@@ -153,6 +154,7 @@ void M_CheckUnlockConditions(void);
 UINT8 M_UpdateUnlockablesAndExtraEmblems(void);
 void M_SilentUpdateUnlockablesAndEmblems(void);
 UINT8 M_CheckLevelEmblems(void);
+UINT8 M_CompletionEmblems(void);
 
 // Checking unlockable status
 UINT8 M_AnySecretUnlocked(void);
diff --git a/src/m_menu.c b/src/m_menu.c
index f682cd1b5..a269768cb 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -2940,6 +2940,8 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y)
 				curtype = 1; break;
 			case ET_NGRADE: case ET_NTIME:
 				curtype = 2; break;
+			case ET_MAP:
+				curtype = 3; break;
 			default:
 				curtype = 0; break;
 		}
diff --git a/src/y_inter.c b/src/y_inter.c
index 3b14f2837..2e8808d49 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -1007,6 +1007,10 @@ void Y_StartIntermission(void)
 
 				if (modeattacking == ATTACKING_RECORD)
 					Y_UpdateRecordReplays();
+				
+				UINT8 completionEmblems = M_CompletionEmblems();
+				if (completionEmblems)
+					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
 			}
 
 			for (i = 0; i < 4; ++i)
@@ -1106,6 +1110,13 @@ void Y_StartIntermission(void)
 			{
 				if (!stagefailed)
 					mapvisited[gamemap-1] |= MV_BEATEN;
+				
+				// all emeralds/ultimate/perfect emblems won't be possible in ss, oh well?
+				{
+					UINT8 completionEmblems = M_CompletionEmblems();
+					if (completionEmblems)
+						CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
+				}
 			}
 
 			// give out ring bonuses

From 92e785a9f2b01c34e5869e9429e429e31621d4a3 Mon Sep 17 00:00:00 2001
From: TehRealSalt <tehrealsalt@gmail.com>
Date: Wed, 22 Mar 2017 14:45:26 -0400
Subject: [PATCH 2/4] Map emblem type flags

As per toaster's request
---
 src/dehacked.c |  7 ++++++-
 src/m_cond.c   | 33 +++++++++++++++------------------
 src/m_cond.h   |  5 +++++
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/src/dehacked.c b/src/dehacked.c
index cfc711fb2..cc3f196a6 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -7426,7 +7426,12 @@ struct {
 	{"SF_X8AWAYSOUND",SF_X8AWAYSOUND},
 	{"SF_NOINTERRUPT",SF_NOINTERRUPT},
 	{"SF_X2AWAYSOUND",SF_X2AWAYSOUND},
-
+	
+	// Map emblem var flags
+	{"ME_ALLEMERALDS",ME_ALLEMERALDS},
+	{"ME_ULTIMATE",ME_ULTIMATE},
+	{"ME_PERFECT",ME_PERFECT},
+	
 #ifdef HAVE_BLUA
 	// p_local.h constants
 	{"FLOATSPEED",FLOATSPEED},
diff --git a/src/m_cond.c b/src/m_cond.c
index 0955f9506..14d678d8e 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -963,7 +963,7 @@ UINT8 M_CheckLevelEmblems(void)
 	return somethingUnlocked;
 }
 
-UINT8 M_CompletionEmblems(void) // Bah! Duplication! :/
+UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separate print when awarding emblems and it's sorta different enough.
 {
 	INT32 i;
 	INT32 embtype;
@@ -978,23 +978,20 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication! :/
 
 		levelnum = emblemlocations[i].level;
 		embtype = emblemlocations[i].var;
-
-		switch (embtype)
-		{
-			case 1: // Requires map to be beaten with all emeralds
-				res = ((mapvisited[levelnum - 1] & MV_ALLEMERALDS) == MV_ALLEMERALDS);
-				break;
-			case 2: // Requires map to be beaten in Ultimate mode
-				res = ((mapvisited[levelnum - 1] & MV_ULTIMATE) == MV_ULTIMATE);
-				break;
-			case 3: // Requires map to be beaten with a perfect bonus
-				res = ((mapvisited[levelnum - 1] & MV_PERFECT) == MV_PERFECT);
-				break;
-			default: // Requires map to be beaten, no special requirements
-				res = ((mapvisited[levelnum - 1] & MV_BEATEN) == MV_BEATEN);
-				break;
-		}
-
+		
+		UINT8 flags = MV_BEATEN;
+		
+		if (embtype & ME_ALLEMERALDS)
+			flags |= MV_ALLEMERALDS;
+		
+		if (embtype & ME_ULTIMATE)
+			flags |= MV_ULTIMATE;
+		
+		if (embtype & ME_PERFECT)
+			flags |= MV_PERFECT;
+		
+		res = ((mapvisited[levelnum - 1] & flags) == flags);
+		
 		emblemlocations[i].collected = res;
 		if (res)
 			++somethingUnlocked;
diff --git a/src/m_cond.h b/src/m_cond.h
index 521e1d1f4..94802f665 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -75,6 +75,11 @@ typedef struct
 #define ET_NTIME  6
 #define ET_MAP    7
 
+// Map emblem flags
+#define ME_ALLEMERALDS 1
+#define ME_ULTIMATE    2
+#define ME_PERFECT     4
+
 typedef struct
 {
 	UINT8 type;      ///< Emblem type

From 965846b0da68ae9624af98a4e768d4c641872e26 Mon Sep 17 00:00:00 2001
From: TehRealSalt <tehrealsalt@gmail.com>
Date: Thu, 23 Mar 2017 01:17:31 -0400
Subject: [PATCH 3/4] More consistency

As per MI's request
---
 src/y_inter.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/src/y_inter.c b/src/y_inter.c
index 2e8808d49..5548fe346 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -912,7 +912,8 @@ static void Y_UpdateRecordReplays(void)
 void Y_StartIntermission(void)
 {
 	INT32 i;
-
+	UINT8 completionEmblems = M_CompletionEmblems();
+	
 	intertic = -1;
 
 #ifdef PARANOIA
@@ -1008,7 +1009,6 @@ void Y_StartIntermission(void)
 				if (modeattacking == ATTACKING_RECORD)
 					Y_UpdateRecordReplays();
 				
-				UINT8 completionEmblems = M_CompletionEmblems();
 				if (completionEmblems)
 					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
 			}
@@ -1112,11 +1112,8 @@ void Y_StartIntermission(void)
 					mapvisited[gamemap-1] |= MV_BEATEN;
 				
 				// all emeralds/ultimate/perfect emblems won't be possible in ss, oh well?
-				{
-					UINT8 completionEmblems = M_CompletionEmblems();
-					if (completionEmblems)
-						CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
-				}
+				if (completionEmblems)
+					CONS_Printf(M_GetText("\x82" "Earned %hu emblem%s for level completion.\n"), (UINT16)completionEmblems, completionEmblems > 1 ? "s" : "");
 			}
 
 			// give out ring bonuses

From d7b4b05d9ad79a41165ff19bfed148b25193238d Mon Sep 17 00:00:00 2001
From: Monster Iestyn <iestynjealous@ntlworld.com>
Date: Tue, 28 Mar 2017 21:30:31 +0100
Subject: [PATCH 4/4] Fix remaining mixed-declaration-and-code issue detected
 when compiling

---
 src/m_cond.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/m_cond.c b/src/m_cond.c
index 14d678d8e..7f977c15d 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -970,6 +970,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
 	INT16 levelnum;
 	UINT8 res;
 	UINT8 somethingUnlocked = 0;
+	UINT8 flags;
 
 	for (i = 0; i < numemblems; ++i)
 	{
@@ -978,8 +979,7 @@ UINT8 M_CompletionEmblems(void) // Bah! Duplication sucks, but it's for a separa
 
 		levelnum = emblemlocations[i].level;
 		embtype = emblemlocations[i].var;
-		
-		UINT8 flags = MV_BEATEN;
+		flags = MV_BEATEN;
 		
 		if (embtype & ME_ALLEMERALDS)
 			flags |= MV_ALLEMERALDS;