From 8a965687d3a58c214490d4f3b8b381e5426dc3ce Mon Sep 17 00:00:00 2001
From: Juliano Leal Goncalves <julealgon@gmail.com>
Date: Wed, 29 Sep 2021 01:17:14 -0300
Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Remove=20multiple=20game=20diffi?=
 =?UTF-8?q?culties?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CMakeLists.txt              |   2 +-
 Source/DiabloUI/diabloui.h  |   3 +-
 Source/DiabloUI/selgame.cpp | 162 ------------------------------------
 Source/DiabloUI/selgame.h   |  15 ----
 Source/DiabloUI/selhero.cpp |  18 +---
 Source/diablo.cpp           |   9 +-
 Source/gendung.h            |   6 --
 Source/items.cpp            |  13 +--
 Source/loadsave.cpp         |  21 +++--
 Source/menu.cpp             |   3 +-
 Source/monster.cpp          | 101 +---------------------
 Source/multi.h              |   1 -
 Source/pack.cpp             |   4 -
 Source/pack.h               |   4 +-
 Source/pfile.cpp            |   1 -
 Source/player.cpp           |   2 -
 Source/player.h             |   2 -
 17 files changed, 24 insertions(+), 343 deletions(-)
 delete mode 100644 Source/DiabloUI/selgame.cpp
 delete mode 100644 Source/DiabloUI/selgame.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9141c05b1f5..eea702d3726 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -324,7 +324,7 @@ set(libdevilutionx_SRCS
   Source/DiabloUI/progress.cpp
   Source/DiabloUI/scrollbar.cpp
   
-  Source/DiabloUI/selgame.cpp
+  
   Source/DiabloUI/selhero.cpp
   Source/DiabloUI/selok.cpp
   Source/DiabloUI/selyesno.cpp
diff --git a/Source/DiabloUI/diabloui.h b/Source/DiabloUI/diabloui.h
index 9dac0bc921f..858fb040910 100644
--- a/Source/DiabloUI/diabloui.h
+++ b/Source/DiabloUI/diabloui.h
@@ -55,7 +55,6 @@ struct _uiheroinfo {
 	char name[16];
 	uint8_t level;
 	HeroClass heroclass;
-	uint8_t herorank;
 	uint16_t strength;
 	uint16_t magic;
 	uint16_t dexterity;
@@ -83,7 +82,7 @@ inline SDL_Surface *DiabloUiSurface()
 void UiDestroy();
 void UiTitleDialog();
 void UiInitialize();
-void UiSelHeroSingDialog(bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), bool (*fncreate)(_uiheroinfo *), bool (*fnremove)(_uiheroinfo *), void (*fnstats)(unsigned int, _uidefaultstats *), _selhero_selections *dlgresult, uint32_t *saveNumber, _difficulty *difficulty);
+void UiSelHeroSingDialog(bool (*fninfo)(bool (*fninfofunc)(_uiheroinfo *)), bool (*fncreate)(_uiheroinfo *), bool (*fnremove)(_uiheroinfo *), void (*fnstats)(unsigned int, _uidefaultstats *), _selhero_selections *dlgresult, uint32_t *saveNumber);
 bool UiCreditsDialog();
 bool UiSupportDialog();
 bool UiMainMenuDialog(const char *name, _mainmenu_selections *pdwResult, void (*fnSound)(const char *file), int attractTimeOut);
diff --git a/Source/DiabloUI/selgame.cpp b/Source/DiabloUI/selgame.cpp
deleted file mode 100644
index d355fa131eb..00000000000
--- a/Source/DiabloUI/selgame.cpp
+++ /dev/null
@@ -1,162 +0,0 @@
-#include "selgame.h"
-
-#include <fmt/format.h>
-
-#include "DiabloUI/diabloui.h"
-#include "DiabloUI/dialogs.h"
-#include "DiabloUI/selhero.h"
-#include "DiabloUI/selok.h"
-#include "config.h"
-#include "control.h"
-#include "menu.h"
-#include "options.h"
-#include "storm/storm.h"
-
-namespace devilution {
-
-char selgame_Label[32];
-char selgame_Ip[129] = "";
-char selgame_Password[16] = "";
-char selgame_Description[256];
-bool selgame_enteringGame;
-bool selgame_endMenu;
-int *gdwPlayerId;
-_difficulty nDifficulty;
-int nTickRate;
-int heroLevel;
-
-static GameData *m_game_data;
-extern int provider;
-
-#define DESCRIPTION_WIDTH 205
-
-namespace {
-
-const char *title = "";
-
-std::vector<std::unique_ptr<UiListItem>> vecSelGameDlgItems;
-std::vector<std::unique_ptr<UiItemBase>> vecSelGameDialog;
-
-} // namespace
-
-void selgame_FreeVectors()
-{
-	vecSelGameDlgItems.clear();
-
-	vecSelGameDialog.clear();
-}
-
-void selgame_Free()
-{
-	ArtBackground.Unload();
-
-	selgame_FreeVectors();
-}
-
-/**
- * @brief Load the current hero level from save file
- * @param pInfo Hero info
- * @return always true
- */
-bool UpdateHeroLevel(_uiheroinfo *pInfo)
-{
-	if (pInfo->saveNumber == gSaveNumber)
-		heroLevel = pInfo->level;
-
-	return true;
-}
-
-void selgame_GameSelection_Select()
-{
-	selgame_enteringGame = true;
-
-	gfnHeroInfo(UpdateHeroLevel);
-
-	selgame_FreeVectors();
-
-	UiAddBackground(&vecSelGameDialog);
-	UiAddLogo(&vecSelGameDialog);
-
-	SDL_Rect rect1 = { (Sint16)(PANEL_LEFT + 24), (Sint16)(UI_OFFSET_Y + 161), 590, 35 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtText>(&title, rect1, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
-
-	SDL_Rect rect2 = { (Sint16)(PANEL_LEFT + 34), (Sint16)(UI_OFFSET_Y + 211), 205, 33 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Label, rect2, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
-
-	SDL_Rect rect3 = { (Sint16)(PANEL_LEFT + 35), (Sint16)(UI_OFFSET_Y + 256), DESCRIPTION_WIDTH, 192 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtText>(selgame_Description, rect3, UiFlags::FontSize12 | UiFlags::ColorUiSilverDark, 1, 16));
-
-	title = "Create Game";
-
-	SDL_Rect rect4 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 211), 295, 35 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtText>("Select Difficulty", rect4, UiFlags::AlignCenter | UiFlags::FontSize30 | UiFlags::ColorUiSilver, 3));
-
-	vecSelGameDlgItems.push_back(std::make_unique<UiListItem>("Normal", DIFF_NORMAL));
-	vecSelGameDlgItems.push_back(std::make_unique<UiListItem>("Nightmare", DIFF_NIGHTMARE));
-	vecSelGameDlgItems.push_back(std::make_unique<UiListItem>("Hell", DIFF_HELL));
-
-	vecSelGameDialog.push_back(std::make_unique<UiList>(vecSelGameDlgItems, PANEL_LEFT + 300, (UI_OFFSET_Y + 282), 295, 26, UiFlags::AlignCenter | UiFlags::FontSize24 | UiFlags::ColorUiGold));
-
-	SDL_Rect rect5 = { (Sint16)(PANEL_LEFT + 299), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>("OK", &UiFocusNavigationSelect, rect5, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
-
-	SDL_Rect rect6 = { (Sint16)(PANEL_LEFT + 449), (Sint16)(UI_OFFSET_Y + 427), 140, 35 };
-	vecSelGameDialog.push_back(std::make_unique<UiArtTextButton>("CANCEL", &UiFocusNavigationEsc, rect6, UiFlags::AlignCenter | UiFlags::VerticalCenter | UiFlags::FontSize30 | UiFlags::ColorUiGold));
-
-	UiInitList(vecSelGameDlgItems.size(), selgame_Diff_Focus, selgame_Diff_Select, selgame_Diff_Esc, vecSelGameDialog, true);
-}
-
-void selgame_GameSelection_Esc()
-{
-	UiInitList_clear();
-	selgame_enteringGame = false;
-	selgame_endMenu = true;
-}
-
-void selgame_Diff_Focus(int value)
-{
-	switch (vecSelGameDlgItems[value]->m_value) {
-	case DIFF_NORMAL:
-		strncpy(selgame_Label, "Normal", sizeof(selgame_Label) - 1);
-		strncpy(selgame_Description, "Normal Difficulty\nThis is where a starting character should begin the quest to defeat Diablo.", sizeof(selgame_Description) - 1);
-		break;
-	case DIFF_NIGHTMARE:
-		strncpy(selgame_Label, "Nightmare", sizeof(selgame_Label) - 1);
-		strncpy(selgame_Description, "Nightmare Difficulty\nThe denizens of the Labyrinth have been bolstered and will prove to be a greater challenge. This is recommended for experienced characters only.", sizeof(selgame_Description) - 1);
-		break;
-	case DIFF_HELL:
-		strncpy(selgame_Label, "Hell", sizeof(selgame_Label) - 1);
-		strncpy(selgame_Description, "Hell Difficulty\nThe most powerful of the underworld's creatures lurk at the gateway into Hell. Only the most experienced characters should venture in this realm.", sizeof(selgame_Description) - 1);
-		break;
-	}
-	WordWrapString(selgame_Description, DESCRIPTION_WIDTH);
-}
-
-void selgame_Diff_Select(int value)
-{
-	nDifficulty = (_difficulty)vecSelGameDlgItems[value]->m_value;
-
-	// This is part of a dangerous hack to enable difficulty selection in single-player.
-	// FIXME: Dialogs should not refer to each other's variables.
-
-	// We're in the selhero loop instead of the selgame one.
-	// Free the selgame data and flag the end of the selhero loop.
-	selhero_endMenu = true;
-
-	// We only call FreeVectors because ArtBackground.Unload()
-	// will be called by selheroFree().
-	selgame_FreeVectors();
-
-	// We must clear the InitList because selhero's loop will perform
-	// one more iteration after this function exits.
-	UiInitList_clear();
-}
-
-void selgame_Diff_Esc()
-{
-	selgame_Free();
-
-	selhero_Init();
-	selhero_List_Init();
-}
-} // namespace devilution
diff --git a/Source/DiabloUI/selgame.h b/Source/DiabloUI/selgame.h
deleted file mode 100644
index db146b28f29..00000000000
--- a/Source/DiabloUI/selgame.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-#include "gendung.h"
-
-namespace devilution {
-
-extern _difficulty nDifficulty;
-
-void selgame_GameSelection_Select();
-void selgame_GameSelection_Esc();
-void selgame_Diff_Focus(int value);
-void selgame_Diff_Select(int value);
-void selgame_Diff_Esc();
-
-} // namespace devilution
diff --git a/Source/DiabloUI/selhero.cpp b/Source/DiabloUI/selhero.cpp
index 66b6e9748ee..8a3c1ca16ff 100644
--- a/Source/DiabloUI/selhero.cpp
+++ b/Source/DiabloUI/selhero.cpp
@@ -9,7 +9,6 @@
 #include "DiabloUI/diabloui.h"
 #include "DiabloUI/dialogs.h"
 #include "DiabloUI/scrollbar.h"
-#include "DiabloUI/selgame.h"
 #include "DiabloUI/selok.h"
 #include "DiabloUI/selyesno.h"
 #include "control.h"
@@ -307,19 +306,8 @@ void SelheroLoadSelect(int value)
 		return;
 	}
 
-	// This is part of a dangerous hack to enable difficulty selection in single-player.
-	// FIXME: Dialogs should not refer to each other's variables.
-
-	// We disable `selhero_endMenu` and replace the background and art
-	// and the item list with the difficulty selection ones.
-	//
-	// This means selhero's render loop will render selgame's items,
-	// which happens to work because the render loops are similar.
-	selhero_endMenu = false;
 	SelheroFree();
-	LoadBackgroundArt("ui_art\\selgame.pcx");
-	selgame_GameSelection_Select();
-
+	selhero_endMenu = true;
 	selhero_result = SELHERO_NEW_DUNGEON;
 }
 
@@ -472,11 +460,9 @@ void UiSelHeroSingDialog(
     bool (*fnremove)(_uiheroinfo *),
     void (*fnstats)(unsigned int, _uidefaultstats *),
     _selhero_selections *dlgresult,
-    uint32_t *saveNumber,
-    _difficulty *difficulty)
+    uint32_t *saveNumber)
 {
 	UiSelHeroDialog(fninfo, fncreate, fnstats, fnremove, dlgresult, saveNumber);
-	*difficulty = nDifficulty;
 }
 
 } // namespace devilution
diff --git a/Source/diablo.cpp b/Source/diablo.cpp
index 66c15807027..cd277d46fb5 100644
--- a/Source/diablo.cpp
+++ b/Source/diablo.cpp
@@ -1340,13 +1340,8 @@ void InitKeymapActions()
 	    'V',
 	    [] {
 		    char pszStr[120];
-		    const char *difficulties[3] = {
-			    "Normal",
-			    "Nightmare",
-			    "Hell",
-		    };
-		    strcpy(pszStr, fmt::format("{:s}, version = {:s}, mode = {:s}",
-		                       gszProductName, PROJECT_VERSION, difficulties[sgGameInitInfo.nDifficulty])
+		    strcpy(pszStr, fmt::format("{:s}, version = {:s}",
+		                       gszProductName, PROJECT_VERSION)
 		                       .c_str());
 		    NetSendCmdString(1 << MyPlayerId, pszStr);
 	    },
diff --git a/Source/gendung.h b/Source/gendung.h
index 8ab4396404b..290d4b7b399 100644
--- a/Source/gendung.h
+++ b/Source/gendung.h
@@ -78,12 +78,6 @@ enum {
 	// clang-format on
 };
 
-enum _difficulty : uint8_t {
-	DIFF_NORMAL,
-	DIFF_NIGHTMARE,
-	DIFF_HELL,
-};
-
 struct ScrollStruct {
 	/** @brief Tile offset of camera. */
 	Point tile;
diff --git a/Source/items.cpp b/Source/items.cpp
index fbf53268bba..1b0e74d3559 100644
--- a/Source/items.cpp
+++ b/Source/items.cpp
@@ -3218,19 +3218,8 @@ void GetItemAttrs(Item &item, int itemData, int lvl)
 	if (item._itype != ItemType::Gold)
 		return;
 
-	int rndv;
 	int itemlevel = ItemsGetCurrlevel();
-	switch (sgGameInitInfo.nDifficulty) {
-	case DIFF_NORMAL:
-		rndv = 5 * itemlevel + GenerateRnd(10 * itemlevel);
-		break;
-	case DIFF_NIGHTMARE:
-		rndv = 5 * (itemlevel + 16) + GenerateRnd(10 * (itemlevel + 16));
-		break;
-	case DIFF_HELL:
-		rndv = 5 * (itemlevel + 32) + GenerateRnd(10 * (itemlevel + 32));
-		break;
-	}
+	int rndv = 5 * itemlevel + GenerateRnd(10 * itemlevel);
 	if (leveltype == DTYPE_HELL)
 		rndv += rndv / 8;
 
diff --git a/Source/loadsave.cpp b/Source/loadsave.cpp
index 33a22b328b8..7012a6fc2ba 100644
--- a/Source/loadsave.cpp
+++ b/Source/loadsave.cpp
@@ -525,8 +525,12 @@ void LoadPlayer(LoadHelper &file, Player &player)
 	player.wReflections = file.NextLE<uint16_t>();
 	file.Skip(14); // Available bytes
 
-	player.pDiabloKillLevel = file.NextLE<uint32_t>();
-	player.pDifficulty = static_cast<_difficulty>(file.NextLE<uint32_t>());
+	// Skip Diablo kill level
+	file.Skip<uint32_t>();
+
+	// Skip difficulty
+	file.Skip<uint32_t>();
+
 	player.pDamAcFlags = file.NextLE<uint32_t>();
 	file.Skip(20); // Available bytes
 	CalcPlrItemVals(player, false);
@@ -1195,8 +1199,12 @@ void SavePlayer(SaveHelper &file, const Player &player)
 	file.WriteLE<uint16_t>(player.wReflections);
 	file.Skip(14); // Available bytes
 
-	file.WriteLE<uint32_t>(player.pDiabloKillLevel);
-	file.WriteLE<uint32_t>(player.pDifficulty);
+	// Skip Diablo kill level
+	file.Skip<uint32_t>();
+
+	// Skip difficulty
+	file.Skip<uint32_t>();
+
 	file.WriteLE<uint32_t>(player.pDamAcFlags);
 	file.Skip(20); // Available bytes
 
@@ -1648,10 +1656,6 @@ void LoadGame(bool firstflag)
 
 	LoadPlayer(file, myPlayer);
 
-	sgGameInitInfo.nDifficulty = myPlayer.pDifficulty;
-	if (sgGameInitInfo.nDifficulty < DIFF_NORMAL || sgGameInitInfo.nDifficulty > DIFF_HELL)
-		sgGameInitInfo.nDifficulty = DIFF_NORMAL;
-
 	for (int i = 0; i < giNumberQuests; i++)
 		LoadQuest(&file, i);
 	for (int i = 0; i < MAXPORTAL; i++)
@@ -1861,7 +1865,6 @@ void SaveGameData()
 	}
 
 	auto &myPlayer = Players[MyPlayerId];
-	myPlayer.pDifficulty = sgGameInitInfo.nDifficulty;
 	SavePlayer(file, myPlayer);
 
 	for (int i = 0; i < giNumberQuests; i++)
diff --git a/Source/menu.cpp b/Source/menu.cpp
index 0440499a73c..56c08b70ad9 100644
--- a/Source/menu.cpp
+++ b/Source/menu.cpp
@@ -73,8 +73,7 @@ bool mainmenu_select_hero_dialog(GameData *gameData)
 		pfile_delete_save,
 		pfile_ui_set_class_stats,
 		&dlgresult,
-		&gSaveNumber,
-		&gameData->nDifficulty);
+		&gSaveNumber);
 
 	gbLoadGame = (dlgresult == SELHERO_CONTINUE);
 
diff --git a/Source/monster.cpp b/Source/monster.cpp
index 6812f4e4466..8ae85e5f8e3 100644
--- a/Source/monster.cpp
+++ b/Source/monster.cpp
@@ -50,12 +50,6 @@ bool sgbSaveSoundOn;
 
 namespace {
 
-#define NIGHTMARE_TO_HIT_BONUS 85
-#define HELL_TO_HIT_BONUS 120
-
-#define NIGHTMARE_AC_BONUS 50
-#define HELL_AC_BONUS 80
-
 /** Tracks which missile files are already loaded */
 int totalmonsters;
 int monstimgtot;
@@ -208,38 +202,6 @@ void InitMonster(Monster &monster, Direction rd, int mtype, Point position)
 		monster._mFlags |= MFLAG_ALLOW_SPECIAL;
 		monster._mmode = MonsterMode::SpecialMeleeAttack;
 	}
-
-	if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
-		monster._mmaxhp = 3 * monster._mmaxhp;
-		monster._mmaxhp += 64;
-		monster._mhitpoints = monster._mmaxhp;
-		monster.mLevel += 15;
-		monster.mExp = 2 * (monster.mExp + 1000);
-		monster.mHit += NIGHTMARE_TO_HIT_BONUS;
-		monster.mDamage += { 2 };
-		monster.mDamage *= 2;
-		monster.mHit2 += NIGHTMARE_TO_HIT_BONUS;
-		monster.mDamage2 += { 2 };
-		monster.mDamage2 *= 2;
-		monster.mArmorClass += NIGHTMARE_AC_BONUS;
-	} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
-		monster._mmaxhp = 4 * monster._mmaxhp;
-		if (gbIsHellfire)
-			monster._mmaxhp += 100 << 6;
-		else
-			monster._mmaxhp += 192;
-		monster._mhitpoints = monster._mmaxhp;
-		monster.mLevel += 30;
-		monster.mExp = 4 * (monster.mExp + 1000);
-		monster.mHit += HELL_TO_HIT_BONUS;
-		monster.mDamage *= 4;
-		monster.mDamage += { 6 };
-		monster.mHit2 += HELL_TO_HIT_BONUS;
-		monster.mDamage2 *= 4;
-		monster.mDamage2 += { 6 };
-		monster.mArmorClass += HELL_AC_BONUS;
-		monster.mMagicRes = monster.MData->mMagicRes2;
-	}
 }
 
 bool CanPlaceMonster(int xp, int yp)
@@ -485,34 +447,6 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
 		monster._mgoal = MGOAL_INQUIRING;
 	}
 
-	if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
-		monster._mmaxhp = 3 * monster._mmaxhp;
-		if (gbIsHellfire)
-			monster._mmaxhp += 50 << 6;
-		else
-			monster._mmaxhp += 64;
-		monster.mLevel += 15;
-		monster._mhitpoints = monster._mmaxhp;
-		monster.mExp = 2 * (monster.mExp + 1000);
-		monster.mDamage += { 2 };
-		monster.mDamage *= 2;
-		monster.mDamage2 += { 2 };
-		monster.mDamage2 *= 2;
-	} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
-		monster._mmaxhp = 4 * monster._mmaxhp;
-		if (gbIsHellfire)
-			monster._mmaxhp += 100 << 6;
-		else
-			monster._mmaxhp += 192;
-		monster.mLevel += 30;
-		monster._mhitpoints = monster._mmaxhp;
-		monster.mExp = 4 * (monster.mExp + 1000);
-		monster.mDamage *= 4;
-		monster.mDamage += { 6 };
-		monster.mDamage2 *= 4;
-		monster.mDamage2 += { 6 };
-	}
-
 	char filestr[64];
 	sprintf(filestr, "Monsters\\Monsters\\%s.TRN", uniqueMonsterData.mTrnName);
 	LoadFileInMem(filestr, &LightTables[256 * (uniquetrans + 19)], 256);
@@ -522,23 +456,9 @@ void PlaceUniqueMonst(int uniqindex, int miniontype, int bosspacksize)
 	if (uniqueMonsterData.customHitpoints != 0) {
 		monster.mHit = uniqueMonsterData.customHitpoints;
 		monster.mHit2 = uniqueMonsterData.customHitpoints;
-
-		if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
-			monster.mHit += NIGHTMARE_TO_HIT_BONUS;
-			monster.mHit2 += NIGHTMARE_TO_HIT_BONUS;
-		} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
-			monster.mHit += HELL_TO_HIT_BONUS;
-			monster.mHit2 += HELL_TO_HIT_BONUS;
-		}
 	}
 	if (uniqueMonsterData.customArmorClass != 0) {
 		monster.mArmorClass = uniqueMonsterData.customArmorClass;
-
-		if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
-			monster.mArmorClass += NIGHTMARE_AC_BONUS;
-		} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
-			monster.mArmorClass += HELL_AC_BONUS;
-		}
 	}
 
 	ActiveMonsterCount++;
@@ -2365,7 +2285,7 @@ void ScavengerAi(int i)
 			StartEating(monster);
 			if ((monster._mFlags & MFLAG_NOHEAL) == 0) {
 				if (gbIsHellfire) {
-					int mMaxHP = monster._mmaxhp; // BUGFIX use _mmaxhp or we loose health when difficulty isn't normal (fixed)
+					int mMaxHP = monster._mmaxhp;
 					monster._mhitpoints += mMaxHP / 8;
 					if (monster._mhitpoints > monster._mmaxhp)
 						monster._mhitpoints = monster._mmaxhp;
@@ -3989,10 +3909,6 @@ void PrepDoEnding()
 	MyPlayerIsDead = false;
 	cineflag = true;
 
-	auto &myPlayer = Players[MyPlayerId];
-
-	myPlayer.pDiabloKillLevel = std::max(myPlayer.pDiabloKillLevel, static_cast<uint8_t>(sgGameInitInfo.nDifficulty + 1));
-
 	for (auto &player : Players) {
 		player._pmode = PM_QUIT;
 		player._pInvincible = true;
@@ -4501,24 +4417,11 @@ void PrintMonstHistory(int mt)
 		if (maxHP < 1)
 			maxHP = 1;
 
-		int hpBonusNightmare = 1;
-		int hpBonusHell = 3;
-		if (gbIsHellfire) {
-			hpBonusNightmare = 50;
-			hpBonusHell = 100;
-		}
-		if (sgGameInitInfo.nDifficulty == DIFF_NIGHTMARE) {
-			minHP = 3 * minHP + hpBonusNightmare;
-			maxHP = 3 * maxHP + hpBonusNightmare;
-		} else if (sgGameInitInfo.nDifficulty == DIFF_HELL) {
-			minHP = 4 * minHP + hpBonusHell;
-			maxHP = 4 * maxHP + hpBonusHell;
-		}
 		strcpy(tempstr, fmt::format("Hit Points: {:d}-{:d}", minHP, maxHP).c_str());
 		AddPanelString(tempstr);
 	}
 	if (MonsterKillCounts[mt] >= 15) {
-		int res = (sgGameInitInfo.nDifficulty != DIFF_HELL) ? MonstersData[mt].mMagicRes : MonstersData[mt].mMagicRes2;
+		int res = MonstersData[mt].mMagicRes;
 		if ((res & (RESIST_MAGIC | RESIST_FIRE | RESIST_LIGHTNING | IMMUNE_MAGIC | IMMUNE_FIRE | IMMUNE_LIGHTNING)) == 0) {
 			strcpy(tempstr, "No magic resistance");
 			AddPanelString(tempstr);
diff --git a/Source/multi.h b/Source/multi.h
index 188cafef114..2fb42dedd2d 100644
--- a/Source/multi.h
+++ b/Source/multi.h
@@ -19,7 +19,6 @@ struct GameData {
 	/** Used to initialise the seed table for dungeon levels so players in multiplayer games generate the same layout */
 	uint32_t dwSeed;
 	uint32_t programid;
-	_difficulty nDifficulty;
 	uint8_t nTickRate;
 	uint8_t bRunInTown;
 	uint8_t bTheoQuest;
diff --git a/Source/pack.cpp b/Source/pack.cpp
index 93875478ab5..33d621daca7 100644
--- a/Source/pack.cpp
+++ b/Source/pack.cpp
@@ -122,9 +122,7 @@ void PackPlayer(PlayerPack *pPack, const Player &player, bool manashield)
 	}
 
 	pPack->wReflections = SDL_SwapLE16(player.wReflections);
-	pPack->pDifficulty = SDL_SwapLE32(player.pDifficulty);
 	pPack->pDamAcFlags = SDL_SwapLE32(player.pDamAcFlags);
-	pPack->pDiabloKillLevel = SDL_SwapLE32(player.pDiabloKillLevel);
 	pPack->bIsHellfire = gbIsHellfire ? 1 : 0;
 
 	if (manashield)
@@ -256,10 +254,8 @@ void UnPackPlayer(const PlayerPack *pPack, Player &player, bool netSync)
 	player.pDungMsgs = 0;
 	player.pDungMsgs2 = 0;
 	player.pLvlLoad = 0;
-	player.pDiabloKillLevel = SDL_SwapLE32(pPack->pDiabloKillLevel);
 	player.pBattleNet = pPack->pBattleNet != 0;
 	player.pManaShield = SDL_SwapLE32(pPack->pManaShield);
-	player.pDifficulty = (_difficulty)SDL_SwapLE32(pPack->pDifficulty);
 	player.pDamAcFlags = SDL_SwapLE32(pPack->pDamAcFlags);
 }
 
diff --git a/Source/pack.h b/Source/pack.h
index 72c7b8fd32e..a782187229e 100644
--- a/Source/pack.h
+++ b/Source/pack.h
@@ -72,8 +72,8 @@ struct PlayerPack {
 	int16_t wReserved2;  // For future use
 	int8_t pSplLvl2[10]; // Hellfire spells
 	int16_t wReserved8;  // For future use
-	uint32_t pDiabloKillLevel;
-	uint32_t pDifficulty;
+	uint32_t pDiabloKillLevelReserved;
+	uint32_t pDifficultyReserved;
 	int32_t pDamAcFlags;
 	int32_t dwReserved[5]; // For future use
 };
diff --git a/Source/pfile.cpp b/Source/pfile.cpp
index 4e88911cfc8..65cfe5c2ca2 100644
--- a/Source/pfile.cpp
+++ b/Source/pfile.cpp
@@ -182,7 +182,6 @@ void Game2UiPlayer(const Player &player, _uiheroinfo *heroinfo, bool bHasSaveFil
 	heroinfo->dexterity = player._pDexterity;
 	heroinfo->vitality = player._pVitality;
 	heroinfo->hassaved = bHasSaveFile;
-	heroinfo->herorank = player.pDiabloKillLevel;
 }
 
 bool GetFileName(uint8_t lvl, char *dst)
diff --git a/Source/player.cpp b/Source/player.cpp
index beceeaf3e9f..b83c9fc9560 100644
--- a/Source/player.cpp
+++ b/Source/player.cpp
@@ -2363,8 +2363,6 @@ void CreatePlayer(int playerId, HeroClass c)
 	player.pDungMsgs = 0;
 	player.pDungMsgs2 = 0;
 	player.pLvlLoad = 0;
-	player.pDiabloKillLevel = 0;
-	player.pDifficulty = DIFF_NORMAL;
 
 	player._pLevel = 1;
 
diff --git a/Source/player.h b/Source/player.h
index d71ce6f5a86..d0d8f309c9a 100644
--- a/Source/player.h
+++ b/Source/player.h
@@ -292,8 +292,6 @@ struct Player {
 	uint8_t pDungMsgs2;
 	bool pOriginalCathedral;
 	uint16_t wReflections;
-	uint8_t pDiabloKillLevel;
-	_difficulty pDifficulty;
 	uint32_t pDamAcFlags;
 
 	void CalcScrolls();