[Scummvm-git-logs] scummvm master -> c28da3a729c4df1b265e264f8595f7c94eaa5124

sev- noreply at scummvm.org
Sun Feb 5 20:36:35 UTC 2023


This automated email contains information about 242 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
4e6c72b975 EFH: Add skeleton engine
76f7fad096 EFH: Partial implementation of initEngine()
01fb53ec98 EFH: Implement some functions loading files
d679199d67 EFH: More work on initEngine
acec83040b EFH: Implement decompression, add searchman directories
ed94879a48 EFH: Clean decompression code, add DumpFile, fix some uselessly specified paths
0ba6472979 EFH : Add some more functions
825d755a63 EFH: Fix issue in loadTechMapImp
2ec0e43a25 EFH: Implement loadMapMonsters, add encounter monster const array
1a2914912c EFH: Fix crash in previous commit, implement decryptImpFile()
db4dc8ab92 EFH: Implement copyCurrentPlaceToBuffer
e87ddaf1fd EFH: Fix rImageFile, init palette, hack a display function
24aca2246c EFH: Move font data to constants
2ab89d40b4 EFH: Renaming, remove unused parameters in a couple of functions
6ca672552a EFH: Implement drawBox
2d5377a276 EFH: Refactor a bit the intro, implement getLastCharAfterAnimCount, remove more useless parameters from functions
159ba2b577 EFH: Implement script_parse() and several underlying functions, some refactoring around Items and NPCS
f7c609ebdb EFH: Fix a couple of crashes
99f3f1e727 EFH: Implement string display
2bbd63c0bc EFH: Implement displayLowStatusScreen and some other functions, refactor AnimInfo
9f3174bd5e EFH: Implement getEquipmentDefense
05ba2b7d59 EFH: Implement drawMap, some renaming
e48753cf6d EFH: Disable noisy useless code
63534f8a34 EFH: Start implementing main loop
8874d2f926 EFH: Fix event handler, some renaming
f20fd2d935 EFH: Some more renaming
2e2803591f EFH: Fix map initialization (loading savegame)
28bf1807e7 EFH: Start implementing interactions with monsters
e70972c170 EFH: Implement sub174A0
c51010ccdf EFH: Fix redraw, implement sub15581, renaming
51d4c3f9d1 EFH: Implement handleWinSequence and getInput
cc86b83031 EFH: Implement handleNewRoundEffetcs
50803c32e2 EFH: Implement various menu functions
40ad50f161 EFH: Fix number of menu lines, add some convenient keycodes in the menus, some small renaming and clean up
bc88c24707 EFH: More work on status menu
a3cbeb5857 EFH: Implement displayCharacterSummary
902b1398ce EFH: Implement some stubs
6357fd7b66 EFH: Implement sub22AA8, refactor _mapUnknownPtr
c6ae134051 EFH: Implement object manipulation (sub19E2E), move some functions to graphics and utils
6cc1cc1a25 Fix selectOtherCharFromTeam()
36744e2dd3 EFH: Some renaming, fix a couple of issues
232e260453 EFH: Fix handleCharacterJoining, add chooseCharacterToReplace
5f3c36217e EFH: Implement some more stubs
c8ee5e07dd EFH: Fix issue in sub221FA()
468aeeaa27 EFH: Add 3 missing key mapped in main loop (some more are still missing)
2cf05c0432 EFH: Add keyboard mapping for save and load game
13e6100ec7 EFH: Start working on handleFight
c164d4854e EFH: More work on handleFight / Action A
f3c3f63076 EFH: More work on handleFight / Action A (2)
790f00cb9d EFH: Finish the implementation of handleFight / Action A
f63a39055d EFH: Implement handlefight - lastAction D, H and U
4b7e91fead EFH: More work on handleFight
706496f1bd EFH: Implement 3 more stubs in handleFight
73d6cf6b0a EFH: Implement 2 more stubs in handleFight
70127ffe6d EFH: Implement 1 stubs
668b33d2d9 EFH: Implement getDeathTypeDescription
7f38961051 EFH: Fix issue in getDeathTypeDescription, some renaming
9b34c6766a EFH: Implement getXPAndSearchCorpse
2584221af2 EFH: Implement 4 more functions
7ac43704a7 EFH: Implement one more stub
fd7b6755fb EFH: Implement 2 more stubs, rename a function
e6e84a6c7e EFH: Implement sub1BE9A
f3bf1bfbc5 EFH: Add some debug traces, some renaming
5cb54e5922 EFH: Small modification in NPCStruct, some renaming
8cffee5e89 EFH: Turn _mapGameMap and _curPlace into arrays
b329930013 EFH: Turn _tileFact into an array of struct, add comments on object types in sub1BC74
20b099c025 EFH: Fix loading of _mapGameMap (regression introduced 2 or 3 commits ago)
d29e4ed7f0 EFH: Fix unitialized variables in constructor, remove initializations in initEngine()
c5707c7046 EFH: Put debug traces everywhere
902e1f06f2 EFH: Fix an issue in displayAnimFrame, small refactoring, add some debug traces
11c5a89891 EFH: Fix delay, fix a kind of collision
f9471c12ed EFH: Some renaming
2435653bc8 EFH: Some renaming, improve some comments
6796634043 EFH: more renaming
a651ff0b9d EFH: Fix missing initialization in handleFight
cadc61de7a EFH: Fix debug string for drawText
c253ae5a54 EFH: Fix getStringWidth (fix 2nd text page in the intro)
8f5128f1a3 EFH: Some renaming in script_parse
70147a0310 EFH: Fix display of the last part of the intro
cbe49b22ce EFH: Fix getInputBlocking
c66d0eee23 EFH: Fix opening dialog when using phone booth
0acc221f4f EFH: Fix the display of the gate first message and the board.
14bb81d797 EFH: Fix bugs in opcode 12 and 13, fix issues in readNumberArray and getNumber
d1acf3e1f7 EFH: Fix readNumberArray. It's now possible to teleport!! \o/
abfd4848ed EFH: Fix transparency
fb064ef223 EFH: Fix DrawColorRect usage in sub1C219 (fix display when reading descriptions or dialogs)
a3916952a6 EFH: Some renaming, add a note in drawChar
144819e53f EFH: Fix moonwalk occurring when getting close to the left and top border of the maps
309f10be4d EFH: Some renaming in drawMap
1071de9f8b EFH: Add some comments in the script parser, fix the display of conditional dialogs
272b688b72 EFH: Fix crash when interacting with a special character
164b5825e9 EFH: Fix double execution of opcodes, start fixing encounter of special characters
024ba4e02d EFH: Fix another issue in sub21820
f1d9b538c4 EFH: Fix a couple of issues in the Y/N check related to save/load games, move some debug strings to debugC
8082c472fe EFH: Change the safeguard in getRandom to make it more robust, change debug to debugC after proofreading the code, add s
73fabe7176 EFH: Fix a bug in the fight system, change the type of an argument to bool
d88b4bce4d EFH: Add comments, fix a bug in handleFight_lastAction_A
654b6ad177 EFH: some renaming, fix a debug message
b8f84a33f5 EFH: Implement animFl in handleAndMapInput, fix a check in sub191FF, some renaming
36a6700abf EFH: Fix bug in combat system
43d189fd56 EFH: Fix typo in the message about armor effect
c4c96555b4 EFH: Add stubs for sound generation
7f2c549983 EFH: Fix compilation
1043a315a9 EFH: Turn _nameBuffer into a Common::String
27b7beae68 EFH: Fixa couple of previously usages of "copystring"
c6bd02fb8e EFH: Turn _enemyNamePt2 into a Common::String
3ca7a67c1e EFH: Turn _characterNamePt2 into a Common::String
8008d096bc EFH: Turn _characterNamePt1 into a Common::String
cf5dd14c7a EFH: More conversions from char [] to Common::String
0258f7009f EFH: more work on Common::String, somehow fix a crash in dialogs
2d6f4f7f17 EFH: "Remove" copyString()
8251081c09 EFH: Start preparing TECH and MAP files for savegames
8acbbcafb0 EFH: Fix typo in combats
b629145627 EFH: Preload maps
d695ab3437 EFH: Partial implementation of savegames. Loading is missing.
638696444d EFH: Add save date & time
e54b01d474 EFH: Partial loading code
0d158f1583 EFH: Fix parsing of savegame
df4ac48e9f EFH: Fix loading (hopefully)
143c483bde EFH: Load from launcher
a3046a0be0 EFH: Janitorial - Remove trailing spaces & tabs
473b74aab3 EFH: Fix headers (GPLv3)
7ec543b2bf EFH: Remove game type, simplify game descriptions
e10d31a6b9 EFH: Fix alignment in metaengine, reorder some includes, remove a useless include
17a6120f5a EFH: Start splitting efh.cpp
22227d37e2 EFH: take into account some more comments raised by sev during the first code review
c833b8a55b EFH: Partial rewrite of file loading
4605be8169 EFH: Change uint8 to uint in some loops
1f7fe868ad EFH: Fix missing space in while statements
8f115830aa EFH: remove the use of int16 in most loops, fix a compilation warning
d03b0043dd EFH: Fix formatting, remove an obsolete comment
bc7de3a10a EFH: Split some more functions from efh.cpp
452eedce4e EFH: move some more functions out of efh.cpp, some renaming
88299f7967 EFH: turn _messageToBePrinted into a Common::String
0df6c4b880 EFH: Remove an original unused debug flag, fix some warnings
68b66cad83 EFH: turn some more char[] into Common::String, fix 4 warnings
db6ba84b0f EFH: Fix another warning
6c11b653a3 EFH: turn some more char[] into Common::String
d598eefac4 EFH: Fix bug in displayImp1Text, renaming
41dd4d0b4b EFH: Some renaming, verify some more functions (and use debugC for those)
86b0c137c9 EFH: move some functions from efh to fight, tag some more functions as reviewed (via the use of debugC)
19fae17e60 EFH: Fix a bug in checkMonsterCollision(), some renaming
7e326f5cd3 EFH: validate some more functions, some renaming and code simplification
4395cfc17e EFH: Double check more functions, some renaming
a354207813 EFH: Disable saving during intro, winning sequence and after death, some renaming and functions review
6e5899047a EFH: Move several functions from EFH to Menu and Fight
eaee54c083 EFH: Move more functions to menu.cpp, change savegame format, some renaming
f004457157 EFH: turn _unk2C8AA into a int16, lot of renaming related to monster moves
1708c03287 EFH: Fix endian issue, some renaming
6aea8334bc EFH: Verify some more functions, some renaming
968499e2dc EFH: Renaming, validate some more functions
88c3402688 EFH: Move initialization code to init.cpp, fix bug in script_parse (case 6), renaming
d705fe9776 EFH: Fix bugs in handleFight_lastAction_A(), renaming
ec7bafa223 EFH: Renaming, fix bug in sub1BE9A()
88ad3db32d EFH: Review giveItemTo(), renaming + fix a bug in handleStatusMenu()
4a9ac53f03 EFH: Validate some more functions, more renaming
a28c93becf EFH: Fix display of low status window
2042def6a0 EFH: Validate some more functions, more renaming
fea76a9724 EFH: Review two more functions, small refactoring and some renaming
4eb3e39efe EFH: Fix a (likely) original bug, renaming and partial refactoring of ItemStruct (pronoun)
9a293d2074 EFH: finish pronoun refactoring, some renaming
204f23ba1b EFH: refactor the use of InvObject._stat1, fix a bug in hasAdequateDefense_2(), in sub19E2E() and in  displayCharacterSu
946b1740a5 EFH: Fix a (likely) bug in sub1D8C2()
594156ae64 EFH: Fix a bug in handleFight, fix handleFight_lastAction_U, rename (between others) useObject()
69e5fb04cb EFH: Validate 2 functions, renaming
231a5bca12 EFH: Fix bug in tryToggleEquipped, renaming and validation of some more functions
7122fd549b EFH: More renaming
0d8ba6ba74 EFH: Rename last field in MapMonster structure
c28ff1990e EFH: refactor findMapSpecialTileIndex, validate a couple of functions, more renaming
36ea4314d2 EFH: WIP sound code
d5eb4d85a4 EFH: fix a bug in sub22293(), validate 2 functions, some renaming
8f3ad37290 EFH: Fix a bug in handleFight_lastAction_A, validate multiple functions, renaming
cb8897d782 EFH: More renaming
3dbb8bb1a0 EFH: Fix implementation of checkSpecialItemsOnCurrentPlace(), modify displayCharacterInformationOrSkills() so it doesn't
1f15de9b97 EFH: Move getTeamMonsterAnimId to fight.cpp (and validate it), some renaming in script_parse
878576311d EFH: Change EFH_EFH_H_ to EFH_H based on sev's review. Fix a typo
ba46f70a62 EFH: Change include order in EFH.H (sev's review)
cd888fec43 EFH: Fix bug in tryToggleEquipped()
a976d28c1d EFH: Fix a bug in unequipItem(), fix a bug in displayString_3()
d773048869 EFH: Fix several issues in handleStatusMenu() / Trade
5bc5534ca3 EFH: Make menu code slightly more readable by using an enum
751f2859ea EFH: Fix a bug in giveItemTo()
dad84346eb EFH: Validate handleStatusMenu, remove duplicate code
f524624382 EFH: Rename displayString_3 to displayStringInSmallWindowWithBorder
a5407440f4 EFH: Validate one more function, renaming
a2e496f783 EFH: Add a new enum, validate some more functions, some renaming
0e6a5d9d0c EFH: Fix bug in characterSearchesMonsterCorpse()
b8544bb762 EFH: Fix a couple of issues in sub1C956, renaming
ac5da028ef EFH: Renaming
d6650f6ca3 EFH: Validate addNewOpponents(), some renaming
90e16512d5 EFH: Fix CppCheck warnings, add some comments, validate loadPlacesFile()
2ec85960ad EFH: Validate more functions, renaming
789917e174 EFH: Fix issues in getDeathTypeDescription, renaming
ddb0cc8dbe EFH: rename determineTeamTarget(), fix issues in it
e8fed6ff3b EFH: Validate 4 more functions, fix a bug in chooseCharacterToReplace()
b9424bd35d EFH: Add safeguards in transitionMap() and setSpecialTechZone(), move selectMonsterGroup() to fight.cpp, validate some m
adc85ef185 EFH: More validations and renaming
ba52ee0cc7 EFH: rename handleDamageOnArmor() and getTeamAttackRoundPlans(), validate two functions
a0ae5cb427 EFH: Move handleDamageOnArmor to fight.cpp
6e402815ef EFH: Validate 3 more functions
8f7bf6b265 EFH: rewrite the pre-loading of "map" files, related refactoring
7b1e1c7362 EFH: Fix missing bit in savegames
f997af9702 EFH: Fix (hopefully) several Clang warnings
e501c8a8c8 EFH: Remove saveEfhGame, directly call the appropriate dialog
0b9d9b1446 EFH: Rename displayEncounterInfo()
03746ad322 EFH: some renaming in handleFight_lastAction_A, invert some if statement to reduce code depth
a95b4960e0 EFH: Split handleFight_MobstersAttack out of handleFight()
6179bb75ad EFH: Rename last SUB function
04f3b5ff72 EFH: Some work on song parsing
577fbde5ba EFH: ... Music implementation! 0_o
af35f1c3bd EFH: Sync volume settings, add a purge of keyboard events to stop exiting the splash screen accidentally
a25e1b09c9 EFH: Improve delay length in title music
f52852512e EFH: Implementation of generateSound2 (based on assembly, no idea about how it should sound like on real hardware)
16cc90a973 EFH: Implement generateSound3
6fa1582bfa EFH: Add the last sound generation functions
90ceabd3fc EFH: Delete _mainSurface on exit
6c027c0373 EFH: Some renaming
a33db72da4 EFH: Move songDelay, playNote and PlaySong to sound.sound.cpp
207bbbbbbf EFH: Turn some debug into debugC()
0ee97e0a65 EFH: Use hex values for palette definition
b62431dd4d EFH: Fix fileorder in makefile
cdd3004c29 EFH: Make use of dump-scripts command instead of defines
956913fbbe EFH: Add brackets for look consistency
f41c0e85ed EFH: Add code to dump decoded maps
de2f2390ee EFH: Introduce getArticle(), some renaming
e20186c0bc EFH: Some renaming in drawMap
21ea9c9729 EFH: Start making code less verbose, remove a useless parameter to getEquipmentDefense()
116e15b355 EFH: Add code to keep track of character 2 status (and related duration) when character 1 leaves
bd88a709f2 EFH: Remove an unused buffer, rename another one
cb467912a6 EFH: More code simplification
2a48a8f6c6 EFH: Fix issue in regen
e5cd8dc6ef EFH: Add comment in checkMonsterMovementType, refactor computeMapAnimation and more code simplification
103b590d07 EFH: Remove useless parameter from setMapMonsterAggressivenessAndMovementType(), simplify more code
c6f3e50a28 EFH: Rename 3 previously unknown variables
4e8c31e90e EFH: Remove unused original debug code, start grouping team and teamMonster variables
598a669091 EFH: Refactor TeamChar
41e39d27cf EFH: Fix bug when using bugle
fdd742bfbf EFH: refactor TeamMonster
3a68ef3cf1 EFH: Simplify code in addNewOpponents, add a comment in useObject() about the description of a cure to being frozen
9c02a5b55f EFH: rename _tileBankSubFileArray, move teamChar initialization to its own init()
a24acf909d EFH: Some renaming and comments
c28da3a729 EFH: Fix warnings


Commit: 4e6c72b975b9d627e3d48a908b0dd111b404937b
    https://github.com/scummvm/scummvm/commit/4e6c72b975b9d627e3d48a908b0dd111b404937b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Add skeleton engine

Changed paths:
  A engines/efh/configure.engine
  A engines/efh/detection.cpp
  A engines/efh/detection.h
  A engines/efh/efh.cpp
  A engines/efh/efh.h
  A engines/efh/metaengine.cpp
  A engines/efh/module.mk


diff --git a/engines/efh/configure.engine b/engines/efh/configure.engine
new file mode 100644
index 00000000000..523cdfaa00c
--- /dev/null
+++ b/engines/efh/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine efh "Escape From Hell" no
diff --git a/engines/efh/detection.cpp b/engines/efh/detection.cpp
new file mode 100644
index 00000000000..7f570bd78e0
--- /dev/null
+++ b/engines/efh/detection.cpp
@@ -0,0 +1,80 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "base/plugins.h"
+#include "engines/advancedDetector.h"
+#include "common/textconsole.h"
+
+#include "efh/detection.h"
+
+namespace Efh {
+
+static const PlainGameDescriptor efhGames[] = {
+	// Games
+	{"efh", "Escape From Hell"},
+	{nullptr, nullptr}
+};
+
+static const EfhGameDescription gameDescriptions[] = {
+
+	// Escape From Hell English - Unpacked version
+	{
+		{"efh", nullptr, AD_ENTRY1s("escape.exe", "2702f8f713e113a853a925d29aecc709", 147312),
+			Common::EN_ANY,
+			Common::kPlatformDOS,
+			ADGF_UNSTABLE,
+			GUIO0()
+		},
+		kGameTypeEfh
+	},
+	// Escape From Hell English
+	{
+		{"efh", nullptr, AD_ENTRY1s("escape.exe", "1ca4ae3f2ea66c30d1ef3e257a86cd05", 141487),
+		 Common::EN_ANY,
+		 Common::kPlatformDOS,
+		 ADGF_UNSTABLE,
+		 GUIO0()},
+		kGameTypeEfh},
+	{AD_TABLE_END_MARKER, kGameTypeNone}
+};
+
+class EfhMetaEngineDetection : public AdvancedMetaEngineDetection {
+public:
+	EfhMetaEngineDetection() : AdvancedMetaEngineDetection(gameDescriptions, sizeof(EfhGameDescription), efhGames) {
+	}
+
+	const char *getEngineId() const override {
+		return "efh";
+	}
+
+	const char *getName() const override {
+		return "Efh";
+	}
+
+	const char *getOriginalCopyright() const override {
+		return "Escape From Hell (C) Electronic Arts, 1990";
+	}
+};
+
+} // End of namespace efh
+
+REGISTER_PLUGIN_STATIC(EFH_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, Efh::EfhMetaEngineDetection);
diff --git a/engines/efh/detection.h b/engines/efh/detection.h
new file mode 100644
index 00000000000..9c4a40452b8
--- /dev/null
+++ b/engines/efh/detection.h
@@ -0,0 +1,42 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef EFH_DETECTION_H
+#define EFH_DETECTION_H
+
+#include "engines/advancedDetector.h"
+
+namespace Efh {
+
+enum GameType {
+	kGameTypeNone  = 0,
+	kGameTypeEfh
+};
+
+struct EfhGameDescription {
+	ADGameDescription desc;
+	GameType gameType;
+};
+
+} // End of namespace Efh
+
+#endif // EFH_DETECTION_H
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
new file mode 100644
index 00000000000..3747ec438e4
--- /dev/null
+++ b/engines/efh/efh.cpp
@@ -0,0 +1,105 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/system.h"
+#include "common/random.h"
+#include "common/error.h"
+#include "common/config-manager.h"
+#include "common/events.h"
+#include "engines/util.h"
+#include "graphics/cursorman.h"
+
+#include "efh/efh.h"
+#include "engines/util.h"
+
+namespace Efh {
+
+EfhEngine *EfhEngine::s_Engine = 0;
+
+EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
+	_system = syst;
+	_rnd = nullptr;
+
+	_shouldQuit = false;
+	_eventMan = nullptr;
+	_lastTime = 0;
+	_gameType = kGameTypeNone;
+	_platform = Common::kPlatformUnknown;
+	_mainSurface = nullptr;
+}
+
+EfhEngine::~EfhEngine() {
+	delete _rnd;
+}
+
+bool EfhEngine::hasFeature(EngineFeature f) const {
+	return (f == kSupportsReturnToLauncher) || (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
+}
+
+const char *EfhEngine::getCopyrightString() const {
+	return "Escape From Hell (C) Electronic Arts, 1991";
+}
+
+GameType EfhEngine::getGameType() const {
+	return _gameType;
+}
+
+Common::Platform EfhEngine::getPlatform() const {
+	return _platform;
+}
+
+Common::Error EfhEngine::run() {
+	s_Engine = this;
+	initialize();
+	initGraphics(320, 200);
+
+	_mainSurface = new Graphics::Surface();
+	_mainSurface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
+/*
+	// Setup mixer
+	syncSoundSettings();
+	_soundHandler->init();
+
+	CursorMan.replaceCursor(_normalCursor, 16, 16, 0, 0, 0);
+	CursorMan.showMouse(true);
+*/
+	return Common::kNoError;
+}
+
+void EfhEngine::initialize() {
+	_rnd = new Common::RandomSource("efh");
+	_rnd->setSeed(42);                              // Kick random number generator
+	_shouldQuit = false;
+}
+
+
+void EfhEngine::syncSoundSettings() {
+	Engine::syncSoundSettings();
+
+//	_sound->syncVolume();
+}
+
+Common::String EfhEngine::getSavegameFilename(int slot) {
+	return _targetName + Common::String::format("-%02d.SAV", slot);
+}
+
+} // End of namespace Efh
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
new file mode 100644
index 00000000000..22b6ceac8d7
--- /dev/null
+++ b/engines/efh/efh.h
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef EFH_EFH_H
+#define EFH_EFH_H
+
+#include "efh/detection.h"
+
+#include "common/file.h"
+#include "common/rect.h"
+#include "common/events.h"
+
+#include "engines/engine.h"
+#include "graphics/palette.h"
+#include "graphics/surface.h"
+
+namespace Common {
+class RandomSource;
+}
+
+/**
+ * This is the namespace of the Efh engine.
+ *
+ * Status of this engine:
+ * - Skeletton
+ *
+ * Games using this engine:
+ * - Escape From Hell
+ * 
+ * Escape From Hell is based on a modified Wasteland engine, so this engine could eventually, one day, also support:
+ * - Wasteland
+ * - Fountain of Dreams
+ */
+namespace Efh {
+
+static const int kSavegameVersion = 1;
+
+struct EfhGameDescription;
+
+class EfhEngine : public Engine {
+public:
+	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
+	~EfhEngine() override;
+
+	OSystem *_system;
+	Graphics::Surface *_mainSurface;
+	Common::RandomSource *_rnd;
+
+
+	const EfhGameDescription *_gameDescription;
+	uint32 getFeatures() const;
+	const char *getGameId() const;
+
+	void initGame(const EfhGameDescription *gd);
+	GameType getGameType() const;
+	Common::Platform getPlatform() const;
+
+	bool hasFeature(EngineFeature f) const override;
+	const char *getCopyrightString() const;
+
+	Common::String getSavegameFilename(int slot);
+	void syncSoundSettings() override;
+
+	bool _shouldQuit;
+
+protected:
+	Common::EventManager *_eventMan;
+	int _lastTime;
+
+	// Engine APIs
+	Common::Error run() override;
+	void handleMenu();
+
+private:
+	static EfhEngine *s_Engine;
+
+	GameType _gameType;
+	Common::Platform _platform;
+
+	void initialize();
+};
+
+} // End of namespace Efh
+
+#endif
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
new file mode 100644
index 00000000000..9857fb0bee7
--- /dev/null
+++ b/engines/efh/metaengine.cpp
@@ -0,0 +1,204 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "engines/advancedDetector.h"
+#include "common/system.h"
+#include "common/savefile.h"
+#include "common/textconsole.h"
+#include "graphics/thumbnail.h"
+#include "graphics/surface.h"
+
+#include "efh/efh.h"
+#include "efh/detection.h"
+
+namespace Efh {
+
+uint32 EfhEngine::getFeatures() const {
+	return _gameDescription->desc.flags;
+}
+
+const char *EfhEngine::getGameId() const {
+	return _gameDescription->desc.gameId;
+}
+
+} // End of namespace Efh
+
+namespace Efh {
+
+class EfhMetaEngine : public AdvancedMetaEngine {
+public:
+	const char *getName() const override {
+		return "efh";
+	}
+
+	Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const override;
+	bool hasFeature(MetaEngineFeature f) const override;
+
+	int getMaximumSaveSlot() const override;
+	SaveStateList listSaves(const char *target) const override;
+	SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
+	void removeSaveState(const char *target, int slot) const override;
+};
+
+Common::Error EfhMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
+	*engine = new EfhEngine(syst, (const EfhGameDescription *)gd);
+	((EfhEngine *)*engine)->initGame((const EfhGameDescription *)gd);
+	return Common::kNoError;
+}
+
+bool EfhMetaEngine::hasFeature(MetaEngineFeature f) const {
+	return
+		(f == kSupportsListSaves) ||
+		(f == kSupportsLoadingDuringStartup) ||
+		(f == kSupportsDeleteSave) ||
+		(f == kSavesSupportMetaInfo) ||
+		(f == kSavesSupportThumbnail) ||
+		(f == kSavesSupportCreationDate);
+}
+
+int EfhMetaEngine::getMaximumSaveSlot() const {
+	return 99;
+}
+
+SaveStateList EfhMetaEngine::listSaves(const char *target) const {
+	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+	Common::StringArray filenames;
+	Common::String pattern = target;
+	pattern += "-##.SAV";
+
+	filenames = saveFileMan->listSavefiles(pattern);
+
+	SaveStateList saveList;
+	char slot[3];
+	int slotNum = 0;
+	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
+		slot[0] = filename->c_str()[filename->size() - 6];
+		slot[1] = filename->c_str()[filename->size() - 5];
+		slot[2] = '\0';
+		// Obtain the last 2 digits of the filename (without extension), since they correspond to the save slot
+		slotNum = atoi(slot);
+		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
+			if (file) {
+				int saveVersion = file->readByte();
+
+				if (saveVersion != kSavegameVersion) {
+					warning("Savegame of incompatible version");
+					delete file;
+					continue;
+				}
+
+				// read name
+				uint16 nameSize = file->readUint16BE();
+				if (nameSize >= 255) {
+					delete file;
+					continue;
+				}
+				char name[256];
+				file->read(name, nameSize);
+				name[nameSize] = 0;
+
+				saveList.push_back(SaveStateDescriptor(this, slotNum, name));
+				delete file;
+			}
+		}
+	}
+
+	Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
+	return saveList;
+}
+
+SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s-%02d.SAV", target, slot);
+	Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
+
+	if (file) {
+		int saveVersion = file->readByte();
+
+		if (saveVersion != kSavegameVersion) {
+			warning("Savegame of incompatible version");
+			delete file;
+			return SaveStateDescriptor();
+		}
+
+		uint32 saveNameLength = file->readUint16BE();
+		Common::String saveName;
+		for (uint32 i = 0; i < saveNameLength; ++i) {
+			char curChr = file->readByte();
+			saveName += curChr;
+		}
+
+		SaveStateDescriptor desc(this, slot, saveName);
+
+		Graphics::Surface *thumbnail;
+		if (!Graphics::loadThumbnail(*file, thumbnail)) {
+			delete file;
+			return SaveStateDescriptor();
+		}
+		desc.setThumbnail(thumbnail);
+
+		desc.setDeletableFlag(true);
+		desc.setWriteProtectedFlag(false);
+
+		uint32 saveDate = file->readUint32BE();
+		uint16 saveTime = file->readUint16BE();
+
+		int day = (saveDate >> 24) & 0xFF;
+		int month = (saveDate >> 16) & 0xFF;
+		int year = saveDate & 0xFFFF;
+
+		desc.setSaveDate(year, month, day);
+
+		int hour = (saveTime >> 8) & 0xFF;
+		int minutes = saveTime & 0xFF;
+
+		desc.setSaveTime(hour, minutes);
+		desc.setDeletableFlag(slot != 0);
+		desc.setWriteProtectedFlag(slot == 0);
+
+		delete file;
+		return desc;
+	}
+	return SaveStateDescriptor();
+}
+
+void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
+	Common::String fileName = Common::String::format("%s-%02d.SAV", target, slot);
+	g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
+} // End of namespace Efh
+
+#if PLUGIN_ENABLED_DYNAMIC(EFH)
+	REGISTER_PLUGIN_DYNAMIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
+#else
+REGISTER_PLUGIN_STATIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
+#endif
+
+namespace Efh {
+
+void EfhEngine::initGame(const EfhGameDescription *gd) {
+	_gameType = gd->gameType;
+	_platform = gd->desc.platform;
+}
+
+} // End of namespace Efh
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
new file mode 100644
index 00000000000..6b8f7bdee6c
--- /dev/null
+++ b/engines/efh/module.mk
@@ -0,0 +1,19 @@
+MODULE := engines/efh
+
+MODULE_OBJS = \
+	efh.o \
+	metaengine.o
+
+MODULE_DIRS += \
+	engines/efh
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_EFH), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
+
+# Detection objects
+DETECT_OBJS += $(MODULE)/detection.o


Commit: 76f7fad096a257fbaf21bfaa14a60eddec7182a8
    https://github.com/scummvm/scummvm/commit/76f7fad096a257fbaf21bfaa14a60eddec7182a8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Partial implementation of initEngine()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3747ec438e4..5af49384ee3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -45,10 +45,45 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_gameType = kGameTypeNone;
 	_platform = Common::kPlatformUnknown;
 	_mainSurface = nullptr;
+
+	_videoMode = 0;
+	_graphicsStruct = nullptr;
+	_mapBitmapRef = nullptr;
+	_mapUnknownPtr = nullptr;
+	_mapMonstersPtr = nullptr;
+	_mapGameMapPtr = nullptr;
+
+	_defaultBoxColor = 0;
+
+	_fontDescr._widthArray = nullptr;
+	_fontDescr._extraLines = nullptr;
+	_fontDescr._fontData = nullptr;
+	_fontDescr._charHeight = 0;
+	_fontDescr._extraHorizontalSpace = _fontDescr._extraVerticalSpace = 0;
+
+	_word31E9E = 0;
+	_oldAnimImageSetId = -1;
+	_animImageSetId = 254;
+	_paletteTransformationConstant = 10;
+
+	for (int i = 0; i < 12; ++i)
+		_circleImageSubFileArray[i] = nullptr;
+
+	_imageDataPtr._dataPtr = nullptr;
+	_imageDataPtr._width = 0;
+	_imageDataPtr._startX = _imageDataPtr._startY = 0;
+	_imageDataPtr._height = 0;
+	_imageDataPtr._fieldA = 0;
+	_imageDataPtr._paletteTransformation = 0;
+	_imageDataPtr._fieldD = 0;
+
+	for (int i = 0; i < 3; ++i)
+		_currentTileBankImageSetId[i] = -1;
 }
 
 EfhEngine::~EfhEngine() {
 	delete _rnd;
+	delete _graphicsStruct;
 }
 
 bool EfhEngine::hasFeature(EngineFeature f) const {
@@ -82,6 +117,13 @@ Common::Error EfhEngine::run() {
 	CursorMan.replaceCursor(_normalCursor, 16, 16, 0, 0, 0);
 	CursorMan.showMouse(true);
 */
+	initEngine();
+	sub15150(-1);
+	sub12A7F();
+	displayLowStatusScreen(-1);
+
+	warning("STUB - Main loop");
+
 	return Common::kNoError;
 }
 
@@ -91,6 +133,35 @@ void EfhEngine::initialize() {
 	_shouldQuit = false;
 }
 
+int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
+	Common::File f;
+	if (!f.open(filename))
+		error("Unable to find file %s", filename.c_str());
+
+	int size = f.size();
+	
+	return f.read(destBuffer, size);
+}
+
+void EfhEngine::readAnimInfo() {
+	warning("STUB - readAnimInfo");
+}
+
+void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
+	warning("STUB - displayAnimFrames");
+}
+
+void EfhEngine::readTileFact() {
+	warning("STUB - readTileFact");
+}
+
+void EfhEngine::readItems() {
+	warning("STUB - readItems");
+}
+
+void EfhEngine::loadNPCS() {
+	warning("STUB - loadNPCS");
+}
 
 void EfhEngine::syncSoundSettings() {
 	Engine::syncSoundSettings();
@@ -102,4 +173,275 @@ Common::String EfhEngine::getSavegameFilename(int slot) {
 	return _targetName + Common::String::format("-%02d.SAV", slot);
 }
 
+void EfhEngine::initEngine() {
+	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
+	memset(_bufferCharBM, 0, sizeof(_bufferCharBM));
+	_graphicsStruct = new EfhGraphicsStruct;
+	memset(_graphicsStruct->_vgaLineBuffer, 0, sizeof(_graphicsStruct->_vgaLineBuffer));
+	_graphicsStruct->_shiftValue = 0;
+	_graphicsStruct->_width = 320;
+	_graphicsStruct->_height = 200;
+	_graphicsStruct->_area = Common::Rect(0, 0, 319, 199);
+
+	for (int i = 0; i < 3; ++i) {
+		memset(_tileBank[i], 0, sizeof(_tileBank[i]));
+	}
+
+	memset(_circleImageBuf, 0, sizeof(_circleImageBuf));
+	memset(_portraitBuf, 0, sizeof(_portraitBuf));
+	memset(_hiResImageBuf, 0, sizeof(_hiResImageBuf));
+	memset(_loResImageBuf, 0, sizeof(_loResImageBuf));
+	memset(_menuBuf, 0, sizeof(_menuBuf));
+	memset(_windowWithBorderBuf, 0, sizeof(_windowWithBorderBuf));
+	memset(_map, 0, sizeof(_map));
+	memset(_places, 0, sizeof(_places));
+	memset(_curPlace, 0, sizeof(_curPlace));
+	memset(_npcBuf, 0, sizeof(_npcBuf));
+	memset(_imp1, 0, sizeof(_imp1));
+	memset(_imp2, 0, sizeof(_imp2));
+	memset(_titleSong, 0, sizeof(_titleSong));
+	memset(_items, 0, sizeof(_items));
+	memset(_tileFact, 0, sizeof(_tileFact));
+	memset(_animInfo, 0, sizeof(_animInfo));
+	memset(_history, 0, sizeof(_history));
+	memset(_techData, 0, sizeof(_techData));
+
+	_mapBitmapRef = &_map[0];
+	_mapUnknownPtr = &_map[2];
+	_mapMonstersPtr = &_map[902];
+	_mapGameMapPtr = &_map[2758];
+
+	_graphicsStruct->_shiftValue = 0x2000;
+
+	_defaultBoxColor = 7;
+
+	// Init Font
+	static uint8 fontWidthArray[96] = {
+		3, 2, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 3, 3, 2, 7, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 1, 4, 4, 4,
+		4, 4, 4, 4, 4, 3, 4, 4, 4, 7, 5, 4, 4, 4, 4, 4, 5, 4, 5, 7, 5, 5, 5, 3, 7, 3, 5, 0, 2, 4, 4, 4, 4, 4, 4, 4,
+		4, 1, 2, 4, 1, 7, 4, 4, 4, 4, 4, 4, 3, 4, 5, 7, 4, 4, 5, 3, 0, 3, 0, 0
+	};
+
+	static uint8 fontExtraLinesArray[96] = {
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3,
+		1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 0, 0
+	};
+
+	static Font fontData[96] = {
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00},
+		{0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x00, 0x00},
+		{0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20, 0x00},
+		{0xC8, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x98, 0x00},
+		{0x20, 0x50, 0x20, 0x40, 0xA8, 0x90, 0x68, 0x00},
+		{0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40},
+		{0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40},
+		{0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00, 0x00},
+		{0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40},
+		{0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00},
+		{0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00},
+		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+		{0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00},
+		{0x60, 0x90, 0x10, 0x20, 0x40, 0x80, 0xF0, 0x00},
+		{0x60, 0x90, 0x10, 0x20, 0x10, 0x90, 0x60, 0x00},
+		{0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10, 0x00},
+		{0xF0, 0x80, 0xE0, 0x10, 0x10, 0x90, 0x60, 0x00},
+		{0x60, 0x90, 0x80, 0xE0, 0x90, 0x90, 0x60, 0x00},
+		{0xF0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00},
+		{0x60, 0x90, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00},
+		{0x60, 0x90, 0x90, 0x70, 0x10, 0x90, 0x60, 0x00},
+		{0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00},
+		{0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00},
+		{0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x00},
+		{0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00},
+		{0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80, 0x00},
+		{0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x60, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
+		{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0xE0, 0x00},
+		{0x60, 0x90, 0x80, 0x80, 0x80, 0x90, 0x60, 0x00},
+		{0xE0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE0, 0x00},
+		{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0xF0, 0x00},
+		{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x80, 0x00},
+		{0x60, 0x90, 0x80, 0xB0, 0x90, 0x90, 0x70, 0x00},
+		{0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
+		{0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00},
+		{0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00},
+		{0x90, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
+		{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00},
+		{0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00},
+		{0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x00},
+		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+		{0xE0, 0x90, 0x90, 0xE0, 0x80, 0x80, 0x80, 0x00},
+		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x10},
+		{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
+		{0x60, 0x90, 0x80, 0x60, 0x10, 0x90, 0x60, 0x00},
+		{0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00},
+		{0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+		{0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
+		{0x82, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x82, 0x00},
+		{0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00},
+		{0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, 0x00},
+		{0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00},
+		{0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0},
+		{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00},
+		{0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60},
+		{0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x60, 0x10, 0x70, 0x90, 0x70, 0x00},
+		{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00},
+		{0x00, 0x00, 0x60, 0x90, 0x80, 0x90, 0x60, 0x00},
+		{0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x70, 0x00},
+		{0x00, 0x00, 0x60, 0x90, 0xF0, 0x80, 0x60, 0x00},
+		{0x30, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
+		{0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0, 0x00},
+		{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
+		{0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
+		{0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80},
+		{0x80, 0x80, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x00},
+		{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
+		{0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00},
+		{0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
+		{0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x60, 0x00},
+		{0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x80, 0x80},
+		{0x00, 0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0x10},
+		{0x00, 0x00, 0xB0, 0xC0, 0x80, 0x80, 0x80, 0x00},
+		{0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xE0, 0x00},
+		{0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
+		{0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x00},
+		{0x00, 0x00, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
+		{0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x6E, 0x00},
+		{0x00, 0x00, 0x90, 0x90, 0x60, 0x90, 0x90, 0x00},
+		{0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0},
+		{0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00},
+		{0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+	};
+
+	_fontDescr._widthArray = fontWidthArray;
+	_fontDescr._extraLines = fontExtraLinesArray;
+	_fontDescr._fontData = fontData;
+	_fontDescr._charHeight = 8;
+	_fontDescr._extraVerticalSpace = 3;
+	_fontDescr._extraHorizontalSpace = 1;
+	_word31E9E = 0;
+
+	saveAnimImageSetId();
+
+	// Save int 1C
+	// Set new int 1C:
+	// TODO: Implement that in the main loop
+	// static uint8 counter = 0;
+	// ++counter;
+	// if (counter == 4) {
+	//    counter = 0;
+	//    tick220Fl = 1;
+	// }
+
+	// Load Title Screen
+	loadImageSet(11, (uint8 *)_circleImageBuf, (uint8 **)_circleImageSubFileArray, 0, _paletteTransformationConstant, (uint8 *)_hiResImageBuf, (uint8 *)_loResImageBuf);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+
+	// Load map tiles bitmaps
+	loadImageSetToTileBank(1, 1);
+	loadImageSetToTileBank(2, 2);
+
+	// Load characters bitmaps
+	loadImageSetToTileBank(3, 6);
+
+	// Load 320*200 Menu screen
+	Common::String fileName = Common::String::format("images\\imageset.%d", 10);
+	readFileToBuffer(fileName, _menuBuf);
+
+	// Load 96*64 Window with pink border and yellow bottom
+	fileName = Common::String::format("images\\imageset.%d", 12);
+	readFileToBuffer(fileName, _windowWithBorderBuf);
+
+	readAnimInfo();
+
+	displayAnimFrames(254, 0);
+	saveAnimImageSetId();
+	readTileFact();
+	readItems();
+	loadNPCS();
+
+	warning("STUB - initEngine");
+}
+
+void EfhEngine::saveAnimImageSetId() {
+	_oldAnimImageSetId = _animImageSetId;
+	_animImageSetId = 255;
+}
+
+void EfhEngine::sub15150(int i) {
+	warning("STUB - sub15150");
+}
+
+void EfhEngine::sub12A7F() {
+	warning("STUB - sub12A7F");
+}
+
+void EfhEngine::displayLowStatusScreen(int i) {
+	warning("STUB - displayLowStatusScreen");
+}
+
+void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer) {
+	warning("STUB - loadImageSet");
+}
+
+void EfhEngine::displayFctFullScreen() {
+	// CHECKME: 200 is in the original but looks suspicious.
+	displayBitmapAtPos(0, 0, 319, 200);
+}
+
+void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY) {
+	warning("STUB - displayBitmapAtPos");
+}
+
+void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
+	warning("STUB - sub24D92");
+}
+
+void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
+	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
+	int16 bankId = tileBankId - 1;
+	int16 setId = imageSetId - 1;
+
+	if (_currentTileBankImageSetId[bankId] == setId)
+		return;
+
+	_currentTileBankImageSetId[bankId] = setId;
+
+	if (bankId == 0 || bankId == 1)
+		_mapBitmapRef[bankId] = setId;
+
+	int16 ptrIndex = bankId * 72;
+	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+}
+
+void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation) {
+	uint16 height = READ_LE_INT16(imagePtr);
+	uint16 width = READ_LE_INT16(imagePtr + 2);
+	uint8 *imageData = imagePtr + 4;
+
+	_imageDataPtr._fieldA = width;
+	_imageDataPtr._dataPtr = imageData;
+	_imageDataPtr._height = height;
+	_imageDataPtr._width = width * 2;
+	_imageDataPtr._startX = _imageDataPtr._startY = 0;
+	
+	sub24D92(&_imageDataPtr, posX, posY);
+}
 } // End of namespace Efh
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 22b6ceac8d7..3692e6fe0b8 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -56,6 +56,38 @@ static const int kSavegameVersion = 1;
 
 struct EfhGameDescription;
 
+struct EfhGraphicsStruct {
+	uint16 _vgaLineBuffer[200];
+	uint16 _shiftValue;
+	uint16 _width;
+	uint16 _height;
+	Common::Rect _area;
+};
+
+struct Font {
+	uint8 _lines[8];
+};
+
+struct FontDescr {
+	uint8 *_widthArray;
+	uint8 *_extraLines;
+	Font  *_fontData;
+	uint8 _charHeight;
+	uint8 _extraVerticalSpace;
+	uint8 _extraHorizontalSpace;
+};
+
+struct BufferBM {
+	uint8 *_dataPtr;
+	uint16 _width;
+	uint16 _startX;
+	uint16 _startY;
+	uint16 _height;
+	uint16 _fieldA;
+	uint8 _paletteTransformation;
+	uint16 _fieldD;
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -97,6 +129,65 @@ private:
 	Common::Platform _platform;
 
 	void initialize();
+	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
+	void readAnimInfo();
+	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
+	void readTileFact();
+	void readItems();
+	void loadNPCS();
+	void initEngine();
+	void saveAnimImageSetId();
+	void sub15150(int i);
+	void sub12A7F();
+	void displayLowStatusScreen(int i);
+	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
+	void displayFctFullScreen();
+	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
+	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation);
+	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
+	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
+
+	uint8 _videoMode;
+	uint8 _bufferCharBM[128];
+	EfhGraphicsStruct *_graphicsStruct;
+	uint8 _tileBank[3][12000];
+	uint8 _circleImageBuf[40100];
+	uint8 _portraitBuf[25000];
+	uint8 _hiResImageBuf[40100];
+	uint8 _loResImageBuf[40100];
+	uint8 _menuBuf[12500];
+	uint8 _windowWithBorderBuf[1500];
+	uint8 _map[7000];
+	uint8 _places[12000];
+	uint8 _curPlace[600];
+	uint8 _npcBuf[13400];
+	uint8 _imp1[13000];
+	uint8 _imp2[10000];
+	uint8 _titleSong[1024];
+	uint8 _items[8100];
+	uint8 _tileFact[864];
+	uint8 _animInfo[9000];
+	uint8 _history[256];
+	uint8 _techData[4096];
+
+	uint8 *_mapBitmapRef;
+	uint8 *_mapUnknownPtr;
+	uint8 *_mapMonstersPtr;
+	uint8 *_mapGameMapPtr;
+
+	uint8 _defaultBoxColor;
+	FontDescr _fontDescr;
+
+	uint8 _word31E9E;
+
+	int16 _oldAnimImageSetId;
+	int16 _animImageSetId;
+	uint8 _paletteTransformationConstant;
+	uint8 *_circleImageSubFileArray[12];
+	uint8 *_imageSetSubFilesArray[214]; // CHECKME : logically it should be 216
+	BufferBM _imageDataPtr;
+	int16 _currentTileBankImageSetId[3];
+	
 };
 
 } // End of namespace Efh


Commit: 01fb53ec98c8a4dbd46a93cc745febf4b0069d56
    https://github.com/scummvm/scummvm/commit/01fb53ec98c8a4dbd46a93cc745febf4b0069d56
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Implement some functions loading files

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 5af49384ee3..88b0997a34d 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -33,7 +33,31 @@
 
 namespace Efh {
 
-EfhEngine *EfhEngine::s_Engine = 0;
+EfhEngine *EfhEngine::s_Engine = nullptr;
+
+EfhGraphicsStruct::EfhGraphicsStruct() {
+	_vgaLineBuffer = nullptr;
+	_shiftValue = 0;
+	_width = 0;
+	_height = 0;
+	_area = Common::Rect(0, 0, 0, 0);
+}
+EfhGraphicsStruct::EfhGraphicsStruct(int16 *lineBuf, int16 x, int16 y, int16 width, int16 height) {
+	_vgaLineBuffer = lineBuf;
+	_shiftValue = 0;
+	_width = width;
+	_height = height;
+	_area = Common::Rect(x, y, x + width - 1, y + height - 1);
+}
+
+void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
+	// Same buffer address
+	_vgaLineBuffer = src->_vgaLineBuffer;
+	_shiftValue = src->_shiftValue;
+	_width = src->_width;
+	_height = src->_height;
+	_area = src->_area;
+}
 
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	_system = syst;
@@ -46,6 +70,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_platform = Common::kPlatformUnknown;
 	_mainSurface = nullptr;
 
+	_vgaGraphicsStruct = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
+	
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
 	_mapBitmapRef = nullptr;
@@ -79,11 +105,21 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	for (int i = 0; i < 3; ++i)
 		_currentTileBankImageSetId[i] = -1;
+
+	_unkRelatedToAnimImageSetId = 0;
+	_techId = 0;
+	_currentAnimImageSetId = 0xFF;
+
+	for (int i = 0; i < 20; ++i)
+		_portraitSubFilesArray[i] = nullptr;
+
+	_unkAnimRelatedIndex = -1;
 }
 
 EfhEngine::~EfhEngine() {
 	delete _rnd;
 	delete _graphicsStruct;
+	delete _vgaGraphicsStruct;
 }
 
 bool EfhEngine::hasFeature(EngineFeature f) const {
@@ -91,7 +127,7 @@ bool EfhEngine::hasFeature(EngineFeature f) const {
 }
 
 const char *EfhEngine::getCopyrightString() const {
-	return "Escape From Hell (C) Electronic Arts, 1991";
+	return "Escape From Hell (C) Electronic Arts, 1990";
 }
 
 GameType EfhEngine::getGameType() const {
@@ -128,8 +164,8 @@ Common::Error EfhEngine::run() {
 }
 
 void EfhEngine::initialize() {
-	_rnd = new Common::RandomSource("efh");
-	_rnd->setSeed(42);                              // Kick random number generator
+	_rnd = new Common::RandomSource("Hell");
+	_rnd->setSeed(666);                              // Kick random number generator
 	_shouldQuit = false;
 }
 
@@ -144,23 +180,94 @@ int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
 }
 
 void EfhEngine::readAnimInfo() {
-	warning("STUB - readAnimInfo");
+	Common::String fileName = "gendata\\animinfo";
+	readFileToBuffer(fileName, _animInfo);
+}
+
+void EfhEngine::findMapFile(int16 mapId) {
+	if (_word31E9E == 0)
+		return;
+
+	Common::String fileName = Common::String::format("map\\map.%d", mapId);
+	Common::File f;
+	// The original was checking for the file and eventually asking to change floppies
+	if (!f.open(fileName))
+		error("File not found: %s", fileName.c_str());
+
+	f.close();
+}
+
+void EfhEngine::loadNewPortrait() {
+	static int16 unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
+	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
+
+	if (_currentAnimImageSetId == 200 + _unkRelatedToAnimImageSetId)
+		return;
+
+	findMapFile(_techId);
+	_currentAnimImageSetId = 200 + _unkRelatedToAnimImageSetId;
+	int imageSetId = _unkRelatedToAnimImageSetId + 13;
+	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+}
+
+void EfhEngine::loadAnimImageSet() {
+	warning("STUB - loadAnimImageSet");
+	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
+		return;
+
+	findMapFile(_techId);
+
+	_unkAnimRelatedIndex = 0;
+	_currentAnimImageSetId = _animImageSetId;
+
+	int16 animSetId = _animImageSetId + 17;
+	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+}
+
+void EfhEngine::drawUnknownMenuBox() {
+	warning("STUB - drawUnknownMenuBox");
+}
+
+void EfhEngine::displayAnimFrame() {
+	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
+	warning("STUB - displayAnimFrame");
 }
 
 void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
-	warning("STUB - displayAnimFrames");
+	if (animId == 0xFF)
+		return;
+
+	_animImageSetId = animId;
+	if (_animImageSetId == 0xFE)
+		loadNewPortrait();
+	else
+		loadAnimImageSet();
+
+	if (!displayMenuBoxFl)
+		return;
+	
+	for (int i = 0; i < 2; ++i) {
+		drawUnknownMenuBox();
+		displayAnimFrame();
+
+		if (i == 0)
+			displayFctFullScreen();
+	}
 }
 
 void EfhEngine::readTileFact() {
-	warning("STUB - readTileFact");
+	Common::String fileName = "gendata\\tilefact";
+	readFileToBuffer(fileName, _tileFact);
 }
 
 void EfhEngine::readItems() {
-	warning("STUB - readItems");
+	Common::String fileName = "gendata\\items";
+	readFileToBuffer(fileName, _items);
 }
 
 void EfhEngine::loadNPCS() {
-	warning("STUB - loadNPCS");
+	Common::String fileName = "gendata\\npcs";
+	readFileToBuffer(fileName, _npcBuf);
 }
 
 void EfhEngine::syncSoundSettings() {
@@ -177,11 +284,7 @@ void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
 	memset(_bufferCharBM, 0, sizeof(_bufferCharBM));
 	_graphicsStruct = new EfhGraphicsStruct;
-	memset(_graphicsStruct->_vgaLineBuffer, 0, sizeof(_graphicsStruct->_vgaLineBuffer));
-	_graphicsStruct->_shiftValue = 0;
-	_graphicsStruct->_width = 320;
-	_graphicsStruct->_height = 200;
-	_graphicsStruct->_area = Common::Rect(0, 0, 319, 199);
+	_graphicsStruct->copy(_vgaGraphicsStruct);
 
 	for (int i = 0; i < 3; ++i) {
 		memset(_tileBank[i], 0, sizeof(_tileBank[i]));
@@ -371,7 +474,7 @@ void EfhEngine::initEngine() {
 
 	readAnimInfo();
 
-	displayAnimFrames(254, 0);
+	displayAnimFrames(0xFE, false);
 	saveAnimImageSetId();
 	readTileFact();
 	readItems();
@@ -408,6 +511,7 @@ void EfhEngine::displayFctFullScreen() {
 
 void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY) {
 	warning("STUB - displayBitmapAtPos");
+	_graphicsStruct->copy(_vgaGraphicsStruct);
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 3692e6fe0b8..c6f137cd143 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -56,12 +56,18 @@ static const int kSavegameVersion = 1;
 
 struct EfhGameDescription;
 
-struct EfhGraphicsStruct {
-	uint16 _vgaLineBuffer[200];
+class EfhGraphicsStruct {
+public:
+	EfhGraphicsStruct();
+	EfhGraphicsStruct(int16 *lineBuf, int16 x, int16 y, int16 width, int16 height);
+
+	int16 *_vgaLineBuffer;
 	uint16 _shiftValue;
 	uint16 _width;
 	uint16 _height;
 	Common::Rect _area;
+
+	void copy(EfhGraphicsStruct *src);
 };
 
 struct Font {
@@ -131,6 +137,11 @@ private:
 	void initialize();
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void readAnimInfo();
+	void findMapFile(int16 mapId);
+	void loadNewPortrait();
+	void loadAnimImageSet();
+	void drawUnknownMenuBox();
+	void displayAnimFrame();
 	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
 	void readTileFact();
 	void readItems();
@@ -149,6 +160,8 @@ private:
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
+	int16 _vgaLineBuffer[200];
+	EfhGraphicsStruct *_vgaGraphicsStruct;
 	EfhGraphicsStruct *_graphicsStruct;
 	uint8 _tileBank[3][12000];
 	uint8 _circleImageBuf[40100];
@@ -187,7 +200,11 @@ private:
 	uint8 *_imageSetSubFilesArray[214]; // CHECKME : logically it should be 216
 	BufferBM _imageDataPtr;
 	int16 _currentTileBankImageSetId[3];
-	
+	int16 _unkRelatedToAnimImageSetId;
+	int16 _techId;
+	int16 _currentAnimImageSetId;
+	uint8 *_portraitSubFilesArray[20];
+	int16 _unkAnimRelatedIndex;
 };
 
 } // End of namespace Efh


Commit: d679199d67e7ddcc8ab7ccb34085e0d6a504613f
    https://github.com/scummvm/scummvm/commit/d679199d67e7ddcc8ab7ccb34085e0d6a504613f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: More work on initEngine

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 88b0997a34d..f521d890678 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -70,7 +70,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_platform = Common::kPlatformUnknown;
 	_mainSurface = nullptr;
 
-	_vgaGraphicsStruct = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
+	_vgaGraphicsStruct1 = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
+	_vgaGraphicsStruct2 = new EfhGraphicsStruct();
 	
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
@@ -113,13 +114,48 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	for (int i = 0; i < 20; ++i)
 		_portraitSubFilesArray[i] = nullptr;
 
+	for (int i = 0; i < 100; ++i)
+		_imp1PtrArray[i] = nullptr;
+
+	for (int i = 0; i < 432; ++i)
+		_imp2PtrArray[i] = nullptr;
+
 	_unkAnimRelatedIndex = -1;
+
+	_initRect = Common::Rect(0, 0, 0, 0);
+	_engineInitPending = true;
+	_unkVideoRelatedWord1 = 0x0E;
+	_protectionPassed = false;
+	_fullPlaceId = 0xFF;
+	_guessAnimationAmount = 9;
+	_largeMapFlag = 0xFFFF;
+	_teamCharIdArray = 0;
+	_charId = -1;
+	_word2C8B8 = -1;
+
+	for (int i = 0; i < 3; ++i) {
+		_teamCharStatus[i]._status = 0;
+		_teamCharStatus[i]._duration = 0;
+		_unkArray2C8AA[i] = 0;
+	}
+
+	_unkArray2C8AA[2] = 1;
+	_teamSize = 1;
+	_word2C872 = 0;
+	_imageSetSubFilesIdx = 144;
+
+	_mapPosX = _mapPosY = 31;
+	_oldMapPosX = _oldMapPosY = 31;
+	_techDataId_MapPosX = _techDataId_MapPosY = 31;
+
+	_lastMainPlaceId = 0;
 }
 
 EfhEngine::~EfhEngine() {
 	delete _rnd;
 	delete _graphicsStruct;
-	delete _vgaGraphicsStruct;
+	delete _vgaGraphicsStruct1;
+	delete _vgaGraphicsStruct2;
 }
 
 bool EfhEngine::hasFeature(EngineFeature f) const {
@@ -154,10 +190,13 @@ Common::Error EfhEngine::run() {
 	CursorMan.showMouse(true);
 */
 	initEngine();
-	sub15150(-1);
+	sub15150(true);
 	sub12A7F();
 	displayLowStatusScreen(-1);
 
+	if (!_protectionPassed)
+		return Common::kNoError;
+
 	warning("STUB - Main loop");
 
 	return Common::kNoError;
@@ -224,6 +263,54 @@ void EfhEngine::loadAnimImageSet() {
 	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
 }
 
+void EfhEngine::loadHistory() {
+	Common::String fileName = "gendata\\history";
+	readFileToBuffer(fileName, _history);
+}
+
+void EfhEngine::loadTechMapImp(int16 fileId) {
+	if (fileId == 0xFF)
+		return;
+
+	_techId = fileId;
+	findMapFile(_techId);
+
+	Common::String fileName = Common::String::format("maps\\tech.%d", _techId);
+	readFileToBuffer(fileName, _hiResImageBuf);
+	uncompressBuffer(_hiResImageBuf, _techData);
+
+	fileName = Common::String::format("maps\\map.%d", _techId);
+	readFileToBuffer(fileName, _hiResImageBuf);
+	uncompressBuffer(_hiResImageBuf, _map);
+
+	loadImageSetToTileBank(1, _mapBitmapRef[0]);
+	loadImageSetToTileBank(1, _mapBitmapRef[1]);
+
+	initMapMonsters();
+	readImpFile(_techId, true);
+	displayAnimFrames(0xFE, false);
+	
+}
+
+void EfhEngine::loadPlacesFile(uint16 fullPlaceId, int16 unused, bool forceReloadFl) {
+	//TODO : Remove unused parameter when all the calls are implemented
+	if (fullPlaceId == 0xFF)
+		return;
+
+	findMapFile(_techId);
+	_fullPlaceId = fullPlaceId;
+	uint16 minPlace = _lastMainPlaceId * 20;
+	uint16 maxPlace = minPlace + 19;
+
+	if (_fullPlaceId < minPlace || _fullPlaceId > maxPlace || forceReloadFl) {
+		_lastMainPlaceId = _fullPlaceId / 20;
+		Common::String fileName = Common::String::format("maps\\places.%d", _lastMainPlaceId);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _places);
+	}
+	copyCurrentPlaceToBuffer(_fullPlaceId / 20);
+}
+
 void EfhEngine::drawUnknownMenuBox() {
 	warning("STUB - drawUnknownMenuBox");
 }
@@ -270,6 +357,40 @@ void EfhEngine::loadNPCS() {
 	readFileToBuffer(fileName, _npcBuf);
 }
 
+void EfhEngine::setDefaultNoteDuration() {
+	// Original implementation is based on the int1C, which is triggered at 18.2065Hz.
+	// Every 4 times, it sets a flag (thus, approx every 220ms)
+	// The function was checking the keyboard in a loop, incrementing a counter and setting the last character read
+	// The "_defaultNoteDuration" was then set to 7 times this counter
+	//
+	// No implementation required in ScummVM
+}
+
+Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
+	warning("STUB: playSong");
+	return Common::KEYCODE_INVALID;
+}
+
+void EfhEngine::decryptImpFile(bool techMapFl) {
+	warning("STUB - decryptImpFile");	
+}
+
+void EfhEngine::readImpFile(int16 id, bool techMapFl) {
+	Common::String fileName = Common::String::format("imp\\imp.%d", id);
+
+	if (techMapFl)
+		readFileToBuffer(fileName, _imp1);
+	else
+		readFileToBuffer(fileName, _imp2);
+
+	decryptImpFile(techMapFl);
+}
+
+Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
+	warning("STUB - getLastCharAfterAnimCount");
+	return Common::KEYCODE_INVALID;
+}
+
 void EfhEngine::syncSoundSettings() {
 	Engine::syncSoundSettings();
 
@@ -284,7 +405,7 @@ void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
 	memset(_bufferCharBM, 0, sizeof(_bufferCharBM));
 	_graphicsStruct = new EfhGraphicsStruct;
-	_graphicsStruct->copy(_vgaGraphicsStruct);
+	_graphicsStruct->copy(_vgaGraphicsStruct1);
 
 	for (int i = 0; i < 3; ++i) {
 		memset(_tileBank[i], 0, sizeof(_tileBank[i]));
@@ -314,7 +435,10 @@ void EfhEngine::initEngine() {
 	_mapMonstersPtr = &_map[902];
 	_mapGameMapPtr = &_map[2758];
 
-	_graphicsStruct->_shiftValue = 0x2000;
+	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
+	_vgaGraphicsStruct2->_shiftValue = 0x2000;
+
+	_graphicsStruct->copy(_vgaGraphicsStruct2);
 
 	_defaultBoxColor = 7;
 
@@ -480,7 +604,90 @@ void EfhEngine::initEngine() {
 	readItems();
 	loadNPCS();
 
-	warning("STUB - initEngine");
+	// Load picture room with girlfriend
+	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	fileName = "gendata\\titlsong"; 
+	readFileToBuffer(fileName, _titleSong);
+	setDefaultNoteDuration();
+	Common::KeyCode lastInput = playSong(_titleSong);
+
+	if (lastInput != Common::KEYCODE_ESCAPE) {
+		sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+		displayFctFullScreen();
+		sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+
+		// Load animations on previous picture with GF
+		loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+		readImpFile(100, 0);
+		lastInput = getLastCharAfterAnimCount(8);
+
+		if (lastInput != Common::KEYCODE_ESCAPE) {
+			sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+			sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+			displayFctFullScreen();
+			sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+			sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+			lastInput = getLastCharAfterAnimCount(80);
+			if (lastInput != Common::KEYCODE_ESCAPE) {
+				sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16, _paletteTransformationConstant);
+				sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+				sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+				displayFctFullScreen();
+				sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16, _paletteTransformationConstant);
+				sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+				sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+				lastInput = getLastCharAfterAnimCount(80);
+				if (lastInput != Common::KEYCODE_ESCAPE) {
+					sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16, _paletteTransformationConstant);
+					sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+					sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+					displayFctFullScreen();
+					sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16, _paletteTransformationConstant);
+					sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+					sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+					lastInput = getLastCharAfterAnimCount(80);
+					if (lastInput != Common::KEYCODE_ESCAPE) {
+						sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+						sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+						displayFctFullScreen();
+						sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+						sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+						lastInput = getLastCharAfterAnimCount(80);
+						if (lastInput != Common::KEYCODE_ESCAPE) {
+							sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+							sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+							displayFctFullScreen();
+							sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+							sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+							lastInput = getLastCharAfterAnimCount(80);
+							if (lastInput != Common::KEYCODE_ESCAPE) {
+								sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+								sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+								displayFctFullScreen();
+								sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
+								sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+								lastInput = getLastCharAfterAnimCount(80);
+							}
+						}
+					}
+				}
+			}
+		}		
+	}
+
+	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	readImpFile(99, 0);
+	_word31E9E = 0xFFFF;
+	restoreAnimImageSetId();
+
+	// Save int 24h, set new int24 to handle fatal failure
+	checkProtection();
+	loadGame();
+	_engineInitPending = false;
+	}
+
+void EfhEngine::initMapMonsters() {
+	warning("STUB - initMapMonsters");
 }
 
 void EfhEngine::saveAnimImageSetId() {
@@ -488,7 +695,7 @@ void EfhEngine::saveAnimImageSetId() {
 	_animImageSetId = 255;
 }
 
-void EfhEngine::sub15150(int i) {
+void EfhEngine::sub15150(bool flag) {
 	warning("STUB - sub15150");
 }
 
@@ -511,13 +718,23 @@ void EfhEngine::displayFctFullScreen() {
 
 void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY) {
 	warning("STUB - displayBitmapAtPos");
-	_graphicsStruct->copy(_vgaGraphicsStruct);
+	_graphicsStruct->copy(_vgaGraphicsStruct2);
+	_initRect = Common::Rect(minX, minY, maxX, maxY);
+	displayBitmap(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
+}
+
+void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
+	warning("STUB - displayBitmap");
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 	warning("STUB - sub24D92");
 }
 
+void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {
+	warning("STUB - sub133E5");
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
@@ -535,6 +752,87 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
 }
 
+void EfhEngine::restoreAnimImageSetId() {
+	_animImageSetId = _oldAnimImageSetId;
+}
+
+void EfhEngine::checkProtection() {
+	bool successfulCheck = false;
+	uint protectionItemId = _rnd->getRandomNumber(5);
+	uint ProtectionArrayId = _rnd->getRandomNumber(14);
+	_unkVideoRelatedWord1 = 0xE;
+
+	//CHECKME : Well, yeah, some code may be missing there. Who knows.
+	
+	_protectionPassed = true;
+	sub15150(true);	
+}
+
+void EfhEngine::loadGame() {
+	// The original used a loop to check for the presence of the savegame on the current floppy.
+	// When the savegame wasn't found, it was displaying a screen asking for Disk 1 and was setting a flag used
+	// to call a function after loading right before returning.
+	//
+	// The savegame is used to initialize the engine, so this part is reimplemented.
+	// The check for existence is replaced by an error.
+	//
+	// Fun fact : it was therefore expected to overwrite the original savegame on the floppy each time you saved. What could possibly go wrong?
+
+	Common::String fileName = "gendata\\savegame";
+	Common::File f;
+
+	if (!f.open(fileName))
+		error("Missing file %s", fileName.c_str());
+
+	_techId = f.readSint16LE();
+	_fullPlaceId = f.readUint16LE();
+	_guessAnimationAmount = f.readSint16LE();
+	_largeMapFlag = f.readUint16LE();
+	_teamCharIdArray = f.readSint16LE();
+	_charId = f.readSint16LE();
+	_word2C8B8 = f.readSint16LE();
+
+	for (int i = 0; i < 3; ++i) {
+		_teamCharStatus[i]._status = f.readSint16LE();
+		_teamCharStatus[i]._duration = f.readSint16LE();
+	}
+
+	_teamSize = f.readSint16LE();
+
+	for (int i = 0; i < 3; ++i) {
+		_unkArray2C8AA[i] = f.readSint16LE();		
+	}
+
+	_word2C872 = f.readSint16LE();
+
+	_imageSetSubFilesIdx = f.readSint16LE();
+	_mapPosX = f.readSint16LE();
+	_mapPosY = f.readSint16LE();
+	_techDataId_MapPosX = f.readSint16LE();
+	_techDataId_MapPosY = f.readSint16LE();
+
+	f.close();
+
+	_oldMapPosX = _mapPosX;
+	_oldMapPosY = _mapPosY;
+	_unkRelatedToAnimImageSetId = 0;
+	loadNPCS();
+
+	loadHistory();
+	loadTechMapImp(_techId);
+
+	_lastMainPlaceId = 0xFFFF;
+	loadPlacesFile(_fullPlaceId, 0, true);
+}
+
+void EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
+	warning("TODO: uncompressBuffer");
+}
+
+void EfhEngine::copyCurrentPlaceToBuffer(int id) {
+	warning("STUB - copyCurrentPlaceToBuffer");
+}
+
 void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation) {
 	uint16 height = READ_LE_INT16(imagePtr);
 	uint16 width = READ_LE_INT16(imagePtr + 2);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index c6f137cd143..40a1b612b14 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -94,6 +94,11 @@ struct BufferBM {
 	uint16 _fieldD;
 };
 
+struct CharStatus {
+	int16 _status;
+	int16 _duration;
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -103,7 +108,6 @@ public:
 	Graphics::Surface *_mainSurface;
 	Common::RandomSource *_rnd;
 
-
 	const EfhGameDescription *_gameDescription;
 	uint32 getFeatures() const;
 	const char *getGameId() const;
@@ -140,28 +144,46 @@ private:
 	void findMapFile(int16 mapId);
 	void loadNewPortrait();
 	void loadAnimImageSet();
+	void loadHistory();
+	void loadTechMapImp(int16 fileId);
+	void loadPlacesFile(uint16 fullPlaceId, int16 unused, bool forceReloadFl);
 	void drawUnknownMenuBox();
 	void displayAnimFrame();
 	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
 	void readTileFact();
 	void readItems();
 	void loadNPCS();
+	void setDefaultNoteDuration();
+	Common::KeyCode playSong(uint8 *buffer);
+	void decryptImpFile(bool techMapFl);
+	void readImpFile(int16 id, bool techMapFl);
+	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
 	void initEngine();
+	void initMapMonsters();
 	void saveAnimImageSetId();
-	void sub15150(int i);
-	void sub12A7F();
 	void displayLowStatusScreen(int i);
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
 	void displayFctFullScreen();
 	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
+	void displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
+	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
+	void restoreAnimImageSetId();
+	void checkProtection();
+	void loadGame();
+	void uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
+	void copyCurrentPlaceToBuffer(int id);
+
+	void sub15150(bool flag);
+	void sub12A7F();
 	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation);
 	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
-	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
+	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
 	int16 _vgaLineBuffer[200];
-	EfhGraphicsStruct *_vgaGraphicsStruct;
+	EfhGraphicsStruct *_vgaGraphicsStruct1;
+	EfhGraphicsStruct *_vgaGraphicsStruct2;
 	EfhGraphicsStruct *_graphicsStruct;
 	uint8 _tileBank[3][12000];
 	uint8 _circleImageBuf[40100];
@@ -191,7 +213,8 @@ private:
 	uint8 _defaultBoxColor;
 	FontDescr _fontDescr;
 
-	uint8 _word31E9E;
+	uint16 _word31E9E;
+	uint16 _unkVideoRelatedWord1;
 
 	int16 _oldAnimImageSetId;
 	int16 _animImageSetId;
@@ -205,6 +228,29 @@ private:
 	int16 _currentAnimImageSetId;
 	uint8 *_portraitSubFilesArray[20];
 	int16 _unkAnimRelatedIndex;
+	uint8 *_imp1PtrArray[100];
+	uint8 *_imp2PtrArray[432];
+	uint16 _fullPlaceId;
+	int16 _guessAnimationAmount;
+	uint16 _largeMapFlag; // CHECKME: bool?
+	int16 _teamCharIdArray;
+	int16 _charId;
+	int16 _word2C8B8;
+	
+	Common::Rect _initRect;
+	bool _engineInitPending;
+	bool _protectionPassed;
+
+	CharStatus _teamCharStatus[3];
+	int16 _unkArray2C8AA[3];
+	int16 _teamSize;
+	int16 _word2C872;
+	int16 _imageSetSubFilesIdx;
+
+	int16 _mapPosX, _mapPosY;
+	int16 _oldMapPosX, _oldMapPosY;
+	int16 _techDataId_MapPosX, _techDataId_MapPosY;
+	uint16 _lastMainPlaceId;
 };
 
 } // End of namespace Efh


Commit: acec83040bf2815d918debec8bd308d371ee7248
    https://github.com/scummvm/scummvm/commit/acec83040bf2815d918debec8bd308d371ee7248
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Implement decompression, add searchman directories

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index f521d890678..b684bebd705 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -60,6 +60,13 @@ void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
 }
 
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+
+	SearchMan.addSubDirectoryMatching(gameDataDir, "gendata");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "images");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "imp");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "maps");
+
 	_system = syst;
 	_rnd = nullptr;
 
@@ -575,7 +582,7 @@ void EfhEngine::initEngine() {
 	// }
 
 	// Load Title Screen
-	loadImageSet(11, (uint8 *)_circleImageBuf, (uint8 **)_circleImageSubFileArray, 0, _paletteTransformationConstant, (uint8 *)_hiResImageBuf, (uint8 *)_loResImageBuf);
+	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
 	displayFctFullScreen();
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
 	displayFctFullScreen();
@@ -589,11 +596,11 @@ void EfhEngine::initEngine() {
 	loadImageSetToTileBank(3, 6);
 
 	// Load 320*200 Menu screen
-	Common::String fileName = Common::String::format("images\\imageset.%d", 10);
+	Common::String fileName = Common::String::format("imageset.%d", 10);
 	readFileToBuffer(fileName, _menuBuf);
 
 	// Load 96*64 Window with pink border and yellow bottom
-	fileName = Common::String::format("images\\imageset.%d", 12);
+	fileName = Common::String::format("imageset.%d", 12);
 	readFileToBuffer(fileName, _windowWithBorderBuf);
 
 	readAnimInfo();
@@ -676,7 +683,7 @@ void EfhEngine::initEngine() {
 	}
 
 	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
-	readImpFile(99, 0);
+	readImpFile(99, false);
 	_word31E9E = 0xFFFF;
 	restoreAnimImageSetId();
 
@@ -708,7 +715,27 @@ void EfhEngine::displayLowStatusScreen(int i) {
 }
 
 void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer) {
-	warning("STUB - loadImageSet");
+	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
+	rImageFile(fileName, buffer, subFilesArray, CGAVal, EGAVal, destBuffer, transfBuffer);
+}
+
+void EfhEngine::rImageFile(Common::String filename, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *targetBuffer) {
+	readFileToBuffer(filename, packedBuffer);
+	uncompressBuffer(packedBuffer, targetBuffer);
+
+	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (1 Bpp)
+	// => Write a class to handle that more properly
+	uint8 *ptr = targetBuffer;
+	uint16 counter = 0;
+	while (READ_LE_INT16(ptr) != 0) {
+		subFilesArray[counter] = ptr;
+		++counter;
+		int16 imageWidth = READ_LE_INT16(ptr);
+		ptr += 2;
+		int16 imageHeight = READ_LE_INT16(ptr);
+		ptr += 2;
+		ptr += (imageWidth * imageHeight);
+	}
 }
 
 void EfhEngine::displayFctFullScreen() {
@@ -757,9 +784,9 @@ void EfhEngine::restoreAnimImageSetId() {
 }
 
 void EfhEngine::checkProtection() {
-	bool successfulCheck = false;
-	uint protectionItemId = _rnd->getRandomNumber(5);
-	uint ProtectionArrayId = _rnd->getRandomNumber(14);
+	// bool successfulCheck = false;
+	// uint8 protectionItemId = _rnd->getRandomNumber(5);
+	// uint8 ProtectionArrayId = _rnd->getRandomNumber(14);
 	_unkVideoRelatedWord1 = 0xE;
 
 	//CHECKME : Well, yeah, some code may be missing there. Who knows.
@@ -826,7 +853,54 @@ void EfhEngine::loadGame() {
 }
 
 void EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
-	warning("TODO: uncompressBuffer");
+	if (compressedBuf == nullptr || destBuf == nullptr)
+		error("uncompressBuffer - Invalid pointer used in parameter list");
+
+	uint8 *curPtrDest = destBuf;
+
+	uint16 compSize = READ_LE_UINT16(compressedBuf) + 1;	
+	uint8 *curPtrCompressed = compressedBuf + 2;
+
+	for (;;) {
+		uint8 next = *curPtrCompressed;
+		++curPtrCompressed;
+		--compSize;
+		if (compSize == 0)
+			break;
+
+		if (next != 0xC3) {
+			*curPtrDest = next;
+			++curPtrDest;
+			continue;
+		}
+
+		next = *curPtrCompressed;
+		++curPtrCompressed;
+		--compSize;
+		if (compSize == 0)
+			break;
+
+		if (next == 0) {
+			*curPtrDest = 0xC3;
+			++curPtrDest;
+			continue;
+		}
+
+		uint8 loopVal = next;
+		next = *curPtrCompressed;
+		++curPtrCompressed;
+
+		for (int i = 0; i < loopVal; ++i) {
+			*curPtrDest = next;
+			++curPtrDest;
+		}
+		
+		--compSize;
+		if (compSize == 0)
+			break;
+	}
+
+	curPtrDest[0] = curPtrDest[1] = 0;
 }
 
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 40a1b612b14..4e71f618b42 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -163,6 +163,7 @@ private:
 	void saveAnimImageSetId();
 	void displayLowStatusScreen(int i);
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
+	void rImageFile(Common::String filename, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *targetBuffer);
 	void displayFctFullScreen();
 	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
 	void displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);


Commit: ed94879a48ca8bfd50ee5c756e5dd0313b8cc91e
    https://github.com/scummvm/scummvm/commit/ed94879a48ca8bfd50ee5c756e5dd0313b8cc91e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Clean decompression code, add DumpFile, fix some uselessly specified paths

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b684bebd705..b9ea836fe5f 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -226,7 +226,7 @@ int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
 }
 
 void EfhEngine::readAnimInfo() {
-	Common::String fileName = "gendata\\animinfo";
+	Common::String fileName = "animinfo";
 	readFileToBuffer(fileName, _animInfo);
 }
 
@@ -234,7 +234,7 @@ void EfhEngine::findMapFile(int16 mapId) {
 	if (_word31E9E == 0)
 		return;
 
-	Common::String fileName = Common::String::format("map\\map.%d", mapId);
+	Common::String fileName = Common::String::format("map.%d", mapId);
 	Common::File f;
 	// The original was checking for the file and eventually asking to change floppies
 	if (!f.open(fileName))
@@ -271,7 +271,7 @@ void EfhEngine::loadAnimImageSet() {
 }
 
 void EfhEngine::loadHistory() {
-	Common::String fileName = "gendata\\history";
+	Common::String fileName = "history";
 	readFileToBuffer(fileName, _history);
 }
 
@@ -282,11 +282,11 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	_techId = fileId;
 	findMapFile(_techId);
 
-	Common::String fileName = Common::String::format("maps\\tech.%d", _techId);
+	Common::String fileName = Common::String::format("tech.%d", _techId);
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _techData);
 
-	fileName = Common::String::format("maps\\map.%d", _techId);
+	fileName = Common::String::format("map.%d", _techId);
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _map);
 
@@ -311,7 +311,7 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, int16 unused, bool forceReloa
 
 	if (_fullPlaceId < minPlace || _fullPlaceId > maxPlace || forceReloadFl) {
 		_lastMainPlaceId = _fullPlaceId / 20;
-		Common::String fileName = Common::String::format("maps\\places.%d", _lastMainPlaceId);
+		Common::String fileName = Common::String::format("places.%d", _lastMainPlaceId);
 		readFileToBuffer(fileName, _hiResImageBuf);
 		uncompressBuffer(_hiResImageBuf, _places);
 	}
@@ -350,17 +350,17 @@ void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
 }
 
 void EfhEngine::readTileFact() {
-	Common::String fileName = "gendata\\tilefact";
+	Common::String fileName = "tilefact";
 	readFileToBuffer(fileName, _tileFact);
 }
 
 void EfhEngine::readItems() {
-	Common::String fileName = "gendata\\items";
+	Common::String fileName = "items";
 	readFileToBuffer(fileName, _items);
 }
 
 void EfhEngine::loadNPCS() {
-	Common::String fileName = "gendata\\npcs";
+	Common::String fileName = "npcs";
 	readFileToBuffer(fileName, _npcBuf);
 }
 
@@ -383,7 +383,7 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 }
 
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
-	Common::String fileName = Common::String::format("imp\\imp.%d", id);
+	Common::String fileName = Common::String::format("imp.%d", id);
 
 	if (techMapFl)
 		readFileToBuffer(fileName, _imp1);
@@ -613,7 +613,7 @@ void EfhEngine::initEngine() {
 
 	// Load picture room with girlfriend
 	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
-	fileName = "gendata\\titlsong"; 
+	fileName = "titlsong"; 
 	readFileToBuffer(fileName, _titleSong);
 	setDefaultNoteDuration();
 	Common::KeyCode lastInput = playSong(_titleSong);
@@ -721,8 +721,13 @@ void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArra
 
 void EfhEngine::rImageFile(Common::String filename, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *targetBuffer) {
 	readFileToBuffer(filename, packedBuffer);
-	uncompressBuffer(packedBuffer, targetBuffer);
-
+	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
+	// TODO: Keep this dump for debug purposes only
+	Common::DumpFile dump;
+	dump.open(filename + ".dump");
+	dump.write(targetBuffer, size);
+	// End of dump	
+	
 	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (1 Bpp)
 	// => Write a class to handle that more properly
 	uint8 *ptr = targetBuffer;
@@ -805,7 +810,7 @@ void EfhEngine::loadGame() {
 	//
 	// Fun fact : it was therefore expected to overwrite the original savegame on the floppy each time you saved. What could possibly go wrong?
 
-	Common::String fileName = "gendata\\savegame";
+	Common::String fileName = "savegame";
 	Common::File f;
 
 	if (!f.open(fileName))
@@ -852,7 +857,7 @@ void EfhEngine::loadGame() {
 	loadPlacesFile(_fullPlaceId, 0, true);
 }
 
-void EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
+uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 	if (compressedBuf == nullptr || destBuf == nullptr)
 		error("uncompressBuffer - Invalid pointer used in parameter list");
 
@@ -861,38 +866,36 @@ void EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 	uint16 compSize = READ_LE_UINT16(compressedBuf) + 1;	
 	uint8 *curPtrCompressed = compressedBuf + 2;
 
+	// Not in the original. This has been added for debug purposes (the original function doesn't return a value)
+	uint32 decompSize = 0;
+
 	for (;;) {
-		uint8 next = *curPtrCompressed;
-		++curPtrCompressed;
-		--compSize;
-		if (compSize == 0)
+		uint8 next = *curPtrCompressed++;
+		if (--compSize <= 0)
 			break;
 
 		if (next != 0xC3) {
-			*curPtrDest = next;
-			++curPtrDest;
+			*curPtrDest++ = next;
+			++decompSize;
 			continue;
 		}
 
-		next = *curPtrCompressed;
-		++curPtrCompressed;
-		--compSize;
-		if (compSize == 0)
+		next = *curPtrCompressed++;
+		if (--compSize <= 0)
 			break;
 
 		if (next == 0) {
-			*curPtrDest = 0xC3;
-			++curPtrDest;
+			*curPtrDest++ = 0xC3;
+			++decompSize;
 			continue;
 		}
-
+			
 		uint8 loopVal = next;
-		next = *curPtrCompressed;
-		++curPtrCompressed;
+		next = *curPtrCompressed++;
 
 		for (int i = 0; i < loopVal; ++i) {
-			*curPtrDest = next;
-			++curPtrDest;
+			*curPtrDest++ = next;
+			++decompSize;
 		}
 		
 		--compSize;
@@ -901,6 +904,9 @@ void EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 	}
 
 	curPtrDest[0] = curPtrDest[1] = 0;
+	decompSize += 2;
+
+	return decompSize;
 }
 
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4e71f618b42..22b5263e67f 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -171,7 +171,7 @@ private:
 	void restoreAnimImageSetId();
 	void checkProtection();
 	void loadGame();
-	void uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
+	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	void copyCurrentPlaceToBuffer(int id);
 
 	void sub15150(bool flag);


Commit: 0ba647297900d8be40330a8842af3539b034308f
    https://github.com/scummvm/scummvm/commit/0ba647297900d8be40330a8842af3539b034308f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH : Add some more functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b9ea836fe5f..2849ff1c98e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -156,6 +156,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_techDataId_MapPosX = _techDataId_MapPosY = 31;
 
 	_lastMainPlaceId = 0;
+	_word2C86E = 0;
+	_dword2C856 = nullptr;
 }
 
 EfhEngine::~EfhEngine() {
@@ -687,11 +689,12 @@ void EfhEngine::initEngine() {
 	_word31E9E = 0xFFFF;
 	restoreAnimImageSetId();
 
-	// Save int 24h, set new int24 to handle fatal failure
+	// Note: The original at this point saves int 24h and sets a new int24 to handle fatal failure
+
 	checkProtection();
 	loadGame();
 	_engineInitPending = false;
-	}
+}
 
 void EfhEngine::initMapMonsters() {
 	warning("STUB - initMapMonsters");
@@ -703,7 +706,28 @@ void EfhEngine::saveAnimImageSetId() {
 }
 
 void EfhEngine::sub15150(bool flag) {
-	warning("STUB - sub15150");
+	uint8 mapTileInfo = getMapTileInfo(_mapPosX, _mapPosY);
+	int16 imageSetId = _currentTileBankImageSetId[mapTileInfo / 72];
+
+	int16 mapImageSetId = (imageSetId * 72) + (mapTileInfo % 72);
+	// CHECKME : Why do we compute this Id if we don't use it?
+	
+	for (int counter = 0; counter < 2; ++counter) {
+		if (counter == 0 || flag) {
+			sub1512B();
+			// TODO: _word2C86E is some kind of counter
+			if (_word2C86E != 0) {
+				// TODO: _dword2C856 is most likely an "Imp" Array
+				// Note: the original was doing the check in the opposite order, which looks really suspicious
+				if ((_dword2C856 != nullptr) && (_dword2C856[0] != 0x30)) {
+					sub221FA(_dword2C856, false);
+				}
+			}
+		}
+
+		if (counter == 0 && flag)
+			displayFctFullScreen();
+	}
 }
 
 void EfhEngine::sub12A7F() {
@@ -767,6 +791,46 @@ void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY,
 	warning("STUB - sub133E5");
 }
 
+void EfhEngine::sub1512B() {
+	displayFullScreenColoredMenuBox(0);
+	sub15094();
+	sub150EE();
+	sub15018();
+	displayAnimFrame();
+	displayLowStatusScreen(0);
+}
+
+void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
+	for (uint8 counter = 0; counter < 2; ++counter) {
+		if (counter == 0 || flag) {
+			drawMenuBox(16, 115, 111, 133, 0);
+			if (impArray != nullptr) {
+				_word2C86E = 4;
+				_dword2C856 = impArray;
+				sub133E5(impArray, 17, 115, 110, 133, 0);
+			}
+		}
+	}
+}
+
+void EfhEngine::sub15094() {
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 112, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[3], 16, 0, _paletteTransformationConstant);
+}
+
+void EfhEngine::sub150EE() {
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 304, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[4], 128, 0, _paletteTransformationConstant);
+}
+
+void EfhEngine::sub15018() {
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[7], 16, 136, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[8], 16, 192, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[5], 0, 136, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[6], 304, 136, _paletteTransformationConstant);
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
@@ -909,6 +973,27 @@ uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 	return decompSize;
 }
 
+uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
+	int size = _largeMapFlag ? 32 : 24;
+
+	return _mapGameMapPtr[mapPosX * size + mapPosY];
+}
+
+void EfhEngine::drawBox(int minX, int minY, int maxX, int maxY) {
+	warning("STUB - drawBox");
+}
+
+void EfhEngine::drawMenuBox(int minX, int minY, int maxX, int maxY, int color) {
+	uint8 oldValue = _defaultBoxColor;
+	_defaultBoxColor = color;
+	drawBox(minX, minY, maxX, maxY);
+	_defaultBoxColor = oldValue;
+}
+
+void EfhEngine::displayFullScreenColoredMenuBox(int color) {
+	drawMenuBox(0, 0, 320, 200, color);
+}
+
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	warning("STUB - copyCurrentPlaceToBuffer");
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 22b5263e67f..40c8a9873e1 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -173,12 +173,21 @@ private:
 	void loadGame();
 	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	void copyCurrentPlaceToBuffer(int id);
+	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
+	void drawBox(int minX, int minY, int maxX, int maxY);
+	void drawMenuBox(int minX, int minY, int maxX, int maxY, int color);
+	void displayFullScreenColoredMenuBox(int color);
 
 	void sub15150(bool flag);
 	void sub12A7F();
 	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation);
 	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
+	void sub1512B();
+	void sub221FA(uint8 *impArray, bool flag);
+	void sub15094();
+	void sub150EE();
+	void sub15018();
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
@@ -252,6 +261,9 @@ private:
 	int16 _oldMapPosX, _oldMapPosY;
 	int16 _techDataId_MapPosX, _techDataId_MapPosY;
 	uint16 _lastMainPlaceId;
+
+	uint8 _word2C86E;
+	uint8 *_dword2C856;
 };
 
 } // End of namespace Efh


Commit: 825d755a63df8436aea5bd16643d8a45449b6b81
    https://github.com/scummvm/scummvm/commit/825d755a63df8436aea5bd16643d8a45449b6b81
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Fix issue in loadTechMapImp

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2849ff1c98e..885afb253d1 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -292,8 +292,8 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _map);
 
-	loadImageSetToTileBank(1, _mapBitmapRef[0]);
-	loadImageSetToTileBank(1, _mapBitmapRef[1]);
+	loadImageSetToTileBank(1, _mapBitmapRef[0] + 1);
+	loadImageSetToTileBank(2, _mapBitmapRef[1] + 1);
 
 	initMapMonsters();
 	readImpFile(_techId, true);
@@ -768,12 +768,11 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *buffer, uint8 **subFi
 }
 
 void EfhEngine::displayFctFullScreen() {
-	// CHECKME: 200 is in the original but looks suspicious.
+	// CHECKME: 319 is in the original but looks suspicious.
 	displayBitmapAtPos(0, 0, 319, 200);
 }
 
 void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY) {
-	warning("STUB - displayBitmapAtPos");
 	_graphicsStruct->copy(_vgaGraphicsStruct2);
 	_initRect = Common::Rect(minX, minY, maxX, maxY);
 	displayBitmap(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
@@ -784,7 +783,52 @@ void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphic
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
+	static uint16 byte2C80C[72] = {
+		   0,    1,    2,    3,    4,    5,    6,    7,
+		   8,    9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+		0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+		0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+		   0,    0,    0,    0, 0x3F,    1, 0xC7,    0
+	};
+
 	warning("STUB - sub24D92");
+	
+#if 0
+	if (bufferBM == nullptr)
+		return;
+
+	Common::Rect unkRect;
+	unkRect.left = posX - bufferBM->_startX;
+	unkRect.right = unkRect.left + bufferBM->_width - 1;
+	unkRect.top = posY - bufferBM->_startY;
+	unkRect.bottom = unkRect.top + bufferBM->_height - 1;
+
+	Common::Rect destRect;
+	if (!computeLargeRect(_graphicsStruct->_area, &unkRect, &destRect))
+		return;
+	
+	uint16 bufferFieldA = bufferBM->_fieldA;
+	int16 deltaMinY = (destRect.top - unkRect.top) * bufferFieldA;
+	int16 destWidth = destRect.width() + 1;
+
+	int16 deltaMinX = -1;
+	int16 tmpVal = (destRect.left - unkRect.left) * 2;
+
+	if (tmpVal < 0)
+		deltaMinX = 0;
+
+	int16 deltaWidth = (unkRect.right - unkRect.left) * 2 - (destRect.right - unkRect.left) * 2 + tmpVal;
+
+	uint8 *si = &bufferBM->_dataPtr[deltaMinY + tmpVal];
+	uint8 ch = bufferBM->_paletteTransformation;
+	uint8 cl = 4;
+	uint16 var3A = byte2C80C[bufferBM->_fieldD << 3];
+	//incomplete
+#endif
 }
 
 void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {


Commit: 2ec0e43a2543637388318dc7e7a86930acc29725
    https://github.com/scummvm/scummvm/commit/2ec0e43a2543637388318dc7e7a86930acc29725
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Implement loadMapMonsters, add encounter monster const array

Changed paths:
  A engines/efh/constants.cpp
  A engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/module.mk


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
new file mode 100644
index 00000000000..79ed75e5d3e
--- /dev/null
+++ b/engines/efh/constants.cpp
@@ -0,0 +1,236 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "efh/constants.h"
+
+namespace Efh {
+
+const Encounter _encounters[] {
+	{"Indian", 0, 5, 50, {64, 64, 68, 70, 92}, 25, 2},
+	{"Warrior", 0, 6, 85, {70, 64, 68, 70, 92}, 35, 2},
+	{"Tracker", 0, 8, 115, {92, 64, 68, 70, 92}, 38, 2},
+	{"Savage", 0, 15, 150, {92, 64, 68, 70, 92}, 50, 2},
+	{"Chief", 0, 50, 200, {94, 64, 70, 92, 95}, 95, 2},
+	{"Archer", 1, 5, 50, {70, 71, 64, 66, 69}, 35, 2},
+	{"Bowman", 1, 10, 50, {70, 71, 64, 66, 69}, 50, 2},
+	{"Ranger", 1, 20, 150, {70, 71, 64, 66, 69}, 45, 2},
+	{"Censor", 2, 5, 35, {205, 64, 64, 64, 64}, 25, 2},
+	{"Noisy Guy", 2, 7, 80, {205, 64, 64, 64, 64}, 27, 2},
+	{"Cruiser", 2, 12, 55, {205, 210, 64, 64, 64}, 32, 2},
+	{"Boomer", 2, 20, 110, {205, 210, 210, 64, 64}, 45, 2},
+	{"Neanderthal", 3, 5, 65, {127, 127, 127, 127, 64}, 25, 2},
+	{"Savage", 3, 7, 90, {127, 127, 127, 127, 64}, 35, 2},
+	{"Roughian", 3, 15, 110, {127, 127, 127, 87, 64}, 37, 2},
+	{"Troglodyte", 3, 20, 135, {127, 127, 127, 127, 64}, 45, 2},
+	{"Scuba Guy", 4, 5, 50, {211, 64, 144, 165, 64}, 25, 2},
+	{"Diver", 4, 12, 80, {211, 165, 144, 165, 64}, 28, 2},
+	{"Surfer", 4, 10, 75, {212, 212, 144, 205, 64}, 30, 2},
+	{"Warrior", 4, 15, 100, {66, 69, 68, 64, 66}, 35, 2},
+	{"Maniac", 4, 20, 150, {214, 201, 205, 81, 90}, 38, 2},
+	{"Loon", 4, 35, 250, {214, 201, 205, 81, 90}, 45, 2},
+	{"Crypt Thing", 5, 15, 200, {215, 215, 215, 217, 217}, 35, 2},
+	{"Crypt Corpse", 5, 20, 250, {215, 215, 215, 217, 217}, 40, 2},
+	{"Zombie", 5, 25, 225, {215, 215, 215, 217, 217}, 45, 2},
+	{"Dead Being", 5, 40, 350, {215, 215, 216, 217, 217}, 55, 2},
+	{"Despair", 6, 10, 125, {127, 127, 128, 128, 129}, 25, 2},
+	{"Apparition", 6, 15, 245, {127, 127, 128, 128, 129}, 29, 2},
+	{"Burial Spirit", 6, 25, 300, {127, 128, 128, 129, 129}, 55, 2},
+	{"Ghoul", 6, 32, 410, {127, 127, 128, 128, 129}, 70, 2},
+	{"Skeleton", 6, 6, 75, {127, 127, 128, 128, 129}, 60, 2},
+	{"Soul", 6, 40, 400, {127, 127, 128, 128, 129}, 62, 2},
+	{"Projection", 6, 27, 350, {127, 127, 128, 128, 129}, 65, 2},
+	{"Cowboy", 7, 5, 150, {90, 90, 90, 90, 91}, 25, 2},
+	{"Sheriff", 7, 8, 250, {90, 90, 90, 91, 91}, 35, 2},
+	{"Bad Bart", 7, 35, 500, {90, 90, 91, 91, 91}, 95, 2},
+	{"Gun Slinger", 7, 20, 380, {90, 90, 91, 91, 91}, 55, 2},
+	{"Fast Draw", 7, 17, 290, {90, 91, 91, 91, 91}, 45, 2},
+	{"Quick Draw", 7, 30, 420, {90, 91, 92, 93, 92}, 65, 2},
+	{"Dinosaur", 8, 35, 200, {128, 128, 128, 126, 126}, 25, 2},
+	{"Biped", 8, 50, 225, {128, 128, 128, 126, 126}, 30, 2},
+	{"Dino Beast", 8, 65, 250, {128, 128, 128, 126, 126}, 35, 2},
+	{"Intellosaur", 8, 80, 380, {128, 128, 128, 126, 126}, 45, 2},
+	{"Awful Animal", 8, 105, 495, {128, 128, 128, 126, 126}, 55, 2},
+	{"Death Serpent", 9, 60, 450, {94, 97, 98, 99, 135}, 75, 2},
+	{"Demon Snake", 9, 80, 580, {97, 98, 94, 99, 137}, 85, 2},
+	{"Fire Lizard", 9, 100, 400, {135, 98, 99, 137, 136}, 95, 2},
+	{"Winged Demon", 9, 110, 475, {97, 98, 138, 139, 140}, 100, 2},
+	{"Duke of Hell", 10, 500, 2000, {137, 138, 139, 140, 135}, 100, 2},
+	{"Beach Fiend", 10, 150, 580, {137, 138, 139, 136, 98}, 100, 2},
+	{"Arch Devil", 10, 2000, 10000, {98, 97, 98, 140, 139}, 100, 2},
+	{"Major Fiend", 10, 195, 666, {98, 99, 98, 99, 137}, 100, 2},
+	{"Enforcer", 11, 20, 110, {127, 126, 76, 75, 145}, 25, 2},
+	{"Grunt", 11, 30, 150, {163, 127, 161, 165, 152}, 35, 2},
+	{"Behemoth", 11, 35, 175, {144, 148, 160, 161, 163}, 45, 2},
+	{"Giant Demon", 11, 50, 245, {127, 107, 151, 155, 159}, 55, 2},
+	{"Slaver", 11, 42, 225, {127, 124, 114, 115, 121}, 65, 2},
+	{"Minor Demon", 12, 6, 100, {73, 73, 130, 130, 130}, 27, 2},
+	{"Common Demon", 12, 9, 150, {73, 73, 130, 130, 130}, 30, 2},
+	{"Small Demon", 12, 15, 175, {73, 73, 73, 73, 130}, 38, 2},
+	{"Simple Demon", 12, 20, 200, {73, 73, 73, 130, 130}, 45, 2},
+	{"Lesser Demon", 12, 12, 160, {73, 73, 73, 73, 73}, 32, 2},
+	{"Warrior", 13, 7, 50, {65, 65, 66, 66, 64}, 30, 2},
+	{"Gladiator", 13, 12, 95, {65, 65, 66, 66, 64}, 35, 2},
+	{"Moutaineer", 13, 10, 80, {66, 66, 80, 72, 64}, 45, 2},
+	{"Strong Guy", 13, 13, 98, {66, 66, 66, 66, 66}, 55, 2},
+	{"Hell Private", 14, 10, 150, {66, 66, 66, 65, 65}, 35, 2},
+	{"Hell Corporal", 14, 15, 150, {66, 66, 66, 65, 65}, 40, 2},
+	{"Hell Sgt.", 14, 17, 150, {66, 66, 66, 65, 65}, 45, 2},
+	{"Hell LT.", 14, 25, 245, {105, 66, 66, 65, 65}, 50, 2},
+	{"Hell Guard", 14, 6, 100, {66, 66, 66, 65, 65}, 20, 2},
+	{"Hell Soldier", 14, 35, 380, {106, 66, 66, 163, 65}, 65, 2},
+	{"Demon Fighter", 14, 40, 400, {106, 105, 163, 65, 65}, 75, 2},
+	{"Ice Beast", 15, 25, 650, {69, 69, 69, 68, 68}, 45, 2},
+	{"Snow Fiend", 15, 30, 666, {132, 69, 69, 68, 68}, 55, 2},
+	{"SalivaMonster", 15, 45, 750, {107, 110, 132, 157, 129}, 65, 2},
+	{"Spit Grunt", 15, 40, 666, {107, 110, 132, 157, 129}, 75, 2},
+	{"Cold Demon", 15, 42, 666, {107, 110, 68, 69, 69}, 85, 2},
+	{"Insectoid", 16, 15, 400, {153, 152, 154, 161, 147}, 35, 2},
+	{"Giant Insect", 16, 17, 400, {94, 96, 96, 202, 202}, 45, 2},
+	{"Insect Guard", 16, 25, 400, {94, 96, 99, 202, 202}, 55, 2},
+	{"Roaming Bug", 16, 35, 450, {94, 96, 99, 136, 134}, 45, 2},
+	{"Blade Bug", 16, 45, 590, {135, 158, 156, 202, 202}, 45, 2},
+	{"Logger", 17, 7, 125, {89, 78, 89, 89, 64}, 30, 2},
+	{"Massacrer", 17, 10, 175, {89, 89, 89, 89, 64}, 35, 2},
+	{"Murderer", 17, 12, 225, {89, 89, 89, 79, 64}, 38, 2},
+	{"Crazy Guy", 17, 13, 235, {89, 87, 88, 89, 64}, 40, 2},
+	{"Massive Dude", 17, 15, 250, {89, 89, 81, 89, 64}, 36, 2},
+	{"Chainsaw Guy", 17, 11, 180, {89, 89, 88, 89, 64}, 45, 2},
+	{"DevilDaughter", 18, 75, 850, {181, 182, 182, 181, 195}, 100, 2},
+	{"Evil Woman", 18, 5, 85, {181, 182, 182, 181, 195}, 35, 2},
+	{"Enchantress'", 18, 7, 150, {181, 182, 182, 181, 195}, 40, 2},    // The extra quote is in the original game
+	{"Temptress'", 18, 9, 200, {181, 182, 182, 181, 195}, 55, 2},      // The extra quote is in the original game
+	{"Lustivious'", 18, 100, 1750, {181, 182, 196, 197, 197}, 100, 1}, // The extra quote is in the original game
+	{"Major Demon", 19, 25, 666, {106, 105, 163, 65, 65}, 45, 2},
+	{"Giant Demon", 19, 50, 865, {106, 105, 163, 65, 65}, 55, 2},
+	{"Gnarly Demon", 19, 75, 999, {106, 105, 163, 65, 65}, 65, 2},
+	{"Pit Fiend", 19, 40, 777, {114, 113, 163, 163, 163}, 95, 2},
+	{"Hellish Fiend", 19, 80, 1500, {113, 114, 113, 163, 163}, 100, 2},
+	{"Monk", 20, 6, 75, {0, 0, 0, 0, 0}, 0, 2},
+	{"Unholy Monk", 20, 12, 100, {202, 197, 96, 108, 149}, 30, 2},
+	{"Evil Monk", 20, 15, 150, {202, 197, 96, 153, 149}, 33, 2},
+	{"Sacrificer", 20, 18, 185, {202, 197, 108, 108, 108}, 37, 2},
+	{"Nasty Guy", 20, 25, 200, {202, 197, 96, 153, 149}, 45, 2},
+	{"Mutant Demon", 21, 15, 100, {93, 91, 90, 94, 95}, 35, 2},
+	{"Hell Captain", 21, 25, 275, {93, 91, 90, 94, 95}, 37, 2},
+	{"Muscle Demon", 21, 32, 350, {93, 91, 90, 94, 95}, 40, 2},
+	{"Blaster Demon", 21, 60, 690, {93, 91, 90, 94, 95}, 45, 2},
+	{"Knight", 22, 15, 150, {133, 133, 150, 128, 128}, 35, 2},
+	{"Evil Knight", 22, 25, 200, {133, 150, 116, 122, 128}, 40, 2},
+	{"UnJust Knight", 22, 35, 375, {133, 150, 128, 122, 128}, 45, 2},
+	{"Astray Knight", 22, 50, 450, {133, 150, 120, 121, 128}, 65, 2},
+	{"Anit-Paladin", 22, 75, 750, {109, 115, 128, 128, 128}, 85, 2},
+	{"Moaning", 23, 3, 3, {72, 78, 81, 83, 83}, 50, 2},
+	{"Tormented", 23, 5, 5, {72, 78, 81, 83, 83}, 50, 2},
+	{"Suffering", 23, 4, 4, {72, 78, 81, 83, 83}, 50, 2},
+	{"Starving Guy", 23, 2, 2, {72, 78, 81, 83, 83}, 50, 2},
+	{"Withered Soul", 23, 1, 1, {72, 78, 81, 83, 83}, 50, 2},
+	{"Ogre", 24, 20, 275, {109, 106, 65, 163, 163}, 45, 2},
+	{"ElectroKnight", 24, 25, 290, {109, 106, 65, 163, 163}, 55, 2},
+	{"Energy Demon", 24, 30, 320, {109, 106, 65, 163, 163}, 55, 2},
+	{"Power Devil", 24, 35, 350, {107, 109, 114, 207, 207}, 65, 2},
+	{"Sorcerer", 24, 42, 400, {109, 106, 65, 163, 163}, 75, 2},
+	{"Enchanter", 24, 35, 350, {109, 106, 65, 163, 163}, 85, 2},
+	{"Canon Monk", 28, 35, 100, {0, 0, 0, 0, 0}, 0, 2},
+	{"Canon Monk", 28, 35, 100, {0, 0, 0, 0, 0}, 0, 2},
+	{"Canon Monk", 28, 35, 100, {0, 0, 0, 0, 0}, 0, 2},
+	{"Canon Monk", 28, 35, 100, {0, 0, 0, 0, 0}, 0, 2},
+	{"Canon Monk", 28, 35, 100, {0, 0, 0, 0, 0}, 0, 2},
+	{"Screamer", 26, 5, 35, {152, 152, 146, 145, 64}, 30, 2},
+	{"Moaner", 26, 7, 40, {152, 152, 146, 145, 64}, 35, 2},
+	{"Screacher", 26, 12, 85, {152, 152, 146, 145, 64}, 40, 2},
+	{"Singer", 26, 15, 100, {152, 152, 146, 145, 64}, 45, 2},
+	{"Pilot", 27, 12, 150, {90, 90, 90, 92, 92}, 35, 2},
+	{"Crashed Pilot", 27, 20, 200, {90, 90, 90, 92, 92}, 40, 2},
+	{"WW I Pilot", 27, 25, 225, {90, 90, 90, 92, 92}, 45, 2},
+	{"WW II Pilot", 27, 35, 280, {94, 134, 136, 136, 92}, 55, 2},
+	{"Boney Soldier", 27, 45, 350, {90, 134, 136, 137, 138}, 65, 2},
+	{"ModernSoldier", 27, 75, 845, {97, 97, 98, 99, 94}, 95, 2},
+	{"Surpriser", 28, 10, 100, {100, 101, 102, 103, 104}, 35, 2},
+	{"Shocker", 28, 15, 350, {100, 101, 102, 103, 104}, 45, 2},
+	{"Blast Monk", 28, 20, 400, {100, 101, 102, 103, 104}, 55, 2},
+	{"Canon Monk", 28, 28, 480, {100, 101, 102, 103, 104}, 65, 2},
+	{"Killer", 28, 35, 550, {100, 101, 102, 103, 104}, 75, 2},
+	{"Rubber Necker", 29, 45, 1000, {152, 153, 144, 111, 112}, 20, 2},
+	{"Skull Thing", 29, 60, 1250, {113, 114, 115, 105, 112}, 30, 2},
+	{"Laser Eye", 29, 80, 1750, {94, 134, 135, 90, 91}, 40, 2},
+	{"Beamer", 29, 100, 2200, {94, 134, 135, 90, 91}, 50, 2},
+	{"Hideous Beast", 29, 150, 3500, {94, 134, 135, 90, 91}, 60, 2},
+	{"Samurai", 30, 10, 35, {67, 67, 67, 68, 68}, 30, 2},
+	{"Ninja", 30, 15, 90, {67, 67, 67, 68, 68}, 32, 2},
+	{"SegaSamurai", 30, 20, 150, {67, 67, 67, 68, 68}, 45, 2},
+	{"NintendoNinja", 30, 35, 220, {67, 67, 67, 68, 68}, 45, 2},
+	{"OrientalSlayr", 30, 45, 250, {67, 67, 67, 68, 68}, 55, 2},
+	{"Soldier", 31, 10, 100, {100, 101, 102, 90, 92}, 30, 2},
+	{"Fighter", 31, 15, 125, {100, 93, 94, 96, 104}, 35, 2},
+	{"Grenader", 31, 20, 175, {100, 101, 102, 103, 104}, 45, 2},
+	{"Gunner", 31, 25, 190, {137, 136, 135, 134, 94}, 50, 2},
+	{"Scratche", 32, 6, 95, {0, 0, 0, 0, 0}, 0, 2},
+	{"Claw", 32, 15, 150, {0, 0, 0, 0, 0}, 0, 2},
+	{"Claw Demon", 32, 25, 264, {0, 0, 0, 0, 0}, 0, 2},
+	{"Talon Demon", 32, 35, 300, {0, 0, 0, 0, 0}, 0, 2},
+	{"Malicioun", 32, 50, 350, {0, 0, 0, 0, 0}, 0, 2},
+	{"Imp", 33, 3, 100, {64, 64, 131, 131, 131}, 35, 2},
+	{"Tiny Demon", 33, 6, 150, {64, 132, 131, 131, 131}, 40, 2},
+	{"Short Devil", 33, 12, 255, {132, 132, 131, 131, 132}, 45, 2},
+	{"Gremlin", 33, 25, 300, {64, 64, 131, 131, 131}, 50, 2},
+	{"Thug", 34, 8, 175, {93, 93, 94, 92, 95}, 30, 2},
+	{"Punk", 34, 15, 250, {93, 93, 94, 92, 95}, 35, 2},
+	{"Killer", 34, 18, 275, {93, 93, 94, 92, 95}, 40, 2},
+	{"Street Dude", 34, 25, 350, {93, 93, 94, 92, 95}, 45, 2},
+	{"Slasher", 35, 5, 190, {131, 131, 131, 131, 131}, 30, 2},
+	{"Blade Demon", 35, 15, 250, {132, 131, 131, 131, 131}, 35, 2},
+	{"Cleaver Devil", 35, 30, 290, {132, 132, 131, 131, 131}, 45, 2},
+	{"Stench Beast", 36, 6, 75, {0, 0, 0, 0, 0}, 0, 2},
+	{"Breather", 36, 10, 150, {0, 0, 0, 0, 0}, 0, 2},
+	{"Smelly Thing", 36, 15, 175, {0, 0, 0, 0, 0}, 0, 2},
+	{"Ugly Devil", 36, 25, 225, {0, 0, 0, 0, 0}, 0, 2},
+	{"Surf Nazi", 37, 5, 67, {64, 86, 218, 218, 219}, 30, 2},
+	{"Beacher", 37, 8, 95, {64, 86, 218, 218, 219}, 35, 2},
+	{"Scum", 37, 12, 125, {64, 86, 218, 218, 219}, 45, 2},
+	{"Waste", 37, 18, 150, {64, 86, 218, 218, 219}, 55, 2},
+	{"Duelist", 38, 6, 65, {65, 65, 65, 147, 66}, 40, 2},
+	{"Sword Guy", 38, 10, 87, {65, 155, 65, 153, 66}, 50, 2},
+	{"Muskateer", 38, 15, 97, {65, 65, 154, 66, 66}, 65, 2},
+	{"Valkyrie", 39, 7, 37, {65, 65, 65, 66, 66}, 35, 2},
+	{"WarriorMaiden", 39, 20, 137, {65, 65, 65, 66, 66}, 55, 2},
+	{"Worm King", 40, 150, 4500, {202, 194, 195, 181, 181}, 100, 2},
+	{"Worm Lord", 40, 100, 3300, {202, 194, 195, 181, 181}, 100, 2},
+	{"Eye of Hell", 40, 60, 1200, {202, 194, 195, 181, 181}, 70, 2},
+	{"Visionary", 40, 40, 800, {202, 194, 195, 181, 181}, 55, 2},
+	{"Thing", 40, 25, 650, {202, 194, 195, 181, 181}, 45, 2},
+	{"Zombie", 41, 10, 450, {97, 97, 98, 98, 127}, 35, 2},
+	{"Police Dude", 41, 25, 350, {97, 161, 148, 98, 127}, 45, 2},
+	{"Cop", 41, 15, 275, {97, 152, 98, 156, 127}, 30, 2},
+	{"Dark Cop", 41, 20, 300, {97, 162, 98, 98, 127}, 35, 2},
+	{"Bully Cop", 41, 25, 350, {97, 97, 98, 98, 127}, 45, 2},
+	{"Drowning", 42, 10, 50, {0, 0, 0, 0, 0}, 0, 2},
+	{"Watery Guy", 42, 35, 150, {0, 0, 0, 0, 0}, 0, 2},
+	{"Evangelist", 43, 8, 50, {0, 0, 0, 0, 0}, 0, 2},
+	{"Preacher", 43, 15, 150, {0, 0, 0, 0, 0}, 0, 2},
+	{"Smooth Talker", 43, 20, 175, {0, 0, 0, 0, 0}, 0, 2},
+	{"Hulk", 44, 20, 100, {220, 220, 220, 220, 202}, 32, 0},
+	{"MIGHTY Guy", 44, 30, 200, {220, 220, 220, 220, 202}, 43, 2},
+	{"Powerful Dude", 44, 45, 400, {220, 220, 220, 220, 202}, 55, 2},
+	{ "XXXXXXXXXXXXX", 0xFF, 0xFFFF, 0xFFFF, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, 0, 0 }
+};
+
+} // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
new file mode 100644
index 00000000000..4a709f8004e
--- /dev/null
+++ b/engines/efh/constants.h
@@ -0,0 +1,44 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef EFH_CONSTANTS_H
+#define EFH_CONSTANTS_H
+
+#include "common/scummsys.h"
+
+namespace Efh {
+
+struct Encounter {
+	char _name[14];
+	uint8 _animId;
+	uint16 _pictureRef;
+	uint16 _xpGiven;
+	uint16 _dropItemId[5];
+	uint8 _dropOccurrencePct;
+	uint8 _nameArticle;
+};
+
+extern const Encounter _encounters[];
+
+} // End of namespace Efh
+
+#endif // EFH_CONSTANTS_H
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 885afb253d1..9264dffbe8a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -29,6 +29,8 @@
 #include "graphics/cursorman.h"
 
 #include "efh/efh.h"
+#include "efh/constants.h"
+
 #include "engines/util.h"
 
 namespace Efh {
@@ -291,6 +293,9 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	fileName = Common::String::format("map.%d", _techId);
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _map);
+	// This is not present in the original.
+	// The purpose is to properly load the mapMonster data in an array of struct in order to use it without being a pain afterwards
+	loadMapMonsters();
 
 	loadImageSetToTileBank(1, _mapBitmapRef[0] + 1);
 	loadImageSetToTileBank(2, _mapBitmapRef[1] + 1);
@@ -441,7 +446,24 @@ void EfhEngine::initEngine() {
 
 	_mapBitmapRef = &_map[0];
 	_mapUnknownPtr = &_map[2];
-	_mapMonstersPtr = &_map[902];
+
+	// Replaces _mapMonstersPtr which was equal to &_map[902];
+	for (int i = 0; i < 64; ++i) {
+		_mapMonsters[i]._possessivePronounSHL6 = 0;
+		_mapMonsters[i]._field_1 = 0;
+		_mapMonsters[i]._guess_fullPlaceId = 0xFF;
+		_mapMonsters[i]._posX = 0;
+		_mapMonsters[i]._posY = 0;
+		_mapMonsters[i]._itemId_Weapon = 0;
+		_mapMonsters[i]._field_6 = 0;
+		_mapMonsters[i]._MonsterRef = 0;
+		_mapMonsters[i]._field_8 = 0;
+		_mapMonsters[i]._field_9 = 0;
+		_mapMonsters[i]._groupSize = 0;
+		for (int j = 0; j < 9; ++j)
+			_mapMonsters[i]._pictureRef[j] = 0;
+	}
+	
 	_mapGameMapPtr = &_map[2758];
 
 	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
@@ -697,7 +719,50 @@ void EfhEngine::initEngine() {
 }
 
 void EfhEngine::initMapMonsters() {
-	warning("STUB - initMapMonsters");
+	for (uint8 monsterId = 0; monsterId < 64; ++monsterId) {
+		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+			continue;
+
+		for (uint8 counter = 0; counter < 9; ++counter)
+			_mapMonsters[monsterId]._pictureRef[counter] = 0;
+
+		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
+		if (groupSize == 0)
+			groupSize = _rnd->getRandomNumber(10);
+
+		for (uint8 counter = 0; counter < groupSize; ++counter) {
+			uint rand100 = _rnd->getRandomNumber(99) + 1;
+			uint16 pictureRef = _encounters[_mapMonsters[monsterId]._MonsterRef]._pictureRef;
+
+			if (rand100 <= 25) {
+				uint16 delta = _rnd->getRandomNumber((pictureRef / 2) - 1) + 1;
+				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef - delta;
+			} else if (rand100 <= 75) {
+				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef;
+			} else {
+				uint16 delta = _rnd->getRandomNumber((pictureRef / 2) - 1) + 1;
+				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef + delta;
+			}
+		}		
+	}
+}
+
+void EfhEngine::loadMapMonsters() {
+	for (int i = 0; i < 64; ++i) {
+		_mapMonsters[i]._possessivePronounSHL6 = _mapMonstersPtr[29 * i];
+		_mapMonsters[i]._field_1 = _mapMonstersPtr[29 * i + 1];
+		_mapMonsters[i]._guess_fullPlaceId = _mapMonstersPtr[29 * i + 2];
+		_mapMonsters[i]._posX = _mapMonstersPtr[29 * i + 3];
+		_mapMonsters[i]._posY = _mapMonstersPtr[29 * i + 4];
+		_mapMonsters[i]._itemId_Weapon = _mapMonstersPtr[29 * i + 5];
+		_mapMonsters[i]._field_6 = _mapMonstersPtr[29 * i + 6];
+		_mapMonsters[i]._MonsterRef = _mapMonstersPtr[29 * i + 7];
+		_mapMonsters[i]._field_8 = _mapMonstersPtr[29 * i + 8];
+		_mapMonsters[i]._field_9 = _mapMonstersPtr[29 * i + 9];
+		_mapMonsters[i]._groupSize = _mapMonstersPtr[29 * i + 10];
+		for (int j = 0; j < 9; ++j)
+			_mapMonsters[i]._pictureRef[j] = READ_LE_UINT16(&_mapMonstersPtr[29 * i + 11 + j * 2]);
+	}
 }
 
 void EfhEngine::saveAnimImageSetId() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 40c8a9873e1..47dccd733c3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -99,6 +99,21 @@ struct CharStatus {
 	int16 _duration;
 };
 
+struct MapMonster {
+	uint8 _possessivePronounSHL6;
+	uint8 _field_1;
+	uint8 _guess_fullPlaceId; // unsigned? Magic values are 0xFF and 0xFE
+	uint8 _posX;
+	uint8 _posY;
+	uint8 _itemId_Weapon;
+	uint8 _field_6;
+	uint8 _MonsterRef;
+	uint8 _field_8;
+	uint8 _field_9;
+	uint8 _groupSize;
+	uint16 _pictureRef[9];
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -160,6 +175,7 @@ private:
 	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
 	void initEngine();
 	void initMapMonsters();
+	void loadMapMonsters();
 	void saveAnimImageSetId();
 	void displayLowStatusScreen(int i);
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
@@ -218,6 +234,7 @@ private:
 	uint8 *_mapBitmapRef;
 	uint8 *_mapUnknownPtr;
 	uint8 *_mapMonstersPtr;
+	MapMonster _mapMonsters[64];
 	uint8 *_mapGameMapPtr;
 
 	uint8 _defaultBoxColor;
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index 6b8f7bdee6c..cd1d0983a97 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -1,6 +1,7 @@
 MODULE := engines/efh
 
 MODULE_OBJS = \
+	constants.o \
 	efh.o \
 	metaengine.o
 


Commit: 1a2914912c1930969a5eb8098a4f3b61ad1efb17
    https://github.com/scummvm/scummvm/commit/1a2914912c1930969a5eb8098a4f3b61ad1efb17
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Fix crash in previous commit, implement decryptImpFile()

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9264dffbe8a..ea0ed3b8d60 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -386,7 +386,39 @@ Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 }
 
 void EfhEngine::decryptImpFile(bool techMapFl) {
-	warning("STUB - decryptImpFile");	
+	uint16 counter = 0;
+	uint16 target;
+	uint8 *curPtr;
+
+	if (!techMapFl) {
+		_imp2PtrArray[++counter] = curPtr = _imp2;
+		target = 431;
+	} else {
+		_imp2PtrArray[++counter] = curPtr = _imp1;
+		target = 99;
+	}
+
+	do {
+		*curPtr = (*curPtr - 3) ^ 0xD7;
+		if (*curPtr == 0x40) {
+			curPtr += 3;
+			if (!techMapFl)
+				_imp2PtrArray[++counter] = curPtr;
+			else
+				_imp1PtrArray[++counter] = curPtr;
+		} else
+			++curPtr;
+	} while (*curPtr != 0x60 && counter <= target);
+
+	Common::DumpFile dump;
+	if (!techMapFl) {
+		dump.open("imp2_unc.dump");
+		dump.write(_imp2, curPtr - _imp2);
+	} else {
+		dump.open("imp1_unc.dump");
+		dump.write(_imp1, curPtr - _imp1);
+	}
+	dump.close();
 }
 
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
@@ -748,6 +780,8 @@ void EfhEngine::initMapMonsters() {
 }
 
 void EfhEngine::loadMapMonsters() {
+	_mapMonstersPtr = &_map[902];
+
 	for (int i = 0; i < 64; ++i) {
 		_mapMonsters[i]._possessivePronounSHL6 = _mapMonstersPtr[29 * i];
 		_mapMonsters[i]._field_1 = _mapMonstersPtr[29 * i + 1];


Commit: db4dc8ab92d863ddbd4b63bcc266764d3d580f09
    https://github.com/scummvm/scummvm/commit/db4dc8ab92d863ddbd4b63bcc266764d3d580f09
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Implement copyCurrentPlaceToBuffer

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ea0ed3b8d60..0368d937cbe 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1138,7 +1138,10 @@ void EfhEngine::displayFullScreenColoredMenuBox(int color) {
 }
 
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
-	warning("STUB - copyCurrentPlaceToBuffer");
+	uint8 *placesPtr = &_places[576 * id];
+
+	// Note that 576 = 24 * 24
+	memcpy(_curPlace, placesPtr, 24 * 24);
 }
 
 void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation) {


Commit: e87ddaf1fd2719d3c29db0939d2c080313c057f0
    https://github.com/scummvm/scummvm/commit/e87ddaf1fd2719d3c29db0939d2c080313c057f0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Fix rImageFile, init palette, hack a display function

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0368d937cbe..e6d3cda5ca1 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -185,6 +185,30 @@ Common::Platform EfhEngine::getPlatform() const {
 	return _platform;
 }
 
+void EfhEngine::initPalette() {
+	const uint8 pal[3 * 16] = {
+		0, 0, 0,
+		0, 0, 170,
+		0, 170, 0,
+		0, 170, 170,
+		170, 0, 0,
+		170, 0, 170,
+		170, 85, 0,
+		170, 170, 170,
+		85, 85, 85,
+		85, 85, 255,
+		1, 1, 1,
+		85, 255, 255,
+		255, 85, 85,
+		255, 85, 255,
+		255, 255, 85,
+		255, 255, 255
+	};
+	
+	_system->getPaletteManager()->setPalette(pal, 0, 16);
+	_system->updateScreen();
+}
+
 Common::Error EfhEngine::run() {
 	s_Engine = this;
 	initialize();
@@ -192,6 +216,8 @@ Common::Error EfhEngine::run() {
 
 	_mainSurface = new Graphics::Surface();
 	_mainSurface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
+
+	initPalette();
 /*
 	// Setup mixer
 	syncSoundSettings();
@@ -842,7 +868,7 @@ void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArra
 	rImageFile(fileName, buffer, subFilesArray, CGAVal, EGAVal, destBuffer, transfBuffer);
 }
 
-void EfhEngine::rImageFile(Common::String filename, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *targetBuffer) {
+void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *transformedBuf) {
 	readFileToBuffer(filename, packedBuffer);
 	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
 	// TODO: Keep this dump for debug purposes only
@@ -879,6 +905,8 @@ void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 max
 
 void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
 	warning("STUB - displayBitmap");
+	
+	
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
@@ -928,6 +956,22 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 	uint16 var3A = byte2C80C[bufferBM->_fieldD << 3];
 	//incomplete
 #endif
+
+
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
+	warning("%d %d - startX %d startY %d width %d height %d fieldA %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_fieldA, bufferBM->_fieldD);
+	int counter = 0;
+	for (int j = 0; j < bufferBM->_height; ++j) {
+		for (int i = 0; i < bufferBM->_fieldA; ++i) {
+			destPtr[320 * j + 2 * i] = bufferBM->_dataPtr[counter] >> 4;
+			destPtr[320 * j + 2 * i + 1] = bufferBM->_dataPtr[counter] & 0xF;
+			++counter;
+		}
+	}
+
+	_system->copyRectToScreen((byte *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+	_system->updateScreen();
+	_system->delayMillis(200);
 }
 
 void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 47dccd733c3..c84e07068bb 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -142,7 +142,6 @@ public:
 protected:
 	Common::EventManager *_eventMan;
 	int _lastTime;
-
 	// Engine APIs
 	Common::Error run() override;
 	void handleMenu();
@@ -153,6 +152,7 @@ private:
 	GameType _gameType;
 	Common::Platform _platform;
 
+	void initPalette();
 	void initialize();
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void readAnimInfo();
@@ -179,7 +179,7 @@ private:
 	void saveAnimImageSetId();
 	void displayLowStatusScreen(int i);
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
-	void rImageFile(Common::String filename, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *targetBuffer);
+	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *transformedBuffer);
 	void displayFctFullScreen();
 	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
 	void displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);


Commit: 24aca2246c5634efc140b2a894356b12e808146e
    https://github.com/scummvm/scummvm/commit/24aca2246c5634efc140b2a894356b12e808146e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Move font data to constants

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 79ed75e5d3e..6ccc10c048b 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -23,6 +23,114 @@
 #include "efh/constants.h"
 
 namespace Efh {
+const uint8 fontWidthArray[96] = {
+	3, 2, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 3, 3, 2, 7, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 1, 4, 4, 4,
+	4, 4, 4, 4, 4, 3, 4, 4, 4, 7, 5, 4, 4, 4, 4, 4, 5, 4, 5, 7, 5, 5, 5, 3, 7, 3, 5, 0, 2, 4, 4, 4, 4, 4, 4, 4,
+	4, 1, 2, 4, 1, 7, 4, 4, 4, 4, 4, 4, 3, 4, 5, 7, 4, 4, 5, 3, 0, 3, 0, 0};
+
+const uint8 fontExtraLinesArray[96] = {
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3,
+	1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 0, 0};
+
+const Font fontData[96] = {
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00},
+	{0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x00, 0x00},
+	{0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20, 0x00},
+	{0xC8, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x98, 0x00},
+	{0x20, 0x50, 0x20, 0x40, 0xA8, 0x90, 0x68, 0x00},
+	{0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40},
+	{0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40},
+	{0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00, 0x00},
+	{0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40},
+	{0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00},
+	{0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00},
+	{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+	{0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00},
+	{0x60, 0x90, 0x10, 0x20, 0x40, 0x80, 0xF0, 0x00},
+	{0x60, 0x90, 0x10, 0x20, 0x10, 0x90, 0x60, 0x00},
+	{0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10, 0x00},
+	{0xF0, 0x80, 0xE0, 0x10, 0x10, 0x90, 0x60, 0x00},
+	{0x60, 0x90, 0x80, 0xE0, 0x90, 0x90, 0x60, 0x00},
+	{0xF0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00},
+	{0x60, 0x90, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00},
+	{0x60, 0x90, 0x90, 0x70, 0x10, 0x90, 0x60, 0x00},
+	{0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00},
+	{0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00},
+	{0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x00},
+	{0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00},
+	{0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80, 0x00},
+	{0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x60, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
+	{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0xE0, 0x00},
+	{0x60, 0x90, 0x80, 0x80, 0x80, 0x90, 0x60, 0x00},
+	{0xE0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE0, 0x00},
+	{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0xF0, 0x00},
+	{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x80, 0x00},
+	{0x60, 0x90, 0x80, 0xB0, 0x90, 0x90, 0x70, 0x00},
+	{0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
+	{0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00},
+	{0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00},
+	{0x90, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
+	{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00},
+	{0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00},
+	{0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x00},
+	{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+	{0xE0, 0x90, 0x90, 0xE0, 0x80, 0x80, 0x80, 0x00},
+	{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x10},
+	{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
+	{0x60, 0x90, 0x80, 0x60, 0x10, 0x90, 0x60, 0x00},
+	{0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00},
+	{0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
+	{0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
+	{0x82, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x82, 0x00},
+	{0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00},
+	{0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, 0x00},
+	{0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00},
+	{0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0},
+	{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00},
+	{0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60},
+	{0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x60, 0x10, 0x70, 0x90, 0x70, 0x00},
+	{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00},
+	{0x00, 0x00, 0x60, 0x90, 0x80, 0x90, 0x60, 0x00},
+	{0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x70, 0x00},
+	{0x00, 0x00, 0x60, 0x90, 0xF0, 0x80, 0x60, 0x00},
+	{0x30, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
+	{0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0, 0x00},
+	{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
+	{0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
+	{0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80},
+	{0x80, 0x80, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x00},
+	{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
+	{0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00},
+	{0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
+	{0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x60, 0x00},
+	{0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x80, 0x80},
+	{0x00, 0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0x10},
+	{0x00, 0x00, 0xB0, 0xC0, 0x80, 0x80, 0x80, 0x00},
+	{0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xE0, 0x00},
+	{0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
+	{0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x00},
+	{0x00, 0x00, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
+	{0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x6E, 0x00},
+	{0x00, 0x00, 0x90, 0x90, 0x60, 0x90, 0x90, 0x00},
+	{0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0},
+	{0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00},
+	{0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+};
 
 const Encounter _encounters[] {
 	{"Indian", 0, 5, 50, {64, 64, 68, 70, 92}, 25, 2},
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 4a709f8004e..d64235fd93b 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -26,6 +26,9 @@
 #include "common/scummsys.h"
 
 namespace Efh {
+struct Font {
+	uint8 _lines[8];
+};
 
 struct Encounter {
 	char _name[14];
@@ -37,6 +40,9 @@ struct Encounter {
 	uint8 _nameArticle;
 };
 
+extern const uint8 fontWidthArray[96];
+extern const uint8 fontExtraLinesArray[96];
+extern const Font fontData[96];
 extern const Encounter _encounters[];
 
 } // End of namespace Efh
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e6d3cda5ca1..86436d49487 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -32,6 +32,7 @@
 #include "efh/constants.h"
 
 #include "engines/util.h"
+#include "graphics/palette.h"
 
 namespace Efh {
 
@@ -532,117 +533,6 @@ void EfhEngine::initEngine() {
 	_defaultBoxColor = 7;
 
 	// Init Font
-	static uint8 fontWidthArray[96] = {
-		3, 2, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 3, 3, 2, 7, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 1, 4, 4, 4,
-		4, 4, 4, 4, 4, 3, 4, 4, 4, 7, 5, 4, 4, 4, 4, 4, 5, 4, 5, 7, 5, 5, 5, 3, 7, 3, 5, 0, 2, 4, 4, 4, 4, 4, 4, 4,
-		4, 1, 2, 4, 1, 7, 4, 4, 4, 4, 4, 4, 3, 4, 5, 7, 4, 4, 5, 3, 0, 3, 0, 0
-	};
-
-	static uint8 fontExtraLinesArray[96] = {
-		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3,
-		1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 0, 0
-	};
-
-	static Font fontData[96] = {
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00},
-		{0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x50, 0xF8, 0x50, 0xF8, 0x50, 0x00, 0x00},
-		{0x20, 0x78, 0xA0, 0x70, 0x28, 0xF0, 0x20, 0x00},
-		{0xC8, 0xC8, 0x10, 0x20, 0x40, 0x98, 0x98, 0x00},
-		{0x20, 0x50, 0x20, 0x40, 0xA8, 0x90, 0x68, 0x00},
-		{0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40},
-		{0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40},
-		{0x00, 0xA8, 0x70, 0xF8, 0x70, 0xA8, 0x00, 0x00},
-		{0x00, 0x20, 0x20, 0xF8, 0x20, 0x20, 0x00, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40},
-		{0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00},
-		{0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00},
-		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
-		{0x40, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00},
-		{0x60, 0x90, 0x10, 0x20, 0x40, 0x80, 0xF0, 0x00},
-		{0x60, 0x90, 0x10, 0x20, 0x10, 0x90, 0x60, 0x00},
-		{0x10, 0x30, 0x50, 0x90, 0xF8, 0x10, 0x10, 0x00},
-		{0xF0, 0x80, 0xE0, 0x10, 0x10, 0x90, 0x60, 0x00},
-		{0x60, 0x90, 0x80, 0xE0, 0x90, 0x90, 0x60, 0x00},
-		{0xF0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x00},
-		{0x60, 0x90, 0x90, 0x60, 0x90, 0x90, 0x60, 0x00},
-		{0x60, 0x90, 0x90, 0x70, 0x10, 0x90, 0x60, 0x00},
-		{0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00},
-		{0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x40, 0x00},
-		{0x10, 0x20, 0x40, 0x80, 0x40, 0x20, 0x10, 0x00},
-		{0x00, 0x00, 0xF8, 0x00, 0x00, 0xF8, 0x00, 0x00},
-		{0x80, 0x40, 0x20, 0x10, 0x20, 0x40, 0x80, 0x00},
-		{0x70, 0x88, 0x08, 0x10, 0x20, 0x00, 0x20, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x60, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
-		{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0xE0, 0x00},
-		{0x60, 0x90, 0x80, 0x80, 0x80, 0x90, 0x60, 0x00},
-		{0xE0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE0, 0x00},
-		{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0xF0, 0x00},
-		{0xF0, 0x80, 0x80, 0xE0, 0x80, 0x80, 0x80, 0x00},
-		{0x60, 0x90, 0x80, 0xB0, 0x90, 0x90, 0x70, 0x00},
-		{0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x00},
-		{0xE0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xE0, 0x00},
-		{0x10, 0x10, 0x10, 0x10, 0x10, 0x90, 0x60, 0x00},
-		{0x90, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
-		{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0, 0x00},
-		{0x82, 0xC6, 0xAA, 0x92, 0x82, 0x82, 0x82, 0x00},
-		{0x88, 0x88, 0xC8, 0xA8, 0x98, 0x88, 0x88, 0x00},
-		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
-		{0xE0, 0x90, 0x90, 0xE0, 0x80, 0x80, 0x80, 0x00},
-		{0x60, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x10},
-		{0xE0, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x00},
-		{0x60, 0x90, 0x80, 0x60, 0x10, 0x90, 0x60, 0x00},
-		{0xF8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00},
-		{0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x60, 0x00},
-		{0x88, 0x88, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
-		{0x82, 0x82, 0x82, 0x92, 0xAA, 0xC6, 0x82, 0x00},
-		{0x88, 0x88, 0x50, 0x20, 0x50, 0x88, 0x88, 0x00},
-		{0x88, 0x88, 0x50, 0x20, 0x20, 0x20, 0x20, 0x00},
-		{0xF8, 0x08, 0x10, 0x20, 0x40, 0x80, 0xF8, 0x00},
-		{0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0},
-		{0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x00},
-		{0x60, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60},
-		{0x20, 0x50, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x80, 0x80, 0x40, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x60, 0x10, 0x70, 0x90, 0x70, 0x00},
-		{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x00},
-		{0x00, 0x00, 0x60, 0x90, 0x80, 0x90, 0x60, 0x00},
-		{0x10, 0x10, 0x70, 0x90, 0x90, 0x90, 0x70, 0x00},
-		{0x00, 0x00, 0x60, 0x90, 0xF0, 0x80, 0x60, 0x00},
-		{0x30, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
-		{0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0, 0x00},
-		{0x80, 0x80, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
-		{0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
-		{0x40, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80},
-		{0x80, 0x80, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x00},
-		{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00},
-		{0x00, 0x00, 0xEC, 0x92, 0x92, 0x92, 0x92, 0x00},
-		{0x00, 0x00, 0xE0, 0x90, 0x90, 0x90, 0x90, 0x00},
-		{0x00, 0x00, 0x60, 0x90, 0x90, 0x90, 0x60, 0x00},
-		{0x00, 0xE0, 0x90, 0x90, 0x90, 0xE0, 0x80, 0x80},
-		{0x00, 0x70, 0x90, 0x90, 0x90, 0x70, 0x10, 0x10},
-		{0x00, 0x00, 0xB0, 0xC0, 0x80, 0x80, 0x80, 0x00},
-		{0x00, 0x00, 0x70, 0x80, 0x60, 0x10, 0xE0, 0x00},
-		{0x40, 0x40, 0xE0, 0x40, 0x40, 0x40, 0x40, 0x00},
-		{0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x00},
-		{0x00, 0x00, 0x88, 0x50, 0x50, 0x20, 0x20, 0x00},
-		{0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x6E, 0x00},
-		{0x00, 0x00, 0x90, 0x90, 0x60, 0x90, 0x90, 0x00},
-		{0x00, 0x90, 0x90, 0x90, 0x90, 0x70, 0x10, 0xE0},
-		{0x00, 0x00, 0xF8, 0x10, 0x20, 0x40, 0xF8, 0x00},
-		{0x20, 0x40, 0x40, 0x80, 0x40, 0x40, 0x20, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x80, 0x40, 0x40, 0x20, 0x40, 0x40, 0x80, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
-	};
-
 	_fontDescr._widthArray = fontWidthArray;
 	_fontDescr._extraLines = fontExtraLinesArray;
 	_fontDescr._fontData = fontData;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index c84e07068bb..77f91d66dde 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -24,15 +24,16 @@
 #define EFH_EFH_H
 
 #include "efh/detection.h"
+#include "efh/constants.h"
 
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/events.h"
 
 #include "engines/engine.h"
-#include "graphics/palette.h"
 #include "graphics/surface.h"
 
+
 namespace Common {
 class RandomSource;
 }
@@ -70,14 +71,10 @@ public:
 	void copy(EfhGraphicsStruct *src);
 };
 
-struct Font {
-	uint8 _lines[8];
-};
-
 struct FontDescr {
-	uint8 *_widthArray;
-	uint8 *_extraLines;
-	Font  *_fontData;
+	const uint8 *_widthArray;
+	const uint8 *_extraLines;
+	const Font  *_fontData;
 	uint8 _charHeight;
 	uint8 _extraVerticalSpace;
 	uint8 _extraHorizontalSpace;


Commit: 2ab89d40b4ad108d37fc6454f62262a387f2dea9
    https://github.com/scummvm/scummvm/commit/2ab89d40b4ad108d37fc6454f62262a387f2dea9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:32+01:00

Commit Message:
EFH: Renaming, remove unused parameters in a couple of functions

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 6ccc10c048b..1e3bda56d24 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -22,18 +22,20 @@
 
 #include "efh/constants.h"
 
+#include "engine.h"
+
 namespace Efh {
-const uint8 fontWidthArray[96] = {
+const uint8 kFontWidthArray[96] = {
 	3, 2, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 3, 3, 2, 7, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 1, 4, 4, 4,
 	4, 4, 4, 4, 4, 3, 4, 4, 4, 7, 5, 4, 4, 4, 4, 4, 5, 4, 5, 7, 5, 5, 5, 3, 7, 3, 5, 0, 2, 4, 4, 4, 4, 4, 4, 4,
 	4, 1, 2, 4, 1, 7, 4, 4, 4, 4, 4, 4, 3, 4, 5, 7, 4, 4, 5, 3, 0, 3, 0, 0};
 
-const uint8 fontExtraLinesArray[96] = {
+const uint8 kFontExtraLinesArray[96] = {
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 3,
 	1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 0, 0};
 
-const Font fontData[96] = {
+const Font kFontData[96] = {
 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
 	{0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x80, 0x00},
 	{0xA0, 0xA0, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00},
@@ -132,7 +134,7 @@ const Font fontData[96] = {
 	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
-const Encounter _encounters[] {
+const Encounter kEncounters[] {
 	{"Indian", 0, 5, 50, {64, 64, 68, 70, 92}, 25, 2},
 	{"Warrior", 0, 6, 85, {70, 64, 68, 70, 92}, 35, 2},
 	{"Tracker", 0, 8, 115, {92, 64, 68, 70, 92}, 38, 2},
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index d64235fd93b..7b49ecdfdf0 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -40,10 +40,10 @@ struct Encounter {
 	uint8 _nameArticle;
 };
 
-extern const uint8 fontWidthArray[96];
-extern const uint8 fontExtraLinesArray[96];
-extern const Font fontData[96];
-extern const Encounter _encounters[];
+extern const uint8 kFontWidthArray[96];
+extern const uint8 kFontExtraLinesArray[96];
+extern const Font kFontData[96];
+extern const Encounter kEncounters[];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 86436d49487..1bb54b1ad28 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -26,14 +26,11 @@
 #include "common/config-manager.h"
 #include "common/events.h"
 #include "engines/util.h"
-#include "graphics/cursorman.h"
+#include "graphics/palette.h"
 
 #include "efh/efh.h"
 #include "efh/constants.h"
 
-#include "engines/util.h"
-#include "graphics/palette.h"
-
 namespace Efh {
 
 EfhEngine *EfhEngine::s_Engine = nullptr;
@@ -45,7 +42,7 @@ EfhGraphicsStruct::EfhGraphicsStruct() {
 	_height = 0;
 	_area = Common::Rect(0, 0, 0, 0);
 }
-EfhGraphicsStruct::EfhGraphicsStruct(int16 *lineBuf, int16 x, int16 y, int16 width, int16 height) {
+EfhGraphicsStruct::EfhGraphicsStruct(int8 **lineBuf, int16 x, int16 y, int16 width, int16 height) {
 	_vgaLineBuffer = lineBuf;
 	_shiftValue = 0;
 	_width = width;
@@ -284,7 +281,7 @@ void EfhEngine::loadNewPortrait() {
 	findMapFile(_techId);
 	_currentAnimImageSetId = 200 + _unkRelatedToAnimImageSetId;
 	int imageSetId = _unkRelatedToAnimImageSetId + 13;
-	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
 }
 
 void EfhEngine::loadAnimImageSet() {
@@ -298,7 +295,7 @@ void EfhEngine::loadAnimImageSet() {
 	_currentAnimImageSetId = _animImageSetId;
 
 	int16 animSetId = _animImageSetId + 17;
-	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
 }
 
 void EfhEngine::loadHistory() {
@@ -533,9 +530,9 @@ void EfhEngine::initEngine() {
 	_defaultBoxColor = 7;
 
 	// Init Font
-	_fontDescr._widthArray = fontWidthArray;
-	_fontDescr._extraLines = fontExtraLinesArray;
-	_fontDescr._fontData = fontData;
+	_fontDescr._widthArray = kFontWidthArray;
+	_fontDescr._extraLines = kFontExtraLinesArray;
+	_fontDescr._fontData = kFontData;
 	_fontDescr._charHeight = 8;
 	_fontDescr._extraVerticalSpace = 3;
 	_fontDescr._extraHorizontalSpace = 1;
@@ -554,7 +551,7 @@ void EfhEngine::initEngine() {
 	// }
 
 	// Load Title Screen
-	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	displayFctFullScreen();
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
 	displayFctFullScreen();
@@ -584,7 +581,7 @@ void EfhEngine::initEngine() {
 	loadNPCS();
 
 	// Load picture room with girlfriend
-	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	fileName = "titlsong"; 
 	readFileToBuffer(fileName, _titleSong);
 	setDefaultNoteDuration();
@@ -596,7 +593,7 @@ void EfhEngine::initEngine() {
 		sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
 
 		// Load animations on previous picture with GF
-		loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+		loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 		readImpFile(100, 0);
 		lastInput = getLastCharAfterAnimCount(8);
 
@@ -654,7 +651,7 @@ void EfhEngine::initEngine() {
 		}		
 	}
 
-	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	readImpFile(99, false);
 	_word31E9E = 0xFFFF;
 	restoreAnimImageSetId();
@@ -680,7 +677,7 @@ void EfhEngine::initMapMonsters() {
 
 		for (uint8 counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = _rnd->getRandomNumber(99) + 1;
-			uint16 pictureRef = _encounters[_mapMonsters[monsterId]._MonsterRef]._pictureRef;
+			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._MonsterRef]._pictureRef;
 
 			if (rand100 <= 25) {
 				uint16 delta = _rnd->getRandomNumber((pictureRef / 2) - 1) + 1;
@@ -753,12 +750,12 @@ void EfhEngine::displayLowStatusScreen(int i) {
 	warning("STUB - displayLowStatusScreen");
 }
 
-void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer) {
+void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
 	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
-	rImageFile(fileName, buffer, subFilesArray, CGAVal, EGAVal, destBuffer, transfBuffer);
+	rImageFile(fileName, buffer, subFilesArray, destBuffer);
 }
 
-void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *transformedBuf) {
+void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
 	readFileToBuffer(filename, packedBuffer);
 	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
 	// TODO: Keep this dump for debug purposes only
@@ -767,7 +764,7 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 	dump.write(targetBuffer, size);
 	// End of dump	
 	
-	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (1 Bpp)
+	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
 	// => Write a class to handle that more properly
 	uint8 *ptr = targetBuffer;
 	uint16 counter = 0;
@@ -795,8 +792,6 @@ void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 max
 
 void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
 	warning("STUB - displayBitmap");
-	
-	
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
@@ -922,7 +917,7 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 		_mapBitmapRef[bankId] = setId;
 
 	int16 ptrIndex = bankId * 72;
-	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], 0, _paletteTransformationConstant, _hiResImageBuf, _loResImageBuf);
+	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _hiResImageBuf);
 }
 
 void EfhEngine::restoreAnimImageSetId() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 77f91d66dde..d6ffb8de2b9 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -60,9 +60,9 @@ struct EfhGameDescription;
 class EfhGraphicsStruct {
 public:
 	EfhGraphicsStruct();
-	EfhGraphicsStruct(int16 *lineBuf, int16 x, int16 y, int16 width, int16 height);
+	EfhGraphicsStruct(int8 **lineBuf, int16 x, int16 y, int16 width, int16 height);
 
-	int16 *_vgaLineBuffer;
+	int8 **_vgaLineBuffer;
 	uint16 _shiftValue;
 	uint16 _width;
 	uint16 _height;
@@ -175,8 +175,8 @@ private:
 	void loadMapMonsters();
 	void saveAnimImageSetId();
 	void displayLowStatusScreen(int i);
-	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *destBuffer, uint8 *transfBuffer);
-	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, char CGAVal, char EGAVal, uint8 *packedBuffer, uint8 *transformedBuffer);
+	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
+	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
 	void displayFctFullScreen();
 	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
 	void displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
@@ -204,7 +204,7 @@ private:
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
-	int16 _vgaLineBuffer[200];
+	int8 *_vgaLineBuffer[200];
 	EfhGraphicsStruct *_vgaGraphicsStruct1;
 	EfhGraphicsStruct *_vgaGraphicsStruct2;
 	EfhGraphicsStruct *_graphicsStruct;


Commit: 6ca672552a1187b5bf19eec1fc6b4181ac88868b
    https://github.com/scummvm/scummvm/commit/6ca672552a1187b5bf19eec1fc6b4181ac88868b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement drawBox

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 1bb54b1ad28..14f14fba1b3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -79,7 +79,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	_vgaGraphicsStruct1 = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
 	_vgaGraphicsStruct2 = new EfhGraphicsStruct();
-	
+
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
 	_mapBitmapRef = nullptr;
@@ -844,7 +844,7 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 
 
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
-	warning("%d %d - startX %d startY %d width %d height %d fieldA %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_fieldA, bufferBM->_fieldD);
+	// warning("%d %d - startX %d startY %d width %d height %d fieldA %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_fieldA, bufferBM->_fieldD);
 	int counter = 0;
 	for (int j = 0; j < bufferBM->_height; ++j) {
 		for (int i = 0; i < bufferBM->_fieldA; ++i) {
@@ -1051,14 +1051,42 @@ uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	return _mapGameMapPtr[mapPosX * size + mapPosY];
 }
 
-void EfhEngine::drawBox(int minX, int minY, int maxX, int maxY) {
-	warning("STUB - drawBox");
+void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
+	if (minY > maxY)
+		SWAP(minY, maxY);
+
+	if (minX > maxX)
+		SWAP(minX, maxX);
+	
+	// warning("drawRect - _graphicsStruct x %d -> %d, y %d -> %d", _graphicsStruct->_area.left, _graphicsStruct->_area.right, _graphicsStruct->_area.top, _graphicsStruct->_area.bottom);
+
+	minX = CLIP(minX, 0, 319);
+	maxX = CLIP(maxX, 0, 319);
+	minY = CLIP(minY, 0, 199);
+	maxY = CLIP(maxY, 0, 199);
+	
+	int deltaY = 1 + maxY - minY;
+	int deltaX = 1 + maxX - minX;
+
+	uint8 color = _defaultBoxColor & 0xF;
+	bool xorColor = (_defaultBoxColor & 0x40) != 0;
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(minX, minY);
+	
+	for (int line = 0; line < deltaY; ++line) {
+		for (int col = 0; col < deltaX; ++col) {
+			if (xorColor)
+				destPtr[320 * line + col] ^= color;
+			else
+				destPtr[320 * line + col] = color;
+		}
+	}
+	
 }
 
 void EfhEngine::drawMenuBox(int minX, int minY, int maxX, int maxY, int color) {
 	uint8 oldValue = _defaultBoxColor;
 	_defaultBoxColor = color;
-	drawBox(minX, minY, maxX, maxY);
+	drawRect(minX, minY, maxX, maxY);
 	_defaultBoxColor = oldValue;
 }
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index d6ffb8de2b9..b22c589b7e8 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -187,7 +187,7 @@ private:
 	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	void copyCurrentPlaceToBuffer(int id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
-	void drawBox(int minX, int minY, int maxX, int maxY);
+	void drawRect(int minX, int minY, int maxX, int maxY);
 	void drawMenuBox(int minX, int minY, int maxX, int maxY, int color);
 	void displayFullScreenColoredMenuBox(int color);
 


Commit: 2d5377a276f041e8b2a4f4441e9cdedf7bcc34cd
    https://github.com/scummvm/scummvm/commit/2d5377a276f041e8b2a4f4441e9cdedf7bcc34cd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Refactor a bit the intro, implement getLastCharAfterAnimCount, remove more useless parameters from functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 14f14fba1b3..06c9e4475b3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -458,7 +458,101 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 
 Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
 	warning("STUB - getLastCharAfterAnimCount");
-	return Common::KEYCODE_INVALID;
+
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::Event event;
+	do {
+		_system->getEventManager()->pollEvent(event);
+	} while (event.kbd.keycode != Common::KEYCODE_INVALID);
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+	} 
+	
+	return lastChar;
+}
+
+void EfhEngine::playIntro() {
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+
+	// Load animations on previous picture with GF
+	loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
+	readImpFile(100, 0);
+	Common::KeyCode lastInput = getLastCharAfterAnimCount(8);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+	lastInput = getLastCharAfterAnimCount(80);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+	lastInput = getLastCharAfterAnimCount(80);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+	lastInput = getLastCharAfterAnimCount(80);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+	lastInput = getLastCharAfterAnimCount(80);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+	lastInput = getLastCharAfterAnimCount(80);
+	if (lastInput == Common::KEYCODE_ESCAPE)
+		return;
+
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+	displayFctFullScreen();
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+	getLastCharAfterAnimCount(80);
 }
 
 void EfhEngine::syncSoundSettings() {
@@ -553,9 +647,9 @@ void EfhEngine::initEngine() {
 	// Load Title Screen
 	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
 
 	// Load map tiles bitmaps
 	loadImageSetToTileBank(1, 1);
@@ -588,67 +682,7 @@ void EfhEngine::initEngine() {
 	Common::KeyCode lastInput = playSong(_titleSong);
 
 	if (lastInput != Common::KEYCODE_ESCAPE) {
-		sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
-		displayFctFullScreen();
-		sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
-
-		// Load animations on previous picture with GF
-		loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
-		readImpFile(100, 0);
-		lastInput = getLastCharAfterAnimCount(8);
-
-		if (lastInput != Common::KEYCODE_ESCAPE) {
-			sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-			sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
-			displayFctFullScreen();
-			sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-			sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
-			lastInput = getLastCharAfterAnimCount(80);
-			if (lastInput != Common::KEYCODE_ESCAPE) {
-				sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16, _paletteTransformationConstant);
-				sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-				sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
-				displayFctFullScreen();
-				sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16, _paletteTransformationConstant);
-				sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-				sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
-				lastInput = getLastCharAfterAnimCount(80);
-				if (lastInput != Common::KEYCODE_ESCAPE) {
-					sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16, _paletteTransformationConstant);
-					sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-					sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
-					displayFctFullScreen();
-					sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16, _paletteTransformationConstant);
-					sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-					sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
-					lastInput = getLastCharAfterAnimCount(80);
-					if (lastInput != Common::KEYCODE_ESCAPE) {
-						sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-						sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
-						displayFctFullScreen();
-						sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-						sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
-						lastInput = getLastCharAfterAnimCount(80);
-						if (lastInput != Common::KEYCODE_ESCAPE) {
-							sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-							sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
-							displayFctFullScreen();
-							sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-							sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
-							lastInput = getLastCharAfterAnimCount(80);
-							if (lastInput != Common::KEYCODE_ESCAPE) {
-								sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-								sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
-								displayFctFullScreen();
-								sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144, _paletteTransformationConstant);
-								sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
-								lastInput = getLastCharAfterAnimCount(80);
-							}
-						}
-					}
-				}
-			}
-		}		
+		playIntro();
 	}
 
 	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
@@ -795,6 +829,7 @@ void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphic
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
+#if 0
 	static uint16 byte2C80C[72] = {
 		   0,    1,    2,    3,    4,    5,    6,    7,
 		   8,    9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
@@ -807,9 +842,6 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 		   0,    0,    0,    0, 0x3F,    1, 0xC7,    0
 	};
 
-	warning("STUB - sub24D92");
-	
-#if 0
 	if (bufferBM == nullptr)
 		return;
 
@@ -842,7 +874,7 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 	//incomplete
 #endif
 
-
+	// TODO: Quick code to display stuff, may require to really reverse the actual function
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
 	// warning("%d %d - startX %d startY %d width %d height %d fieldA %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_fieldA, bufferBM->_fieldD);
 	int counter = 0;
@@ -856,7 +888,6 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 
 	_system->copyRectToScreen((byte *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
 	_system->updateScreen();
-	_system->delayMillis(200);
 }
 
 void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {
@@ -886,21 +917,44 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 }
 
 void EfhEngine::sub15094() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 112, 0, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[3], 16, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 112, 0);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[3], 16, 0);
 }
 
 void EfhEngine::sub150EE() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 304, 0, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[4], 128, 0, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 304, 0);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[4], 128, 0);
 }
 
 void EfhEngine::sub15018() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[7], 16, 136, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[8], 16, 192, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[5], 0, 136, _paletteTransformationConstant);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[6], 304, 136, _paletteTransformationConstant);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[7], 16, 136);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[8], 16, 192);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[5], 0, 136);
+	sub10B77_unkDisplayFct1(_circleImageSubFileArray[6], 304, 136);
+}
+
+void EfhEngine::setNumLock() {
+	// No implementation in ScummVM
+}
+
+void EfhEngine::unkfct_mapFunction() {
+	warning("STUB - unkfct_mapFunction");
+}
+
+void EfhEngine::unkFct_anim() {
+	setNumLock();
+
+	if (_engineInitPending)
+		return;
+
+	if (_animImageSetId != 0xFF) {
+		displayNextAnimFrame();
+		displayFctFullScreen();
+		displayAnimFrame();
+	}
+
+	unkfct_mapFunction();
 }
 
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
@@ -1094,6 +1148,28 @@ void EfhEngine::displayFullScreenColoredMenuBox(int color) {
 	drawMenuBox(0, 0, 320, 200, color);
 }
 
+Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
+	// The original checks for the joystick input
+	Common::Event event;
+	_system->getEventManager()->pollEvent(event);
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+	if (event.type == Common::EVENT_KEYUP) {
+		retVal = event.kbd.keycode;
+	} 	
+
+	if (animFl) {
+		warning("STUB - handleAndMapInput - animFl");
+	}
+	return retVal;
+}
+
+void EfhEngine::displayNextAnimFrame() {
+	if (++_unkAnimRelatedIndex >= 15)
+		_unkAnimRelatedIndex = 0;
+
+	displayAnimFrame();
+}
+
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	uint8 *placesPtr = &_places[576 * id];
 
@@ -1101,7 +1177,7 @@ void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	memcpy(_curPlace, placesPtr, 24 * 24);
 }
 
-void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation) {
+void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY) {
 	uint16 height = READ_LE_INT16(imagePtr);
 	uint16 width = READ_LE_INT16(imagePtr + 2);
 	uint8 *imageData = imagePtr + 4;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b22c589b7e8..28e8a8d05c0 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -170,6 +170,7 @@ private:
 	void decryptImpFile(bool techMapFl);
 	void readImpFile(int16 id, bool techMapFl);
 	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
+	void playIntro();
 	void initEngine();
 	void initMapMonsters();
 	void loadMapMonsters();
@@ -190,10 +191,12 @@ private:
 	void drawRect(int minX, int minY, int maxX, int maxY);
 	void drawMenuBox(int minX, int minY, int maxX, int maxY, int color);
 	void displayFullScreenColoredMenuBox(int color);
+	Common::KeyCode handleAndMapInput(bool animFl);
+	void displayNextAnimFrame();
 
 	void sub15150(bool flag);
 	void sub12A7F();
-	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY, uint8 guess_paletteTransformation);
+	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY);
 	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
 	void sub1512B();
@@ -201,6 +204,9 @@ private:
 	void sub15094();
 	void sub150EE();
 	void sub15018();
+	void setNumLock();
+	void unkfct_mapFunction();
+	void unkFct_anim();
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];


Commit: 159ba2b577ab807701054827f86931e6eb519be3
    https://github.com/scummvm/scummvm/commit/159ba2b577ab807701054827f86931e6eb519be3
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement script_parse() and several underlying functions, some refactoring around Items and NPCS

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 06c9e4475b3..32922d67433 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -59,6 +59,87 @@ void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
 	_area = src->_area;
 }
 
+void InvObject::init() {
+	_ref = 0;
+	_stat1 = 0;
+	_stat2 = 0;
+}
+
+void ItemStruct::init() {
+	for (int16 idx = 0; idx < 15; ++idx)
+		_name[idx] = 0;
+
+	_damage = 0;
+	_defense = 0;
+	_attacks = 0;
+	_uses = 0;
+	field_13 = 0;
+	_range = 0;
+	_attackType = 0;
+	field_16 = 0;
+	field17_attackTypeDefense = 0;
+	field_18 = 0;
+	field_19 = 0;
+	field_1A = 0;
+}
+
+void NPCStruct::init() {
+	for (int i = 0; i < 9; ++i)
+		_name[i] =  0;
+	field_9 = 0;
+	field_A = 0;
+	field_B = 0;
+	field_C = 0;
+	field_D = 0;
+	field_E = 0;
+	field_F = 0;
+	field_10 = 0;
+	field_11 = 0;
+	field_12 = 0;
+	field_14 = 0;
+	_xp = 0;
+
+	for (int i = 0; i < 15; ++i)
+		_activeScore[i] = 0;
+
+	for (int i = 0; i < 11; ++i) {
+		_passiveScore[i] = 0;
+		_infoScore[i] = 0;
+	}
+
+	field_3F = 0;
+	field_40 = 0;
+
+	for (int i = 0; i < 10; ++i)
+		_inventory[i].init();
+	
+	_possessivePronounSHL6 = 0;
+	_speed = 0;
+	field_6B = 0;
+	field_6C = 0;
+	field_6D = 0;
+	_unkItemId = 0;
+	field_6F = 0;
+	field_70 = 0;
+	field_71 = 0;
+	field_72 = 0;
+	field_73 = 0;
+	_hitPoints = 0;
+	_maxHP = 0;
+	field_78 = 0;
+	field_79 = 0;
+	field_7B = 0;
+	field_7D = 0;
+	field_7E = 0;
+	field_7F = 0;
+	field_80 = 0;
+	field_81 = 0;
+	field_82 = 0;
+	field_83 = 0;
+	field_84 = 0;
+	field_85 = 0;
+}
+
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 
@@ -107,7 +188,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_imageDataPtr._width = 0;
 	_imageDataPtr._startX = _imageDataPtr._startY = 0;
 	_imageDataPtr._height = 0;
-	_imageDataPtr._fieldA = 0;
+	_imageDataPtr._lineDataSize = 0;
 	_imageDataPtr._paletteTransformation = 0;
 	_imageDataPtr._fieldD = 0;
 
@@ -118,8 +199,10 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_techId = 0;
 	_currentAnimImageSetId = 0xFF;
 
-	for (int i = 0; i < 20; ++i)
+	for (int i = 0; i < 20; ++i) {
 		_portraitSubFilesArray[i] = nullptr;
+		_ennemyNamePt2[i] = 0;
+	}
 
 	for (int i = 0; i < 100; ++i)
 		_imp1PtrArray[i] = nullptr;
@@ -136,9 +219,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_fullPlaceId = 0xFF;
 	_guessAnimationAmount = 9;
 	_largeMapFlag = 0xFFFF;
-	_teamCharIdArray = 0;
-	_charId = -1;
-	_word2C8B8 = -1;
+	_teamCharId[0] = 0;
+	_teamCharId[1] = _teamCharId[2] = -1;
 
 	for (int i = 0; i < 3; ++i) {
 		_teamCharStatus[i]._status = 0;
@@ -155,9 +237,16 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_oldMapPosX = _oldMapPosY = 31;
 	_techDataId_MapPosX = _techDataId_MapPosY = 31;
 
+	_textPosX = 0;
+	_textPosY = 0;
+
 	_lastMainPlaceId = 0;
 	_word2C86E = 0;
 	_dword2C856 = nullptr;
+	_word2C880 = 0;
+	_word2C894 = 0;
+	_word2C8D7 = -1;
+	_word2C87A = false;
 }
 
 EfhEngine::~EfhEngine() {
@@ -220,9 +309,6 @@ Common::Error EfhEngine::run() {
 	// Setup mixer
 	syncSoundSettings();
 	_soundHandler->init();
-
-	CursorMan.replaceCursor(_normalCursor, 16, 16, 0, 0, 0);
-	CursorMan.showMouse(true);
 */
 	initEngine();
 	sub15150(true);
@@ -330,7 +416,7 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	
 }
 
-void EfhEngine::loadPlacesFile(uint16 fullPlaceId, int16 unused, bool forceReloadFl) {
+void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 	//TODO : Remove unused parameter when all the calls are implemented
 	if (fullPlaceId == 0xFF)
 		return;
@@ -387,12 +473,98 @@ void EfhEngine::readTileFact() {
 
 void EfhEngine::readItems() {
 	Common::String fileName = "items";
-	readFileToBuffer(fileName, _items);
+	uint8 itemBuff[8100];
+	readFileToBuffer(fileName, itemBuff);
+	uint8 *curPtr = itemBuff;
+
+	for (int i = 0; i < 300; ++i) {
+		for (int16 idx = 0; idx < 15; ++idx)
+			_items[i]._name[idx] = *curPtr++;
+
+		
+		_items[i]._damage = *curPtr++;
+		_items[i]._defense = *curPtr++;
+		_items[i]._attacks = *curPtr++;
+		_items[i]._uses = *curPtr++;
+		_items[i].field_13 = *curPtr++;
+		_items[i]._range = *curPtr++;
+		_items[i]._attackType = *curPtr++;
+		_items[i].field_16 = *curPtr++;
+		_items[i].field17_attackTypeDefense = *curPtr++;
+		_items[i].field_18 = *curPtr++;
+		_items[i].field_19 = *curPtr++;
+		_items[i].field_1A = *curPtr++;
+	}
 }
 
 void EfhEngine::loadNPCS() {
 	Common::String fileName = "npcs";
-	readFileToBuffer(fileName, _npcBuf);
+	uint8 npcLoading[13400];
+	readFileToBuffer(fileName, npcLoading);
+	uint8 *curPtr = npcLoading;
+
+	for (int i = 0; i < 99; ++i) {
+		for (int idx = 0; idx < 9; ++idx)
+			_npcBuf[i]._name[idx] = *curPtr++;
+		_npcBuf[i].field_9 = *curPtr++;
+		_npcBuf[i].field_A = *curPtr++;
+		_npcBuf[i].field_B = *curPtr++;
+		_npcBuf[i].field_C = *curPtr++;
+		_npcBuf[i].field_D = *curPtr++;
+		_npcBuf[i].field_E = *curPtr++;
+		_npcBuf[i].field_F = *curPtr++;
+		_npcBuf[i].field_10 = *curPtr++;
+		_npcBuf[i].field_11 = *curPtr++;
+		_npcBuf[i].field_12 = READ_LE_INT16(curPtr);
+		_npcBuf[i].field_14 = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i]._xp = READ_LE_INT32(curPtr);
+		curPtr += 4;
+		for (int idx = 0; idx < 15; ++idx) {
+			_npcBuf[i]._activeScore[idx] = *curPtr++;
+		}
+		for (int idx = 0; idx < 11; ++idx) {
+			_npcBuf[i]._passiveScore[idx] = *curPtr++;
+		}
+		for (int idx = 0; idx < 11; ++idx) {
+			_npcBuf[i]._infoScore[idx] = *curPtr++;
+		}
+		_npcBuf[i].field_3F = *curPtr++;
+		_npcBuf[i].field_40 = *curPtr++;
+		for (int idx = 0; idx < 10; ++idx) {
+			_npcBuf[i]._inventory[idx]._ref = READ_LE_INT16(curPtr);
+			curPtr += 2;
+			_npcBuf[i]._inventory[idx]._stat1 = *curPtr++;
+			_npcBuf[i]._inventory[idx]._stat2 = *curPtr++;
+		}
+		_npcBuf[i]._possessivePronounSHL6 = *curPtr++;
+		_npcBuf[i]._speed = *curPtr++;
+		_npcBuf[i].field_6B = *curPtr++;
+		_npcBuf[i].field_6C = *curPtr++;
+		_npcBuf[i].field_6D = *curPtr++;
+		_npcBuf[i]._unkItemId = *curPtr++;
+		_npcBuf[i].field_6F = *curPtr++;
+		_npcBuf[i].field_70 = *curPtr++;
+		_npcBuf[i].field_71 = *curPtr++;
+		_npcBuf[i].field_72 = *curPtr++;
+		_npcBuf[i].field_73 = *curPtr++;
+		_npcBuf[i]._hitPoints = READ_LE_INT16(curPtr);
+		_npcBuf[i]._maxHP = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i].field_78 = *curPtr++;
+		_npcBuf[i].field_79 = READ_LE_INT16(curPtr);
+		_npcBuf[i].field_7B = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i].field_7D = *curPtr++;
+		_npcBuf[i].field_7E = *curPtr++;
+		_npcBuf[i].field_7F = *curPtr++;
+		_npcBuf[i].field_80 = *curPtr++;
+		_npcBuf[i].field_81 = *curPtr++;
+		_npcBuf[i].field_82 = *curPtr++;
+		_npcBuf[i].field_83 = *curPtr++;
+		_npcBuf[i].field_84 = *curPtr++;
+		_npcBuf[i].field_85 = *curPtr++;
+	}
 }
 
 void EfhEngine::setDefaultNoteDuration() {
@@ -415,10 +587,10 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 	uint8 *curPtr;
 
 	if (!techMapFl) {
-		_imp2PtrArray[++counter] = curPtr = _imp2;
+		_imp2PtrArray[counter++] = curPtr = _imp2;
 		target = 431;
 	} else {
-		_imp2PtrArray[++counter] = curPtr = _imp1;
+		_imp2PtrArray[counter++] = curPtr = _imp1;
 		target = 99;
 	}
 
@@ -427,9 +599,9 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 		if (*curPtr == 0x40) {
 			curPtr += 3;
 			if (!techMapFl)
-				_imp2PtrArray[++counter] = curPtr;
+				_imp2PtrArray[counter++] = curPtr;
 			else
-				_imp1PtrArray[++counter] = curPtr;
+				_imp1PtrArray[counter++] = curPtr;
 		} else
 			++curPtr;
 	} while (*curPtr != 0x60 && counter <= target);
@@ -498,6 +670,7 @@ void EfhEngine::playIntro() {
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
+	// With GF on the bed
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
@@ -507,6 +680,7 @@ void EfhEngine::playIntro() {
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
+	// Poof
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16);
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
@@ -518,6 +692,7 @@ void EfhEngine::playIntro() {
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
+	// On the phone
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16);
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
@@ -588,7 +763,8 @@ void EfhEngine::initEngine() {
 	memset(_imp1, 0, sizeof(_imp1));
 	memset(_imp2, 0, sizeof(_imp2));
 	memset(_titleSong, 0, sizeof(_titleSong));
-	memset(_items, 0, sizeof(_items));
+	for (int i = 0; i < 300; ++i)
+		_items[i].init();
 	memset(_tileFact, 0, sizeof(_tileFact));
 	memset(_animInfo, 0, sizeof(_animInfo));
 	memset(_history, 0, sizeof(_history));
@@ -707,19 +883,19 @@ void EfhEngine::initMapMonsters() {
 
 		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
 		if (groupSize == 0)
-			groupSize = _rnd->getRandomNumber(10);
+			groupSize = getRandom(10);
 
 		for (uint8 counter = 0; counter < groupSize; ++counter) {
-			uint rand100 = _rnd->getRandomNumber(99) + 1;
+			uint rand100 = getRandom(100);
 			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._MonsterRef]._pictureRef;
 
 			if (rand100 <= 25) {
-				uint16 delta = _rnd->getRandomNumber((pictureRef / 2) - 1) + 1;
+				uint16 delta = getRandom(pictureRef / 2);
 				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef - delta;
 			} else if (rand100 <= 75) {
 				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef;
 			} else {
-				uint16 delta = _rnd->getRandomNumber((pictureRef / 2) - 1) + 1;
+				uint16 delta = getRandom(pictureRef / 2);
 				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef + delta;
 			}
 		}		
@@ -815,83 +991,629 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 
 void EfhEngine::displayFctFullScreen() {
 	// CHECKME: 319 is in the original but looks suspicious.
-	displayBitmapAtPos(0, 0, 319, 200);
+	copyDirtyRect(0, 0, 319, 200);
 }
 
-void EfhEngine::displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY) {
+void EfhEngine::copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
 	_graphicsStruct->copy(_vgaGraphicsStruct2);
 	_initRect = Common::Rect(minX, minY, maxX, maxY);
-	displayBitmap(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
+	copyGraphicBufferFromTo(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
 }
 
-void EfhEngine::displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
-	warning("STUB - displayBitmap");
+void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
+	warning("STUB - copyGraphicBufferFromTo");
 }
 
 void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
-#if 0
-	static uint16 byte2C80C[72] = {
-		   0,    1,    2,    3,    4,    5,    6,    7,
-		   8,    9, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-		0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-		0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
-		0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-		0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
-		0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-		0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
-		   0,    0,    0,    0, 0x3F,    1, 0xC7,    0
-	};
+	// TODO: Quick code to display stuff, may require to really reverse the actual function
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
+	// warning("%d %d - startX %d startY %d width %d height %d lineDataSize %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_lineDataSize, bufferBM->_fieldD);
+	int counter = 0;
+	for (int line = 0; line < bufferBM->_height; ++line) {
+		for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
+			destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
+			destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
+			++counter;
+		}
+	}
 
-	if (bufferBM == nullptr)
-		return;
+	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+	_system->updateScreen();
+}
 
-	Common::Rect unkRect;
-	unkRect.left = posX - bufferBM->_startX;
-	unkRect.right = unkRect.left + bufferBM->_width - 1;
-	unkRect.top = posY - bufferBM->_startY;
-	unkRect.bottom = unkRect.top + bufferBM->_height - 1;
+uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
+	uint8 *buffer = srcBuffer;
 
-	Common::Rect destRect;
-	if (!computeLargeRect(_graphicsStruct->_area, &unkRect, &destRect))
-		return;
-	
-	uint16 bufferFieldA = bufferBM->_fieldA;
-	int16 deltaMinY = (destRect.top - unkRect.top) * bufferFieldA;
-	int16 destWidth = destRect.width() + 1;
+	for (int16 i = 0; i < destArraySize; ++i) {
+		buffer = script_getNumber(buffer, &destArray[i]);
+	}
 
-	int16 deltaMinX = -1;
-	int16 tmpVal = (destRect.left - unkRect.left) * 2;
+	return buffer;
+}
 
-	if (tmpVal < 0)
-		deltaMinX = 0;
+uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
+	uint8 *buffer = srcBuffer; 
+	int16 var2 = 0;
+	for (;;) {
+		uint8 curChar = *buffer;
+		if (curChar < 0x30 || curChar > 0x39) {
+			*retval = var2;
+			return buffer;
+		}
+		var2 = var2 * 10 + curChar - 0x30;
+	}
+}
 
-	int16 deltaWidth = (unkRect.right - unkRect.left) * 2 - (destRect.right - unkRect.left) * 2 + tmpVal;
+void EfhEngine::removeObject(int16 charId, int16 objectId) {
+	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
+	_npcBuf[charId]._inventory[objectId]._stat1 = 0;
+	_npcBuf[charId]._inventory[objectId]._stat2 = 0;
+}
 
-	uint8 *si = &bufferBM->_dataPtr[deltaMinY + tmpVal];
-	uint8 ch = bufferBM->_paletteTransformation;
-	uint8 cl = 4;
-	uint16 var3A = byte2C80C[bufferBM->_fieldD << 3];
-	//incomplete
-#endif
+void EfhEngine::totalPartyKill() {
+	for (int16 counter = 0; counter < 3; ++counter) {
+		if (_teamCharId[counter] != -1)
+			_npcBuf[counter]._hitPoints = 0;
+	}
+}
 
-	// TODO: Quick code to display stuff, may require to really reverse the actual function
-	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
-	// warning("%d %d - startX %d startY %d width %d height %d fieldA %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_fieldA, bufferBM->_fieldD);
-	int counter = 0;
-	for (int j = 0; j < bufferBM->_height; ++j) {
-		for (int i = 0; i < bufferBM->_fieldA; ++i) {
-			destPtr[320 * j + 2 * i] = bufferBM->_dataPtr[counter] >> 4;
-			destPtr[320 * j + 2 * i + 1] = bufferBM->_dataPtr[counter] & 0xF;
-			++counter;
+int16 EfhEngine::getRandom(int16 maxVal) {
+	if (maxVal == 0)
+		return 0;
+
+	return 1 + _rnd->getRandomNumber(maxVal - 1);
+}
+
+void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
+	warning("STUB - removeCharacterFromTeam");
+}
+
+void EfhEngine::emptyFunction(int i) {
+	// TODO: Eventually remove this useless function
+}
+
+void EfhEngine::refreshTeamSize() {
+	_teamSize = 0;
+	for (int16 counter = 0; counter < 3; ++counter) {
+		if (_teamCharId[counter] != -1)
+			++_teamSize;
+	}
+}
+
+bool EfhEngine::isCharacterATeamMember(int16 id) {
+	for (int16 counter = 0; counter < _teamSize; ++counter) {
+		if (_teamCharId[counter] == id)
+			return true;
+	}
+
+	return false;
+}
+
+void EfhEngine::handleWinSequence() {
+	warning("STUB - handleWinSequence");
+}
+
+bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
+	warning("STUB - giveItemTo");
+
+	return false;
+}
+
+void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
+	warning("STUB - sub26437");
+}
+
+void EfhEngine::displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY) {
+	uint16 length = getStringWidth(str);
+	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
+	sub26437(str, startCenteredDisplayX, posY, _unkVideoRelatedWord1);
+}
+
+int16 EfhEngine::chooseCharacterToReplace() {
+	warning("STUB - chooseCharacterToReplace");
+	return 0x1B;
+}
+
+int16 EfhEngine::handleCharacterJoining() {
+	static char strReplaceWho[13] = "Replace Who?";
+	for (int16 counter = 0; counter < 3; ++counter) {
+		if (_teamCharId[counter] == -1) {
+			return counter;
 		}
 	}
 
-	_system->copyRectToScreen((byte *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
-	_system->updateScreen();
+	for (int16 counter = 0; counter < 2; ++counter) {
+		drawMenuBox(200, 112, 278, 132, 0);
+		displayCenteredString(strReplaceWho, 200, 278, 117);
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+
+	int16 charId = chooseCharacterToReplace();
+	for (int16 counter = 0; counter < 2; ++counter) {
+		drawMenuBox(200, 112, 278, 132, 0);
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+
+	if (charId == 0x1B) // Escape Keycode
+		return -1;
+
+	removeCharacterFromTeam(charId);
+}
+
+void EfhEngine::drawMapWindow() {
+	drawMenuBox(128, 8, 303, 135, 0);
+}
+
+void EfhEngine::copyString(uint8 *srcStr, uint8 *destStr) {
+	uint8 lastChar = 1;
+	int16 idx = 0;
+
+	while (lastChar != 0) {
+		lastChar = destStr[idx] = srcStr[idx];
+	}
+}
+
+int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX, int maxY, int argC) {	
+	bool doneFlag = false;
+	int16 var_F2 = 0xFFFF;
+	int16 var_F0 = 0xFF;
+	int16 var_EE = 0xFF;
+	const char *stringToDisplay = " ";
+	uint16 curLine = 0;
+	int16 numbLines = (1 + maxY - posY) / 9;
+	int16 width = maxX - posX;
+	int16 var_114 = getStringWidth((char *)stringToDisplay);
+	uint8 *buffer = stringBuffer;
+	char var_EC[80];
+	char dest[150];
+	memset(var_EC, 0, sizeof(var_EC));
+	memset(dest, 0, sizeof(dest));
+	int16 var_116 = 0;
+	setTextPos(posX, curLine * 9 + posY);
+
+	while (!doneFlag) {
+		uint8 curChar = *buffer;
+		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
+			var_F2 = 0;
+			var_EC[++var_116] = curChar;
+			++buffer;
+			continue;
+		}
+
+		if (curChar != 0x5E) {
+			if (curChar == 0)
+				doneFlag = true;
+			else if (curChar == 0x7C)
+				var_F2 = 0;
+
+			var_EC[var_116] = 0;
+			int16 var_11A = getStringWidth(var_EC);
+			int16 var_118 = var_114 + getStringWidth(dest);
+
+			if (var_118 + var_11A > width || curChar == 0x7C) {
+				if (curLine >= numbLines) {
+					doneFlag = true;
+				} else {
+					if (var_F2 == 0)
+						unkFct_displayString_2(dest);
+
+					*dest = 0;
+					strcpy(dest, var_EC);
+					strcat(dest, " ");
+					++curLine;
+					setTextPos(posX, posY + curLine * 9);
+					var_116 = 0;
+				}
+			} else {
+				strcat(dest, var_EC);
+				strcat(dest, " ");
+				var_116 = 0;
+			}
+			++buffer;
+			continue;
+		}
+
+		// At this point, curChar == 0x5E
+		++buffer;
+		int16 var_108 = 0;
+		buffer = script_getNumber(buffer, &var_108);
+		int16 scriptNumberArray[10];
+		memset(scriptNumberArray, 0, ARRAYSIZE(scriptNumberArray));
+
+		switch (var_108) {
+		case 0x00:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				if (_largeMapFlag) {
+					_largeMapFlag = false;
+					_techDataId_MapPosX = _mapPosX;
+					_techDataId_MapPosY = _mapPosY;
+				}
+				_oldMapPosX = _mapPosX = scriptNumberArray[1];
+				_oldMapPosY = _mapPosY = scriptNumberArray[2];
+				loadPlacesFile(scriptNumberArray[0], false);
+				_word2C880 = -1;
+				_word2C894 = -1;
+			}
+			break;
+		case 0x01:
+			if (argC != 0) {
+				_largeMapFlag = true;
+				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
+				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
+				_word2C880 = -1;
+				_word2C894 = -1;
+			}
+			break;
+		case 0x02:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				if (_word2C8D7)
+					writeTechAndMapFiles();
+				_oldMapPosX = _mapPosX = scriptNumberArray[1];
+				_oldMapPosY = _mapPosY = scriptNumberArray[2];
+				loadTechMapImp(scriptNumberArray[0]);
+				_largeMapFlag = true;
+				_word2C880 = -1;
+				_word2C894 = -1;
+				doneFlag = true;
+			}
+			break;
+		case 0x03:
+			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[2] - scriptNumberArray[0];
+				int16 var10E = scriptNumberArray[3] - scriptNumberArray[1];
+
+				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
+				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
+				_word2C880 = -1;
+				_word2C894 = -1;
+			}
+			break;
+		case 0x04:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				_mapPosX = scriptNumberArray[0];
+				_mapPosY = scriptNumberArray[1];
+				_word2C880 = -1;
+				_word2C894 = -1;
+			}
+			break;
+		case 0x05:
+			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = scriptNumberArray[1];
+					_npcBuf[var110]._activeScore[var10E] += scriptNumberArray[2] & 0xFF;
+					_npcBuf[var110]._activeScore[var10E] -= scriptNumberArray[3] & 0xFF;
+				}
+			}
+			break;
+		case 0x06:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = scriptNumberArray[1];
+					_npcBuf[var110]._activeScore[var10E] = scriptNumberArray[1];
+				}
+			}
+			break;
+		case 0x07:
+			if (argC != 0) {
+				totalPartyKill();
+				emptyFunction(2);
+			}
+			break;
+		case 0x08:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0 && scriptNumberArray[0] != -1) {
+				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
+			}
+			break;		
+		case 0x09:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = getRandom(scriptNumberArray[1]);
+					_npcBuf[var110]._hitPoints += var10E;
+					if (_npcBuf[var110]._hitPoints > _npcBuf[var110]._maxHP)
+						_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				}
+			}
+			break;
+		case 0x0A:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				}
+			}
+			break;
+		case 0x0B:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = getRandom(scriptNumberArray[1]);
+					_npcBuf[var110]._hitPoints -= var10E;
+					if (_npcBuf[var110]._hitPoints < 0)
+						_npcBuf[var110]._hitPoints = 0;
+				}
+			}
+			break;
+		case 0x0C:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				bool found = false;
+				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
+					for (int16 objectId = 0; objectId < 10; ++objectId) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+							removeObject(_teamCharId[counter], objectId);
+							found = true;
+							break;
+						}						
+					}
+				}
+			}
+			break;
+		case 0x0D:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				for (int16 counter = 0; counter < _teamSize; ++counter) {
+					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
+						break;
+				}
+			}
+			break;
+		case 0x0E:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[0];
+				bool found = false;
+				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
+					for (int16 objectId = 0; objectId < 10; ++objectId) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+							found = true;
+							break;
+						}
+					}
+				}
+
+				if (found)
+					var_F0 = scriptNumberArray[1];
+				else
+					var_F0 = scriptNumberArray[2];
+			}
+			break;
+		case 0x0F:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[0];
+				if (isCharacterATeamMember(var110))
+					var_F0 = scriptNumberArray[1];
+				else
+					var_F0 = scriptNumberArray[2];	
+			}
+			break;
+		case 0x10:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0)
+				var_F0 = scriptNumberArray[0];
+
+			break;
+		case 0x11:
+			if (argC != 0)
+				_unkArray2C8AA[0] = 0;
+			break;
+		case 0x12:
+			if (argC != 0) {
+				int16 var110 = sub151FD(_mapPosX, _mapPosY);
+				if (var110 != -1)
+					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+			}
+			break;
+		case 0x13:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0 && _largeMapFlag) {
+				_word2C87A = true;
+				loadPlacesFile(scriptNumberArray[0], false);
+				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
+				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
+				var_F0 = -1;
+			}
+			break;
+		case 0x14:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[0];
+				if (!isCharacterATeamMember(var110))
+					var_EE = var110;
+				var_F0 = -1;
+			}
+			break;
+		case 0x15:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				_oldMapPosX = _mapPosX = scriptNumberArray[0];
+				_oldMapPosY = _mapPosY = scriptNumberArray[1];
+				_largeMapFlag = true;
+				_word2C894 = 0xFFFF;
+			}
+			break;
+		case 0x16:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[0];
+				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
+				if (isCharacterATeamMember(var110)) {
+					for (int16 counter = 0; counter < 3; ++counter) {
+						if (_teamCharId[counter] == var110) {
+							removeCharacterFromTeam(counter);
+							break;
+						}
+					}
+				}				
+			}
+			break;
+		case 0x17:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[0];
+				displayAnimFrames(var110, true);
+			}
+			break;
+		case 0x18:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = scriptNumberArray[1] - scriptNumberArray[0] + 1;
+				bool found = false;
+				var110 = getRandom(var110) + scriptNumberArray[0] - 1;
+				int16 counter;
+				for (counter = 0; counter < _teamSize; ++counter) {
+					if (giveItemTo(_teamCharId[counter], var110, 0xFF)) {
+						found = true;
+						break;
+					}
+				}
+
+				if (!found) {
+					drawMapWindow();
+					displayFctFullScreen();
+					drawMapWindow();
+					var110 = sub1C219("Nothing...", 1, 2, 0xFFFF);
+					displayFctFullScreen();
+				} else {
+					warning("STUB case 0x18");
+					copyString((uint8 *)_npcBuf[_teamCharId[counter]]._name, (uint8 *)_ennemyNamePt2);
+					copyString((uint8 *)_items[var110]._name, buffer);
+					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, (char *)buffer);
+					drawMapWindow();
+					displayFctFullScreen();
+					drawMapWindow();
+					var110 = sub1C219(dest, 1, 2, 0xFFFF);
+					displayFctFullScreen();
+				}
+
+				var110 = sub151FD(_mapPosX, _mapPosY);
+				if (var110 != -1) {
+					_mapUnknownPtr[var110 * 9 + 1] = 0xFF;
+				}
+				_word2C894 = 0xFFFF;
+			}
+			break;
+		case 0x19:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				if (_largeMapFlag) {
+					_mapGameMapPtr[scriptNumberArray[0] * 6 + scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+				} else {
+					_curPlace[scriptNumberArray[0] * 24 + scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+				}
+			}
+			break;
+		case 0x1A:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (var110 != -1) {
+					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+				}
+			}
+			break;
+		case 0x1B:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (var110 != -1) {
+					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+				}
+				_mapUnknownPtr[9 * scriptNumberArray[2] + 1] = scriptNumberArray[0];
+				_mapUnknownPtr[9 * scriptNumberArray[2] + 2] = scriptNumberArray[1];
+			}
+			break;
+		case 0x1C:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				_history[scriptNumberArray[0]] = 0xFF;
+			}
+			break;
+		case 0x1D:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0) {
+				_history[scriptNumberArray[0]] = 0;
+			}
+			break;
+		case 0x1E:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (argC != 0) {
+				if (_history[scriptNumberArray[0]] == 0)
+					var_F0 = scriptNumberArray[2];
+				else
+					var_F0 = scriptNumberArray[1];
+			}
+			break;
+		case 0x1F:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (argC != 0)
+				_unkArray2C8AA[0] = scriptNumberArray[0];
+
+			break;
+		case 0x20:
+			if (argC != 0) {
+				handleWinSequence();
+				_system->quit();
+			}
+		default:
+			break;
+		}
+	}
+
+	if (*dest != 0 && curLine < numbLines && var_F2 == 0)
+		unkFct_displayString_2(dest);
+
+	if (var_EE != 0xFF) {
+		displayLowStatusScreen(-1);
+		int16 teamSlot = handleCharacterJoining();
+		if (teamSlot > -1) {
+			_teamCharId[teamSlot] = var_EE;
+		}
+		refreshTeamSize();
+	}
+
+	return var_F0;
 }
 
 void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {
-	warning("STUB - sub133E5");
+	uint16 stringIdx = 0;
+	uint8 message[200];
+	memset(message, 0, sizeof(message));
+	
+	for (;;) {
+		uint8 curChar = *impPtr;
+		if (curChar == 0 || curChar == 0x40 || curChar == 0x60)
+			break;
+
+		if (curChar == 0x0D) {
+			message[stringIdx++] = ' ';
+			++impPtr;
+		} else if (curChar == 0x0A) {
+			++impPtr;
+		} else {
+			message[stringIdx++] = curChar;
+			++impPtr;
+		}
+	}
+
+	script_parse(message, posX, posY, maxX, maxY, argC);
 }
 
 void EfhEngine::sub1512B() {
@@ -934,6 +1656,24 @@ void EfhEngine::sub15018() {
 	sub10B77_unkDisplayFct1(_circleImageSubFileArray[6], 304, 136);
 }
 
+void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
+	warning("STUB: sub15A28");
+}
+
+void EfhEngine::sub2455E(int16 arg0, int16 arg1, int16 arg2) {
+	warning("STUB: sub2455E");
+}
+
+int16 EfhEngine::sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl) {
+	warning("STUB: sub1C219");
+	return -1;
+}
+
+int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
+	warning("STUB: sub151FD");
+	return -1;
+}
+
 void EfhEngine::setNumLock() {
 	// No implementation in ScummVM
 }
@@ -957,6 +1697,10 @@ void EfhEngine::unkFct_anim() {
 	unkfct_mapFunction();
 }
 
+void EfhEngine::unkFct_displayString_2(char *message) {
+	warning("STUB - unkFct_displayString_2 %s", message);
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
@@ -979,9 +1723,6 @@ void EfhEngine::restoreAnimImageSetId() {
 }
 
 void EfhEngine::checkProtection() {
-	// bool successfulCheck = false;
-	// uint8 protectionItemId = _rnd->getRandomNumber(5);
-	// uint8 ProtectionArrayId = _rnd->getRandomNumber(14);
 	_unkVideoRelatedWord1 = 0xE;
 
 	//CHECKME : Well, yeah, some code may be missing there. Who knows.
@@ -997,8 +1738,6 @@ void EfhEngine::loadGame() {
 	//
 	// The savegame is used to initialize the engine, so this part is reimplemented.
 	// The check for existence is replaced by an error.
-	//
-	// Fun fact : it was therefore expected to overwrite the original savegame on the floppy each time you saved. What could possibly go wrong?
 
 	Common::String fileName = "savegame";
 	Common::File f;
@@ -1010,9 +1749,9 @@ void EfhEngine::loadGame() {
 	_fullPlaceId = f.readUint16LE();
 	_guessAnimationAmount = f.readSint16LE();
 	_largeMapFlag = f.readUint16LE();
-	_teamCharIdArray = f.readSint16LE();
-	_charId = f.readSint16LE();
-	_word2C8B8 = f.readSint16LE();
+	_teamCharId[0] = f.readSint16LE();
+	_teamCharId[1] = f.readSint16LE();
+	_teamCharId[2] = f.readSint16LE();
 
 	for (int i = 0; i < 3; ++i) {
 		_teamCharStatus[i]._status = f.readSint16LE();
@@ -1044,7 +1783,7 @@ void EfhEngine::loadGame() {
 	loadTechMapImp(_techId);
 
 	_lastMainPlaceId = 0xFFFF;
-	loadPlacesFile(_fullPlaceId, 0, true);
+	loadPlacesFile(_fullPlaceId, true);
 }
 
 uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
@@ -1170,6 +1909,34 @@ void EfhEngine::displayNextAnimFrame() {
 	displayAnimFrame();
 }
 
+void EfhEngine::writeTechAndMapFiles() {
+	warning("STUB - writeTechAndMapFiles");
+}
+
+uint16 EfhEngine::getStringWidth(char *buffer) {
+	uint16 retVal = 0;
+
+	for (;;) {
+		uint8 curChar = (uint8) *buffer++;
+		if (curChar == 0) {
+			--buffer;
+			break;
+		}
+
+		if (curChar < 0x20)
+			continue;
+
+		retVal += _fontDescr._widthArray[curChar - 0x20] + 1;
+	}
+
+	return retVal;
+}
+
+void EfhEngine::setTextPos(int16 textPosX, int16 textPosY) {
+	_textPosX = textPosX;
+	_textPosY = textPosY;
+}
+
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	uint8 *placesPtr = &_places[576 * id];
 
@@ -1182,10 +1949,10 @@ void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY)
 	uint16 width = READ_LE_INT16(imagePtr + 2);
 	uint8 *imageData = imagePtr + 4;
 
-	_imageDataPtr._fieldA = width;
+	_imageDataPtr._lineDataSize = width;
 	_imageDataPtr._dataPtr = imageData;
 	_imageDataPtr._height = height;
-	_imageDataPtr._width = width * 2;
+	_imageDataPtr._width = width * 2; // 2 pixels per byte
 	_imageDataPtr._startX = _imageDataPtr._startY = 0;
 	
 	sub24D92(&_imageDataPtr, posX, posY);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 28e8a8d05c0..b05429f43a5 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -71,6 +71,81 @@ public:
 	void copy(EfhGraphicsStruct *src);
 };
 
+struct InvObject {
+	int16 _ref;
+	uint8 _stat1;
+	uint8 _stat2;
+
+	void init();
+};
+
+struct ItemStruct {
+	char _name[15];
+	uint8 _damage;
+	uint8 _defense;
+	uint8 _attacks;
+	uint8 _uses;
+	uint8 field_13;
+	uint8 _range;
+	uint8 _attackType;
+	uint8 field_16;
+	uint8 field17_attackTypeDefense;
+	uint8 field_18;
+	uint8 field_19;
+	uint8 field_1A;
+
+	void init();
+};
+
+struct NPCStruct {
+	char _name[9];
+	uint8 field_9;
+	uint8 field_A;
+	uint8 field_B;
+	uint8 field_C;
+	uint8 field_D;
+	uint8 field_E;
+	uint8 field_F;
+	uint8 field_10;
+	uint8 field_11;
+	uint16 field_12;
+	uint16 field_14;
+	uint32 _xp;
+	uint8 _activeScore[15];
+	uint8 _passiveScore[11];
+	uint8 _infoScore[11];
+	uint8 field_3F;
+	uint8 field_40;
+	InvObject _inventory[10];
+	uint8 _possessivePronounSHL6;
+	uint8 _speed;
+	uint8 field_6B;
+	uint8 field_6C;
+	uint8 field_6D;
+	uint8 _unkItemId;
+	uint8 field_6F;
+	uint8 field_70;
+	uint8 field_71;
+	uint8 field_72;
+	uint8 field_73;
+	int16 _hitPoints;
+	int16 _maxHP;
+	uint8 field_78;
+	uint16 field_79;
+	uint16 field_7B;
+	uint8 field_7D;
+	uint8 field_7E;
+	uint8 field_7F;
+	uint8 field_80;
+	uint8 field_81;
+	uint8 field_82;
+	uint8 field_83;
+	uint8 field_84;
+	uint8 field_85;
+
+	void init();
+};
+
 struct FontDescr {
 	const uint8 *_widthArray;
 	const uint8 *_extraLines;
@@ -86,7 +161,7 @@ struct BufferBM {
 	uint16 _startX;
 	uint16 _startY;
 	uint16 _height;
-	uint16 _fieldA;
+	uint16 _lineDataSize;
 	uint8 _paletteTransformation;
 	uint16 _fieldD;
 };
@@ -158,7 +233,7 @@ private:
 	void loadAnimImageSet();
 	void loadHistory();
 	void loadTechMapImp(int16 fileId);
-	void loadPlacesFile(uint16 fullPlaceId, int16 unused, bool forceReloadFl);
+	void loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl);
 	void drawUnknownMenuBox();
 	void displayAnimFrame();
 	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
@@ -179,8 +254,8 @@ private:
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
 	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
 	void displayFctFullScreen();
-	void displayBitmapAtPos(int16 minX, int16 minY, int16 maxX, int16 maxY);
-	void displayBitmap(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
+	void copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY);
+	void copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
 	void restoreAnimImageSetId();
 	void checkProtection();
@@ -193,20 +268,46 @@ private:
 	void displayFullScreenColoredMenuBox(int color);
 	Common::KeyCode handleAndMapInput(bool animFl);
 	void displayNextAnimFrame();
+	void writeTechAndMapFiles();
+	uint16 getStringWidth(char *buffer);
+	void setTextPos(int16 textPosX, int16 textPosY);
 
 	void sub15150(bool flag);
 	void sub12A7F();
 	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY);
 	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
+	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
+	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
+	void removeObject(int16 charId, int16 objectId);
+	void totalPartyKill();
+	int16 getRandom(int16 maxVal);
+	void removeCharacterFromTeam(int16 teamMemberId);
+	void emptyFunction(int i);
+	void refreshTeamSize();
+	bool isCharacterATeamMember(int16 id);
+	void handleWinSequence();
+	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
+	void sub26437(char * str, int16 startX, int16 startY, uint16 unkFl);
+	void displayCenteredString(char * str, int16 minX, int16 maxX, int16 posY);
+	int16 chooseCharacterToReplace();
+	int16 handleCharacterJoining();
+	void drawMapWindow();
+	void copyString(uint8 *srcStr, uint8 *destStr);
+	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
 	void sub1512B();
 	void sub221FA(uint8 *impArray, bool flag);
 	void sub15094();
 	void sub150EE();
 	void sub15018();
+	void sub15A28(int16 arg0, int16 arg2);
+	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
+	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
+	int16 sub151FD(int16 posX, int16 posY);
 	void setNumLock();
 	void unkfct_mapFunction();
 	void unkFct_anim();
+	void unkFct_displayString_2(char *message);
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
@@ -224,15 +325,16 @@ private:
 	uint8 _map[7000];
 	uint8 _places[12000];
 	uint8 _curPlace[600];
-	uint8 _npcBuf[13400];
+	NPCStruct _npcBuf[100];
 	uint8 _imp1[13000];
 	uint8 _imp2[10000];
 	uint8 _titleSong[1024];
-	uint8 _items[8100];
+	ItemStruct _items[300];
 	uint8 _tileFact[864];
 	uint8 _animInfo[9000];
 	uint8 _history[256];
 	uint8 _techData[4096];
+	char _ennemyNamePt2[20];
 
 	uint8 *_mapBitmapRef;
 	uint8 *_mapUnknownPtr;
@@ -263,9 +365,9 @@ private:
 	uint16 _fullPlaceId;
 	int16 _guessAnimationAmount;
 	uint16 _largeMapFlag; // CHECKME: bool?
-	int16 _teamCharIdArray;
-	int16 _charId;
-	int16 _word2C8B8;
+	int16 _teamCharId[3];
+	int16 _textPosX;
+	int16 _textPosY;
 	
 	Common::Rect _initRect;
 	bool _engineInitPending;
@@ -275,6 +377,11 @@ private:
 	int16 _unkArray2C8AA[3];
 	int16 _teamSize;
 	int16 _word2C872;
+	int16 _word2C880;
+	int16 _word2C894;
+	int16 _word2C8D7;
+	bool _word2C87A;
+
 	int16 _imageSetSubFilesIdx;
 
 	int16 _mapPosX, _mapPosY;


Commit: f7c609ebdb7ad65337a5d646d92ac97379269112
    https://github.com/scummvm/scummvm/commit/f7c609ebdb7ad65337a5d646d92ac97379269112
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Fix a couple of crashes

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 32922d67433..877e3e45d7b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -202,6 +202,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	for (int i = 0; i < 20; ++i) {
 		_portraitSubFilesArray[i] = nullptr;
 		_ennemyNamePt2[i] = 0;
+		_nameBuffer[i] = 0;
 	}
 
 	for (int i = 0; i < 100; ++i)
@@ -247,6 +248,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C894 = 0;
 	_word2C8D7 = -1;
 	_word2C87A = false;
+
+	memset(_messageToBePrinted, 0, 400);
 }
 
 EfhEngine::~EfhEngine() {
@@ -1140,6 +1143,7 @@ int16 EfhEngine::handleCharacterJoining() {
 		return -1;
 
 	removeCharacterFromTeam(charId);
+	return 2;
 }
 
 void EfhEngine::drawMapWindow() {
@@ -1157,7 +1161,7 @@ void EfhEngine::copyString(uint8 *srcStr, uint8 *destStr) {
 
 int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX, int maxY, int argC) {	
 	bool doneFlag = false;
-	int16 var_F2 = 0xFFFF;
+	int16 var_F2 = -1;
 	int16 var_F0 = 0xFF;
 	int16 var_EE = 0xFF;
 	const char *stringToDisplay = " ";
@@ -1446,7 +1450,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosX = _mapPosX = scriptNumberArray[0];
 				_oldMapPosY = _mapPosY = scriptNumberArray[1];
 				_largeMapFlag = true;
-				_word2C894 = 0xFFFF;
+				_word2C894 = -1;
 			}
 			break;
 		case 0x16:
@@ -1494,8 +1498,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				} else {
 					warning("STUB case 0x18");
 					copyString((uint8 *)_npcBuf[_teamCharId[counter]]._name, (uint8 *)_ennemyNamePt2);
-					copyString((uint8 *)_items[var110]._name, buffer);
-					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, (char *)buffer);
+					copyString((uint8 *)_items[var110]._name, (uint8 *)_nameBuffer);
+					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, _nameBuffer);
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
@@ -1507,7 +1511,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				if (var110 != -1) {
 					_mapUnknownPtr[var110 * 9 + 1] = 0xFF;
 				}
-				_word2C894 = 0xFFFF;
+				_word2C894 = -1;
 			}
 			break;
 		case 0x19:
@@ -1592,28 +1596,29 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 	return var_F0;
 }
 
-void EfhEngine::sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC) {
+void EfhEngine::sub133E5(uint8 *srcPtr, int posX, int posY, int maxX, int maxY, int argC) {
 	uint16 stringIdx = 0;
-	uint8 message[200];
-	memset(message, 0, sizeof(message));
+	uint8 *impPtr = srcPtr;
+	memset(_messageToBePrinted, 0, 200);
 	
 	for (;;) {
 		uint8 curChar = *impPtr;
+		
 		if (curChar == 0 || curChar == 0x40 || curChar == 0x60)
 			break;
 
 		if (curChar == 0x0D) {
-			message[stringIdx++] = ' ';
+			_messageToBePrinted[stringIdx++] = ' ';
 			++impPtr;
 		} else if (curChar == 0x0A) {
 			++impPtr;
 		} else {
-			message[stringIdx++] = curChar;
+			_messageToBePrinted[stringIdx++] = curChar;
 			++impPtr;
 		}
 	}
 
-	script_parse(message, posX, posY, maxX, maxY, argC);
+	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, argC);
 }
 
 void EfhEngine::sub1512B() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b05429f43a5..dbcc49bd30a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -335,7 +335,9 @@ private:
 	uint8 _history[256];
 	uint8 _techData[4096];
 	char _ennemyNamePt2[20];
-
+	char _nameBuffer[20];
+	uint8 _messageToBePrinted[400];
+	
 	uint8 *_mapBitmapRef;
 	uint8 *_mapUnknownPtr;
 	uint8 *_mapMonstersPtr;


Commit: 99f3f1e727a0a74c0ece9ea0a9b94016e45a43b7
    https://github.com/scummvm/scummvm/commit/99f3f1e727a0a74c0ece9ea0a9b94016e45a43b7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement string display

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 877e3e45d7b..c79573c94e6 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -248,6 +248,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C894 = 0;
 	_word2C8D7 = -1;
 	_word2C87A = false;
+	_unk_sub26437_flag = 0;
 
 	memset(_messageToBePrinted, 0, 400);
 }
@@ -581,6 +582,8 @@ void EfhEngine::setDefaultNoteDuration() {
 
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	warning("STUB: playSong");
+	_system->delayMillis(1000);
+	
 	return Common::KEYCODE_INVALID;
 }
 
@@ -632,8 +635,6 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 }
 
 Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
-	warning("STUB - getLastCharAfterAnimCount");
-
 	if (delay == 0)
 		return Common::KEYCODE_INVALID;
 
@@ -668,7 +669,7 @@ void EfhEngine::playIntro() {
 
 	// Load animations on previous picture with GF
 	loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
-	readImpFile(100, 0);
+	readImpFile(100, false);
 	Common::KeyCode lastInput = getLastCharAfterAnimCount(8);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -995,6 +996,10 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 void EfhEngine::displayFctFullScreen() {
 	// CHECKME: 319 is in the original but looks suspicious.
 	copyDirtyRect(0, 0, 319, 200);
+
+	
+	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+	_system->updateScreen();
 }
 
 void EfhEngine::copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
@@ -1020,8 +1025,8 @@ void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
 		}
 	}
 
-	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
-	_system->updateScreen();
+//	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+//	_system->updateScreen();
 }
 
 uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
@@ -1103,7 +1108,40 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
 }
 
 void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
-	warning("STUB - sub26437");
+	uint8 *curPtr = (uint8 *)str;
+	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
+	_unk_sub26437_flag = unkFl & 0x3FFF;
+	int16 minX = startX;
+	int16 minY = startY;                                 // Used in case 0x8000
+	int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
+
+	if (unkFl & 0x8000) {
+		warning("STUB - sub26437 - 0x8000");
+	}
+
+	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
+		if (curChar == 0x0A) {
+			startX = minX;
+			startY += lineHeight;
+			continue;
+		}
+
+		if (curChar < 0x20)
+			continue;
+
+		uint16 characterId = (curChar + 0xE0) & 0xFF;
+		uint8 charWidth = _fontDescr._widthArray[characterId];
+
+		if (startX + charWidth >= 319) {
+			startX = minX;
+			startY += lineHeight;
+		}
+
+		uint8 varC = _fontDescr._extraLines[characterId];
+		sub252CE(curChar, startX, startY + varC);
+		startX += charWidth + _fontDescr._extraHorizontalSpace;
+	}
+	
 }
 
 void EfhEngine::displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY) {
@@ -1181,7 +1219,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 		uint8 curChar = *buffer;
 		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
 			var_F2 = 0;
-			var_EC[++var_116] = curChar;
+			var_EC[var_116++] = curChar;
 			++buffer;
 			continue;
 		}
@@ -1496,7 +1534,6 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					var110 = sub1C219("Nothing...", 1, 2, 0xFFFF);
 					displayFctFullScreen();
 				} else {
-					warning("STUB case 0x18");
 					copyString((uint8 *)_npcBuf[_teamCharId[counter]]._name, (uint8 *)_ennemyNamePt2);
 					copyString((uint8 *)_items[var110]._name, (uint8 *)_nameBuffer);
 					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, _nameBuffer);
@@ -1679,6 +1716,23 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	return -1;
 }
 
+void EfhEngine::sub252CE(uint8 curChar, int16 posX, int posY) {
+	// Quick hacked display, may require rework
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
+
+	int16 charId = curChar - 0x20;
+	uint8 width = _fontDescr._widthArray[charId];
+
+	for (int16 line = 0; line < 8; ++line) {
+		int16 x = 0;
+		for (int i = 7; i >= 7 - width; --i) {
+			if (_fontDescr._fontData[charId]._lines[line] & (1 << i))
+				destPtr[320 * line + x] = 14;
+			++x;
+		}
+	}	
+}
+
 void EfhEngine::setNumLock() {
 	// No implementation in ScummVM
 }
@@ -1702,8 +1756,21 @@ void EfhEngine::unkFct_anim() {
 	unkfct_mapFunction();
 }
 
+void EfhEngine::setNextCharacterPos() {
+	if (_textPosX <= 311)
+		return;
+
+	_textPosX = 0;
+	_textPosY += 8;
+
+	if (_textPosY > 191)
+		_textPosY = 0;
+}
+
 void EfhEngine::unkFct_displayString_2(char *message) {
-	warning("STUB - unkFct_displayString_2 %s", message);
+	sub26437(message, _textPosX, _textPosY, _unkVideoRelatedWord1);
+	_textPosX += getStringWidth(message) + 1;
+	setNextCharacterPos();
 }
 
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index dbcc49bd30a..28e17f2dc55 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -304,9 +304,12 @@ private:
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
+	void sub252CE(uint8 curChar, int16 posX, int posY);
+
 	void setNumLock();
 	void unkfct_mapFunction();
 	void unkFct_anim();
+	void setNextCharacterPos();
 	void unkFct_displayString_2(char *message);
 
 	uint8 _videoMode;
@@ -383,6 +386,7 @@ private:
 	int16 _word2C894;
 	int16 _word2C8D7;
 	bool _word2C87A;
+	int16 _unk_sub26437_flag;
 
 	int16 _imageSetSubFilesIdx;
 


Commit: 2bbd63c0bca80f5be87b6018001e0bb4b284c6da
    https://github.com/scummvm/scummvm/commit/2bbd63c0bca80f5be87b6018001e0bb4b284c6da
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement displayLowStatusScreen and some other functions, refactor AnimInfo

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c79573c94e6..bb9809cce60 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -65,6 +65,20 @@ void InvObject::init() {
 	_stat2 = 0;
 }
 
+void UnkAnimStruct::init() {
+	field0 = field1 = field2 = field3 = 0;
+}
+
+void AnimInfo::init() {
+	for (int i = 0; i < 15; ++i)
+		_unkAnimArray[i].init();
+
+	for (int i = 0; i < 10; ++i) {
+		_field3C_startY[i] = 0;
+		_field46_startX[i] = 0;
+	}
+}
+
 void ItemStruct::init() {
 	for (int16 idx = 0; idx < 15; ++idx)
 		_name[idx] = 0;
@@ -247,8 +261,11 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C880 = 0;
 	_word2C894 = 0;
 	_word2C8D7 = -1;
+	_word2C876 = true;
+	_word2C878 = true;
 	_word2C87A = false;
 	_unk_sub26437_flag = 0;
+	_word2C8D9 = 0;
 
 	memset(_messageToBePrinted, 0, 400);
 }
@@ -317,13 +334,15 @@ Common::Error EfhEngine::run() {
 	initEngine();
 	sub15150(true);
 	sub12A7F();
-	displayLowStatusScreen(-1);
+	displayLowStatusScreen(true);
 
 	if (!_protectionPassed)
 		return Common::kNoError;
 
 	warning("STUB - Main loop");
-
+	for (;;) {
+		displayFctFullScreen();
+	}
 	return Common::kNoError;
 }
 
@@ -345,7 +364,27 @@ int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
 
 void EfhEngine::readAnimInfo() {
 	Common::String fileName = "animinfo";
-	readFileToBuffer(fileName, _animInfo);
+	uint8 animInfoBuf[9000];
+	memset(animInfoBuf, 0, 9000);
+	uint8 *curPtr = animInfoBuf;
+	
+	readFileToBuffer(fileName, animInfoBuf);
+	for (int i = 0; i < 100; ++i) {
+		for (int id = 0; id < 15; ++id) {
+			_animInfo[i]._unkAnimArray[id].field0 = *curPtr++;
+			_animInfo[i]._unkAnimArray[id].field1 = *curPtr++;
+			_animInfo[i]._unkAnimArray[id].field2 = *curPtr++;
+			_animInfo[i]._unkAnimArray[id].field3 = *curPtr++;
+		}
+
+		for (int id = 0; id < 10; ++id)
+			_animInfo[i]._field3C_startY[id] = *curPtr++;
+
+		for (int id = 0; id < 10; ++id) {
+			_animInfo[i]._field46_startX[id] = READ_LE_INT16(curPtr);
+			curPtr += 2;
+		}
+	}
 }
 
 void EfhEngine::findMapFile(int16 mapId) {
@@ -445,7 +484,22 @@ void EfhEngine::drawUnknownMenuBox() {
 
 void EfhEngine::displayAnimFrame() {
 	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
-	warning("STUB - displayAnimFrame");
+
+	if (_animImageSetId == 0xFF)
+		return;
+
+	if (_animImageSetId == 0xFE) {
+		sub10B77_unkDisplayFct1(_portraitSubFilesArray[0], 16, 8);
+		return;
+	}
+
+	sub10B77_unkDisplayFct1(_portraitSubFilesArray[0], 16, 8);
+	for (int i = 0; i < 4; ++i) {
+		int16 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex].field0;
+		if (var2 == 0xFF)
+			continue;
+		sub10B77_unkDisplayFct1(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
+	}
 }
 
 void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
@@ -770,7 +824,10 @@ void EfhEngine::initEngine() {
 	for (int i = 0; i < 300; ++i)
 		_items[i].init();
 	memset(_tileFact, 0, sizeof(_tileFact));
-	memset(_animInfo, 0, sizeof(_animInfo));
+
+	for (int i = 0; i < 100; ++i)
+		_animInfo[i].init();
+
 	memset(_history, 0, sizeof(_history));
 	memset(_techData, 0, sizeof(_techData));
 
@@ -931,6 +988,30 @@ void EfhEngine::saveAnimImageSetId() {
 	_animImageSetId = 255;
 }
 
+int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
+	warning("STUB: getEquipmentDefense");
+	return 0;
+}
+
+uint16 EfhEngine::sub1C80A(int16 charId, int field18, bool flag) {
+	for (int i = 0; i < 10; ++i) {
+		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
+			continue;
+
+		int16 itemId = _npcBuf[charId]._inventory[i]._ref;
+		
+		if (_items[itemId].field_18 != field18)
+			continue;
+
+		if (!flag)
+			return i;
+
+		return itemId;
+	}
+
+	return 0x7FFF;
+}
+
 void EfhEngine::sub15150(bool flag) {
 	uint8 mapTileInfo = getMapTileInfo(_mapPosX, _mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[mapTileInfo / 72];
@@ -956,12 +1037,108 @@ void EfhEngine::sub15150(bool flag) {
 	}
 }
 
+void EfhEngine::sub1258F(bool largeMapFl, int16 posX, int16 posY, int imapSize, bool unkFl1, bool unkFl2) {
+	warning("STUB : sub1258F");
+}
+
+void EfhEngine::sub1256E(int16 posX, int16 posY) {
+	sub1258F(false, posX, posY, 23, _word2C876, _word2C878);
+}
+
+void EfhEngine::sub1254C(int16 posX, int16 posY) {
+	sub1258F(true, posX, posY, 63, _word2C876, _word2C878);
+}
+
 void EfhEngine::sub12A7F() {
-	warning("STUB - sub12A7F");
+	for (int16 counter = 0; counter < 2; ++counter) {
+		_word2C894 = 0;
+		if (!_largeMapFlag) {
+			if (_fullPlaceId != 0xFF)
+				sub1256E(_mapPosX, _mapPosY);
+
+			if (_word2C8D9 != 0)
+				sub150EE();
+		} else {
+			if (_techId != 0xFF)
+				sub1254C(_mapPosX, _mapPosY);
+			
+			if (_word2C8D9 != 0)
+				sub150EE();
+		}
+		if (counter == 0)
+			displayFctFullScreen();
+	}
 }
 
-void EfhEngine::displayLowStatusScreen(int i) {
-	warning("STUB - displayLowStatusScreen");
+void EfhEngine::displayLowStatusScreen(bool flag) {
+	static char strName[5] = "Name";
+	static char strDef[4] = "DEF";
+	static char strHp[3] = "HP";
+	static char strMaxHp[7] = "Max HP";
+	static char strWeapon[7] = "Weapon";
+	static char strDead[9] = "* DEAD *";
+
+	char buffer[80];
+	memset(buffer, 0, 80);
+	
+	for (int counter = 0; counter < 2; ++counter) {
+		if (counter == 0 || flag) {
+			unkFct_displayMenuBox_2(0);
+			set_unkVideoRelatedWord1_to_0Fh();
+			displayCenteredString(strName, 16, 88, 152);
+			displayCenteredString(strDef, 104, 128, 152);
+			displayCenteredString(strHp, 144, 176, 152);
+			displayCenteredString(strMaxHp, 192, 224, 152);
+			displayCenteredString(strWeapon, 225, 302, 152);
+			set_unkVideoRelatedWord1_to_0Ch();
+
+			for (int i = 0; i < 3; ++i) {
+				if (_teamCharId[i] == -1)
+					continue;
+				int16 charId = _teamCharId[i];
+				int16 textPosY = 161 + 9 * i;
+				copyString(_npcBuf[charId]._name, buffer);
+				setTextPos(16, textPosY);
+				unkFct_displayString_2(buffer);
+				sprintf(buffer, "%d", getEquipmentDefense(charId, false));
+				displayCenteredString(buffer, 104, 128, textPosY);
+				sprintf(buffer, "%d", _npcBuf[charId]._hitPoints);
+				displayCenteredString(buffer, 144, 176, textPosY);
+				sprintf(buffer, "%d", _npcBuf[charId]._maxHP);
+				displayCenteredString(buffer, 192, 224, textPosY);
+
+				if (_npcBuf[charId]._hitPoints <= 0) {
+					displayCenteredString(strDead, 225, 302, textPosY);
+					continue;
+				}
+
+				switch (_teamCharStatus[i]._status) {
+				case 0: {
+					uint16 var4 = sub1C80A(charId, 9, true);
+					if (var4 == 0x7FFF)
+						strcpy(_nameBuffer, "(NONE)");
+					else
+						copyString(_items[var4]._name, _nameBuffer);
+					}
+					break;				
+				case 1:
+					strcpy(_nameBuffer, "* ASLEEP *");
+					break;
+				case 2:
+					strcpy(_nameBuffer, "* FROZEN *");
+					break;
+				default:
+					strcpy(_nameBuffer, "* DISABLED *");
+					break;
+				}
+
+				displayCenteredString(_nameBuffer, 225, 302, textPosY);
+			}
+		}
+
+		if (counter == 0 && flag)
+			displayFctFullScreen();
+	}
 }
 
 void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
@@ -1188,12 +1365,13 @@ void EfhEngine::drawMapWindow() {
 	drawMenuBox(128, 8, 303, 135, 0);
 }
 
-void EfhEngine::copyString(uint8 *srcStr, uint8 *destStr) {
-	uint8 lastChar = 1;
+void EfhEngine::copyString(char *srcStr, char *destStr) {
+	char lastChar = 1;
 	int16 idx = 0;
 
 	while (lastChar != 0) {
 		lastChar = destStr[idx] = srcStr[idx];
+		++idx;
 	}
 }
 
@@ -1534,8 +1712,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					var110 = sub1C219("Nothing...", 1, 2, 0xFFFF);
 					displayFctFullScreen();
 				} else {
-					copyString((uint8 *)_npcBuf[_teamCharId[counter]]._name, (uint8 *)_ennemyNamePt2);
-					copyString((uint8 *)_items[var110]._name, (uint8 *)_nameBuffer);
+					copyString(_npcBuf[_teamCharId[counter]]._name, _ennemyNamePt2);
+					copyString(_items[var110]._name, _nameBuffer);
 					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, _nameBuffer);
 					drawMapWindow();
 					displayFctFullScreen();
@@ -1622,7 +1800,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 		unkFct_displayString_2(dest);
 
 	if (var_EE != 0xFF) {
-		displayLowStatusScreen(-1);
+		displayLowStatusScreen(true);
 		int16 teamSlot = handleCharacterJoining();
 		if (teamSlot > -1) {
 			_teamCharId[teamSlot] = var_EE;
@@ -1664,7 +1842,7 @@ void EfhEngine::sub1512B() {
 	sub150EE();
 	sub15018();
 	displayAnimFrame();
-	displayLowStatusScreen(0);
+	displayLowStatusScreen(false);
 }
 
 void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
@@ -1733,6 +1911,20 @@ void EfhEngine::sub252CE(uint8 curChar, int16 posX, int posY) {
 	}	
 }
 
+void EfhEngine::set_unkVideoRelatedWord1_to_0Fh() {
+	if (_videoMode == 8) // CGA
+		_unkVideoRelatedWord1 = 0x3;
+	else
+		_unkVideoRelatedWord1 = 0xF;
+}
+
+void EfhEngine::set_unkVideoRelatedWord1_to_0Ch() {
+	if (_videoMode == 8) // CGA
+		_unkVideoRelatedWord1 = 0x2;
+	else
+		_unkVideoRelatedWord1 = 0xC;
+}
+
 void EfhEngine::setNumLock() {
 	// No implementation in ScummVM
 }
@@ -1773,6 +1965,10 @@ void EfhEngine::unkFct_displayString_2(char *message) {
 	setNextCharacterPos();
 }
 
+void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
+	drawMenuBox(16, 152, 302, 189, color);
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 28e17f2dc55..a666ae12fb1 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -79,6 +79,22 @@ struct InvObject {
 	void init();
 };
 
+struct UnkAnimStruct {
+	uint8 field0;
+	uint8 field1;
+	uint8 field2;
+	uint8 field3;
+
+	void init();
+};
+struct AnimInfo {
+	UnkAnimStruct _unkAnimArray[15];
+	uint8 _field3C_startY[10];
+	uint16 _field46_startX[10];
+
+	void init();
+};
+
 struct ItemStruct {
 	char _name[15];
 	uint8 _damage;
@@ -250,7 +266,9 @@ private:
 	void initMapMonsters();
 	void loadMapMonsters();
 	void saveAnimImageSetId();
-	void displayLowStatusScreen(int i);
+	int16 getEquipmentDefense(int16 charId, bool flag);
+	uint16 sub1C80A(int16 charId, int field18, bool flag);
+	void displayLowStatusScreen(bool flag);
 	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
 	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
 	void displayFctFullScreen();
@@ -273,6 +291,9 @@ private:
 	void setTextPos(int16 textPosX, int16 textPosY);
 
 	void sub15150(bool flag);
+	void sub1258F(bool cond, int16 pos_x, int16 pos_y, int i, bool c876, bool c878);
+	void sub1256E(int16 posX, int16 posY);
+	void sub1254C(int16 posX, int16 posY);
 	void sub12A7F();
 	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY);
 	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
@@ -292,7 +313,7 @@ private:
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	void drawMapWindow();
-	void copyString(uint8 *srcStr, uint8 *destStr);
+	void copyString(char *srcStr, char *destStr);
 	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
 	void sub1512B();
@@ -305,12 +326,15 @@ private:
 	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	void sub252CE(uint8 curChar, int16 posX, int posY);
+	void set_unkVideoRelatedWord1_to_0Fh();
+	void set_unkVideoRelatedWord1_to_0Ch();
 
 	void setNumLock();
 	void unkfct_mapFunction();
 	void unkFct_anim();
 	void setNextCharacterPos();
 	void unkFct_displayString_2(char *message);
+	void unkFct_displayMenuBox_2(int16 color);
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
@@ -334,7 +358,7 @@ private:
 	uint8 _titleSong[1024];
 	ItemStruct _items[300];
 	uint8 _tileFact[864];
-	uint8 _animInfo[9000];
+	AnimInfo _animInfo[100];
 	uint8 _history[256];
 	uint8 _techData[4096];
 	char _ennemyNamePt2[20];
@@ -385,6 +409,8 @@ private:
 	int16 _word2C880;
 	int16 _word2C894;
 	int16 _word2C8D7;
+	bool _word2C876;
+	bool _word2C878;
 	bool _word2C87A;
 	int16 _unk_sub26437_flag;
 
@@ -395,8 +421,9 @@ private:
 	int16 _techDataId_MapPosX, _techDataId_MapPosY;
 	uint16 _lastMainPlaceId;
 
-	uint8 _word2C86E;
+	uint16 _word2C86E;
 	uint8 *_dword2C856;
+	int16 _word2C8D9;
 };
 
 } // End of namespace Efh


Commit: 9f3174bd5e66fa10b2ac388939ff9879a2ca499c
    https://github.com/scummvm/scummvm/commit/9f3174bd5e66fa10b2ac388939ff9879a2ca499c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement getEquipmentDefense

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index bb9809cce60..6fb43ba9d49 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -989,8 +989,30 @@ void EfhEngine::saveAnimImageSetId() {
 }
 
 int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
-	warning("STUB: getEquipmentDefense");
-	return 0;
+	int16 altDef = 0;
+	int16 totalDef = 0;
+	for (int i = 0; i < 10; ++i) {
+		if (_npcBuf[charId]._inventory[i]._ref == 0x7FFF)
+			continue;
+
+		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
+			continue;
+
+		int16 curDef = _npcBuf[charId]._inventory[i]._stat2;
+		if (curDef == 0xFF)
+			curDef = _items[_npcBuf[charId]._inventory[i]._ref]._defense;
+
+		if (curDef <= 0)
+			continue;
+
+		totalDef += curDef;
+		altDef += (curDef / 8) + 1;
+	}
+
+	if (flag)
+		return totalDef;
+
+	return altDef;
 }
 
 uint16 EfhEngine::sub1C80A(int16 charId, int field18, bool flag) {


Commit: 05ba2b7d598f849f70b605584b98d6b2495afe1a
    https://github.com/scummvm/scummvm/commit/05ba2b7d598f849f70b605584b98d6b2495afe1a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Implement drawMap, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6fb43ba9d49..4d5cbc43615 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -229,7 +229,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	_initRect = Common::Rect(0, 0, 0, 0);
 	_engineInitPending = true;
-	_unkVideoRelatedWord1 = 0x0E;
+	_textColor = 0x0E; // Yellow
 	_protectionPassed = false;
 	_fullPlaceId = 0xFF;
 	_guessAnimationAmount = 9;
@@ -489,16 +489,16 @@ void EfhEngine::displayAnimFrame() {
 		return;
 
 	if (_animImageSetId == 0xFE) {
-		sub10B77_unkDisplayFct1(_portraitSubFilesArray[0], 16, 8);
+		displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
 		return;
 	}
 
-	sub10B77_unkDisplayFct1(_portraitSubFilesArray[0], 16, 8);
+	displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
 	for (int i = 0; i < 4; ++i) {
 		int16 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex].field0;
 		if (var2 == 0xFF)
 			continue;
-		sub10B77_unkDisplayFct1(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
+		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
 	}
 }
 
@@ -717,9 +717,9 @@ Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
 }
 
 void EfhEngine::playIntro() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 
 	// Load animations on previous picture with GF
 	loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
@@ -729,61 +729,61 @@ void EfhEngine::playIntro() {
 		return;
 
 	// With GF on the bed
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	// Poof
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 110, 16);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	// On the phone
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 110, 16);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 144);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
 	getLastCharAfterAnimCount(80);
 }
@@ -884,9 +884,9 @@ void EfhEngine::initEngine() {
 	// Load Title Screen
 	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 
 	// Load map tiles bitmaps
 	loadImageSetToTileBank(1, 1);
@@ -1043,7 +1043,7 @@ void EfhEngine::sub15150(bool flag) {
 	
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
-			sub1512B();
+			displayGameScreen();
 			// TODO: _word2C86E is some kind of counter
 			if (_word2C86E != 0) {
 				// TODO: _dword2C856 is most likely an "Imp" Array
@@ -1059,16 +1059,105 @@ void EfhEngine::sub15150(bool flag) {
 	}
 }
 
-void EfhEngine::sub1258F(bool largeMapFl, int16 posX, int16 posY, int imapSize, bool unkFl1, bool unkFl2) {
-	warning("STUB : sub1258F");
+void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool unkFl1, bool unkFl2) {
+	int16 unkPosX = 5;
+	int16 unkPosY = 4;
+	int16 posX = 0;
+	int16 posY = 0;
+	int16 var6 = 0;
+	int16 minX = mapPosX - 5;
+	int16 minY = mapPosY - 4;
+
+	if (minX < 0) {
+		unkPosX -= minX;
+		minX = 0;
+	}
+
+	if (minY < 0) {
+		unkPosY -= minY;
+		minY = 0;
+	}
+
+	int16 maxX = minX + 10;
+	int16 maxY = minY + 7;
+
+	if (maxX > mapSize) {
+		unkPosX += (maxX - mapSize);
+		maxX = mapSize;
+		minX = mapSize - 10;
+	}
+
+	if (maxY > mapSize) {
+		unkPosY += (maxY - mapSize);
+		maxY = mapSize;
+		minY = mapSize - 7;
+	}
+
+	int16 var10 = 8;
+	for (int16 counterY = minY; counterY <= maxY; ++counterY) {
+		int16 var12 = 128;
+		for (int16 var16 = minX; var16 <= maxX; ++var16) {
+			if (largeMapFl) {
+				int16 idx = _mapGameMapPtr[(var16 * 64) + counterY]; // 64 = large map size (square)
+				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
+			} else {
+				int16 idx = _curPlace[(var16 * 24) + counterY]; // 24 = small map size (square)
+				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
+			}
+			var12 += 16;
+		}
+		var10 += 16;
+	}
+
+	if (unkFl1) {
+		int16 var12 = 128 + unkPosX * 16;
+		int16 var10 = 8 + unkPosY * 16;
+		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], var12, var10);
+	}
+
+	if (unkFl2) {
+		for (int16 var16 = 0; var16 < 64; ++var16) {
+			if ((_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == _fullPlaceId)){
+				bool var4 = false;
+				posX = _mapMonsters[var16]._posX;
+				posY = _mapMonsters[var16]._posY;
+
+				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
+					continue;
+
+				for (int16 counterY = 0; counterY < 9 && !var4; ++counterY) {
+					if (_mapMonsters[var16]._pictureRef[counterY] > 0)
+						var4 = true;
+				}
+
+				if (!var4)
+					continue;
+
+				var6 = 148 + kEncounters[_mapMonsters[var16]._MonsterRef]._animId;
+				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
+
+				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._field_1))
+					continue;
+
+				int16 var12 = 128 + (posX - minX) * 16;
+				var10 = 8 + (posY - minY) * 16;
+				displayRawDataAtPos(_imageSetSubFilesArray[var6], var12, var10);
+			}
+		}
+	}
+
+	if (_word2C8D7 != 0)
+		return;
+
+	warning("drawMap() - unexpected code reached, not implemented");
 }
 
-void EfhEngine::sub1256E(int16 posX, int16 posY) {
-	sub1258F(false, posX, posY, 23, _word2C876, _word2C878);
+void EfhEngine::displaySmallMap(int16 posX, int16 posY) {
+	drawMap(false, posX, posY, 23, _word2C876, _word2C878);
 }
 
-void EfhEngine::sub1254C(int16 posX, int16 posY) {
-	sub1258F(true, posX, posY, 63, _word2C876, _word2C878);
+void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
+	drawMap(true, posX, posY, 63, _word2C876, _word2C878);
 }
 
 void EfhEngine::sub12A7F() {
@@ -1076,16 +1165,16 @@ void EfhEngine::sub12A7F() {
 		_word2C894 = 0;
 		if (!_largeMapFlag) {
 			if (_fullPlaceId != 0xFF)
-				sub1256E(_mapPosX, _mapPosY);
+				displaySmallMap(_mapPosX, _mapPosY);
 
 			if (_word2C8D9 != 0)
-				sub150EE();
+				drawUpperRightBorders();
 		} else {
 			if (_techId != 0xFF)
-				sub1254C(_mapPosX, _mapPosY);
+				displayLargeMap(_mapPosX, _mapPosY);
 			
 			if (_word2C8D9 != 0)
-				sub150EE();
+				drawUpperRightBorders();
 		}
 		if (counter == 0)
 			displayFctFullScreen();
@@ -1106,13 +1195,13 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			unkFct_displayMenuBox_2(0);
-			set_unkVideoRelatedWord1_to_0Fh();
+			setTextColorWhite();
 			displayCenteredString(strName, 16, 88, 152);
 			displayCenteredString(strDef, 104, 128, 152);
 			displayCenteredString(strHp, 144, 176, 152);
 			displayCenteredString(strMaxHp, 192, 224, 152);
 			displayCenteredString(strWeapon, 225, 302, 152);
-			set_unkVideoRelatedWord1_to_0Ch();
+			setTextColorRed();
 
 			for (int i = 0; i < 3; ++i) {
 				if (_teamCharId[i] == -1)
@@ -1211,7 +1300,7 @@ void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct,
 	warning("STUB - copyGraphicBufferFromTo");
 }
 
-void EfhEngine::sub24D92(BufferBM *bufferBM, int16 posX, int16 posY) {
+void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY) {
 	// TODO: Quick code to display stuff, may require to really reverse the actual function
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
 	// warning("%d %d - startX %d startY %d width %d height %d lineDataSize %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_lineDataSize, bufferBM->_fieldD);
@@ -1346,7 +1435,7 @@ void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
 void EfhEngine::displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY) {
 	uint16 length = getStringWidth(str);
 	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
-	sub26437(str, startCenteredDisplayX, posY, _unkVideoRelatedWord1);
+	sub26437(str, startCenteredDisplayX, posY, _textColor);
 }
 
 int16 EfhEngine::chooseCharacterToReplace() {
@@ -1363,7 +1452,7 @@ int16 EfhEngine::handleCharacterJoining() {
 	}
 
 	for (int16 counter = 0; counter < 2; ++counter) {
-		drawMenuBox(200, 112, 278, 132, 0);
+		drawColoredRect(200, 112, 278, 132, 0);
 		displayCenteredString(strReplaceWho, 200, 278, 117);
 		if (counter == 0)
 			displayFctFullScreen();
@@ -1371,7 +1460,7 @@ int16 EfhEngine::handleCharacterJoining() {
 
 	int16 charId = chooseCharacterToReplace();
 	for (int16 counter = 0; counter < 2; ++counter) {
-		drawMenuBox(200, 112, 278, 132, 0);
+		drawColoredRect(200, 112, 278, 132, 0);
 		if (counter == 0)
 			displayFctFullScreen();
 	}
@@ -1384,7 +1473,7 @@ int16 EfhEngine::handleCharacterJoining() {
 }
 
 void EfhEngine::drawMapWindow() {
-	drawMenuBox(128, 8, 303, 135, 0);
+	drawColoredRect(128, 8, 303, 135, 0);
 }
 
 void EfhEngine::copyString(char *srcStr, char *destStr) {
@@ -1858,11 +1947,11 @@ void EfhEngine::sub133E5(uint8 *srcPtr, int posX, int posY, int maxX, int maxY,
 	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, argC);
 }
 
-void EfhEngine::sub1512B() {
-	displayFullScreenColoredMenuBox(0);
-	sub15094();
-	sub150EE();
-	sub15018();
+void EfhEngine::displayGameScreen() {
+	clearScreen(0);
+	drawUpperLeftBorders();
+	drawUpperRightBorders();
+	drawBottomBorders();
 	displayAnimFrame();
 	displayLowStatusScreen(false);
 }
@@ -1870,7 +1959,7 @@ void EfhEngine::sub1512B() {
 void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 	for (uint8 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
-			drawMenuBox(16, 115, 111, 133, 0);
+			drawColoredRect(16, 115, 111, 133, 0);
 			if (impArray != nullptr) {
 				_word2C86E = 4;
 				_dword2C856 = impArray;
@@ -1880,22 +1969,22 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 	}
 }
 
-void EfhEngine::sub15094() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[0], 0, 0);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[1], 112, 0);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[3], 16, 0);
+void EfhEngine::drawUpperLeftBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[1], 112, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[3], 16, 0);
 }
 
-void EfhEngine::sub150EE() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[2], 304, 0);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[4], 128, 0);
+void EfhEngine::drawUpperRightBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[2], 304, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[4], 128, 0);
 }
 
-void EfhEngine::sub15018() {
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[7], 16, 136);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[8], 16, 192);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[5], 0, 136);
-	sub10B77_unkDisplayFct1(_circleImageSubFileArray[6], 304, 136);
+void EfhEngine::drawBottomBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[7], 16, 136);
+	displayRawDataAtPos(_circleImageSubFileArray[8], 16, 192);
+	displayRawDataAtPos(_circleImageSubFileArray[5], 0, 136);
+	displayRawDataAtPos(_circleImageSubFileArray[6], 304, 136);
 }
 
 void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
@@ -1927,24 +2016,31 @@ void EfhEngine::sub252CE(uint8 curChar, int16 posX, int posY) {
 		int16 x = 0;
 		for (int i = 7; i >= 7 - width; --i) {
 			if (_fontDescr._fontData[charId]._lines[line] & (1 << i))
-				destPtr[320 * line + x] = 14;
+				destPtr[320 * line + x] = _textColor;
 			++x;
 		}
 	}	
 }
 
-void EfhEngine::set_unkVideoRelatedWord1_to_0Fh() {
+void EfhEngine::setTextColorWhite() {
+	if (_videoMode == 8) // CGA
+		_textColor = 0x3;
+	else
+		_textColor = 0xF;
+}
+
+void EfhEngine::setTextColorRed() {
 	if (_videoMode == 8) // CGA
-		_unkVideoRelatedWord1 = 0x3;
+		_textColor = 0x2;
 	else
-		_unkVideoRelatedWord1 = 0xF;
+		_textColor = 0xC;
 }
 
-void EfhEngine::set_unkVideoRelatedWord1_to_0Ch() {
+void EfhEngine::setTextColor_08h() {
 	if (_videoMode == 8) // CGA
-		_unkVideoRelatedWord1 = 0x2;
+		_textColor = 0x1;
 	else
-		_unkVideoRelatedWord1 = 0xC;
+		_textColor = 0x8;
 }
 
 void EfhEngine::setNumLock() {
@@ -1982,13 +2078,13 @@ void EfhEngine::setNextCharacterPos() {
 }
 
 void EfhEngine::unkFct_displayString_2(char *message) {
-	sub26437(message, _textPosX, _textPosY, _unkVideoRelatedWord1);
+	sub26437(message, _textPosX, _textPosY, _textColor);
 	_textPosX += getStringWidth(message) + 1;
 	setNextCharacterPos();
 }
 
 void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
-	drawMenuBox(16, 152, 302, 189, color);
+	drawColoredRect(16, 152, 302, 189, color);
 }
 
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
@@ -2013,7 +2109,7 @@ void EfhEngine::restoreAnimImageSetId() {
 }
 
 void EfhEngine::checkProtection() {
-	_unkVideoRelatedWord1 = 0xE;
+	_textColor = 0xE;
 
 	//CHECKME : Well, yeah, some code may be missing there. Who knows.
 	
@@ -2166,15 +2262,15 @@ void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
 	
 }
 
-void EfhEngine::drawMenuBox(int minX, int minY, int maxX, int maxY, int color) {
+void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int color) {
 	uint8 oldValue = _defaultBoxColor;
 	_defaultBoxColor = color;
 	drawRect(minX, minY, maxX, maxY);
 	_defaultBoxColor = oldValue;
 }
 
-void EfhEngine::displayFullScreenColoredMenuBox(int color) {
-	drawMenuBox(0, 0, 320, 200, color);
+void EfhEngine::clearScreen(int color) {
+	drawColoredRect(0, 0, 320, 200, color);
 }
 
 Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
@@ -2234,7 +2330,7 @@ void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	memcpy(_curPlace, placesPtr, 24 * 24);
 }
 
-void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY) {
+void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
 	uint16 height = READ_LE_INT16(imagePtr);
 	uint16 width = READ_LE_INT16(imagePtr + 2);
 	uint8 *imageData = imagePtr + 4;
@@ -2245,6 +2341,6 @@ void EfhEngine::sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY)
 	_imageDataPtr._width = width * 2; // 2 pixels per byte
 	_imageDataPtr._startX = _imageDataPtr._startY = 0;
 	
-	sub24D92(&_imageDataPtr, posX, posY);
+	displayBufferBmAtPos(&_imageDataPtr, posX, posY);
 }
 } // End of namespace Efh
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a666ae12fb1..bea50bb78e3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -282,8 +282,8 @@ private:
 	void copyCurrentPlaceToBuffer(int id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
 	void drawRect(int minX, int minY, int maxX, int maxY);
-	void drawMenuBox(int minX, int minY, int maxX, int maxY, int color);
-	void displayFullScreenColoredMenuBox(int color);
+	void drawColoredRect(int minX, int minY, int maxX, int maxY, int color);
+	void clearScreen(int color);
 	Common::KeyCode handleAndMapInput(bool animFl);
 	void displayNextAnimFrame();
 	void writeTechAndMapFiles();
@@ -291,12 +291,12 @@ private:
 	void setTextPos(int16 textPosX, int16 textPosY);
 
 	void sub15150(bool flag);
-	void sub1258F(bool cond, int16 pos_x, int16 pos_y, int i, bool c876, bool c878);
-	void sub1256E(int16 posX, int16 posY);
-	void sub1254C(int16 posX, int16 posY);
+	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool unkFl1, bool unkFl2);
+	void displaySmallMap(int16 posX, int16 posY);
+	void displayLargeMap(int16 posX, int16 posY);
 	void sub12A7F();
-	void sub10B77_unkDisplayFct1(uint8 *imagePtr, int16 posX, int16 posY);
-	void sub24D92(BufferBM *bufferBM, int16 posX, int16 posY);
+	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
+	void displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY);
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
 	void removeObject(int16 charId, int16 objectId);
@@ -316,18 +316,19 @@ private:
 	void copyString(char *srcStr, char *destStr);
 	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
-	void sub1512B();
+	void displayGameScreen();
 	void sub221FA(uint8 *impArray, bool flag);
-	void sub15094();
-	void sub150EE();
-	void sub15018();
+	void drawUpperLeftBorders();
+	void drawUpperRightBorders();
+	void drawBottomBorders();
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	void sub252CE(uint8 curChar, int16 posX, int posY);
-	void set_unkVideoRelatedWord1_to_0Fh();
-	void set_unkVideoRelatedWord1_to_0Ch();
+	void setTextColorWhite();
+	void setTextColorRed();
+	void setTextColor_08h();
 
 	void setNumLock();
 	void unkfct_mapFunction();
@@ -375,7 +376,7 @@ private:
 	FontDescr _fontDescr;
 
 	uint16 _word31E9E;
-	uint16 _unkVideoRelatedWord1;
+	uint16 _textColor;
 
 	int16 _oldAnimImageSetId;
 	int16 _animImageSetId;


Commit: e48753cf6dff5e336c6f8ee0c12c8d6aba0aeae3
    https://github.com/scummvm/scummvm/commit/e48753cf6dff5e336c6f8ee0c12c8d6aba0aeae3
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Disable noisy useless code

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4d5cbc43615..403681f507b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1283,8 +1283,7 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 
 void EfhEngine::displayFctFullScreen() {
 	// CHECKME: 319 is in the original but looks suspicious.
-	copyDirtyRect(0, 0, 319, 200);
-
+	// copyDirtyRect(0, 0, 319, 200);
 	
 	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
 	_system->updateScreen();


Commit: 63534f8a346f75bd11fa7b1d3cff4e825129d106
    https://github.com/scummvm/scummvm/commit/63534f8a346f75bd11fa7b1d3cff4e825129d106
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Start implementing main loop

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 403681f507b..8041fa5a425 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -247,6 +247,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_teamSize = 1;
 	_word2C872 = 0;
 	_imageSetSubFilesIdx = 144;
+	_oldImageSetSubFilesIdx = 144;
 
 	_mapPosX = _mapPosY = 31;
 	_oldMapPosX = _oldMapPosY = 31;
@@ -258,14 +259,15 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_lastMainPlaceId = 0;
 	_word2C86E = 0;
 	_dword2C856 = nullptr;
-	_word2C880 = 0;
-	_word2C894 = 0;
-	_word2C8D7 = -1;
+	_word2C880 = false;
+	_word2C894 = false;
+	_word2C8D7 = true;
 	_word2C876 = true;
 	_word2C878 = true;
 	_word2C87A = false;
 	_unk_sub26437_flag = 0;
-	_word2C8D9 = 0;
+	_word2C8D9 = false;
+	_word2C8D5 = false;
 
 	memset(_messageToBePrinted, 0, 400);
 }
@@ -339,8 +341,123 @@ Common::Error EfhEngine::run() {
 	if (!_protectionPassed)
 		return Common::kNoError;
 
+	uint32 lastMs = _system->getMillis();
 	warning("STUB - Main loop");
 	for (;;) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			unkFct_anim();
+		}
+
+		Common::Event event;
+		_system->getEventManager()->pollEvent(event);
+		Common::KeyCode retVal = Common::KEYCODE_INVALID; 
+		Common::KeyCode lastInput = getLastCharAfterAnimCount(4);
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = lastInput;
+		}
+
+		switch (retVal) {
+		case Common::KEYCODE_DOWN:
+		case Common::KEYCODE_KP2:
+			goSouth();
+			_imageSetSubFilesIdx = 144;
+			break;
+		case Common::KEYCODE_UP:
+		case Common::KEYCODE_KP8:
+			goNorth();
+			_imageSetSubFilesIdx = 145;
+			break;
+		case Common::KEYCODE_RIGHT:
+		case Common::KEYCODE_KP6:
+			goEast();
+			_imageSetSubFilesIdx = 146;
+			break;
+		case Common::KEYCODE_LEFT:
+		case Common::KEYCODE_KP4:
+			goWest();
+			_imageSetSubFilesIdx = 147;
+			break;
+		case Common::KEYCODE_PAGEUP:
+		case Common::KEYCODE_KP9:
+			goNorthEast();
+			_imageSetSubFilesIdx = 146;
+			break;
+		case Common::KEYCODE_PAGEDOWN:
+		case Common::KEYCODE_KP3:
+			goSouthEast();
+			_imageSetSubFilesIdx = 146;
+			break;
+		case Common::KEYCODE_END:
+		case Common::KEYCODE_KP1:
+			goSouthWest();
+			_imageSetSubFilesIdx = 147;
+			break;
+		case Common::KEYCODE_HOME:
+		case Common::KEYCODE_KP7:
+			goNorthWest();
+			_imageSetSubFilesIdx = 147;
+			break;
+
+		default:
+			if (retVal != Common::KEYCODE_INVALID)
+				warning("Main Loop: Unhandled input %d", retVal);
+			break;
+		}
+
+		if ((_mapPosX != _oldMapPosX || _mapPosY != _oldMapPosY) && !_shouldQuit) {
+			int16 var4 = sub16E14();
+			if (!_word2C8D5 || var4 != 0) {
+				_oldMapPosX = _mapPosX;
+				_oldMapPosY = _mapPosY;
+				_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
+				_word2C894 = true;
+			} else {
+				_mapPosX = _oldMapPosX;
+				_mapPosY = _oldMapPosY;
+				if (_oldImageSetSubFilesIdx != _imageSetSubFilesIdx) {
+					_word2C894 = true;
+					_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
+				}
+			}
+			if (_largeMapFlag) {
+				_techDataId_MapPosX = _mapPosX;
+				_techDataId_MapPosY = _mapPosY;
+			}			
+		}
+
+		if (!_shouldQuit) {
+			sub174A0();
+		}
+
+		if (_word2C894 && !_shouldQuit) {
+			sub12A7F();
+			displayLowStatusScreen(true);
+		}
+
+		if (!_shouldQuit) {
+			handleNewRoundEffects();
+
+			if (_word2C86E > 0) {
+				if (--_word2C86E == 0) {
+					sub221FA(nullptr, true);
+				}
+			}
+		}
+
+		if (--_unkArray2C8AA[0] < 0 && !_shouldQuit)
+			_unkArray2C8AA[0] = 0;
+
+		if (isTPK()) {
+			if (handleDeathMenu())
+				_shouldQuit = true;
+		}
+		
+		warning("Main loop - missing implementation");
+		
 		displayFctFullScreen();
 	}
 	return Common::kNoError;
@@ -1111,7 +1228,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 
 	if (unkFl1) {
 		int16 var12 = 128 + unkPosX * 16;
-		int16 var10 = 8 + unkPosY * 16;
+		var10 = 8 + unkPosY * 16;
 		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], var12, var10);
 	}
 
@@ -1146,7 +1263,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 		}
 	}
 
-	if (_word2C8D7 != 0)
+	if (_word2C8D7)
 		return;
 
 	warning("drawMap() - unexpected code reached, not implemented");
@@ -1162,18 +1279,18 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 
 void EfhEngine::sub12A7F() {
 	for (int16 counter = 0; counter < 2; ++counter) {
-		_word2C894 = 0;
+		_word2C894 = false;
 		if (!_largeMapFlag) {
 			if (_fullPlaceId != 0xFF)
 				displaySmallMap(_mapPosX, _mapPosY);
 
-			if (_word2C8D9 != 0)
+			if (_word2C8D9)
 				drawUpperRightBorders();
 		} else {
 			if (_techId != 0xFF)
 				displayLargeMap(_mapPosX, _mapPosY);
 			
-			if (_word2C8D9 != 0)
+			if (_word2C8D9)
 				drawUpperRightBorders();
 		}
 		if (counter == 0)
@@ -1384,6 +1501,16 @@ bool EfhEngine::isCharacterATeamMember(int16 id) {
 	return false;
 }
 
+bool EfhEngine::isTPK() {
+	int16 zeroedChar = 0;
+	for (int16 counter = 0; counter < _teamSize; ++counter) {
+		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
+			++zeroedChar;
+	}
+
+	return zeroedChar == _teamSize;
+}
+
 void EfhEngine::handleWinSequence() {
 	warning("STUB - handleWinSequence");
 }
@@ -1564,8 +1691,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosX = _mapPosX = scriptNumberArray[1];
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadPlacesFile(scriptNumberArray[0], false);
-				_word2C880 = -1;
-				_word2C894 = -1;
+				_word2C880 = true;
+				_word2C894 = true;
 			}
 			break;
 		case 0x01:
@@ -1573,8 +1700,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_largeMapFlag = true;
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
 				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
-				_word2C880 = -1;
-				_word2C894 = -1;
+				_word2C880 = true;
+				_word2C894 = true;
 			}
 			break;
 		case 0x02:
@@ -1586,8 +1713,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadTechMapImp(scriptNumberArray[0]);
 				_largeMapFlag = true;
-				_word2C880 = -1;
-				_word2C894 = -1;
+				_word2C880 = true;
+				_word2C894 = true;
 				doneFlag = true;
 			}
 			break;
@@ -1599,8 +1726,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 
 				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
 				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
-				_word2C880 = -1;
-				_word2C894 = -1;
+				_word2C880 = true;
+				_word2C894 = true;
 			}
 			break;
 		case 0x04:
@@ -1608,8 +1735,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			if (argC != 0) {
 				_mapPosX = scriptNumberArray[0];
 				_mapPosY = scriptNumberArray[1];
-				_word2C880 = -1;
-				_word2C894 = -1;
+				_word2C880 = true;
+				_word2C894 = true;
 			}
 			break;
 		case 0x05:
@@ -1776,7 +1903,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosX = _mapPosX = scriptNumberArray[0];
 				_oldMapPosY = _mapPosY = scriptNumberArray[1];
 				_largeMapFlag = true;
-				_word2C894 = -1;
+				_word2C894 = true;
 			}
 			break;
 		case 0x16:
@@ -1836,7 +1963,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				if (var110 != -1) {
 					_mapUnknownPtr[var110 * 9 + 1] = 0xFF;
 				}
-				_word2C894 = -1;
+				_word2C894 = true;
 			}
 			break;
 		case 0x19:
@@ -2042,12 +2169,199 @@ void EfhEngine::setTextColor_08h() {
 		_textColor = 0x8;
 }
 
+bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+
+	if (mapPosX == 0 && (mapPosY == 0 || mapPosY == maxMapBlocks))
+		return true;
+
+	if (mapPosX == maxMapBlocks && (mapPosY == 0 || mapPosY == maxMapBlocks))
+		return true;
+
+	return false;
+}
+
+void EfhEngine::goSouth() {
+	if (_largeMapFlag) {
+		if (++_mapPosY > 63)
+			_mapPosY = 63;
+	} else {
+		if (++_mapPosY > 23)
+			_mapPosY = 23;
+	}
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goNorth() {
+	if (--_mapPosY < 0)
+		_mapPosY = 0;
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goEast() {
+	if (_largeMapFlag) {
+		if (++_mapPosX > 63)
+			_mapPosX = 63;
+	} else {
+		if (++_mapPosX > 23)
+			_mapPosX = 23;
+	}
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goWest() {
+	if (--_mapPosX < 0)
+		_mapPosX = 0;
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goNorthEast() {
+	if (--_mapPosY < 0)
+		_mapPosY = 0;
+
+	if (_largeMapFlag) {
+		if (++_mapPosX > 63)
+			_mapPosX = 63;
+	} else {
+		if (++_mapPosX > 23)
+			_mapPosX = 23;
+	}
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goSouthEast() {
+	if (_largeMapFlag) {
+		if (++_mapPosX > 63)
+			_mapPosX = 63;
+	} else {
+		if (++_mapPosX > 23)
+			_mapPosX = 23;
+	}
+
+	if (_largeMapFlag) {
+		if (++_mapPosY > 63)
+			_mapPosY = 63;
+	} else {
+		if (++_mapPosY > 23)
+			_mapPosY = 23;
+	}
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goNorthWest() {
+	if (--_mapPosY < 0)
+		_mapPosY = 0;
+
+	if (--_mapPosX < 0)
+		_mapPosX = 0;
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::goSouthWest() {
+	if (--_mapPosX < 0)
+		_mapPosX = 0;
+
+	if (_largeMapFlag) {
+		if (++_mapPosY > 63)
+			_mapPosY = 63;
+	} else {
+		if (++_mapPosY > 23)
+			_mapPosY = 23;
+	}
+
+	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+	}
+}
+
+void EfhEngine::handleNewRoundEffects() {
+	warning("STUB: handleNewRoundEffects");
+}
+
+bool EfhEngine::handleDeathMenu() {
+	warning("STUB: handleDeathMenu");
+	return false;
+}
+
 void EfhEngine::setNumLock() {
 	// No implementation in ScummVM
 }
 
-void EfhEngine::unkfct_mapFunction() {
-	warning("STUB - unkfct_mapFunction");
+void EfhEngine::computeMapAnimation() {
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+
+	int16 minMapX = _mapPosX - 5;
+	int16 minMapY = _mapPosY - 4;
+
+	if (minMapX < 0)
+		minMapX = 0;
+	if (minMapY < 0)
+		minMapY = 0;
+
+	int16 maxMapX = minMapX + 10;
+	int16 maxMapY = minMapY + 7;
+
+	if (maxMapX > maxMapBlocks)
+		maxMapX = maxMapBlocks;
+	if (maxMapY > maxMapBlocks)
+		maxMapY = maxMapBlocks;
+
+	for (int16 counterY = minMapY; counterY < maxMapY; ++counterY) {
+		for (int16 counterX = minMapX; counterX < maxMapX; ++counterX) {
+			if (_largeMapFlag) {
+				if (_currentTileBankImageSetId[0] != 0)
+					continue;
+				int16 var4 = _mapGameMapPtr[counterX * 64 + counterY];
+				if (var4 >= 1 && var4 <= 0xF) {
+					if (getRandom(100) < 50)
+						_mapGameMapPtr[counterX * 64 + counterY] += 0xC5;
+				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
+					if (getRandom(100) < 50)
+						_mapGameMapPtr[counterX * 64 + counterY] -= 0xC5;
+				}
+			} else {
+				if (_currentTileBankImageSetId[0] != 0)
+					continue;
+				int16 var4 = _curPlace[counterX * 24 + counterY];
+				if (var4 >= 1 && var4 <= 0xF) {
+					if (getRandom(100) < 50)
+						_curPlace[counterX * 24 + counterY] += 0xC5;
+				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
+					if (getRandom(100) < 50)
+						_curPlace[counterX * 24 + counterY] -= 0xC5;
+				}
+			}
+		}
+	}
 }
 
 void EfhEngine::unkFct_anim() {
@@ -2062,7 +2376,7 @@ void EfhEngine::unkFct_anim() {
 		displayAnimFrame();
 	}
 
-	unkfct_mapFunction();
+	computeMapAnimation();
 }
 
 void EfhEngine::setNextCharacterPos() {
@@ -2086,6 +2400,15 @@ void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
 	drawColoredRect(16, 152, 302, 189, color);
 }
 
+void EfhEngine::sub174A0() {
+	warning("STUB: sub174A0");
+}
+
+bool EfhEngine::sub16E14() {
+	warning("STUB: sub16E14");
+	return false;
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index bea50bb78e3..dc6a642e235 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -306,6 +306,7 @@ private:
 	void emptyFunction(int i);
 	void refreshTeamSize();
 	bool isCharacterATeamMember(int16 id);
+	bool isTPK();
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
 	void sub26437(char * str, int16 startX, int16 startY, uint16 unkFl);
@@ -329,13 +330,26 @@ private:
 	void setTextColorWhite();
 	void setTextColorRed();
 	void setTextColor_08h();
+	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
+	void goSouth();
+	void goNorth();
+	void goEast();
+	void goWest();
+	void goNorthEast();
+	void goSouthEast();
+	void goNorthWest();
+	void goSouthWest();
+	void handleNewRoundEffects();
+	bool handleDeathMenu();
 
 	void setNumLock();
-	void unkfct_mapFunction();
+	void computeMapAnimation();
 	void unkFct_anim();
 	void setNextCharacterPos();
 	void unkFct_displayString_2(char *message);
 	void unkFct_displayMenuBox_2(int16 color);
+	void sub174A0();
+	bool sub16E14();
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
@@ -407,15 +421,16 @@ private:
 	int16 _unkArray2C8AA[3];
 	int16 _teamSize;
 	int16 _word2C872;
-	int16 _word2C880;
-	int16 _word2C894;
-	int16 _word2C8D7;
+	bool _word2C880;
+	bool _word2C894;
+	bool _word2C8D7;
 	bool _word2C876;
 	bool _word2C878;
 	bool _word2C87A;
 	int16 _unk_sub26437_flag;
 
 	int16 _imageSetSubFilesIdx;
+	int16 _oldImageSetSubFilesIdx;
 
 	int16 _mapPosX, _mapPosY;
 	int16 _oldMapPosX, _oldMapPosY;
@@ -424,7 +439,8 @@ private:
 
 	uint16 _word2C86E;
 	uint8 *_dword2C856;
-	int16 _word2C8D9;
+	bool _word2C8D9;
+	bool _word2C8D5; // CHECKME: always 0?
 };
 
 } // End of namespace Efh


Commit: 8874d2f9264910d50fe768fdf518964cb42ef8b6
    https://github.com/scummvm/scummvm/commit/8874d2f9264910d50fe768fdf518964cb42ef8b6
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Fix event handler, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8041fa5a425..bd00f95459c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -247,7 +247,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_teamSize = 1;
 	_word2C872 = 0;
 	_imageSetSubFilesIdx = 144;
-	_oldImageSetSubFilesIdx = 144;
+	_oldImageSetSubFilesIdx = 143;
 
 	_mapPosX = _mapPosY = 31;
 	_oldMapPosX = _oldMapPosY = 31;
@@ -353,12 +353,7 @@ Common::Error EfhEngine::run() {
 		}
 
 		Common::Event event;
-		_system->getEventManager()->pollEvent(event);
-		Common::KeyCode retVal = Common::KEYCODE_INVALID; 
-		Common::KeyCode lastInput = getLastCharAfterAnimCount(4);
-		if (event.type == Common::EVENT_KEYUP) {
-			retVal = lastInput;
-		}
+		Common::KeyCode retVal = getLastCharAfterAnimCount(4);
 
 		switch (retVal) {
 		case Common::KEYCODE_DOWN:
@@ -809,13 +804,8 @@ Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
 	if (delay == 0)
 		return Common::KEYCODE_INVALID;
 
-	Common::Event event;
-	do {
-		_system->getEventManager()->pollEvent(event);
-	} while (event.kbd.keycode != Common::KEYCODE_INVALID);
-
 	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
-
+	
 	uint32 lastMs = _system->getMillis();
 	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
 		_system->delayMillis(20);
@@ -1327,7 +1317,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				int16 textPosY = 161 + 9 * i;
 				copyString(_npcBuf[charId]._name, buffer);
 				setTextPos(16, textPosY);
-				unkFct_displayString_2(buffer);
+				displayStringAtTextPos(buffer);
 				sprintf(buffer, "%d", getEquipmentDefense(charId, false));
 				displayCenteredString(buffer, 104, 128, textPosY);
 				sprintf(buffer, "%d", _npcBuf[charId]._hitPoints);
@@ -1521,7 +1511,7 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
 	return false;
 }
 
-void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
+void EfhEngine::drawString(char *str, int16 startX, int16 startY, uint16 unkFl) {
 	uint8 *curPtr = (uint8 *)str;
 	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
 	_unk_sub26437_flag = unkFl & 0x3FFF;
@@ -1530,7 +1520,7 @@ void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
 	int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
 
 	if (unkFl & 0x8000) {
-		warning("STUB - sub26437 - 0x8000");
+		warning("STUB - drawString - 0x8000");
 	}
 
 	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
@@ -1552,7 +1542,7 @@ void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
 		}
 
 		uint8 varC = _fontDescr._extraLines[characterId];
-		sub252CE(curChar, startX, startY + varC);
+		drawChar(curChar, startX, startY + varC);
 		startX += charWidth + _fontDescr._extraHorizontalSpace;
 	}
 	
@@ -1561,7 +1551,7 @@ void EfhEngine::sub26437(char *str, int16 startX, int16 startY, uint16 unkFl) {
 void EfhEngine::displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY) {
 	uint16 length = getStringWidth(str);
 	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
-	sub26437(str, startCenteredDisplayX, posY, _textColor);
+	drawString(str, startCenteredDisplayX, posY, _textColor);
 }
 
 int16 EfhEngine::chooseCharacterToReplace() {
@@ -1654,7 +1644,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					doneFlag = true;
 				} else {
 					if (var_F2 == 0)
-						unkFct_displayString_2(dest);
+						displayStringAtTextPos(dest);
 
 					*dest = 0;
 					strcpy(dest, var_EC);
@@ -2034,7 +2024,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 	}
 
 	if (*dest != 0 && curLine < numbLines && var_F2 == 0)
-		unkFct_displayString_2(dest);
+		displayStringAtTextPos(dest);
 
 	if (var_EE != 0xFF) {
 		displayLowStatusScreen(true);
@@ -2131,7 +2121,7 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	return -1;
 }
 
-void EfhEngine::sub252CE(uint8 curChar, int16 posX, int posY) {
+void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
 	// Quick hacked display, may require rework
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
 
@@ -2390,8 +2380,8 @@ void EfhEngine::setNextCharacterPos() {
 		_textPosY = 0;
 }
 
-void EfhEngine::unkFct_displayString_2(char *message) {
-	sub26437(message, _textPosX, _textPosY, _textColor);
+void EfhEngine::displayStringAtTextPos(char *message) {
+	drawString(message, _textPosX, _textPosY, _textColor);
 	_textPosX += getStringWidth(message) + 1;
 	setNextCharacterPos();
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index dc6a642e235..e77afa9c6c7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -309,7 +309,7 @@ private:
 	bool isTPK();
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
-	void sub26437(char * str, int16 startX, int16 startY, uint16 unkFl);
+	void drawString(char * str, int16 startX, int16 startY, uint16 unkFl);
 	void displayCenteredString(char * str, int16 minX, int16 maxX, int16 posY);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
@@ -326,7 +326,7 @@ private:
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
-	void sub252CE(uint8 curChar, int16 posX, int posY);
+	void drawChar(uint8 curChar, int16 posX, int posY);
 	void setTextColorWhite();
 	void setTextColorRed();
 	void setTextColor_08h();
@@ -346,7 +346,7 @@ private:
 	void computeMapAnimation();
 	void unkFct_anim();
 	void setNextCharacterPos();
-	void unkFct_displayString_2(char *message);
+	void displayStringAtTextPos(char *message);
 	void unkFct_displayMenuBox_2(int16 color);
 	void sub174A0();
 	bool sub16E14();


Commit: f20fd2d935b965323222528ea6ccf04480e908e9
    https://github.com/scummvm/scummvm/commit/f20fd2d935b965323222528ea6ccf04480e908e9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Some more renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index bd00f95459c..b167354bb14 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -190,7 +190,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_fontDescr._charHeight = 0;
 	_fontDescr._extraHorizontalSpace = _fontDescr._extraVerticalSpace = 0;
 
-	_word31E9E = 0;
+	_word31E9E = false;
 	_oldAnimImageSetId = -1;
 	_animImageSetId = 254;
 	_paletteTransformationConstant = 10;
@@ -262,8 +262,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C880 = false;
 	_word2C894 = false;
 	_word2C8D7 = true;
-	_word2C876 = true;
-	_word2C878 = true;
+	_drawHeroOnMapFl = true;
+	_drawMonstersOnMapFl = true;
 	_word2C87A = false;
 	_unk_sub26437_flag = 0;
 	_word2C8D9 = false;
@@ -500,7 +500,7 @@ void EfhEngine::readAnimInfo() {
 }
 
 void EfhEngine::findMapFile(int16 mapId) {
-	if (_word31E9E == 0)
+	if (!_word31E9E)
 		return;
 
 	Common::String fileName = Common::String::format("map.%d", mapId);
@@ -974,20 +974,10 @@ void EfhEngine::initEngine() {
 	_fontDescr._charHeight = 8;
 	_fontDescr._extraVerticalSpace = 3;
 	_fontDescr._extraHorizontalSpace = 1;
-	_word31E9E = 0;
+	_word31E9E = false;
 
 	saveAnimImageSetId();
 
-	// Save int 1C
-	// Set new int 1C:
-	// TODO: Implement that in the main loop
-	// static uint8 counter = 0;
-	// ++counter;
-	// if (counter == 4) {
-	//    counter = 0;
-	//    tick220Fl = 1;
-	// }
-
 	// Load Title Screen
 	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	displayFctFullScreen();
@@ -1031,7 +1021,7 @@ void EfhEngine::initEngine() {
 
 	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	readImpFile(99, false);
-	_word31E9E = 0xFFFF;
+	_word31E9E = true;
 	restoreAnimImageSetId();
 
 	// Note: The original at this point saves int 24h and sets a new int24 to handle fatal failure
@@ -1166,7 +1156,7 @@ void EfhEngine::sub15150(bool flag) {
 	}
 }
 
-void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool unkFl1, bool unkFl2) {
+void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl) {
 	int16 unkPosX = 5;
 	int16 unkPosY = 4;
 	int16 posX = 0;
@@ -1216,13 +1206,13 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 		var10 += 16;
 	}
 
-	if (unkFl1) {
+	if (drawHeroFl) {
 		int16 var12 = 128 + unkPosX * 16;
 		var10 = 8 + unkPosY * 16;
 		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], var12, var10);
 	}
 
-	if (unkFl2) {
+	if (drawMonstersFl) {
 		for (int16 var16 = 0; var16 < 64; ++var16) {
 			if ((_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == _fullPlaceId)){
 				bool var4 = false;
@@ -1260,11 +1250,11 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 }
 
 void EfhEngine::displaySmallMap(int16 posX, int16 posY) {
-	drawMap(false, posX, posY, 23, _word2C876, _word2C878);
+	drawMap(false, posX, posY, 23, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
 void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
-	drawMap(true, posX, posY, 63, _word2C876, _word2C878);
+	drawMap(true, posX, posY, 63, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
 void EfhEngine::sub12A7F() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e77afa9c6c7..51075a4f936 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -291,7 +291,7 @@ private:
 	void setTextPos(int16 textPosX, int16 textPosY);
 
 	void sub15150(bool flag);
-	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool unkFl1, bool unkFl2);
+	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl);
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
 	void sub12A7F();
@@ -389,7 +389,7 @@ private:
 	uint8 _defaultBoxColor;
 	FontDescr _fontDescr;
 
-	uint16 _word31E9E;
+	bool _word31E9E;
 	uint16 _textColor;
 
 	int16 _oldAnimImageSetId;
@@ -424,8 +424,8 @@ private:
 	bool _word2C880;
 	bool _word2C894;
 	bool _word2C8D7;
-	bool _word2C876;
-	bool _word2C878;
+	bool _drawHeroOnMapFl;
+	bool _drawMonstersOnMapFl;
 	bool _word2C87A;
 	int16 _unk_sub26437_flag;
 


Commit: 2e2803591f28f75218f039129aa987f53a4ba1bc
    https://github.com/scummvm/scummvm/commit/2e2803591f28f75218f039129aa987f53a4ba1bc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:33+01:00

Commit Message:
EFH: Fix map initialization (loading savegame)

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b167354bb14..7679cfdb346 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2448,9 +2448,7 @@ void EfhEngine::loadGame() {
 
 	_teamSize = f.readSint16LE();
 
-	for (int i = 0; i < 3; ++i) {
-		_unkArray2C8AA[i] = f.readSint16LE();		
-	}
+	_unkArray2C8AA[0] = f.readSint16LE();		
 
 	_word2C872 = f.readSint16LE();
 


Commit: 28bf1807e7f81ced20b8d888a128126a79f5d3c4
    https://github.com/scummvm/scummvm/commit/28bf1807e7f81ced20b8d888a128126a79f5d3c4
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Start implementing interactions with monsters

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7679cfdb346..4a5942116d8 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2384,11 +2384,172 @@ void EfhEngine::sub174A0() {
 	warning("STUB: sub174A0");
 }
 
-bool EfhEngine::sub16E14() {
-	warning("STUB: sub16E14");
+bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
+	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+		return false;
+
+	for (int16 counter = 0; counter < 9; ++counter) {
+		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
+			return true;
+	}
+
+	return false;
+}
+
+bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 arg4) {
+	warning("STUB - sub21820");
 	return false;
 }
 
+void EfhEngine::sub221D2(int16 monsterId) {
+	if (monsterId != -1) {
+		_dword2C856 = nullptr;
+		sub21820(monsterId, 5, -1);
+	}
+}
+
+int16 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
+	warning("STUB - sub15581");
+	return 0;
+}
+
+bool EfhEngine::handleFight() {
+	warning("STUB - handleFight");
+	return false;
+}
+
+int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
+	warning("STUB - handleStatusMenu");
+	return 0;
+}
+
+Common::KeyCode EfhEngine::waitForKey() {
+	warning("STUB - waitForKey");
+	return Common::KEYCODE_INVALID;
+}
+
+Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
+	warning("STUB - mapInputCode");
+	return Common::KEYCODE_INVALID;
+}
+
+bool EfhEngine::sub16E14() {
+	int16 var68 = 0;
+	char dest[20];
+	char buffer[80];
+	
+	int16 monsterId;
+	for (monsterId = 0; monsterId < 64; ++monsterId) {
+		if (!checkPictureRefAvailability(monsterId))
+			continue;
+
+		if (!(_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE) && !(!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId))
+			continue;
+
+		if ((_mapMonsters[monsterId]._field_1 & 0x3F) > 0x3D
+		&& (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)))
+			continue;
+
+		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
+			continue;
+
+		if (_word2C8D7 == 0)
+			return false;
+
+		_mapPosX = _oldMapPosX;
+		_mapPosY = _oldMapPosY;
+		if (_imageSetSubFilesIdx != _oldImageSetSubFilesIdx)
+			_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
+		_word2C894 = true;
+
+		int16 var6A = 0;
+		for (int16 var6C = 0; var6C < 9; ++var6C) {
+			if (_mapMonsters[monsterId]._pictureRef[var6C])
+				++var6A;
+		}
+
+		do {
+			for (int16 var6C = 0; var6C < 2; ++var6C) {
+				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
+				if (var1 <= 0x3D) {
+					strcpy(dest, kEncounters[_mapMonsters[monsterId]._MonsterRef]._name);
+					if (var6A > 1)
+						strcat(dest, " ");
+
+					sprintf(buffer, "with %d %s", var6A, dest);
+				} else if (var1 == 0x3E) {
+					strcpy(buffer, "(NOT DEFINED)");
+				} else if (var1 == 0x3F) { // Useless if, it's the last possible value
+					copyString(_npcBuf[_mapMonsters[monsterId]._MonsterRef]._name, dest);
+					sprintf(buffer, "with %s", dest);
+				}
+
+				unkFct_displayMenuBox_2(0);
+				_textColor = 0xE;
+				displayCenteredString((char *)"Interaction", 24, 296, 152);
+				displayCenteredString(buffer, 24, 296, 161);
+				setTextPos(24, 169);
+				setTextColorWhite();
+				displayStringAtTextPos((char *)"T");
+				setTextColorRed();
+				sprintf(buffer, "alk to the %s", dest);
+				displayStringAtTextPos(buffer);
+				setTextPos(24, 178);
+				setTextColorWhite();
+				displayStringAtTextPos((char *)"A");
+				setTextColorRed();
+				sprintf(buffer, "ttack the %s", dest);
+				displayStringAtTextPos(buffer);
+				setTextPos(198, 169);
+				setTextColorWhite();
+				displayStringAtTextPos((char *)"S");
+				setTextColorRed();
+				displayStringAtTextPos((char *)"tatus");
+				setTextPos(198, 178);
+				setTextColorWhite();
+				displayStringAtTextPos((char *)"L");
+				setTextColorRed();
+				displayStringAtTextPos((char *)"eave");
+				if (var6C == 0)
+					displayFctFullScreen();
+			}
+
+			Common::KeyCode input = mapInputCode(waitForKey());
+
+			switch (input) {
+			case Common::KEYCODE_a: // Attack
+				var6A = handleFight();
+				var68 = true;
+				break;
+			case Common::KEYCODE_ESCAPE:
+			case Common::KEYCODE_l: // Leave
+				var68 = true;
+				break;
+			case Common::KEYCODE_s: // Status
+				var6A = handleStatusMenu(1, _teamCharId[0]);
+				var68 = true;
+				_dword2C856 = nullptr;
+				sub15150(true);
+				break;
+			case Common::KEYCODE_t: // Talk
+				sub221D2(monsterId);
+				var68 = true;
+				break;
+			default:
+				warning("STUB: sub16E14 - Missing mapping ?");
+				break;
+			}
+		} while (!var68);
+		return true;
+	}
+
+	monsterId = sub15581(_mapPosX, _mapPosY, 1);
+	if (monsterId == 0 || monsterId == 2)
+		return false;
+
+	return true;
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 51075a4f936..e9ba0830b8d 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -349,6 +349,14 @@ private:
 	void displayStringAtTextPos(char *message);
 	void unkFct_displayMenuBox_2(int16 color);
 	void sub174A0();
+	bool checkPictureRefAvailability(int16 monsterId);
+	bool sub21820(int16 monsterId, int16 arg2, int16 arg4);
+	void sub221D2(int16 monsterId);
+	int16 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
+	bool handleFight();
+	int16 handleStatusMenu(int16 gameMode, int16 charId);
+	Common::KeyCode waitForKey();
+	Common::KeyCode mapInputCode(Common::KeyCode input);
 	bool sub16E14();
 
 	uint8 _videoMode;


Commit: e70972c1707977762686885e6a993d740d4dbcdf
    https://github.com/scummvm/scummvm/commit/e70972c1707977762686885e6a993d740d4dbcdf
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement sub174A0

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4a5942116d8..ae9d5de5305 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -243,6 +243,9 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_unkArray2C8AA[i] = 0;
 	}
 
+	for (int i = 0; i < 5; ++i)
+		_teamMonsterIdArray[i] = -1;
+
 	_unkArray2C8AA[2] = 1;
 	_teamSize = 1;
 	_word2C872 = 0;
@@ -268,6 +271,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_unk_sub26437_flag = 0;
 	_word2C8D9 = false;
 	_word2C8D5 = false;
+	_word2D0BC = false;
 
 	memset(_messageToBePrinted, 0, 400);
 }
@@ -2380,8 +2384,384 @@ void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
 	drawColoredRect(16, 152, 302, 189, color);
 }
 
+int16 EfhEngine::sub16B08(int16 monsterId) {
+	// Simplified version compared to the original
+	int16 maxSize = _largeMapFlag ? 63 : 23;
+	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
+		return 0;
+
+	if (_mapMonsters[monsterId]._posX == _mapPosX && _mapMonsters[monsterId]._posY == _mapPosY)
+		return 0;
+
+	for (int16 counter = 0; counter < 64; ++counter) {
+		if (counter == monsterId)
+			continue;
+
+		if (!checkPictureRefAvailability(counter))
+			continue;
+
+		if (_mapMonsters[monsterId]._guess_fullPlaceId == _mapMonsters[counter]._guess_fullPlaceId
+		 && _mapMonsters[monsterId]._posX == _mapMonsters[counter]._posX
+		 && _mapMonsters[monsterId]._posY == _mapMonsters[counter]._posY)
+			return 0;
+	}
+
+	return sub15581(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, 0);
+}
+
+bool EfhEngine::moveMonsterGroupTowardsGroup_0(int16 monsterId) {
+	if (_mapMonsters[monsterId]._posX < _mapPosX) {
+		--_mapMonsters[monsterId]._posX;
+		if (_mapMonsters[monsterId]._posY < _mapPosY)
+			--_mapMonsters[monsterId]._posY;
+		else if (_mapMonsters[monsterId]._posY > _mapPosY)
+			++_mapMonsters[monsterId]._posY;
+
+		return true;
+	}
+
+	if (_mapMonsters[monsterId]._posX > _mapPosX) {
+		++_mapMonsters[monsterId]._posX;
+		if (_mapMonsters[monsterId]._posY < _mapPosY)
+			--_mapMonsters[monsterId]._posY;
+		else if (_mapMonsters[monsterId]._posY > _mapPosY)
+			++_mapMonsters[monsterId]._posY;
+
+			return true;
+	}
+
+	// Original checks for posX equality, which is the only possible option at this point => skipped
+	if (_mapMonsters[monsterId]._posY < _mapPosY)
+		--_mapMonsters[monsterId]._posY;
+	else if (_mapMonsters[monsterId]._posY > _mapPosY)
+		++_mapMonsters[monsterId]._posY;
+	else
+		return false;
+
+	return true;
+}
+
+bool EfhEngine::moveMonsterGroupTowardsGroup_1(int16 monsterId) {
+	if (_mapMonsters[monsterId]._posX < _mapPosX) {
+		++_mapMonsters[monsterId]._posX;
+		if (_mapMonsters[monsterId]._posY < _mapPosY)
+			++_mapMonsters[monsterId]._posY;
+		else if (_mapMonsters[monsterId]._posY > _mapPosY)
+			--_mapMonsters[monsterId]._posY;
+
+		return true;
+	}
+
+	if (_mapMonsters[monsterId]._posX > _mapPosX) {
+		--_mapMonsters[monsterId]._posX;
+		if (_mapMonsters[monsterId]._posY < _mapPosY)
+			++_mapMonsters[monsterId]._posY;
+		else if (_mapMonsters[monsterId]._posY > _mapPosY)
+			--_mapMonsters[monsterId]._posY;
+
+		return true;
+	}
+
+	// Original checks for posX equality, which is the only possible option at this point => skipped
+	if (_mapMonsters[monsterId]._posY < _mapPosY)
+		++_mapMonsters[monsterId]._posY;
+	else if (_mapMonsters[monsterId]._posY > _mapPosY)
+		--_mapMonsters[monsterId]._posY;
+	else
+		return false;
+
+	return true;
+}
+
+bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
+
+	switch (direction - 1) {
+	case 0:
+		--_mapMonsters[monsterId]._posY;
+		return true;
+	case 1:
+		--_mapMonsters[monsterId]._posY;
+		++_mapMonsters[monsterId]._posX;
+		return true;
+	case 2:
+		++_mapMonsters[monsterId]._posX;
+		return true;
+	case 3:
+		++_mapMonsters[monsterId]._posX;
+		++_mapMonsters[monsterId]._posY;
+		return true;
+	case 4:
+		++_mapMonsters[monsterId]._posY;
+		return true;
+	case 5:
+		++_mapMonsters[monsterId]._posY;
+		--_mapMonsters[monsterId]._posX;
+		return true;
+	case 6:
+		--_mapMonsters[monsterId]._posX;
+		return true;
+	case 7:
+		--_mapMonsters[monsterId]._posX;
+		--_mapMonsters[monsterId]._posY;
+		return true;
+	default:
+		return false;
+	}
+}
+
+bool EfhEngine::moveMonsterGroup(int16 monsterId) {
+	int16 rand100 = getRandom(100);
+
+	if (rand100 < 30)
+		return moveMonsterGroupTowardsGroup_1(monsterId);
+
+	if (rand100 >= 60)
+		// CHECKME: the original seems to only use 1 param??
+		return moveMonsterGroupOther(monsterId, getRandom(8));
+
+	return moveMonsterGroupTowardsGroup_0(monsterId);
+}
+
+int16 EfhEngine::computeMonsterGroupDistance(int monsterId) {
+	int16 monsterPosX = _mapMonsters[monsterId]._posX;
+	int16 monsterPosY = _mapMonsters[monsterId]._posY;
+
+	int16 deltaX = monsterPosX - _mapPosX;
+	int16 deltaY = monsterPosY - _mapPosY;
+
+	return (int16)sqrt(deltaX * deltaX + deltaY * deltaY);
+}
+
+bool EfhEngine::checkWeaponRange(int16 monsterId, int weaponId) {
+	static const int16 kRange[5] = {1, 2, 3, 3, 3};
+
+	assert(_items[weaponId]._range < 5);
+	if (computeMonsterGroupDistance(monsterId) > kRange[_items[weaponId]._range])
+		return false;
+
+	return true;
+}
+
+bool EfhEngine::unkFct_checkMonsterField8(int id, bool teamFlag) {
+	int16 monsterId = id;
+	if (teamFlag)
+		monsterId = _teamMonsterIdArray[id];
+
+	if ((_mapMonsters[monsterId]._field_8 & 0xF) >= 8)
+		return true;
+
+	if (_unkArray2C8AA[0] == 0)
+		return false;
+
+	if ((_mapMonsters[monsterId]._field_8 & 0x80) != 0)
+		return true;
+
+	return false;
+}
+
+bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
+	if (!_word2D0BC)
+		return true;
+
+	for (int16 counter = 0; counter < 5; ++counter) {
+		if (_teamMonsterIdArray[counter] == monsterId && unkFct_checkMonsterField8(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon))
+			return false;
+	}
+
+	return true;
+}
+
+bool EfhEngine::checkIfMonsterOnSameLargelMapPlace(int16 monsterId) {
+	if (_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
+		return true;
+
+	if (!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId)
+		return true;
+
+	return false;
+}
+
+bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
+	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
+}
+
 void EfhEngine::sub174A0() {
-	warning("STUB: sub174A0");
+	static int16 sub174A0_monsterPosX = -1;
+	static int16 sub174A0_monsterPosY = -1;
+	
+	int16 var14 = 0;
+	int16 var6 = 0;
+	_word2C894 = false;
+	int16 unkMonsterId = -1;
+	int16 mapSize = _largeMapFlag ? 63 : 23;
+	int16 minDisplayedMapX = CLIP<int16>(_mapPosX - 10, 0, mapSize);
+	int16 minDisplayedMapY = CLIP<int16>(_mapPosY - 9, 0, mapSize);
+	int16 maxDisplayedMapX = CLIP<int16>(minDisplayedMapX + 20, 0, mapSize);
+	int16 maxDisplayedMapY = CLIP<int16>(minDisplayedMapY + 17, 0, mapSize);
+	
+	for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
+		if (!checkPictureRefAvailability(monsterId))
+			continue;
+
+		if (!checkTeamWeaponRange(monsterId))
+			continue;
+
+		if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+			continue;
+
+		int16 var4 = _mapMonsters[monsterId]._posX;
+		int16 var2 = _mapMonsters[monsterId]._posY;
+
+		if (var4 < minDisplayedMapX || var4 > maxDisplayedMapX || var2 < minDisplayedMapY || var2 > maxDisplayedMapY)
+			continue;
+
+		int16 var1A = 0;
+		var14 = 0;
+
+		sub174A0_monsterPosX = _mapMonsters[monsterId]._posX;
+		sub174A0_monsterPosY = _mapMonsters[monsterId]._posY;
+		int8 var1C = _mapMonsters[monsterId]._field_8 & 0xF;
+
+		if (_unkArray2C8AA[0] != 0 && (_mapMonsters[monsterId]._field_8 & 0x80))
+			var1C = 9;
+
+		int16 var1E = _mapMonsters[monsterId]._field_8 & 0x70;
+		var1E >>= 4;
+
+		int16 var16 = var1E;
+		do {
+			switch (var1C - 1) {
+			case 0:
+				if (getRandom(100) >= 0xE - var1E)
+					var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+				else
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			case 1:
+				if (getRandom(100) >= 0xE - var1E)
+					var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+				else
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			case 2:
+				var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+				break;
+			case 3:
+				var1A = moveMonsterGroup(monsterId);
+				break;
+			case 4:
+				if (getRandom(100) > 0x32 - var1E)
+					var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+				else
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			case 5:
+				if (getRandom(100) > 0x32 - var1E)
+					var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+				else
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			case 6:
+				if (getRandom(100) >= 0x32 - var1E)
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			case 7:
+				// var14 is not a typo.
+				var14 = checkMonsterWeaponRange(monsterId);
+				break;
+			case 8:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					if (getRandom(100) >= 0xE - var1E)
+						var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+					else
+						var1A = moveMonsterGroup(monsterId);
+				}
+				break;
+			case 9:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					if (getRandom(100) >= 0xE - var1E)
+						var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+					else
+						var1A = moveMonsterGroup(monsterId);
+				}
+				break;
+			case 10:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+				}
+				break;
+			case 11:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					var1A = moveMonsterGroup(monsterId);
+				}
+				break;
+			case 12:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					if (getRandom(100) >= 0x32 - var1E)
+						var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+					else
+						var1A = moveMonsterGroup(monsterId);
+				}
+				break;
+			case 13:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0) {
+					if (getRandom(100) >= 0x32 - var1E)
+						var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+					else
+						var1A = moveMonsterGroup(monsterId);
+				}
+				break;
+			case 14:
+				var14 = checkMonsterWeaponRange(monsterId);
+				if (var14 == 0 && getRandom(100) >= 0x32 - var1E)
+					var1A = moveMonsterGroup(monsterId);
+				break;
+			default:
+				break;
+			}
+
+			for (;;) {
+				if (var1A == 0) {
+					if (var14 == 0) {
+						var1A = -1;
+					} else {
+						unkMonsterId = monsterId;
+						var1A = -1;
+					}
+				} else {
+					int16 var18 = sub16B08(monsterId);
+
+					if (var18 == 0) {
+						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
+						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
+						var1A = 0;
+						--var16;
+					} else if (var18 == 2) {
+						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
+						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
+					}
+				}
+
+				if (var1A == 0 && var16 == 1 && var1E > 1) {
+					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+					continue;
+				}
+				
+				break;
+			}
+			
+		} while (var1A == 0 && var16 > 0);
+		
+	}
+
+	if (unkMonsterId != -1)
+		handleFight(unkMonsterId);
 }
 
 bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
@@ -2413,7 +2793,7 @@ int16 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return 0;
 }
 
-bool EfhEngine::handleFight() {
+bool EfhEngine::handleFight(int16 monsterId) {
 	warning("STUB - handleFight");
 	return false;
 }
@@ -2453,7 +2833,7 @@ bool EfhEngine::sub16E14() {
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
 			continue;
 
-		if (_word2C8D7 == 0)
+		if (!_word2C8D7)
 			return false;
 
 		_mapPosX = _oldMapPosX;
@@ -2518,7 +2898,7 @@ bool EfhEngine::sub16E14() {
 
 			switch (input) {
 			case Common::KEYCODE_a: // Attack
-				var6A = handleFight();
+				var6A = handleFight(monsterId);
 				var68 = true;
 				break;
 			case Common::KEYCODE_ESCAPE:
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e9ba0830b8d..b8a324343cf 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -348,12 +348,23 @@ private:
 	void setNextCharacterPos();
 	void displayStringAtTextPos(char *message);
 	void unkFct_displayMenuBox_2(int16 color);
+	int16 sub16B08(int16 monsterId);
+	bool moveMonsterGroupTowardsGroup_0(int16 monsterId);
+	bool moveMonsterGroupTowardsGroup_1(int16 monsterId);
+	bool moveMonsterGroupOther(int16 monsterId, int16 direction);
+	bool moveMonsterGroup(int16 monsterId);
+	int16 computeMonsterGroupDistance(int monsterId);
+	bool checkWeaponRange(int16 monsterId, int weaponId);
+	bool unkFct_checkMonsterField8(int id, bool teamFlag);
+	bool checkTeamWeaponRange(int16 monsterId);
+	bool checkIfMonsterOnSameLargelMapPlace(int16 monsterId);
+	bool checkMonsterWeaponRange(int16 monsterId);
 	void sub174A0();
 	bool checkPictureRefAvailability(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 arg4);
 	void sub221D2(int16 monsterId);
 	int16 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
-	bool handleFight();
+	bool handleFight(int16 monsterId);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	Common::KeyCode waitForKey();
 	Common::KeyCode mapInputCode(Common::KeyCode input);
@@ -425,6 +436,7 @@ private:
 	bool _engineInitPending;
 	bool _protectionPassed;
 
+	int16 _teamMonsterIdArray[5];
 	CharStatus _teamCharStatus[3];
 	int16 _unkArray2C8AA[3];
 	int16 _teamSize;
@@ -449,6 +461,7 @@ private:
 	uint8 *_dword2C856;
 	bool _word2C8D9;
 	bool _word2C8D5; // CHECKME: always 0?
+	bool _word2D0BC;
 };
 
 } // End of namespace Efh


Commit: c51010ccdf135be27ed6f8db6b0bfbc57d277a03
    https://github.com/scummvm/scummvm/commit/c51010ccdf135be27ed6f8db6b0bfbc57d277a03
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Fix redraw, implement sub15581, renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ae9d5de5305..c4d1166951a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -263,7 +263,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C86E = 0;
 	_dword2C856 = nullptr;
 	_word2C880 = false;
-	_word2C894 = false;
+	_redrawNeededFl = false;
 	_word2C8D7 = true;
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
@@ -339,7 +339,7 @@ Common::Error EfhEngine::run() {
 */
 	initEngine();
 	sub15150(true);
-	sub12A7F();
+	redrawScreen();
 	displayLowStatusScreen(true);
 
 	if (!_protectionPassed)
@@ -413,12 +413,12 @@ Common::Error EfhEngine::run() {
 				_oldMapPosX = _mapPosX;
 				_oldMapPosY = _mapPosY;
 				_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			} else {
 				_mapPosX = _oldMapPosX;
 				_mapPosY = _oldMapPosY;
 				if (_oldImageSetSubFilesIdx != _imageSetSubFilesIdx) {
-					_word2C894 = true;
+					_redrawNeededFl = true;
 					_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
 				}
 			}
@@ -432,8 +432,8 @@ Common::Error EfhEngine::run() {
 			sub174A0();
 		}
 
-		if (_word2C894 && !_shouldQuit) {
-			sub12A7F();
+		if (_redrawNeededFl && !_shouldQuit) {
+			redrawScreen();
 			displayLowStatusScreen(true);
 		}
 
@@ -1261,9 +1261,9 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 	drawMap(true, posX, posY, 63, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
-void EfhEngine::sub12A7F() {
+void EfhEngine::redrawScreen() {
 	for (int16 counter = 0; counter < 2; ++counter) {
-		_word2C894 = false;
+		_redrawNeededFl = false;
 		if (!_largeMapFlag) {
 			if (_fullPlaceId != 0xFF)
 				displaySmallMap(_mapPosX, _mapPosY);
@@ -1385,7 +1385,8 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 void EfhEngine::displayFctFullScreen() {
 	// CHECKME: 319 is in the original but looks suspicious.
 	// copyDirtyRect(0, 0, 319, 200);
-	
+
+	warning("Char pos %d %d old pos %d %d", _mapPosX, _mapPosY, _oldMapPosX, _oldMapPosY);
 	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
 	_system->updateScreen();
 }
@@ -1676,7 +1677,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadPlacesFile(scriptNumberArray[0], false);
 				_word2C880 = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x01:
@@ -1685,7 +1686,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
 				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
 				_word2C880 = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x02:
@@ -1698,7 +1699,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				loadTechMapImp(scriptNumberArray[0]);
 				_largeMapFlag = true;
 				_word2C880 = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 				doneFlag = true;
 			}
 			break;
@@ -1711,7 +1712,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
 				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
 				_word2C880 = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x04:
@@ -1720,7 +1721,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_mapPosX = scriptNumberArray[0];
 				_mapPosY = scriptNumberArray[1];
 				_word2C880 = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x05:
@@ -1887,7 +1888,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				_oldMapPosX = _mapPosX = scriptNumberArray[0];
 				_oldMapPosY = _mapPosY = scriptNumberArray[1];
 				_largeMapFlag = true;
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x16:
@@ -1947,7 +1948,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 				if (var110 != -1) {
 					_mapUnknownPtr[var110 * 9 + 1] = 0xFF;
 				}
-				_word2C894 = true;
+				_redrawNeededFl = true;
 			}
 			break;
 		case 0x19:
@@ -2384,7 +2385,7 @@ void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
 	drawColoredRect(16, 152, 302, 189, color);
 }
 
-int16 EfhEngine::sub16B08(int16 monsterId) {
+int8 EfhEngine::sub16B08(int16 monsterId) {
 	// Simplified version compared to the original
 	int16 maxSize = _largeMapFlag ? 63 : 23;
 	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
@@ -2409,7 +2410,7 @@ int16 EfhEngine::sub16B08(int16 monsterId) {
 	return sub15581(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, 0);
 }
 
-bool EfhEngine::moveMonsterGroupTowardsGroup_0(int16 monsterId) {
+bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		--_mapMonsters[monsterId]._posX;
 		if (_mapMonsters[monsterId]._posY < _mapPosY)
@@ -2441,7 +2442,7 @@ bool EfhEngine::moveMonsterGroupTowardsGroup_0(int16 monsterId) {
 	return true;
 }
 
-bool EfhEngine::moveMonsterGroupTowardsGroup_1(int16 monsterId) {
+bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		++_mapMonsters[monsterId]._posX;
 		if (_mapMonsters[monsterId]._posY < _mapPosY)
@@ -2513,13 +2514,13 @@ bool EfhEngine::moveMonsterGroup(int16 monsterId) {
 	int16 rand100 = getRandom(100);
 
 	if (rand100 < 30)
-		return moveMonsterGroupTowardsGroup_1(monsterId);
+		return moveMonsterTowardsTeam(monsterId);
 
 	if (rand100 >= 60)
 		// CHECKME: the original seems to only use 1 param??
 		return moveMonsterGroupOther(monsterId, getRandom(8));
 
-	return moveMonsterGroupTowardsGroup_0(monsterId);
+	return moveMonsterAwayFromTeam(monsterId);
 }
 
 int16 EfhEngine::computeMonsterGroupDistance(int monsterId) {
@@ -2591,7 +2592,7 @@ void EfhEngine::sub174A0() {
 	
 	int16 var14 = 0;
 	int16 var6 = 0;
-	_word2C894 = false;
+	_redrawNeededFl = true;
 	int16 unkMonsterId = -1;
 	int16 mapSize = _largeMapFlag ? 63 : 23;
 	int16 minDisplayedMapX = CLIP<int16>(_mapPosX - 10, 0, mapSize);
@@ -2615,7 +2616,7 @@ void EfhEngine::sub174A0() {
 		if (var4 < minDisplayedMapX || var4 > maxDisplayedMapX || var2 < minDisplayedMapY || var2 > maxDisplayedMapY)
 			continue;
 
-		int16 var1A = 0;
+		bool var1A = false;
 		var14 = 0;
 
 		sub174A0_monsterPosX = _mapMonsters[monsterId]._posX;
@@ -2633,13 +2634,13 @@ void EfhEngine::sub174A0() {
 			switch (var1C - 1) {
 			case 0:
 				if (getRandom(100) >= 0xE - var1E)
-					var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+					var1A = moveMonsterTowardsTeam(monsterId);
 				else
 					var1A = moveMonsterGroup(monsterId);
 				break;
 			case 1:
 				if (getRandom(100) >= 0xE - var1E)
-					var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+					var1A = moveMonsterAwayFromTeam(monsterId);
 				else
 					var1A = moveMonsterGroup(monsterId);
 				break;
@@ -2651,13 +2652,13 @@ void EfhEngine::sub174A0() {
 				break;
 			case 4:
 				if (getRandom(100) > 0x32 - var1E)
-					var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+					var1A = moveMonsterTowardsTeam(monsterId);
 				else
 					var1A = moveMonsterGroup(monsterId);
 				break;
 			case 5:
 				if (getRandom(100) > 0x32 - var1E)
-					var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+					var1A = moveMonsterAwayFromTeam(monsterId);
 				else
 					var1A = moveMonsterGroup(monsterId);
 				break;
@@ -2673,7 +2674,7 @@ void EfhEngine::sub174A0() {
 				var14 = checkMonsterWeaponRange(monsterId);
 				if (var14 == 0) {
 					if (getRandom(100) >= 0xE - var1E)
-						var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+						var1A = moveMonsterTowardsTeam(monsterId);
 					else
 						var1A = moveMonsterGroup(monsterId);
 				}
@@ -2682,7 +2683,7 @@ void EfhEngine::sub174A0() {
 				var14 = checkMonsterWeaponRange(monsterId);
 				if (var14 == 0) {
 					if (getRandom(100) >= 0xE - var1E)
-						var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+						var1A = moveMonsterAwayFromTeam(monsterId);
 					else
 						var1A = moveMonsterGroup(monsterId);
 				}
@@ -2703,7 +2704,7 @@ void EfhEngine::sub174A0() {
 				var14 = checkMonsterWeaponRange(monsterId);
 				if (var14 == 0) {
 					if (getRandom(100) >= 0x32 - var1E)
-						var1A = moveMonsterGroupTowardsGroup_1(monsterId);
+						var1A = moveMonsterTowardsTeam(monsterId);
 					else
 						var1A = moveMonsterGroup(monsterId);
 				}
@@ -2712,7 +2713,7 @@ void EfhEngine::sub174A0() {
 				var14 = checkMonsterWeaponRange(monsterId);
 				if (var14 == 0) {
 					if (getRandom(100) >= 0x32 - var1E)
-						var1A = moveMonsterGroupTowardsGroup_0(monsterId);
+						var1A = moveMonsterAwayFromTeam(monsterId);
 					else
 						var1A = moveMonsterGroup(monsterId);
 				}
@@ -2727,20 +2728,20 @@ void EfhEngine::sub174A0() {
 			}
 
 			for (;;) {
-				if (var1A == 0) {
+				if (!var1A) {
 					if (var14 == 0) {
-						var1A = -1;
+						var1A = true;
 					} else {
 						unkMonsterId = monsterId;
-						var1A = -1;
+						var1A = true;
 					}
 				} else {
-					int16 var18 = sub16B08(monsterId);
+					int8 var18 = sub16B08(monsterId);
 
 					if (var18 == 0) {
 						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
 						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
-						var1A = 0;
+						var1A = false;
 						--var16;
 					} else if (var18 == 2) {
 						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
@@ -2748,16 +2749,14 @@ void EfhEngine::sub174A0() {
 					}
 				}
 
-				if (var1A == 0 && var16 == 1 && var1E > 1) {
+				if (!var1A && var16 == 1 && var1E > 1) {
 					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
 					continue;
 				}
 				
 				break;
 			}
-			
-		} while (var1A == 0 && var16 > 0);
-		
+		} while (!var1A && var16 > 0);
 	}
 
 	if (unkMonsterId != -1)
@@ -2788,9 +2787,42 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
-int16 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
+bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 _arg6, int16 arg8, int16 imageSetId) {
+	warning("STUB - sub22293");
+	return false;
+}
+
+int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	warning("STUB - sub15581");
-	return 0;
+	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
+	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
+	imageSetId *= 72;
+	imageSetId += curTileInfo % 72;
+
+	if (arg4 == 1 && _word2C8D7) {
+		int16 var2 = sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, imageSetId);
+	}
+
+	if (_word2C880) {
+		_word2C880 = false;
+		return -1;
+	}
+	if (_tileFact[imageSetId * 2 + 1] != 0xFF && !_word2C8D5) {
+		if ((arg4 == 1 && _word2C8D7) || (arg4 == 0 && _word2C8D7 && imageSetId != 128 && imageSetId != 121)) {
+			if (_largeMapFlag) {
+				_mapGameMapPtr[mapPosX * 64 + mapPosY] = _tileFact[imageSetId * 2 + 1];
+			} else {
+				_curPlace[mapPosX * 24 + mapPosY] = _tileFact[imageSetId * 2 + 1];
+			}
+
+			_redrawNeededFl = true;
+			if (_tileFact[imageSetId * 2] == 0)
+				return 2;
+			return 1;
+		}
+	}
+
+	return _tileFact[imageSetId * 2];
 }
 
 bool EfhEngine::handleFight(int16 monsterId) {
@@ -2840,7 +2872,7 @@ bool EfhEngine::sub16E14() {
 		_mapPosY = _oldMapPosY;
 		if (_imageSetSubFilesIdx != _oldImageSetSubFilesIdx)
 			_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
-		_word2C894 = true;
+		_redrawNeededFl = true;
 
 		int16 var6A = 0;
 		for (int16 var6C = 0; var6C < 9; ++var6C) {
@@ -2923,8 +2955,8 @@ bool EfhEngine::sub16E14() {
 		return true;
 	}
 
-	monsterId = sub15581(_mapPosX, _mapPosY, 1);
-	if (monsterId == 0 || monsterId == 2)
+	int8 check = sub15581(_mapPosX, _mapPosY, 1);
+	if (check == 0 || check == 2)
 		return false;
 
 	return true;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b8a324343cf..5b2eb1f6120 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -294,7 +294,7 @@ private:
 	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl);
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
-	void sub12A7F();
+	void redrawScreen();
 	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
 	void displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY);
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
@@ -348,9 +348,9 @@ private:
 	void setNextCharacterPos();
 	void displayStringAtTextPos(char *message);
 	void unkFct_displayMenuBox_2(int16 color);
-	int16 sub16B08(int16 monsterId);
-	bool moveMonsterGroupTowardsGroup_0(int16 monsterId);
-	bool moveMonsterGroupTowardsGroup_1(int16 monsterId);
+	int8 sub16B08(int16 monsterId);
+	bool moveMonsterAwayFromTeam(int16 monsterId);
+	bool moveMonsterTowardsTeam(int16 monsterId);
 	bool moveMonsterGroupOther(int16 monsterId, int16 direction);
 	bool moveMonsterGroup(int16 monsterId);
 	int16 computeMonsterGroupDistance(int monsterId);
@@ -363,7 +363,8 @@ private:
 	bool checkPictureRefAvailability(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 arg4);
 	void sub221D2(int16 monsterId);
-	int16 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
+	bool sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 _arg6, int16 arg8, int16 imageSetId);
+	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
 	bool handleFight(int16 monsterId);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	Common::KeyCode waitForKey();
@@ -442,7 +443,7 @@ private:
 	int16 _teamSize;
 	int16 _word2C872;
 	bool _word2C880;
-	bool _word2C894;
+	bool _redrawNeededFl;
 	bool _word2C8D7;
 	bool _drawHeroOnMapFl;
 	bool _drawMonstersOnMapFl;


Commit: 51d4c3f9d1545aa5f68ae0ef5a97230eb0c6aa91
    https://github.com/scummvm/scummvm/commit/51d4c3f9d1545aa5f68ae0ef5a97230eb0c6aa91
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement handleWinSequence and getInput

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c4d1166951a..506c34616ac 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1496,8 +1496,109 @@ bool EfhEngine::isTPK() {
 	return zeroedChar == _teamSize;
 }
 
+Common::KeyCode EfhEngine::getInput(int16 delay) {
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+		if (lastChar != Common::KEYCODE_INVALID)
+			retVal = lastChar;
+	}
+
+	return retVal;
+}
+
 void EfhEngine::handleWinSequence() {
-	warning("STUB - handleWinSequence");
+	saveAnimImageSetId();
+	findMapFile(18);
+	// clearMemory();
+	uint8 *decompBuffer = (uint8 *)malloc(41000);
+	uint8 *winSeqBuf3 = (uint8 *)malloc(40100);
+	uint8 *winSeqBuf4 = (uint8 *)malloc(40100);
+
+	uint8 *winSeqSubFilesArray1[10];
+	uint8 *winSeqSubFilesArray2[20];
+	loadImageSet(64, winSeqBuf3, winSeqSubFilesArray1, decompBuffer);
+	loadImageSet(65, winSeqBuf4, winSeqSubFilesArray2, decompBuffer);
+
+	for (int16 counter = 0; counter < 2; ++counter) {
+		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
+		displayRawDataAtPos(winSeqSubFilesArray2[0], 136, 48);
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+
+	getInput(12);
+	for (int16 counter2 = 1; counter2 < 8; ++counter2) {
+		for (int16 counter = 0; counter < 2; ++counter) {
+			displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
+			displayRawDataAtPos(winSeqSubFilesArray2[counter2], 136, 48);
+			if (counter == 0)
+				displayFctFullScreen();
+		}
+		getInput(1);
+	}
+
+	Common::KeyCode var59 = Common::KEYCODE_INVALID;
+
+	while(var59 != Common::KEYCODE_ESCAPE) {
+		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
+		displayFctFullScreen();
+		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
+		var59 = getInput(32);
+		if (var59 != Common::KEYCODE_ESCAPE) {
+			displayRawDataAtPos(winSeqSubFilesArray2[10], 136, 72);
+			displayFctFullScreen();
+			displayRawDataAtPos(winSeqSubFilesArray2[10], 136, 72);
+			var59 = getInput(1);
+		}
+
+		if (var59 != Common::KEYCODE_ESCAPE) {
+			displayRawDataAtPos(winSeqSubFilesArray2[11], 136, 72);
+			displayFctFullScreen();
+			displayRawDataAtPos(winSeqSubFilesArray2[11], 136, 72);
+			var59 = getInput(1);
+		}
+
+		if (var59 != Common::KEYCODE_ESCAPE) {
+			displayRawDataAtPos(winSeqSubFilesArray2[12], 136, 72);
+			displayFctFullScreen();
+			displayRawDataAtPos(winSeqSubFilesArray2[12], 136, 72);
+			var59 = getInput(1);
+		}
+
+		if (var59 != Common::KEYCODE_ESCAPE) {
+			displayRawDataAtPos(winSeqSubFilesArray2[13], 136, 72);
+			displayFctFullScreen();
+			displayRawDataAtPos(winSeqSubFilesArray2[13], 136, 72);
+			var59 = getInput(1);
+		}
+
+		if (var59 != Common::KEYCODE_ESCAPE) {
+			displayRawDataAtPos(winSeqSubFilesArray2[14], 136, 72);
+			displayFctFullScreen();
+			displayRawDataAtPos(winSeqSubFilesArray2[14], 136, 72);
+			var59 = getInput(1);
+		}
+	}
+	
+	free(decompBuffer);
+	free(winSeqBuf3);
+	free(winSeqBuf4);
 }
 
 bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 5b2eb1f6120..4644a424b62 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -307,6 +307,7 @@ private:
 	void refreshTeamSize();
 	bool isCharacterATeamMember(int16 id);
 	bool isTPK();
+	Common::KeyCode getInput(int16 delay);
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
 	void drawString(char * str, int16 startX, int16 startY, uint16 unkFl);


Commit: cc86b83031ed340793fb57b5d582ba1055edc150
    https://github.com/scummvm/scummvm/commit/cc86b83031ed340793fb57b5d582ba1055edc150
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement handleNewRoundEffetcs

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 506c34616ac..d81d90ffbe9 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1386,7 +1386,6 @@ void EfhEngine::displayFctFullScreen() {
 	// CHECKME: 319 is in the original but looks suspicious.
 	// copyDirtyRect(0, 0, 319, 200);
 
-	warning("Char pos %d %d old pos %d %d", _mapPosX, _mapPosY, _oldMapPosX, _oldMapPosY);
 	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
 	_system->updateScreen();
 }
@@ -2390,7 +2389,28 @@ void EfhEngine::goSouthWest() {
 }
 
 void EfhEngine::handleNewRoundEffects() {
-	warning("STUB: handleNewRoundEffects");
+	static int16 regenCounter = 0;
+
+	if (!_word2C8D7)
+		return;
+
+	for (int16 counter = 0; counter < _teamSize; ++counter) {
+		if (_teamCharStatus[counter]._status == 0) // normal
+			continue;
+		if (--_teamCharStatus[counter]._duration <= 0) {
+			_teamCharStatus[counter]._status = 0;
+			_teamCharStatus[counter]._duration = 0;
+		}
+	}
+
+	if (++regenCounter <= 8)
+		return;
+
+	for (int16 counter = 0; counter < _teamSize; ++counter) {
+		if (++_npcBuf[_teamCharId[counter]]._hitPoints > _npcBuf[_teamCharId[counter]]._maxHP)
+			_npcBuf[_teamCharId[counter]]._hitPoints = _npcBuf[_teamCharId[counter]]._maxHP;
+	}
+	regenCounter = 0;
 }
 
 bool EfhEngine::handleDeathMenu() {
@@ -2894,7 +2914,6 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 _arg6,
 }
 
 int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
-	warning("STUB - sub15581");
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
 	imageSetId *= 72;


Commit: 50803c32e2038aec28eca36759f5ec1303a33f5a
    https://github.com/scummvm/scummvm/commit/50803c32e2038aec28eca36759f5ec1303a33f5a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement various menu functions

Changed paths:
    engines/efh/constants.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 1e3bda56d24..0547cbc14da 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -25,6 +25,7 @@
 #include "engine.h"
 
 namespace Efh {
+
 const uint8 kFontWidthArray[96] = {
 	3, 2, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 3, 3, 2, 7, 4, 3, 4, 4, 5, 4, 4, 4, 4, 4, 3, 4, 4, 5, 4, 5, 1, 4, 4, 4,
 	4, 4, 4, 4, 4, 3, 4, 4, 4, 7, 5, 4, 4, 4, 4, 4, 5, 4, 5, 7, 5, 5, 5, 3, 7, 3, 5, 0, 2, 4, 4, 4, 4, 4, 4, 4,
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d81d90ffbe9..92226250469 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -272,6 +272,14 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C8D9 = false;
 	_word2C8D5 = false;
 	_word2D0BC = false;
+	_word2C8D2 = false;
+	_word2D0BE = 0;
+	_word2D0BA = 0;
+
+
+	for (int i = 0; i < 15; ++i) {
+		_word3273A[i] = 0;
+	}
 
 	memset(_messageToBePrinted, 0, 400);
 }
@@ -804,29 +812,6 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 	decryptImpFile(techMapFl);
 }
 
-Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
-	if (delay == 0)
-		return Common::KEYCODE_INVALID;
-
-	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
-	
-	uint32 lastMs = _system->getMillis();
-	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 200) {
-			lastMs = newMs;
-			--delay;
-			unkFct_anim();
-		}
-
-		lastChar = handleAndMapInput(false);
-	} 
-	
-	return lastChar;
-}
-
 void EfhEngine::playIntro() {
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
@@ -1495,32 +1480,6 @@ bool EfhEngine::isTPK() {
 	return zeroedChar == _teamSize;
 }
 
-Common::KeyCode EfhEngine::getInput(int16 delay) {
-	if (delay == 0)
-		return Common::KEYCODE_INVALID;
-
-	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
-	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-
-	uint32 lastMs = _system->getMillis();
-	while (delay > 0) {
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 200) {
-			lastMs = newMs;
-			--delay;
-			unkFct_anim();
-		}
-
-		lastChar = handleAndMapInput(false);
-		if (lastChar != Common::KEYCODE_INVALID)
-			retVal = lastChar;
-	}
-
-	return retVal;
-}
-
 void EfhEngine::handleWinSequence() {
 	saveAnimImageSetId();
 	findMapFile(18);
@@ -2423,7 +2382,7 @@ void EfhEngine::setNumLock() {
 }
 
 void EfhEngine::computeMapAnimation() {
-	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+	const int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
 	int16 minMapX = _mapPosX - 5;
 	int16 minMapY = _mapPosY - 4;
@@ -2446,7 +2405,7 @@ void EfhEngine::computeMapAnimation() {
 			if (_largeMapFlag) {
 				if (_currentTileBankImageSetId[0] != 0)
 					continue;
-				int16 var4 = _mapGameMapPtr[counterX * 64 + counterY];
+				uint8 var4 = _mapGameMapPtr[counterX * 64 + counterY];
 				if (var4 >= 1 && var4 <= 0xF) {
 					if (getRandom(100) < 50)
 						_mapGameMapPtr[counterX * 64 + counterY] += 0xC5;
@@ -2457,7 +2416,7 @@ void EfhEngine::computeMapAnimation() {
 			} else {
 				if (_currentTileBankImageSetId[0] != 0)
 					continue;
-				int16 var4 = _curPlace[counterX * 24 + counterY];
+				uint8 var4 = _curPlace[counterX * 24 + counterY];
 				if (var4 >= 1 && var4 <= 0xF) {
 					if (getRandom(100) < 50)
 						_curPlace[counterX * 24 + counterY] += 0xC5;
@@ -2908,8 +2867,89 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
-bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 _arg6, int16 arg8, int16 imageSetId) {
-	warning("STUB - sub22293");
+void EfhEngine::sub22AA8(uint16 arg0) {
+	warning("STUB - sub22AA8");
+}
+
+bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, int16 arg8, int16 imageSetId) {
+	int16 var8 = sub151FD(mapPosX, mapPosY);
+
+	if (var8 == -1) {
+		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
+			sub221FA(_imp2PtrArray[imageSetId], true);
+	} else if (var8 == 0) {
+		if (_mapUnknownPtr[var8 * 9 + 3] == 0xFF) {
+			sub22AA8(_mapUnknownPtr[var8 * 9 + 5]); // word!
+			return true;
+		} else if (_mapUnknownPtr[var8 * 9 + 3] == 0xFE) {
+			for (int16 counter = 0; counter < _teamSize; ++counter) {
+				if (_teamCharId[counter] == -1)
+					continue;
+				if (_teamCharId[counter] == _mapUnknownPtr[var8 * 9 + 4]) {
+					sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+					return true;
+				}
+			}
+		} else if (_mapUnknownPtr[var8 * 9 + 3] == 0xFD) {
+			for (int16 counter = 0; counter < _teamSize; ++counter) {
+				if (_teamCharId[counter] == -1)
+					continue;
+
+				for (int16 var2 = 0; var2 < 10; ++var2) {
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknownPtr[var8 * 9 + 4]) {
+						sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+						return true;
+					}
+				}
+			}
+		// original makes a useless check on (_mapUnknownPtr[var8 * 9 + 3] > 0x7F)
+		} else if (_mapUnknownPtr[var8 * 9 + 3] <= 0x77) {
+			int16 var6 = _mapUnknownPtr[var8 * 9 + 3];
+			for (int counter = 0; counter < _teamSize; ++counter) {
+				if (_teamCharId[counter] == -1)
+					continue;
+
+				for (int16 var2 = 0; var2 < 39; ++var2) {
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var2] >= _mapUnknownPtr[var8 * 9 + 4]) {
+						sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+						return true;
+					}
+				}
+			}
+		}
+	} else {
+		if ((_mapUnknownPtr[var8 * 9 + 3] == 0xFA && arg8 == 1)
+		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFC && arg8 == 2)
+		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFB && arg8 == 3)) {
+			if (_mapUnknownPtr[var8 * 9 + 4] == arg6) {
+				sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+				return true;
+			}
+		} else if (arg8 == 4) {
+			int16 var6 = _mapUnknownPtr[var8 * 9 + 3];
+			if (var6 >= 0x7B && var6 <= 0xEF) {
+				var6 -= 0x78;
+				if (var6 >= 0 && var6 <= 0x8B && var6 == arg6 && _mapUnknownPtr[var8 * 9 + 4] <= _npcBuf[arg4]._activeScore[arg6]) {
+					sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+					return true;
+				}
+			}		
+		}
+	}
+
+	for (int16 counter = 0; counter < 64; ++counter) {
+		if (!sub21820(counter, arg8, arg6))
+			return true;
+	}
+
+	if ((arg8 == 4 && _mapUnknownPtr[var8 * 9 + 3] < 0xFA) || arg8 != 4) {
+		if (_mapUnknownPtr[var8 * 9 + 7] > 0xFE) // word!!
+			return false;
+		sub22AA8(_mapUnknownPtr[var8 * 9 + 7]);
+		return true;		
+	} else
+		return false;
+
 	return false;
 }
 
@@ -2950,19 +2990,538 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	return false;
 }
 
-int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
-	warning("STUB - handleStatusMenu");
-	return 0;
+void EfhEngine::displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str) {
+	char buffer[20];
+	memset(buffer, 0, 20);
+
+	if (menuBoxId == thisBoxId) {
+		if (_word2D0BE == 0)
+			setTextColorWhite();
+		else
+			setTextColor_08h();
+
+		sprintf(buffer, "> %s <", str);
+		displayCenteredString(buffer, minX, maxX, minY);
+		setTextColorRed();
+	} else {
+		if (_word2D0BE == 0)
+			setTextColorRed();
+		else
+			setTextColor_08h();
+
+		displayCenteredString((char *)str, minX, maxX, minY);
+	}
 }
 
-Common::KeyCode EfhEngine::waitForKey() {
-	warning("STUB - waitForKey");
-	return Common::KEYCODE_INVALID;
+void EfhEngine::displayStatusMenu(int16 windowId) {
+	for (int16 counter = 0; counter < 9; ++counter) {
+		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
+	}
+
+	if (_word2D0BE != 0)
+		setTextColor_08h();
+
+	displayMenuItemString(windowId, 0, 80, 134, 39, "EQUIP");
+	displayMenuItemString(windowId, 1, 80, 134, 53, "USE");
+	displayMenuItemString(windowId, 2, 80, 134, 67, "GIVE");
+	displayMenuItemString(windowId, 3, 80, 134, 81, "TRADE");
+	displayMenuItemString(windowId, 4, 80, 134, 95, "DROP");
+	displayMenuItemString(windowId, 5, 80, 134, 109, "INFO.");
+	displayMenuItemString(windowId, 6, 80, 134, 123, "PASSIVE");
+	displayMenuItemString(windowId, 7, 80, 134, 137, "ACTIVE");
+	displayMenuItemString(windowId, 8, 80, 134, 151, "LEAVE");
+
+	setTextColorRed();
 }
 
-Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
-	warning("STUB - mapInputCode");
-	return Common::KEYCODE_INVALID;
+void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
+	warning("STUB: countRightWindowItems");
+}
+
+void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
+	warning("STUB: displayCharacterSummary");
+}
+
+void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId) {
+	warning("STUB: displayCharacterInformationOrSkills");
+}
+
+void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
+	drawColoredRect(144, 15, 310, 184, 0);
+	displayCenteredString((char *)"(ESCape Aborts)", 144, 310, 175);
+	_textColor = 0x0E;
+	switch (menuId) {
+	case 0:
+		displayCenteredString((char *)"Select Item to Equip", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 1:
+		displayCenteredString((char *)"Select Item to Use", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 2:
+		displayCenteredString((char *)"Select Item to Give", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 3:
+		displayCenteredString((char *)"Select Item to Trade", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 4:
+		displayCenteredString((char *)"Select Item to Drop", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 5:
+		displayCenteredString((char *)"Character Information", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 6:
+		displayCenteredString((char *)"Passive Skills", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 7:
+		displayCenteredString((char *)"Active Skills", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 8:
+	case 9:
+		displayCenteredString((char *)"Character Summary", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	}
+}
+
+void EfhEngine::unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
+	displayStatusMenu(windowId);
+
+	countRightWindowItems(menuId, charId);
+	displayStatusMenuActions(menuId, curMenuLine, charId);
+
+	if (refreshFl)
+		displayFctFullScreen();
+}
+
+void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest) {
+	if (buffer == nullptr) {
+		warning("Target Buffer Not Defined...DCImage!"); // That's the original message... And yes, it's wrong: it's checking the source buffer :)
+		return;
+	}
+
+	// Only MCGA handled, the rest is skipped
+	uncompressBuffer(buffer, dest);
+	displayRawDataAtPos(dest, posX, posY);
+	displayFctFullScreen();
+	displayRawDataAtPos(dest, posX, posY);
+}
+
+void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	for (int counter = 0; counter < 2; ++counter) {
+		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
+		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+}
+
+int16 EfhEngine::_guess_displayString_3(const char *str, int16 arg2, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	int16 var2 = 0;
+	
+	for (int16 counter = 0; counter < 2; ++counter) {
+		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
+
+		if (counter == 0) {
+			script_parse((uint8 *)str, 28, 122, 105, 166, 0);
+			displayFctFullScreen();
+		} else {
+			var2 = script_parse((uint8 *)str, 28, 122, 105, 166, -1);
+		}
+	}
+
+	getLastCharAfterAnimCount(_guessAnimationAmount);
+	sub18E80(charId, windowId, menuId, curMenuLine);
+
+	return var2;
+}
+
+bool EfhEngine::isItemCursed(int16 itemId) {
+	if (_items[itemId].field_16 == 21 || _items[itemId].field_16 == 22 || _items[itemId].field_16 == 23)
+		return true;
+
+	return false;
+}
+
+bool EfhEngine::hasObjectEquipped(int16 charId, int16 _objectId) {
+	if ((_npcBuf[charId]._inventory[_objectId]._stat1 & 0x80) == 0)
+		return false;
+
+	return true;
+}
+
+void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	warning("STUB: sub191FF");
+}
+
+int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
+	warning("STUB: sub19E2E");
+
+	return -1;
+}
+
+bool EfhEngine::getValidationFromUser() {
+	Common::KeyCode input = handleAndMapInput(true);
+	if (input == Common::KEYCODE_y) // or if joystick button 1
+		return true;
+
+	return false;
+}
+
+int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
+	int16 menuId = 9;
+	int16 var16 = -1;
+	int16 windowId = -1;
+	int16 curMenuLine = -1;
+	int16 var10 = 0;
+	int16 var2 = 0;
+
+	saveAnimImageSetId();
+
+	_word2C8D2 = true;
+	_word2D0BE = 0;
+
+	sub18E80(charId, windowId, menuId, curMenuLine);
+
+	for (;;) {
+		if (windowId != -1)
+			unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+		else
+			windowId = 0;
+
+		do {
+			Common::KeyCode var19 = handleAndMapInput(false);
+			if (_word2D0BE == 0) {
+				switch (var19) {
+				case Common::KEYCODE_ESCAPE:
+					if (_word2D0BE == 0) { // ?? Useless case ?
+						windowId = 8;
+						var19 = Common::KEYCODE_RETURN;
+					}
+					break;
+				case Common::KEYCODE_a:
+					windowId = 7;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_d:
+					windowId = 4;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_e:
+					windowId = 0;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_g:
+					windowId = 2;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_i:
+					windowId = 5;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_l:
+					windowId = 8;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_p:
+					windowId = 6;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_t:
+					windowId = 3;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_u:
+					windowId = 1;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				// case 0xFB: Joystick button 2
+				default:
+					warning("handleStatusMenu - unhandled keys 0xBA, 0xBB, 0xBC");
+					break;
+				}
+			} else if (_word2D0BE == 1) {
+				if (var19 >= Common::KEYCODE_a && var19 <= Common::KEYCODE_z) {
+					int16 var8 = var19 - Common::KEYCODE_a;
+					if (var8 < _word2D0BA) {
+						curMenuLine = var8;
+						var19 = Common::KEYCODE_RETURN;
+					}
+				}
+
+			}
+
+			switch (var19) {
+			case Common::KEYCODE_RETURN:
+			// case 0xFA: Joystick button 1
+				if (_word2D0BE == 0) {
+					menuId = windowId;
+					if (menuId > 7)
+						var10 = -1;
+					else {
+						_word2D0BE = 1;
+						curMenuLine = 0;
+					}
+				} else if (_word2D0BE == 1) {
+					if (_word2D0BA == 0) {
+						_word2D0BE = 0;
+						curMenuLine = -1;
+						menuId = 9;
+						unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+					} else {
+						var16 = curMenuLine;
+						var10 = -1;
+					}
+				}
+				break;
+			case Common::KEYCODE_ESCAPE:
+				_word2D0BE = 0;
+				curMenuLine = -1;
+				menuId = 9;
+				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+				break;
+			case Common::KEYCODE_2:
+			case Common::KEYCODE_6:
+			// case 0xCC, 0xCF
+				if (_word2D0BE == 0) {
+					if (++windowId == 8)
+						windowId = 0;
+				} else if (_word2D0BE == 1) {
+					if (_word2D0BA != 0) {
+						++curMenuLine;
+						if (curMenuLine > _word2D0BA - 1)
+							curMenuLine = 0;
+					}
+				}
+				break;
+			case Common::KEYCODE_4:
+			case Common::KEYCODE_8:
+			// case 0xC7, 0xCA
+				if (_word2D0BE == 0) {
+					if (--windowId < 0)
+						windowId = 8;
+				} else if (_word2D0BE == 1) {
+					if (_word2D0BA != 0) {
+						--curMenuLine;
+						if (curMenuLine < 0)
+							curMenuLine = _word2D0BA - 1;
+					}
+				}
+				break;
+			}
+
+			if (curMenuLine == -1)
+				unk_StatusMenu(windowId, menuId, curMenuLine, charId, false, true);
+			else
+				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+
+		} while (var10 == 0);
+
+		bool validationFl = true;
+
+		int16 objectId;
+		int16 itemId;
+		switch (menuId) {
+		case 0:
+			objectId = _word3273A[var16];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
+			if (gameMode == 2) {
+				restoreAnimImageSetId();
+				_word2C8D2 = false;
+				return 0x7D00;
+			}
+			break;
+		case 1:
+			objectId = _word3273A[var16];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (gameMode == 2) {
+				restoreAnimImageSetId();
+				_word2C8D2 = false;
+				return objectId;
+			} else {
+				if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
+					_word2C8D2 = false;
+					return -1;
+				} else {
+					int16 var8 = sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
+				}
+			}
+			break;
+		case 2:
+			objectId = _word3273A[var16];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)){
+				_guess_displayString_3("Item is Equipped!  Give anyway?", 0, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					if (gameMode == 2) {
+						_guess_displayString_3("Not a Combat Option !", -1, charId, windowId, menuId, curMenuLine);
+					} else {
+						removeObject(charId, objectId);
+						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
+						if (var8 != 0) {
+							_word2C8D2 = false;
+							return -1;
+						}
+					}
+				}
+			}
+
+			break;
+		case 3:
+			objectId = _word3273A[var16];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)) {
+				_guess_displayString_3("Item is Equipped!  Trade anyway?", 0, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					int16 var6;
+					int16 var8;
+					do {
+						if (_teamCharId[2] != -1) {
+							var8 = _guess_displayString_3("Who will you give the item to?", 0, charId, windowId, menuId, curMenuLine);
+							var2 = 0;
+						} else if (_teamCharId[1]) {
+							var8 = 0x1A;
+							var2 = 0;
+						} else {
+							var2 = -1;
+							if (_teamCharId[0] == charId)
+								var8 = 1;
+							else
+								var8 = 0;
+						}
+
+						if (var8 != 0x1A && var8 != 0x1B) {
+							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
+							if (var6 == 0) {
+								_guess_displayString_3("That character cannot carry anymore!", 0, charId, windowId, menuId, curMenuLine);
+								Common::KeyCode var4 = getLastCharAfterAnimCount(_guessAnimationAmount);
+							}
+						} else {
+							if (var8 == 0x1A) {
+								_guess_displayString_3("No one to trade with!", 0, charId, windowId, menuId, curMenuLine);
+								Common::KeyCode var4 = getLastCharAfterAnimCount(_guessAnimationAmount);
+								var8 = 0x1B;
+							}
+							var6 = 0;
+						}
+					} while (var6 == 0 && var2 == 0 && var8 != 0x1B);
+
+					if (var6) {
+						removeObject(charId, objectId);
+						if (gameMode == 2) {
+							restoreAnimImageSetId();
+							_word2C8D2 = false;
+							return 0x7D00;
+						}
+					}
+
+					sub18E80(charId, windowId, menuId, curMenuLine);
+				}
+			}
+			break;
+		case 4:
+			objectId = _word3273A[var16];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)) {
+				_guess_displayString_3("Item Is Equipped!  Drop Anyway?", 0, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					removeObject(charId, objectId);
+					if (gameMode == 2) {
+						restoreAnimImageSetId();
+						_word2C8D2 = false;
+						return 0x7D00;
+					}
+
+					bool var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1);
+					if (var8) {
+						_word2C8D2 = false;
+						return -1;
+					}
+				}
+			}
+			break;
+		case 5:
+			objectId = _word3273A[var16];
+			if (gameMode == 2) {
+				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_word2C8D2 = false;
+					return 0xFFFF;
+				}
+			}
+			break;
+		case 6: // Identical to case 5?
+			objectId = _word3273A[var16];
+			if (gameMode == 2) {
+				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_word2C8D2 = false;
+					return 0xFFFF;
+				}
+			}
+			break;
+		case 7: // Identical to case 5?
+			objectId = _word3273A[var16];
+			if (gameMode == 2) {
+				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_word2C8D2 = false;
+					return -1;
+				}
+			}
+			break;
+		}
+
+		if (menuId != 8) {
+			var10 = 0;
+			_word2D0BE = 0;
+			menuId = 9;
+			var16 = -1;
+			curMenuLine = -1;
+		}
+
+		if (menuId == 8) {
+			restoreAnimImageSetId();
+			_word2C8D2 = false;
+			return 0x7FFF;
+		}
+	}
+
+	return 0;
 }
 
 bool EfhEngine::sub16E14() {
@@ -3281,6 +3840,88 @@ Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
 	return retVal;
 }
 
+Common::KeyCode EfhEngine::waitForKey() {
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+	Common::Event event;
+
+	uint32 lastMs = _system->getMillis();
+	while (retVal == Common::KEYCODE_INVALID) { // TODO: Check shouldquit()
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			unkFct_anim();
+		}
+
+		_system->getEventManager()->pollEvent(event);
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = event.kbd.keycode;
+		} 	
+	}
+
+	return retVal;
+}
+
+Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
+	// Original is doing:
+	// if input < a or > z : return input
+	// else return (input + 0xE0)
+	// ex: 'a' = 0x61 + 0xE0 = 0x0141, but it's a uint8 so it's 0x41 which is 'A'.
+	// So basically the original works with uppercase letters and do not alter the other inputs.
+	// => no implementation needed.
+	return input;
+}
+
+Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+	}
+
+	return lastChar;
+}
+
+Common::KeyCode EfhEngine::getInput(int16 delay) {
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+		if (lastChar != Common::KEYCODE_INVALID)
+			retVal = lastChar;
+	}
+
+	return retVal;
+}
+
 void EfhEngine::displayNextAnimFrame() {
 	if (++_unkAnimRelatedIndex >= 15)
 		_unkAnimRelatedIndex = 0;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4644a424b62..39f9abc9936 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -310,8 +310,8 @@ private:
 	Common::KeyCode getInput(int16 delay);
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
-	void drawString(char * str, int16 startX, int16 startY, uint16 unkFl);
-	void displayCenteredString(char * str, int16 minX, int16 maxX, int16 posY);
+	void drawString(char *str, int16 startX, int16 startY, uint16 unkFl);
+	void displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	void drawMapWindow();
@@ -364,9 +364,25 @@ private:
 	bool checkPictureRefAvailability(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 arg4);
 	void sub221D2(int16 monsterId);
-	bool sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 _arg6, int16 arg8, int16 imageSetId);
+	void sub22AA8(uint16 arg0);
+	bool sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
 	bool handleFight(int16 monsterId);
+	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
+	void displayStatusMenu(int16 windowId);
+	void countRightWindowItems(int16 menuId, int16 charId);
+	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
+	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
+	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
+	void unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
+	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
+	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 _guess_displayString_3(const char * str, int16 arg2, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	bool isItemCursed(int16 itemId);
+	bool hasObjectEquipped(int16 charId, int16 _objectId);
+	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
+	bool getValidationFromUser();
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	Common::KeyCode waitForKey();
 	Common::KeyCode mapInputCode(Common::KeyCode input);
@@ -464,6 +480,11 @@ private:
 	bool _word2C8D9;
 	bool _word2C8D5; // CHECKME: always 0?
 	bool _word2D0BC;
+	bool _word2C8D2;
+	int16 _word2D0BE;
+	int16 _word2D0BA;
+
+	int16 _word3273A[15];
 };
 
 } // End of namespace Efh


Commit: 40ad50f161e800ce5a8d40fafd5139066816317f
    https://github.com/scummvm/scummvm/commit/40ad50f161e800ce5a8d40fafd5139066816317f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Fix number of menu lines, add some convenient keycodes in the menus, some small renaming and clean up

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 92226250469..e7f37939a78 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -273,7 +273,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C8D5 = false;
 	_word2D0BC = false;
 	_word2C8D2 = false;
-	_word2D0BE = 0;
+	_menuDepth = 0;
 	_word2D0BA = 0;
 
 
@@ -1565,7 +1565,7 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
 	return false;
 }
 
-void EfhEngine::drawString(char *str, int16 startX, int16 startY, uint16 unkFl) {
+void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 unkFl) {
 	uint8 *curPtr = (uint8 *)str;
 	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
 	_unk_sub26437_flag = unkFl & 0x3FFF;
@@ -1602,7 +1602,7 @@ void EfhEngine::drawString(char *str, int16 startX, int16 startY, uint16 unkFl)
 	
 }
 
-void EfhEngine::displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY) {
+void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY) {
 	uint16 length = getStringWidth(str);
 	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
 	drawString(str, startCenteredDisplayX, posY, _textColor);
@@ -1665,7 +1665,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 	uint16 curLine = 0;
 	int16 numbLines = (1 + maxY - posY) / 9;
 	int16 width = maxX - posX;
-	int16 var_114 = getStringWidth((char *)stringToDisplay);
+	int16 var_114 = getStringWidth(stringToDisplay);
 	uint8 *buffer = stringBuffer;
 	char var_EC[80];
 	char dest[150];
@@ -2206,7 +2206,7 @@ void EfhEngine::setTextColorRed() {
 		_textColor = 0xC;
 }
 
-void EfhEngine::setTextColor_08h() {
+void EfhEngine::setTextColorGrey() {
 	if (_videoMode == 8) // CGA
 		_textColor = 0x1;
 	else
@@ -2455,7 +2455,7 @@ void EfhEngine::setNextCharacterPos() {
 		_textPosY = 0;
 }
 
-void EfhEngine::displayStringAtTextPos(char *message) {
+void EfhEngine::displayStringAtTextPos(const char *message) {
 	drawString(message, _textPosX, _textPosY, _textColor);
 	_textPosX += getStringWidth(message) + 1;
 	setNextCharacterPos();
@@ -2995,21 +2995,21 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX,
 	memset(buffer, 0, 20);
 
 	if (menuBoxId == thisBoxId) {
-		if (_word2D0BE == 0)
+		if (_menuDepth == 0)
 			setTextColorWhite();
 		else
-			setTextColor_08h();
+			setTextColorGrey();
 
 		sprintf(buffer, "> %s <", str);
 		displayCenteredString(buffer, minX, maxX, minY);
 		setTextColorRed();
 	} else {
-		if (_word2D0BE == 0)
+		if (_menuDepth == 0)
 			setTextColorRed();
 		else
-			setTextColor_08h();
+			setTextColorGrey();
 
-		displayCenteredString((char *)str, minX, maxX, minY);
+		displayCenteredString(str, minX, maxX, minY);
 	}
 }
 
@@ -3018,8 +3018,8 @@ void EfhEngine::displayStatusMenu(int16 windowId) {
 		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
 	}
 
-	if (_word2D0BE != 0)
-		setTextColor_08h();
+	if (_menuDepth != 0)
+		setTextColorGrey();
 
 	displayMenuItemString(windowId, 0, 80, 134, 39, "EQUIP");
 	displayMenuItemString(windowId, 1, 80, 134, 53, "USE");
@@ -3048,44 +3048,44 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 npc
 
 void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
 	drawColoredRect(144, 15, 310, 184, 0);
-	displayCenteredString((char *)"(ESCape Aborts)", 144, 310, 175);
+	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
 	_textColor = 0x0E;
 	switch (menuId) {
 	case 0:
-		displayCenteredString((char *)"Select Item to Equip", 144, 310, 15);
+		displayCenteredString("Select Item to Equip", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	case 1:
-		displayCenteredString((char *)"Select Item to Use", 144, 310, 15);
+		displayCenteredString("Select Item to Use", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	case 2:
-		displayCenteredString((char *)"Select Item to Give", 144, 310, 15);
+		displayCenteredString("Select Item to Give", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	case 3:
-		displayCenteredString((char *)"Select Item to Trade", 144, 310, 15);
+		displayCenteredString("Select Item to Trade", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	case 4:
-		displayCenteredString((char *)"Select Item to Drop", 144, 310, 15);
+		displayCenteredString("Select Item to Drop", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	case 5:
-		displayCenteredString((char *)"Character Information", 144, 310, 15);
+		displayCenteredString("Character Information", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
 	case 6:
-		displayCenteredString((char *)"Passive Skills", 144, 310, 15);
+		displayCenteredString("Passive Skills", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
 	case 7:
-		displayCenteredString((char *)"Active Skills", 144, 310, 15);
+		displayCenteredString("Active Skills", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
 	case 8:
 	case 9:
-		displayCenteredString((char *)"Character Summary", 144, 310, 15);
+		displayCenteredString("Character Summary", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
 	}
@@ -3124,7 +3124,7 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 	}
 }
 
-int16 EfhEngine::_guess_displayString_3(const char *str, int16 arg2, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
 	int16 var2 = 0;
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
@@ -3139,9 +3139,11 @@ int16 EfhEngine::_guess_displayString_3(const char *str, int16 arg2, int16 charI
 		}
 	}
 
-	getLastCharAfterAnimCount(_guessAnimationAmount);
-	sub18E80(charId, windowId, menuId, curMenuLine);
-
+	if (animFl) {
+		getLastCharAfterAnimCount(_guessAnimationAmount);
+		sub18E80(charId, windowId, menuId, curMenuLine);
+	}
+	
 	return var2;
 }
 
@@ -3188,7 +3190,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	saveAnimImageSetId();
 
 	_word2C8D2 = true;
-	_word2D0BE = 0;
+	_menuDepth = 0;
 
 	sub18E80(charId, windowId, menuId, curMenuLine);
 
@@ -3200,10 +3202,10 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 		do {
 			Common::KeyCode var19 = handleAndMapInput(false);
-			if (_word2D0BE == 0) {
+			if (_menuDepth == 0) {
 				switch (var19) {
 				case Common::KEYCODE_ESCAPE:
-					if (_word2D0BE == 0) { // ?? Useless case ?
+					if (_menuDepth == 0) { // ?? Useless case ?
 						windowId = 8;
 						var19 = Common::KEYCODE_RETURN;
 					}
@@ -3249,7 +3251,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					warning("handleStatusMenu - unhandled keys 0xBA, 0xBB, 0xBC");
 					break;
 				}
-			} else if (_word2D0BE == 1) {
+			} else if (_menuDepth == 1) {
 				if (var19 >= Common::KEYCODE_a && var19 <= Common::KEYCODE_z) {
 					int16 var8 = var19 - Common::KEYCODE_a;
 					if (var8 < _word2D0BA) {
@@ -3263,17 +3265,17 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			switch (var19) {
 			case Common::KEYCODE_RETURN:
 			// case 0xFA: Joystick button 1
-				if (_word2D0BE == 0) {
+				if (_menuDepth == 0) {
 					menuId = windowId;
 					if (menuId > 7)
 						var10 = -1;
 					else {
-						_word2D0BE = 1;
+						_menuDepth = 1;
 						curMenuLine = 0;
 					}
-				} else if (_word2D0BE == 1) {
+				} else if (_menuDepth == 1) {
 					if (_word2D0BA == 0) {
-						_word2D0BE = 0;
+						_menuDepth = 0;
 						curMenuLine = -1;
 						menuId = 9;
 						unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
@@ -3284,18 +3286,23 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				}
 				break;
 			case Common::KEYCODE_ESCAPE:
-				_word2D0BE = 0;
+				_menuDepth = 0;
 				curMenuLine = -1;
 				menuId = 9;
 				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 				break;
 			case Common::KEYCODE_2:
 			case Common::KEYCODE_6:
-			// case 0xCC, 0xCF
-				if (_word2D0BE == 0) {
-					if (++windowId == 8)
+			// Added for ScummVM
+			case Common::KEYCODE_DOWN:
+			case Common::KEYCODE_RIGHT:
+			case Common::KEYCODE_KP2:
+			case Common::KEYCODE_KP6:
+				// Original checks joystick axis: case 0xCC, 0xCF
+				if (_menuDepth == 0) {
+					if (++windowId > 8)
 						windowId = 0;
-				} else if (_word2D0BE == 1) {
+				} else if (_menuDepth == 1) {
 					if (_word2D0BA != 0) {
 						++curMenuLine;
 						if (curMenuLine > _word2D0BA - 1)
@@ -3305,11 +3312,16 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				break;
 			case Common::KEYCODE_4:
 			case Common::KEYCODE_8:
-			// case 0xC7, 0xCA
-				if (_word2D0BE == 0) {
+			// Added for ScummVM
+			case Common::KEYCODE_LEFT:
+			case Common::KEYCODE_UP:
+			case Common::KEYCODE_KP4:
+			case Common::KEYCODE_KP8:
+			// Original checks joystick axis: case 0xC7, 0xCA
+				if (_menuDepth == 0) {
 					if (--windowId < 0)
 						windowId = 8;
-				} else if (_word2D0BE == 1) {
+				} else if (_menuDepth == 1) {
 					if (_word2D0BA != 0) {
 						--curMenuLine;
 						if (curMenuLine < 0)
@@ -3353,7 +3365,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					_word2C8D2 = false;
 					return -1;
 				} else {
-					int16 var8 = sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
+					sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
 				}
 			}
 			break;
@@ -3361,16 +3373,16 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _word3273A[var16];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 			} else if (hasObjectEquipped(charId, objectId)){
-				_guess_displayString_3("Item is Equipped!  Give anyway?", 0, charId, windowId, menuId, curMenuLine);
+				displayString_3("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				sub18E80(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
 					if (gameMode == 2) {
-						_guess_displayString_3("Not a Combat Option !", -1, charId, windowId, menuId, curMenuLine);
+						displayString_3("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
 					} else {
 						removeObject(charId, objectId);
 						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
@@ -3387,9 +3399,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _word3273A[var16];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 			} else if (hasObjectEquipped(charId, objectId)) {
-				_guess_displayString_3("Item is Equipped!  Trade anyway?", 0, charId, windowId, menuId, curMenuLine);
+				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				sub18E80(charId, windowId, menuId, curMenuLine);
@@ -3399,7 +3411,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					int16 var8;
 					do {
 						if (_teamCharId[2] != -1) {
-							var8 = _guess_displayString_3("Who will you give the item to?", 0, charId, windowId, menuId, curMenuLine);
+							var8 = displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
 							var2 = 0;
 						} else if (_teamCharId[1]) {
 							var8 = 0x1A;
@@ -3415,13 +3427,13 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						if (var8 != 0x1A && var8 != 0x1B) {
 							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
 							if (var6 == 0) {
-								_guess_displayString_3("That character cannot carry anymore!", 0, charId, windowId, menuId, curMenuLine);
-								Common::KeyCode var4 = getLastCharAfterAnimCount(_guessAnimationAmount);
+								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
+								getLastCharAfterAnimCount(_guessAnimationAmount);
 							}
 						} else {
 							if (var8 == 0x1A) {
-								_guess_displayString_3("No one to trade with!", 0, charId, windowId, menuId, curMenuLine);
-								Common::KeyCode var4 = getLastCharAfterAnimCount(_guessAnimationAmount);
+								displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
+								getLastCharAfterAnimCount(_guessAnimationAmount);
 								var8 = 0x1B;
 							}
 							var6 = 0;
@@ -3445,9 +3457,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _word3273A[var16];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				_guess_displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", -1, charId, windowId, menuId, curMenuLine);
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 			} else if (hasObjectEquipped(charId, objectId)) {
-				_guess_displayString_3("Item Is Equipped!  Drop Anyway?", 0, charId, windowId, menuId, curMenuLine);
+				displayString_3("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				sub18E80(charId, windowId, menuId, curMenuLine);
@@ -3471,7 +3483,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		case 5:
 			objectId = _word3273A[var16];
 			if (gameMode == 2) {
-				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
@@ -3483,7 +3495,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		case 6: // Identical to case 5?
 			objectId = _word3273A[var16];
 			if (gameMode == 2) {
-				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
@@ -3495,7 +3507,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		case 7: // Identical to case 5?
 			objectId = _word3273A[var16];
 			if (gameMode == 2) {
-				_guess_displayString_3("Not a Combat Option!", 0xFFFF, charId, windowId, menuId, curMenuLine);
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
@@ -3508,7 +3520,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 		if (menuId != 8) {
 			var10 = 0;
-			_word2D0BE = 0;
+			_menuDepth = 0;
 			menuId = 9;
 			var16 = -1;
 			curMenuLine = -1;
@@ -3577,30 +3589,30 @@ bool EfhEngine::sub16E14() {
 
 				unkFct_displayMenuBox_2(0);
 				_textColor = 0xE;
-				displayCenteredString((char *)"Interaction", 24, 296, 152);
+				displayCenteredString("Interaction", 24, 296, 152);
 				displayCenteredString(buffer, 24, 296, 161);
 				setTextPos(24, 169);
 				setTextColorWhite();
-				displayStringAtTextPos((char *)"T");
+				displayStringAtTextPos("T");
 				setTextColorRed();
 				sprintf(buffer, "alk to the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(24, 178);
 				setTextColorWhite();
-				displayStringAtTextPos((char *)"A");
+				displayStringAtTextPos("A");
 				setTextColorRed();
 				sprintf(buffer, "ttack the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(198, 169);
 				setTextColorWhite();
-				displayStringAtTextPos((char *)"S");
+				displayStringAtTextPos("S");
 				setTextColorRed();
-				displayStringAtTextPos((char *)"tatus");
+				displayStringAtTextPos("tatus");
 				setTextPos(198, 178);
 				setTextColorWhite();
-				displayStringAtTextPos((char *)"L");
+				displayStringAtTextPos("L");
 				setTextColorRed();
-				displayStringAtTextPos((char *)"eave");
+				displayStringAtTextPos("eave");
 				if (var6C == 0)
 					displayFctFullScreen();
 			}
@@ -3933,7 +3945,7 @@ void EfhEngine::writeTechAndMapFiles() {
 	warning("STUB - writeTechAndMapFiles");
 }
 
-uint16 EfhEngine::getStringWidth(char *buffer) {
+uint16 EfhEngine::getStringWidth(const char *buffer) {
 	uint16 retVal = 0;
 
 	for (;;) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 39f9abc9936..48ba285bf47 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -287,7 +287,7 @@ private:
 	Common::KeyCode handleAndMapInput(bool animFl);
 	void displayNextAnimFrame();
 	void writeTechAndMapFiles();
-	uint16 getStringWidth(char *buffer);
+	uint16 getStringWidth(const char *buffer);
 	void setTextPos(int16 textPosX, int16 textPosY);
 
 	void sub15150(bool flag);
@@ -310,8 +310,8 @@ private:
 	Common::KeyCode getInput(int16 delay);
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
-	void drawString(char *str, int16 startX, int16 startY, uint16 unkFl);
-	void displayCenteredString(char *str, int16 minX, int16 maxX, int16 posY);
+	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
+	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	void drawMapWindow();
@@ -330,7 +330,7 @@ private:
 	void drawChar(uint8 curChar, int16 posX, int posY);
 	void setTextColorWhite();
 	void setTextColorRed();
-	void setTextColor_08h();
+	void setTextColorGrey();
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
 	void goNorth();
@@ -347,7 +347,7 @@ private:
 	void computeMapAnimation();
 	void unkFct_anim();
 	void setNextCharacterPos();
-	void displayStringAtTextPos(char *message);
+	void displayStringAtTextPos(const char *message);
 	void unkFct_displayMenuBox_2(int16 color);
 	int8 sub16B08(int16 monsterId);
 	bool moveMonsterAwayFromTeam(int16 monsterId);
@@ -377,7 +377,7 @@ private:
 	void unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 _guess_displayString_3(const char * str, int16 arg2, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayString_3(const char * str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 _objectId);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
@@ -481,7 +481,7 @@ private:
 	bool _word2C8D5; // CHECKME: always 0?
 	bool _word2D0BC;
 	bool _word2C8D2;
-	int16 _word2D0BE;
+	int16 _menuDepth;
 	int16 _word2D0BA;
 
 	int16 _word3273A[15];


Commit: bc88c24707e69ed789a13511566bf249eb548dbb
    https://github.com/scummvm/scummvm/commit/bc88c24707e69ed789a13511566bf249eb548dbb
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: More work on status menu

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 0547cbc14da..2a9f580e07d 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -344,4 +344,44 @@ const Encounter kEncounters[] {
 	{ "XXXXXXXXXXXXX", 0xFF, 0xFFFF, 0xFFFF, {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, 0, 0 }
 };
 
+const char kSkillArray[37][20] = {
+	"Flying",
+	"Swimming",
+	"Electrical",
+	"Mechanical",
+	"Hacking",
+	"Bluffing",
+	"Boatman",
+	"Pilot",
+	"Bureaucracy",
+	"Find Trap",
+	"Parachuting",
+	"Pick Lock",
+	"Explosives",
+	"Chemistry",
+	"Steal",
+	"Dueling",
+	"Marksmanship",
+	"Fist Fighting",
+	"Martial Arts",
+	"Acrobatics",
+	"Melee Weapon",
+	"Pistol Combat",
+	"Rifle Combat",
+	"Automatic/SMG",
+	"Archery",
+	"Rocket Lncher",
+	"Strength",
+	"Intelligence",
+	"Piety",
+	"Agility",
+	"Stamina",
+	"Stealth",
+	"Evasion",
+	"Comprehension",
+	"Perception",
+	"Psychic Force",
+	"Alignment"
+};
+
 } // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 7b49ecdfdf0..6ade27d0447 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -44,6 +44,7 @@ extern const uint8 kFontWidthArray[96];
 extern const uint8 kFontExtraLinesArray[96];
 extern const Font kFontData[96];
 extern const Encounter kEncounters[];
+extern const char kSkillArray[37][20];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e7f37939a78..6e77bcd0712 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -216,6 +216,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	for (int i = 0; i < 20; ++i) {
 		_portraitSubFilesArray[i] = nullptr;
 		_ennemyNamePt2[i] = 0;
+		_characterNamePt2[i] = 0;
 		_nameBuffer[i] = 0;
 	}
 
@@ -538,7 +539,6 @@ void EfhEngine::loadNewPortrait() {
 }
 
 void EfhEngine::loadAnimImageSet() {
-	warning("STUB - loadAnimImageSet");
 	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
 		return;
 
@@ -602,8 +602,8 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 	copyCurrentPlaceToBuffer(_fullPlaceId / 20);
 }
 
-void EfhEngine::drawUnknownMenuBox() {
-	warning("STUB - drawUnknownMenuBox");
+void EfhEngine::drawLeftCenterBox() {
+	drawColoredRect(16, 8, 111, 135, 0);
 }
 
 void EfhEngine::displayAnimFrame() {
@@ -640,7 +640,7 @@ void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
 		return;
 	
 	for (int i = 0; i < 2; ++i) {
-		drawUnknownMenuBox();
+		drawLeftCenterBox();
 		displayAnimFrame();
 
 		if (i == 0)
@@ -1065,7 +1065,7 @@ void EfhEngine::loadMapMonsters() {
 		_mapMonsters[i]._field_9 = _mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = _mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
-			_mapMonsters[i]._pictureRef[j] = READ_LE_UINT16(&_mapMonstersPtr[29 * i + 11 + j * 2]);
+			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&_mapMonstersPtr[29 * i + 11 + j * 2]);
 	}
 }
 
@@ -2855,9 +2855,196 @@ bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 	return false;
 }
 
-bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 arg4) {
-	warning("STUB - sub21820");
-	return false;
+void EfhEngine::displayMonsterAnim(int16 monsterId) {
+	int16 animId = kEncounters[_mapMonsters[monsterId]._MonsterRef]._animId;
+	displayAnimFrames(animId, true);
+}
+
+int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
+	int16 count = 0;
+	int16 monsterId;
+
+	if (teamMemberFl)
+		monsterId = _teamMonsterIdArray[id];
+	else
+		monsterId = id;
+
+	for (int16 counter = 0; counter < 9; ++counter) {
+		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
+			++count;
+	}
+
+	return count;
+}
+
+bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
+	if (computeMonsterGroupDistance(monsterId) > 1)
+		return false;
+
+	return true;
+}
+
+bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
+	char buffer[80];
+	memset(buffer, 0, 80);
+
+	int8 var51 = _mapMonsters[monsterId]._possessivePronounSHL6;
+	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+		return false;
+
+	if (countPictureRef(monsterId, false) < 1)
+		return false;
+
+	if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+		return false;
+
+	if (!checkMonsterGroupDistance1OrLess(monsterId))
+		return false;
+
+	if (var51 != 0x3F) {
+		if (_mapMonsters[monsterId]._field_9 == 0xFF || arg2 != 5) {
+			return false;
+		}
+		displayMonsterAnim(monsterId);
+		sub22AA8(_mapMonsters[monsterId]._field_9);
+		displayAnimFrames(0xFE, true);
+		return true;
+	}
+
+	if (isCharacterATeamMember(_mapMonsters[monsterId]._field_1))
+		return false;
+
+	int16 var58 = isCharacterATeamMember(_mapMonsters[monsterId]._field_1);
+	switch (_npcBuf[var58].field_10 - 0xEE) {
+	case 0:
+		if (arg2 == 4 && _npcBuf[var58].field_11 == itemId) {
+			displayMonsterAnim(monsterId);
+			sub22AA8(_npcBuf[var58].field_14);
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+		break;
+	case 1:
+		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
+			displayMonsterAnim(monsterId);
+			sub22AA8(_npcBuf[var58].field_14);
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+		break;
+	case 2:
+		if (arg2 == 1 && _npcBuf[var58].field_11 == itemId) {
+			displayMonsterAnim(monsterId);
+			sub22AA8(_npcBuf[var58].field_14);
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+		break;
+	case 3:
+		if (_history[_npcBuf[var58].field_11] != 0) {
+			displayMonsterAnim(monsterId);
+			sub22AA8(_npcBuf[var58].field_14);
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+		break;
+	case 4:
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			for (int16 charId = 0; charId < 10; ++charId) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
+					removeObject(_teamCharId[counter], charId);
+					displayMonsterAnim(monsterId);
+					sub22AA8(_npcBuf[var58].field_14);
+					displayAnimFrames(0xFE, true);
+					return true;
+				}
+			}
+		}
+		break;
+	case 5:
+		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
+			displayMonsterAnim(monsterId);
+			sub22AA8(_npcBuf[var58].field_14);
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+		break;
+	case 6:
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			for (int16 charId = 0; charId < 10; ++charId) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
+					displayMonsterAnim(monsterId);
+					sub22AA8(_npcBuf[var58].field_14);
+					displayAnimFrames(0xFE, true);
+					return true;
+				}
+			}
+		}
+		break;
+	case 7:
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+				removeCharacterFromTeam(counter);
+				displayMonsterAnim(monsterId);
+				sub22AA8(_npcBuf[var58].field_14);
+				displayAnimFrames(0xFE, true);
+				return true;
+			}
+		}
+		break;
+	case 8:
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+				displayMonsterAnim(monsterId);
+				copyString(_npcBuf[var58]._name, _ennemyNamePt2);
+				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
+				sprintf(buffer, "%s asks that %s leave your party.", _ennemyNamePt2, _characterNamePt2);
+				for (int16 i = 0; i < 2; ++i) {
+					unkFct_displayMenuBox_2(0);
+					_textColor = 0xE;
+					displayCenteredString(buffer, 24, 296, 161);
+					setTextPos(24, 169);
+					displayStringAtTextPos("Will you do this?");
+					if (i == 0)
+						displayFctFullScreen();
+				}
+				setTextColorRed();
+				Common::KeyCode input = mapInputCode(waitForKey());
+				if (input == Common::KEYCODE_y) {
+					removeCharacterFromTeam(counter);
+					sub22AA8(_npcBuf[var58].field_14);
+				}
+				displayAnimFrames(0xFE, true);
+				return true;
+			}
+		}
+		break;
+	case 9:
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+				displayMonsterAnim(monsterId);
+				sub22AA8(_npcBuf[var58].field_14);
+				displayAnimFrames(0xFE, true);
+				return true;
+			}
+		}
+		break;
+	case 16:
+		displayMonsterAnim(monsterId);
+		sub22AA8(_npcBuf[var58].field_14);
+		displayAnimFrames(0xFE, true);
+		return true;
+	default:
+		break;
+	}
+
+	if (_npcBuf[var58].field_12 == 0x7FFF || arg2 != 5)
+		return false;
+
+	displayMonsterAnim(monsterId);
+	sub22AA8(_npcBuf[var58].field_12);
+	displayAnimFrames(0xFE, true);
+	return true;
 }
 
 void EfhEngine::sub221D2(int16 monsterId) {
@@ -2867,11 +3054,11 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
-void EfhEngine::sub22AA8(uint16 arg0) {
-	warning("STUB - sub22AA8");
+void EfhEngine::sub22AA8(int16 arg0) {
+	warning("STUB: sub22AA8");
 }
 
-bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, int16 arg8, int16 imageSetId) {
+bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
 	int16 var8 = sub151FD(mapPosX, mapPosY);
 
 	if (var8 == -1) {
@@ -2921,7 +3108,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, i
 		if ((_mapUnknownPtr[var8 * 9 + 3] == 0xFA && arg8 == 1)
 		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFC && arg8 == 2)
 		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFB && arg8 == 3)) {
-			if (_mapUnknownPtr[var8 * 9 + 4] == arg6) {
+			if (_mapUnknownPtr[var8 * 9 + 4] == itemId) {
 				sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
 				return true;
 			}
@@ -2929,7 +3116,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, i
 			int16 var6 = _mapUnknownPtr[var8 * 9 + 3];
 			if (var6 >= 0x7B && var6 <= 0xEF) {
 				var6 -= 0x78;
-				if (var6 >= 0 && var6 <= 0x8B && var6 == arg6 && _mapUnknownPtr[var8 * 9 + 4] <= _npcBuf[arg4]._activeScore[arg6]) {
+				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknownPtr[var8 * 9 + 4] <= _npcBuf[charId]._activeScore[itemId]) {
 					sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
 					return true;
 				}
@@ -2938,7 +3125,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, i
 	}
 
 	for (int16 counter = 0; counter < 64; ++counter) {
-		if (!sub21820(counter, arg8, arg6))
+		if (!sub21820(counter, arg8, itemId))
 			return true;
 	}
 
@@ -3035,15 +3222,92 @@ void EfhEngine::displayStatusMenu(int16 windowId) {
 }
 
 void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
-	warning("STUB: countRightWindowItems");
+	int16 var2 = 0;
+	int16 var4 = 0;
+	_word2D0BA = 0;
+
+	switch (menuId) {
+	case 0:
+	case 1:
+	case 2:
+	case 3:
+	case 4:
+	case 9:
+		var4 = -1;
+		break;
+	case 5:
+		var4 = 26;
+		var2 = 36;
+		break;
+	case 6:
+		var4 = 15;
+		var2 = 25;
+		break;
+	case 7:
+		var4 = 0;
+		var2 = 14;
+		break;
+	default: // Case 8 + Default
+		var4 = -1;
+		_word2D0BA = 0;
+		break;
+	}
+
+	if (var4 == -1) {
+		for (int16 counter = 0; counter < 10; ++counter) {
+			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
+				_word3273A[_word2D0BA++] = counter;
+			}
+		}
+	} else {
+		for (int16 counter = var4; counter < var2; ++counter) {
+			if (_npcBuf[charId]._activeScore[counter] != 0) {
+				_word3273A[_word2D0BA++] = counter;
+			}
+		}
+	}
 }
 
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	warning("STUB: displayCharacterSummary");
 }
 
-void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId) {
-	warning("STUB: displayCharacterInformationOrSkills");
+void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
+	char buffer[40];
+	memset(buffer, 0, 40);
+
+	setTextColorRed();
+	copyString(_npcBuf[charId]._name, buffer);
+	setTextPos(146, 27);
+	displayStringAtTextPos("Name: ");
+	displayStringAtTextPos(buffer);
+	if (_word2D0BA <= 0) {
+		if (curMenuLine != -1)
+			setTextColorWhite();
+		displayCenteredString("No Skills To Select", 144, 310, 96);
+		setTextColorRed();
+		return;
+	}
+
+	for (int16 counter = 0; counter < _word2D0BA; ++counter) {
+		if (counter == curMenuLine)
+			setTextColorWhite();
+		int16 textPosY = 38 + counter * 9;
+		setTextPos(146, textPosY);
+		if (counter == curMenuLine) {
+			sprintf(buffer, "%c>", 'A' + counter);
+		} else {
+			sprintf(buffer, "%c)", 'A' + counter);
+		}
+
+		displayStringAtTextPos(buffer);
+		setTextPos(163, textPosY);
+		displayStringAtTextPos(kSkillArray[_word3273A[counter]]);
+		sprintf(buffer, "%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
+		setTextPos(278, textPosY);
+		displayStringAtTextPos(buffer);
+		setTextColorRed();
+	}
 }
 
 void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
@@ -3488,7 +3752,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
 					_word2C8D2 = false;
-					return 0xFFFF;
+					return -1;
 				}
 			}
 			break;
@@ -3500,7 +3764,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
 					_word2C8D2 = false;
-					return 0xFFFF;
+					return -1;
 				}
 			}
 			break;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 48ba285bf47..9edd47afd37 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -199,7 +199,7 @@ struct MapMonster {
 	uint8 _field_8;
 	uint8 _field_9;
 	uint8 _groupSize;
-	uint16 _pictureRef[9];
+	int16 _pictureRef[9];
 };
 
 class EfhEngine : public Engine {
@@ -250,7 +250,7 @@ private:
 	void loadHistory();
 	void loadTechMapImp(int16 fileId);
 	void loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl);
-	void drawUnknownMenuBox();
+	void drawLeftCenterBox();
 	void displayAnimFrame();
 	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
 	void readTileFact();
@@ -362,10 +362,13 @@ private:
 	bool checkMonsterWeaponRange(int16 monsterId);
 	void sub174A0();
 	bool checkPictureRefAvailability(int16 monsterId);
-	bool sub21820(int16 monsterId, int16 arg2, int16 arg4);
+	void displayMonsterAnim(int16 monsterId);
+	int16 countPictureRef(int16 id, bool teamMemberFl);
+	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
+	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
 	void sub221D2(int16 monsterId);
-	void sub22AA8(uint16 arg0);
-	bool sub22293(int16 mapPosX, int16 mapPosY, int16 arg4, int16 arg6, int16 arg8, int16 imageSetId);
+	void sub22AA8(int16 arg0);
+	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
@@ -414,6 +417,7 @@ private:
 	uint8 _history[256];
 	uint8 _techData[4096];
 	char _ennemyNamePt2[20];
+	char _characterNamePt2[20];
 	char _nameBuffer[20];
 	uint8 _messageToBePrinted[400];
 	


Commit: a3cbeb5857aab23d7e8e6dde6e8af1bcb9429090
    https://github.com/scummvm/scummvm/commit/a3cbeb5857aab23d7e8e6dde6e8af1bcb9429090
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement displayCharacterSummary

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6e77bcd0712..0e51f7a0baa 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3268,8 +3268,132 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 	}
 }
 
+int16 EfhEngine::getXPLevel(int32 xp) {
+	int16 level = 0;
+	int16 var6 = 1500;
+
+	int32 wrkXp = xp;
+
+	while (wrkXp > 0) {
+		wrkXp -= var6;
+		if (wrkXp >= 0)
+			++level;
+
+		var6 += 1500;
+		if (var6 > 15000)
+			var6 = 15000;
+	}
+
+	return level;
+}
+
+void EfhEngine::displayChar(char character) {
+	char buffer[2];
+	buffer[0] = character;
+	buffer[1] = 0;
+
+	drawString(buffer, _textPosX, _textPosY, _textColor);
+	_textPosX += getStringWidth(buffer) + 1;
+	setNextCharacterPos();
+}
+
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
-	warning("STUB: displayCharacterSummary");
+	char buffer1[40];
+	char buffer2[40];
+	memset(buffer1, 0, 40);
+	memset(buffer2, 0, 40);
+	
+	setTextColorRed();
+	copyString(_npcBuf[npcId]._name, buffer1);
+	setTextPos(146, 27);
+	displayStringAtTextPos("Name: ");
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "Level: %d", getXPLevel(_npcBuf[npcId]._xp));
+	setTextPos(146, 36);
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "XP: %lu", _npcBuf[npcId]._xp);
+	setTextPos(227, 36);
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "Speed: %d", _npcBuf[npcId]._speed);
+	setTextPos(146, 45);
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "Defense: %d", getEquipmentDefense(npcId, false));
+	setTextPos(146, 54);
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "Hit Points: %d", _npcBuf[npcId]._hitPoints);
+	setTextPos(146, 63);
+	displayStringAtTextPos(buffer1);
+	sprintf(buffer1, "Max HP: %d", _npcBuf[npcId]._maxHP);
+	setTextPos(227, 63);
+	displayStringAtTextPos(buffer1);
+	displayCenteredString("Inventory", 144, 310, 72);
+
+	if (_word2D0BA == 0) {
+		if (curMenuLine != -1)
+			setTextColorWhite();
+
+		displayCenteredString("Nothing Carried", 144, 310, 117);
+		setTextColorRed();
+		return;
+	}
+
+	for (int16 counter = 0; counter < _word2D0BA; ++counter) {
+		if (_menuDepth == 0)
+			setTextColorGrey();
+		else {
+			if (counter == curMenuLine)
+				setTextColorWhite();
+		}
+		int16 textPosY = 81 + counter * 9;
+		int16 itemId = _npcBuf[npcId]._inventory[_word3273A[counter]]._ref;
+		if (itemId != 0x7FFF) {
+			if (_npcBuf[npcId]._inventory[_word3273A[counter]]._stat1 & 0x80) {
+				setTextPos(146, textPosY);
+				displayChar('E');
+			}
+		}
+
+		setTextPos(152, textPosY);
+		if (counter == curMenuLine) {
+			sprintf(buffer1, "%c>", 'A' + counter);
+		} else {
+			sprintf(buffer1, "%c)", 'A' + counter);
+		}
+		displayStringAtTextPos(buffer1);
+
+		if (itemId != 0x7FFF) {
+			setTextPos(168, textPosY);
+			copyString(_items[itemId]._name, buffer2);
+			sprintf(buffer1, "  %s", buffer2);
+			displayStringAtTextPos(buffer1);
+			setTextPos(262, textPosY);
+
+			if (_items[itemId]._defense > 0) {
+				int16 var54 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat2;
+				if (var54 == 0xFF) {
+					// useless?
+					var54 = _items[_npcBuf[npcId]._inventory[_word3273A[counter]]._ref]._defense;
+				} else {
+					sprintf(buffer1, "%d", 1 + var54 / 8);
+					displayStringAtTextPos(buffer1);
+					setTextPos(286, textPosY);
+					displayStringAtTextPos("Def");
+				}
+			} else if (_items[itemId]._uses != 0x7F) {
+				int16 var52 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat1;
+				if (var52 != 0x7F) {
+					sprintf(buffer1, "%d", var52);
+					displayStringAtTextPos(buffer1);
+					setTextPos(286, textPosY);
+					if (var52 == 1)
+						displayStringAtTextPos("Use");
+					else
+						displayStringAtTextPos("Uses");
+				}
+			}
+		}
+		setTextColorRed();
+	}
 }
 
 void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
@@ -3425,8 +3549,33 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 _objectId) {
 	return true;
 }
 
+void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+
+	if (isItemCursed(itemId)) {
+		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
+	} else {
+		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
+	}
+	
+}
+
 void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	warning("STUB: sub191FF");
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+
+	if (hasObjectEquipped(charId, objectId)) {
+		equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+	} else {
+		int16 var2 = _items[itemId].field_18;
+		if (var2 != 4) {
+			for (int16 counter = 0; counter < 10; ++counter) {
+				if (var2 != _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
+					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+			}
+		}
+
+		_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
+	}
 }
 
 int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
@@ -3512,7 +3661,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					break;
 				// case 0xFB: Joystick button 2
 				default:
-					warning("handleStatusMenu - unhandled keys 0xBA, 0xBB, 0xBC");
+				//	warning("handleStatusMenu - unhandled keys (or joystick event?) 0xBA, 0xBB, 0xBC");
 					break;
 				}
 			} else if (_menuDepth == 1) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 9edd47afd37..7fbe5ef54db 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -374,6 +374,8 @@ private:
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
 	void displayStatusMenu(int16 windowId);
 	void countRightWindowItems(int16 menuId, int16 charId);
+	int16 getXPLevel(int32 xp);
+	void displayChar(char character);
 	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
 	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
@@ -383,6 +385,7 @@ private:
 	int16 displayString_3(const char * str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 _objectId);
+	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 	bool getValidationFromUser();


Commit: 902b1398ce0a527dcc28695f276a18ac6e13fda2
    https://github.com/scummvm/scummvm/commit/902b1398ce0a527dcc28695f276a18ac6e13fda2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement some stubs

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 2a9f580e07d..0e94b67c90f 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -384,4 +384,13 @@ const char kSkillArray[37][20] = {
 	"Alignment"
 };
 
+const uint8 kByte2C7D0[60] = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 2, 0, 2, 2, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 1, 0, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
 } // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 6ade27d0447..4112f4ee424 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -45,6 +45,7 @@ extern const uint8 kFontExtraLinesArray[96];
 extern const Font kFontData[96];
 extern const Encounter kEncounters[];
 extern const char kSkillArray[37][20];
+extern const uint8 kByte2C7D0[60];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0e51f7a0baa..aa94a0ea44c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1446,7 +1446,22 @@ int16 EfhEngine::getRandom(int16 maxVal) {
 }
 
 void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
-	warning("STUB - removeCharacterFromTeam");
+	int16 charId = _teamCharId[teamMemberId];
+	_npcBuf[charId].field_12 = _npcBuf[charId].field_B;
+	_npcBuf[charId].field_14 = _npcBuf[charId].field_E;
+	_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
+	_npcBuf[charId].field_11 = _npcBuf[charId].field_D;
+
+	_teamCharId[teamMemberId] = -1;
+	_teamCharStatus[teamMemberId]._status = 0;
+	_teamCharStatus[teamMemberId]._duration = 0;
+
+	for (int16 var4 = teamMemberId; var4 < 2; ++var4) {
+		_teamCharId[var4] = _teamCharId[var4 + 1];
+		_teamCharId[var4 + 1] = -1;
+	}
+
+	refreshTeamSize();
 }
 
 void EfhEngine::emptyFunction(int i) {
@@ -1560,7 +1575,22 @@ void EfhEngine::handleWinSequence() {
 }
 
 bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
-	warning("STUB - giveItemTo");
+	for (int16 newObjectId = 0; newObjectId < 10; ++newObjectId) {
+		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
+			continue;
+
+		if (altCharId == 0xFF) {
+			_npcBuf[charId]._inventory[newObjectId]._ref = objectId;
+			_npcBuf[charId]._inventory[newObjectId]._stat2 = _items[objectId]._defense;
+			_npcBuf[charId]._inventory[newObjectId]._stat1 = _items[objectId]._uses;
+		} else {
+			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[altCharId]._inventory[newObjectId]._ref;
+			_npcBuf[charId]._inventory[newObjectId]._stat2 = _npcBuf[altCharId]._inventory[newObjectId]._stat2;
+			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[altCharId]._inventory[newObjectId]._stat1 & 0x7F;
+		}
+
+		return true;
+	}
 
 	return false;
 }
@@ -1990,7 +2020,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219("Nothing...", 1, 2, 0xFFFF);
+					var110 = sub1C219((char *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
 					copyString(_npcBuf[_teamCharId[counter]]._name, _ennemyNamePt2);
@@ -1999,7 +2029,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219(dest, 1, 2, 0xFFFF);
+					var110 = sub1C219(dest, 1, 2, true);
 					displayFctFullScreen();
 				}
 
@@ -2161,17 +2191,106 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 	warning("STUB: sub15A28");
 }
 
-void EfhEngine::sub2455E(int16 arg0, int16 arg1, int16 arg2) {
-	warning("STUB: sub2455E");
+void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
+	warning("TODO: sub2455E - check behavior");
+	uint8 varD = kByte2C7D0[arg0];
+	int16 varC = arg2 - 11;
+	int16 varA = arg4 - 11;
+
+	if (varC < 0)
+		varC = 0;
+
+	if (varA < 0)
+		varA = 0;
+
+	int16 var8 = varC + 23;
+	int16 var6 = varA + 23;
+
+	for (int16 var4 = varC; var4 <= var8; ++var4) {
+		for (int16 var2 = varA; var2 <= var6; ++var2) {
+			_techData[var2 + var4 * 64] = varD;
+		}
+	}
 }
 
-int16 EfhEngine::sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl) {
-	warning("STUB: sub1C219");
-	return -1;
+int16 EfhEngine::sub1C219(char *str, int menuType, int arg4, bool displayTeamWindowFl) {
+	int16 varA = 0xFF;
+	int16 minX, maxX, minY, maxY;
+	
+	switch (menuType) {
+	case 0:
+		minX = 129;
+		minY = 9;
+		maxX = 302;
+		maxY = 18;
+		break;
+	case 1:
+		minX = 129;
+		minY = 9;
+		maxX = 302;
+		maxY = 110;
+		break;
+	case 2:
+		minX = 129;
+		minY = 112;
+		maxX = 302;
+		maxY = 132;
+		break;
+	case 3:
+		minX = 129;
+		minY = 79;
+		maxX = 303;
+		maxY = 107;
+		break;
+	default:
+		minX = minY = 0;
+		maxX = 320;
+		maxY = 200;
+		break;
+	}
+
+	drawColoredRect(minX, maxX, minY, maxY, 0);
+	if (str)
+		varA = script_parse((uint8 *)str, minX, minY, maxX, maxY, -1);
+
+	if (displayTeamWindowFl)
+		displayLowStatusScreen(false);
+
+	if (arg4 != 0) {
+		displayFctFullScreen();
+		if (_word2C87A != 0)
+			_word2C87A = 0;
+		else {
+			drawColoredRect(minX, maxX, minY, maxY, 0);
+			if (str)
+				int16 varC = script_parse((uint8 *)str, minX, minY, maxX, maxY, -1);
+		}
+
+		if (displayTeamWindowFl)
+			displayLowStatusScreen(false);
+
+		if (arg4 >= 2)
+			int16 varC = getLastCharAfterAnimCount(_guessAnimationAmount);
+
+		if (arg4 == 3)
+			drawColoredRect(minX, maxX, minY, maxY, 0);
+	}
+
+	return varA;
 }
 
 int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
-	warning("STUB: sub151FD");
+	if (_largeMapFlag) {
+		for (int16 counter = 0; counter < 100; ++counter) {
+			if (_mapUnknownPtr[counter * 9 + 1] == posX && _mapUnknownPtr[counter * 9 + 2] == posY && _mapUnknownPtr[counter * 9] == 0xFE)
+				return counter;
+		}
+	} else {
+		for (int16 counter = 0; counter < 100; ++counter) {
+			if (_mapUnknownPtr[counter * 9 + 1] == posX && _mapUnknownPtr[counter * 9 + 2] == posY && _mapUnknownPtr[counter * 9] == _fullPlaceId)
+				return counter;
+		}
+	}
 	return -1;
 }
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 7fbe5ef54db..3e07c01af27 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -325,7 +325,7 @@ private:
 	void drawBottomBorders();
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(const char *str, int menuType, int arg4, int displayTeamWindowFl);
+	int16 sub1C219(char *str, int menuType, int arg4, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	void drawChar(uint8 curChar, int16 posX, int posY);
 	void setTextColorWhite();


Commit: 6357fd7b6664fc0b4b476f7ec30fc332883536ed
    https://github.com/scummvm/scummvm/commit/6357fd7b6664fc0b4b476f7ec30fc332883536ed
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement sub22AA8, refactor _mapUnknownPtr

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index aa94a0ea44c..3c15a5070d2 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -65,6 +65,11 @@ void InvObject::init() {
 	_stat2 = 0;
 }
 
+void UnkMapStruct::init() {
+	_field0 = _field1 = _field2 = _field3 = _field4 = 0;
+	_field5 = _field7 = 0;
+}
+
 void UnkAnimStruct::init() {
 	field0 = field1 = field2 = field3 = 0;
 }
@@ -178,8 +183,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
 	_mapBitmapRef = nullptr;
-	_mapUnknownPtr = nullptr;
-	_mapMonstersPtr = nullptr;
 	_mapGameMapPtr = nullptr;
 
 	_defaultBoxColor = 0;
@@ -220,8 +223,10 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_nameBuffer[i] = 0;
 	}
 
-	for (int i = 0; i < 100; ++i)
+	for (int i = 0; i < 100; ++i) {
 		_imp1PtrArray[i] = nullptr;
+		_mapUnknown[i].init();
+	}
 
 	for (int i = 0; i < 432; ++i)
 		_imp2PtrArray[i] = nullptr;
@@ -928,7 +933,6 @@ void EfhEngine::initEngine() {
 	memset(_techData, 0, sizeof(_techData));
 
 	_mapBitmapRef = &_map[0];
-	_mapUnknownPtr = &_map[2];
 
 	// Replaces _mapMonstersPtr which was equal to &_map[902];
 	for (int i = 0; i < 64; ++i) {
@@ -1050,22 +1054,34 @@ void EfhEngine::initMapMonsters() {
 }
 
 void EfhEngine::loadMapMonsters() {
-	_mapMonstersPtr = &_map[902];
+	uint8 *_mapUnknownPtr = &_map[2];
+
+	for (int i = 0; i < 100; ++i) {
+		_mapUnknown[i]._field0 = _mapUnknownPtr[9 * i];
+		_mapUnknown[i]._field1 = _mapUnknownPtr[9 * i + 1];
+		_mapUnknown[i]._field2 = _mapUnknownPtr[9 * i + 2];
+		_mapUnknown[i]._field3 = _mapUnknownPtr[9 * i + 3];
+		_mapUnknown[i]._field4 = _mapUnknownPtr[9 * i + 4];
+		_mapUnknown[i]._field5 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
+		_mapUnknown[i]._field7 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
+	}
+	
+	uint8 *mapMonstersPtr = &_map[902];
 
 	for (int i = 0; i < 64; ++i) {
-		_mapMonsters[i]._possessivePronounSHL6 = _mapMonstersPtr[29 * i];
-		_mapMonsters[i]._field_1 = _mapMonstersPtr[29 * i + 1];
-		_mapMonsters[i]._guess_fullPlaceId = _mapMonstersPtr[29 * i + 2];
-		_mapMonsters[i]._posX = _mapMonstersPtr[29 * i + 3];
-		_mapMonsters[i]._posY = _mapMonstersPtr[29 * i + 4];
-		_mapMonsters[i]._itemId_Weapon = _mapMonstersPtr[29 * i + 5];
-		_mapMonsters[i]._field_6 = _mapMonstersPtr[29 * i + 6];
-		_mapMonsters[i]._MonsterRef = _mapMonstersPtr[29 * i + 7];
-		_mapMonsters[i]._field_8 = _mapMonstersPtr[29 * i + 8];
-		_mapMonsters[i]._field_9 = _mapMonstersPtr[29 * i + 9];
-		_mapMonsters[i]._groupSize = _mapMonstersPtr[29 * i + 10];
+		_mapMonsters[i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
+		_mapMonsters[i]._field_1 = mapMonstersPtr[29 * i + 1];
+		_mapMonsters[i]._guess_fullPlaceId = mapMonstersPtr[29 * i + 2];
+		_mapMonsters[i]._posX = mapMonstersPtr[29 * i + 3];
+		_mapMonsters[i]._posY = mapMonstersPtr[29 * i + 4];
+		_mapMonsters[i]._itemId_Weapon = mapMonstersPtr[29 * i + 5];
+		_mapMonsters[i]._field_6 = mapMonstersPtr[29 * i + 6];
+		_mapMonsters[i]._MonsterRef = mapMonstersPtr[29 * i + 7];
+		_mapMonsters[i]._field_8 = mapMonstersPtr[29 * i + 8];
+		_mapMonsters[i]._field_9 = mapMonstersPtr[29 * i + 9];
+		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
-			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&_mapMonstersPtr[29 * i + 11 + j * 2]);
+			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
 	}
 }
 
@@ -1949,7 +1965,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			if (argC != 0) {
 				int16 var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1)
-					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+					_mapUnknown[var110]._field1 = 0xFF;
 			}
 			break;
 		case 0x13:
@@ -2020,7 +2036,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219((char *)"Nothing...", 1, 2, true);
+					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
 					copyString(_npcBuf[_teamCharId[counter]]._name, _ennemyNamePt2);
@@ -2029,13 +2045,13 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219(dest, 1, 2, true);
+					var110 = sub1C219((uint8 *)dest, 1, 2, true);
 					displayFctFullScreen();
 				}
 
 				var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1) {
-					_mapUnknownPtr[var110 * 9 + 1] = 0xFF;
+					_mapUnknown[var110]._field1 = 0xFF;
 				}
 				_redrawNeededFl = true;
 			}
@@ -2055,7 +2071,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			if (argC != 0) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
-					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+					_mapUnknown[var110]._field1 = 0xFF;
 				}
 			}
 			break;
@@ -2064,10 +2080,10 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			if (argC != 0) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
-					_mapUnknownPtr[9 * var110 + 1] = 0xFF;
+					_mapUnknown[var110]._field1 = 0xFF;
 				}
-				_mapUnknownPtr[9 * scriptNumberArray[2] + 1] = scriptNumberArray[0];
-				_mapUnknownPtr[9 * scriptNumberArray[2] + 2] = scriptNumberArray[1];
+				_mapUnknown[scriptNumberArray[2]]._field1 = scriptNumberArray[0];
+				_mapUnknown[scriptNumberArray[2]]._field2 = scriptNumberArray[1];
 			}
 			break;
 		case 0x1C:
@@ -2213,7 +2229,7 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub1C219(char *str, int menuType, int arg4, bool displayTeamWindowFl) {
+int16 EfhEngine::sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWindowFl) {
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;
 	
@@ -2251,7 +2267,7 @@ int16 EfhEngine::sub1C219(char *str, int menuType, int arg4, bool displayTeamWin
 
 	drawColoredRect(minX, maxX, minY, maxY, 0);
 	if (str)
-		varA = script_parse((uint8 *)str, minX, minY, maxX, maxY, -1);
+		varA = script_parse(str, minX, minY, maxX, maxY, -1);
 
 	if (displayTeamWindowFl)
 		displayLowStatusScreen(false);
@@ -2263,7 +2279,7 @@ int16 EfhEngine::sub1C219(char *str, int menuType, int arg4, bool displayTeamWin
 		else {
 			drawColoredRect(minX, maxX, minY, maxY, 0);
 			if (str)
-				int16 varC = script_parse((uint8 *)str, minX, minY, maxX, maxY, -1);
+				int16 varC = script_parse(str, minX, minY, maxX, maxY, -1);
 		}
 
 		if (displayTeamWindowFl)
@@ -2282,12 +2298,12 @@ int16 EfhEngine::sub1C219(char *str, int menuType, int arg4, bool displayTeamWin
 int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	if (_largeMapFlag) {
 		for (int16 counter = 0; counter < 100; ++counter) {
-			if (_mapUnknownPtr[counter * 9 + 1] == posX && _mapUnknownPtr[counter * 9 + 2] == posY && _mapUnknownPtr[counter * 9] == 0xFE)
+			if (_mapUnknown[counter]._field1 == posX && _mapUnknown[counter]._field2 == posY && _mapUnknown[counter]._field0 == 0xFE)
 				return counter;
 		}
 	} else {
 		for (int16 counter = 0; counter < 100; ++counter) {
-			if (_mapUnknownPtr[counter * 9 + 1] == posX && _mapUnknownPtr[counter * 9 + 2] == posY && _mapUnknownPtr[counter * 9] == _fullPlaceId)
+			if (_mapUnknown[counter]._field1 == posX && _mapUnknown[counter]._field2 == posY && _mapUnknown[counter]._field0 == _fullPlaceId)
 				return counter;
 		}
 	}
@@ -3173,8 +3189,130 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
+Common::KeyCode EfhEngine::getInputBlocking() {
+	// The original checks for the joystick input
+	Common::Event event;
+	_system->getEventManager()->pollEvent(event);
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (retVal == Common::KEYCODE_INVALID) {
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = event.kbd.keycode;
+		}
+
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 220) {
+			lastMs = newMs;
+			unkFct_anim();
+		}
+	}
+	return retVal;
+}
+
 void EfhEngine::sub22AA8(int16 arg0) {
-	warning("STUB: sub22AA8");
+	int16 var8, varA, varC, varE;
+	var8 = varA = varC = varE = 0;
+
+	if (arg0 <= 0xFE) {
+		if (_dword2C856) {
+			_dword2C856 = nullptr;
+			sub221FA(_dword2C856, true);
+		}
+		if (_word2C8D2)
+			sub15150(true);
+
+		int16 var4 = arg0;
+
+		for (;;) {
+			uint8 *var12 = nullptr;
+			if (var4 >= 0 && var4 <= 0xFE) {
+				var12 = _imp1PtrArray[var4];
+			}
+
+			var4 = 0xFF;
+			if (var12 == nullptr)
+				break;
+
+			do {
+				if (varE == 0)
+					memset(_messageToBePrinted, 0, 400);
+				switch (*var12) {
+				case 0x00:
+				case 0x0A:					
+					break;
+				case 0x0D:
+				case 0x20:
+					_messageToBePrinted[varE++] = 0x20;
+					if (++varC >= 350) {
+						_messageToBePrinted[varE] = 0;
+						var8 = -1;
+					}
+					break;
+				case 0x40:
+				case 0x60:
+					varA = -1;
+					break;
+				case 0x7C:
+					_messageToBePrinted[varE++] = 0x7C;
+					varC += 20;
+					if (varC >= 350) {
+						_messageToBePrinted[varE] = 0;
+						var8 = -1;
+					}
+					break;
+				case 0x7E:
+					var8 = -1;
+					break;
+				default:
+				break;
+				}
+				var12 += 1;
+				int16 var2;
+				if (var8 != 0 || varA != 0) {
+					var8 = 0;
+					_messageToBePrinted[varE] = 0;
+					varE = 0;
+					varC = 0;
+					if (*_messageToBePrinted == 0x5E || *_messageToBePrinted == 0) {
+						if (*_messageToBePrinted == 0x5E) {
+							var2 = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
+							_word2C87A = false;
+						}
+					} else {
+						for (int16 counter = 0; counter < 2; ++counter) {
+							drawMapWindow();
+							if (counter == 0)
+								displayFctFullScreen();
+						}
+
+						var2 = sub1C219(_messageToBePrinted, 1, 1, true);
+						if (var2 != 0xFF)
+							var4 = var2;
+						
+						if (var4 != 0xFFFF) {
+							for (int16 counter = 0; counter < 2; ++counter) {
+								if (varA) {
+									displayCenteredString("[DONE]", 128, 303, 117);
+								} else {
+									displayCenteredString("[MORE]", 128, 303, 117);
+								}
+								if (counter == 0)
+									displayFctFullScreen();
+							}
+							getInputBlocking();
+						}
+					}
+					if (var2 != 0xFF)
+						var4 = var2;
+				}
+			} while (var4 != -1 && var4 != 0xFF);
+		}
+	}
+
+	displayAnimFrames(0xFE, true);
 }
 
 bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
@@ -3184,59 +3322,57 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
 			sub221FA(_imp2PtrArray[imageSetId], true);
 	} else if (var8 == 0) {
-		if (_mapUnknownPtr[var8 * 9 + 3] == 0xFF) {
-			sub22AA8(_mapUnknownPtr[var8 * 9 + 5]); // word!
+		if (_mapUnknown[var8]._field3 == 0xFF) {
+			sub22AA8(_mapUnknown[var8]._field5); // word!
 			return true;
-		} else if (_mapUnknownPtr[var8 * 9 + 3] == 0xFE) {
+		} else if (_mapUnknown[var8]._field3 == 0xFE) {
 			for (int16 counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
-				if (_teamCharId[counter] == _mapUnknownPtr[var8 * 9 + 4]) {
-					sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+				if (_teamCharId[counter] == _mapUnknown[var8]._field4) {
+					sub22AA8(_mapUnknown[var8]._field5);
 					return true;
 				}
 			}
-		} else if (_mapUnknownPtr[var8 * 9 + 3] == 0xFD) {
+		} else if (_mapUnknown[var8]._field3 == 0xFD) {
 			for (int16 counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
 				for (int16 var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknownPtr[var8 * 9 + 4]) {
-						sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4) {
+						sub22AA8(_mapUnknown[var8]._field5);
 						return true;
 					}
 				}
 			}
 		// original makes a useless check on (_mapUnknownPtr[var8 * 9 + 3] > 0x7F)
-		} else if (_mapUnknownPtr[var8 * 9 + 3] <= 0x77) {
-			int16 var6 = _mapUnknownPtr[var8 * 9 + 3];
+		} else if (_mapUnknown[var8]._field3 <= 0x77) {
+			int16 var6 = _mapUnknown[var8]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
 				for (int16 var2 = 0; var2 < 39; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var2] >= _mapUnknownPtr[var8 * 9 + 4]) {
-						sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var2] >= _mapUnknown[var8]._field4) {
+						sub22AA8(_mapUnknown[var8]._field5);
 						return true;
 					}
 				}
 			}
 		}
 	} else {
-		if ((_mapUnknownPtr[var8 * 9 + 3] == 0xFA && arg8 == 1)
-		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFC && arg8 == 2)
-		||  (_mapUnknownPtr[var8 * 9 + 3] == 0xFB && arg8 == 3)) {
-			if (_mapUnknownPtr[var8 * 9 + 4] == itemId) {
-				sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+		if ((_mapUnknown[var8]._field3 == 0xFA && arg8 == 1) || (_mapUnknown[var8]._field3 == 0xFC && arg8 == 2) || (_mapUnknown[var8]._field3 == 0xFB && arg8 == 3)) {
+			if (_mapUnknown[var8]._field4 == itemId) {
+				sub22AA8(_mapUnknown[var8]._field5);
 				return true;
 			}
 		} else if (arg8 == 4) {
-			int16 var6 = _mapUnknownPtr[var8 * 9 + 3];
+			int16 var6 = _mapUnknown[var8]._field3;
 			if (var6 >= 0x7B && var6 <= 0xEF) {
 				var6 -= 0x78;
-				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknownPtr[var8 * 9 + 4] <= _npcBuf[charId]._activeScore[itemId]) {
-					sub22AA8(_mapUnknownPtr[var8 * 9 + 5]);
+				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknown[var8]._field4 <= _npcBuf[charId]._activeScore[itemId]) {
+					sub22AA8(_mapUnknown[var8]._field5);
 					return true;
 				}
 			}		
@@ -3248,13 +3384,12 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			return true;
 	}
 
-	if ((arg8 == 4 && _mapUnknownPtr[var8 * 9 + 3] < 0xFA) || arg8 != 4) {
-		if (_mapUnknownPtr[var8 * 9 + 7] > 0xFE) // word!!
+	if ((arg8 == 4 && _mapUnknown[var8]._field3 < 0xFA) || arg8 != 4) {
+		if (_mapUnknown[var8]._field7 > 0xFE)
 			return false;
-		sub22AA8(_mapUnknownPtr[var8 * 9 + 7]);
+		sub22AA8(_mapUnknown[var8]._field7);
 		return true;		
-	} else
-		return false;
+	}
 
 	return false;
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 3e07c01af27..cb33cdc8cf4 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -79,6 +79,18 @@ struct InvObject {
 	void init();
 };
 
+struct UnkMapStruct {
+	uint8 _field0;
+	uint8 _field1;
+	uint8 _field2;
+	uint8 _field3;
+	uint8 _field4;
+	uint16 _field5;
+	uint16 _field7;
+
+	void init();
+};
+
 struct UnkAnimStruct {
 	uint8 field0;
 	uint8 field1;
@@ -325,7 +337,7 @@ private:
 	void drawBottomBorders();
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(char *str, int menuType, int arg4, bool displayTeamWindowFl);
+	int16 sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	void drawChar(uint8 curChar, int16 posX, int posY);
 	void setTextColorWhite();
@@ -367,6 +379,7 @@ private:
 	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
 	void sub221D2(int16 monsterId);
+	Common::KeyCode getInputBlocking();
 	void sub22AA8(int16 arg0);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
@@ -425,8 +438,7 @@ private:
 	uint8 _messageToBePrinted[400];
 	
 	uint8 *_mapBitmapRef;
-	uint8 *_mapUnknownPtr;
-	uint8 *_mapMonstersPtr;
+	UnkMapStruct _mapUnknown[100];
 	MapMonster _mapMonsters[64];
 	uint8 *_mapGameMapPtr;
 


Commit: c6ae134051f6e5f6071365705a18f863704b60e9
    https://github.com/scummvm/scummvm/commit/c6ae134051f6e5f6071365705a18f863704b60e9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Implement object manipulation (sub19E2E), move some functions to graphics and utils

Changed paths:
  A engines/efh/graphics.cpp
  A engines/efh/utils.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/module.mk


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3c15a5070d2..2dde75fa0b3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -26,7 +26,6 @@
 #include "common/config-manager.h"
 #include "common/events.h"
 #include "engines/util.h"
-#include "graphics/palette.h"
 
 #include "efh/efh.h"
 #include "efh/constants.h"
@@ -159,6 +158,13 @@ void NPCStruct::init() {
 	field_85 = 0;
 }
 
+void Stru32686::init() {
+	for (int i = 0; i < 9; ++i) {
+		_field0[i] = 0;
+		_field2[i] = 0;
+	}
+}
+
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 
@@ -247,11 +253,15 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_teamCharStatus[i]._status = 0;
 		_teamCharStatus[i]._duration = 0;
 		_unkArray2C8AA[i] = 0;
+		_word32680[i] = 0;
+		_word32482[i] = 0;
 	}
 
-	for (int i = 0; i < 5; ++i)
+	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
-
+		_stru32686[i].init();
+	}
+	
 	_unkArray2C8AA[2] = 1;
 	_teamSize = 1;
 	_word2C872 = 0;
@@ -313,30 +323,6 @@ Common::Platform EfhEngine::getPlatform() const {
 	return _platform;
 }
 
-void EfhEngine::initPalette() {
-	const uint8 pal[3 * 16] = {
-		0, 0, 0,
-		0, 0, 170,
-		0, 170, 0,
-		0, 170, 170,
-		170, 0, 0,
-		170, 0, 170,
-		170, 85, 0,
-		170, 170, 170,
-		85, 85, 85,
-		85, 85, 255,
-		1, 1, 1,
-		85, 255, 255,
-		255, 85, 85,
-		255, 85, 255,
-		255, 255, 85,
-		255, 255, 255
-	};
-	
-	_system->getPaletteManager()->setPalette(pal, 0, 16);
-	_system->updateScreen();
-}
-
 Common::Error EfhEngine::run() {
 	s_Engine = this;
 	initialize();
@@ -482,16 +468,6 @@ void EfhEngine::initialize() {
 	_shouldQuit = false;
 }
 
-int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
-	Common::File f;
-	if (!f.open(filename))
-		error("Unable to find file %s", filename.c_str());
-
-	int size = f.size();
-	
-	return f.read(destBuffer, size);
-}
-
 void EfhEngine::readAnimInfo() {
 	Common::String fileName = "animinfo";
 	uint8 animInfoBuf[9000];
@@ -607,52 +583,6 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 	copyCurrentPlaceToBuffer(_fullPlaceId / 20);
 }
 
-void EfhEngine::drawLeftCenterBox() {
-	drawColoredRect(16, 8, 111, 135, 0);
-}
-
-void EfhEngine::displayAnimFrame() {
-	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
-
-	if (_animImageSetId == 0xFF)
-		return;
-
-	if (_animImageSetId == 0xFE) {
-		displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
-		return;
-	}
-
-	displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
-	for (int i = 0; i < 4; ++i) {
-		int16 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex].field0;
-		if (var2 == 0xFF)
-			continue;
-		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
-	}
-}
-
-void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
-	if (animId == 0xFF)
-		return;
-
-	_animImageSetId = animId;
-	if (_animImageSetId == 0xFE)
-		loadNewPortrait();
-	else
-		loadAnimImageSet();
-
-	if (!displayMenuBoxFl)
-		return;
-	
-	for (int i = 0; i < 2; ++i) {
-		drawLeftCenterBox();
-		displayAnimFrame();
-
-		if (i == 0)
-			displayFctFullScreen();
-	}
-}
-
 void EfhEngine::readTileFact() {
 	Common::String fileName = "tilefact";
 	readFileToBuffer(fileName, _tileFact);
@@ -754,15 +684,6 @@ void EfhEngine::loadNPCS() {
 	}
 }
 
-void EfhEngine::setDefaultNoteDuration() {
-	// Original implementation is based on the int1C, which is triggered at 18.2065Hz.
-	// Every 4 times, it sets a flag (thus, approx every 220ms)
-	// The function was checking the keyboard in a loop, incrementing a counter and setting the last character read
-	// The "_defaultNoteDuration" was then set to 7 times this counter
-	//
-	// No implementation required in ScummVM
-}
-
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	warning("STUB: playSong");
 	_system->delayMillis(1000);
@@ -770,42 +691,6 @@ Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	return Common::KEYCODE_INVALID;
 }
 
-void EfhEngine::decryptImpFile(bool techMapFl) {
-	uint16 counter = 0;
-	uint16 target;
-	uint8 *curPtr;
-
-	if (!techMapFl) {
-		_imp2PtrArray[counter++] = curPtr = _imp2;
-		target = 431;
-	} else {
-		_imp2PtrArray[counter++] = curPtr = _imp1;
-		target = 99;
-	}
-
-	do {
-		*curPtr = (*curPtr - 3) ^ 0xD7;
-		if (*curPtr == 0x40) {
-			curPtr += 3;
-			if (!techMapFl)
-				_imp2PtrArray[counter++] = curPtr;
-			else
-				_imp1PtrArray[counter++] = curPtr;
-		} else
-			++curPtr;
-	} while (*curPtr != 0x60 && counter <= target);
-
-	Common::DumpFile dump;
-	if (!techMapFl) {
-		dump.open("imp2_unc.dump");
-		dump.write(_imp2, curPtr - _imp2);
-	} else {
-		dump.open("imp1_unc.dump");
-		dump.write(_imp1, curPtr - _imp1);
-	}
-	dump.close();
-}
-
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 	Common::String fileName = Common::String::format("imp.%d", id);
 
@@ -1354,70 +1239,6 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 	}
 }
 
-void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
-	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
-	rImageFile(fileName, buffer, subFilesArray, destBuffer);
-}
-
-void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
-	readFileToBuffer(filename, packedBuffer);
-	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
-	// TODO: Keep this dump for debug purposes only
-	Common::DumpFile dump;
-	dump.open(filename + ".dump");
-	dump.write(targetBuffer, size);
-	// End of dump	
-	
-	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
-	// => Write a class to handle that more properly
-	uint8 *ptr = targetBuffer;
-	uint16 counter = 0;
-	while (READ_LE_INT16(ptr) != 0) {
-		subFilesArray[counter] = ptr;
-		++counter;
-		int16 imageWidth = READ_LE_INT16(ptr);
-		ptr += 2;
-		int16 imageHeight = READ_LE_INT16(ptr);
-		ptr += 2;
-		ptr += (imageWidth * imageHeight);
-	}
-}
-
-void EfhEngine::displayFctFullScreen() {
-	// CHECKME: 319 is in the original but looks suspicious.
-	// copyDirtyRect(0, 0, 319, 200);
-
-	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
-	_system->updateScreen();
-}
-
-void EfhEngine::copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
-	_graphicsStruct->copy(_vgaGraphicsStruct2);
-	_initRect = Common::Rect(minX, minY, maxX, maxY);
-	copyGraphicBufferFromTo(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
-}
-
-void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
-	warning("STUB - copyGraphicBufferFromTo");
-}
-
-void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY) {
-	// TODO: Quick code to display stuff, may require to really reverse the actual function
-	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
-	// warning("%d %d - startX %d startY %d width %d height %d lineDataSize %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_lineDataSize, bufferBM->_fieldD);
-	int counter = 0;
-	for (int line = 0; line < bufferBM->_height; ++line) {
-		for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
-			destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
-			destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
-			++counter;
-		}
-	}
-
-//	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
-//	_system->updateScreen();
-}
-
 uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
 	uint8 *buffer = srcBuffer;
 
@@ -1454,13 +1275,6 @@ void EfhEngine::totalPartyKill() {
 	}
 }
 
-int16 EfhEngine::getRandom(int16 maxVal) {
-	if (maxVal == 0)
-		return 0;
-
-	return 1 + _rnd->getRandomNumber(maxVal - 1);
-}
-
 void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	int16 charId = _teamCharId[teamMemberId];
 	_npcBuf[charId].field_12 = _npcBuf[charId].field_B;
@@ -1480,10 +1294,6 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	refreshTeamSize();
 }
 
-void EfhEngine::emptyFunction(int i) {
-	// TODO: Eventually remove this useless function
-}
-
 void EfhEngine::refreshTeamSize() {
 	_teamSize = 0;
 	for (int16 counter = 0; counter < 3; ++counter) {
@@ -1611,49 +1421,6 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
 	return false;
 }
 
-void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 unkFl) {
-	uint8 *curPtr = (uint8 *)str;
-	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
-	_unk_sub26437_flag = unkFl & 0x3FFF;
-	int16 minX = startX;
-	int16 minY = startY;                                 // Used in case 0x8000
-	int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
-
-	if (unkFl & 0x8000) {
-		warning("STUB - drawString - 0x8000");
-	}
-
-	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
-		if (curChar == 0x0A) {
-			startX = minX;
-			startY += lineHeight;
-			continue;
-		}
-
-		if (curChar < 0x20)
-			continue;
-
-		uint16 characterId = (curChar + 0xE0) & 0xFF;
-		uint8 charWidth = _fontDescr._widthArray[characterId];
-
-		if (startX + charWidth >= 319) {
-			startX = minX;
-			startY += lineHeight;
-		}
-
-		uint8 varC = _fontDescr._extraLines[characterId];
-		drawChar(curChar, startX, startY + varC);
-		startX += charWidth + _fontDescr._extraHorizontalSpace;
-	}
-	
-}
-
-void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY) {
-	uint16 length = getStringWidth(str);
-	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
-	drawString(str, startCenteredDisplayX, posY, _textColor);
-}
-
 int16 EfhEngine::chooseCharacterToReplace() {
 	warning("STUB - chooseCharacterToReplace");
 	return 0x1B;
@@ -1688,20 +1455,6 @@ int16 EfhEngine::handleCharacterJoining() {
 	return 2;
 }
 
-void EfhEngine::drawMapWindow() {
-	drawColoredRect(128, 8, 303, 135, 0);
-}
-
-void EfhEngine::copyString(char *srcStr, char *destStr) {
-	char lastChar = 1;
-	int16 idx = 0;
-
-	while (lastChar != 0) {
-		lastChar = destStr[idx] = srcStr[idx];
-		++idx;
-	}
-}
-
 int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX, int maxY, int argC) {	
 	bool doneFlag = false;
 	int16 var_F2 = -1;
@@ -1853,7 +1606,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 		case 0x07:
 			if (argC != 0) {
 				totalPartyKill();
-				emptyFunction(2);
+				// emptyFunction(2);
 			}
 			break;
 		case 0x08:
@@ -2163,15 +1916,6 @@ void EfhEngine::sub133E5(uint8 *srcPtr, int posX, int posY, int maxX, int maxY,
 	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, argC);
 }
 
-void EfhEngine::displayGameScreen() {
-	clearScreen(0);
-	drawUpperLeftBorders();
-	drawUpperRightBorders();
-	drawBottomBorders();
-	displayAnimFrame();
-	displayLowStatusScreen(false);
-}
-
 void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 	for (uint8 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -2185,24 +1929,6 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 	}
 }
 
-void EfhEngine::drawUpperLeftBorders() {
-	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
-	displayRawDataAtPos(_circleImageSubFileArray[1], 112, 0);
-	displayRawDataAtPos(_circleImageSubFileArray[3], 16, 0);
-}
-
-void EfhEngine::drawUpperRightBorders() {
-	displayRawDataAtPos(_circleImageSubFileArray[2], 304, 0);
-	displayRawDataAtPos(_circleImageSubFileArray[4], 128, 0);
-}
-
-void EfhEngine::drawBottomBorders() {
-	displayRawDataAtPos(_circleImageSubFileArray[7], 16, 136);
-	displayRawDataAtPos(_circleImageSubFileArray[8], 16, 192);
-	displayRawDataAtPos(_circleImageSubFileArray[5], 0, 136);
-	displayRawDataAtPos(_circleImageSubFileArray[6], 304, 136);
-}
-
 void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 	warning("STUB: sub15A28");
 }
@@ -2310,44 +2036,6 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	return -1;
 }
 
-void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
-	// Quick hacked display, may require rework
-	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
-
-	int16 charId = curChar - 0x20;
-	uint8 width = _fontDescr._widthArray[charId];
-
-	for (int16 line = 0; line < 8; ++line) {
-		int16 x = 0;
-		for (int i = 7; i >= 7 - width; --i) {
-			if (_fontDescr._fontData[charId]._lines[line] & (1 << i))
-				destPtr[320 * line + x] = _textColor;
-			++x;
-		}
-	}	
-}
-
-void EfhEngine::setTextColorWhite() {
-	if (_videoMode == 8) // CGA
-		_textColor = 0x3;
-	else
-		_textColor = 0xF;
-}
-
-void EfhEngine::setTextColorRed() {
-	if (_videoMode == 8) // CGA
-		_textColor = 0x2;
-	else
-		_textColor = 0xC;
-}
-
-void EfhEngine::setTextColorGrey() {
-	if (_videoMode == 8) // CGA
-		_textColor = 0x1;
-	else
-		_textColor = 0x8;
-}
-
 bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
 	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
@@ -2512,10 +2200,6 @@ bool EfhEngine::handleDeathMenu() {
 	return false;
 }
 
-void EfhEngine::setNumLock() {
-	// No implementation in ScummVM
-}
-
 void EfhEngine::computeMapAnimation() {
 	const int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
@@ -2579,27 +2263,6 @@ void EfhEngine::unkFct_anim() {
 	computeMapAnimation();
 }
 
-void EfhEngine::setNextCharacterPos() {
-	if (_textPosX <= 311)
-		return;
-
-	_textPosX = 0;
-	_textPosY += 8;
-
-	if (_textPosY > 191)
-		_textPosY = 0;
-}
-
-void EfhEngine::displayStringAtTextPos(const char *message) {
-	drawString(message, _textPosX, _textPosY, _textColor);
-	_textPosX += getStringWidth(message) + 1;
-	setNextCharacterPos();
-}
-
-void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
-	drawColoredRect(16, 152, 302, 189, color);
-}
-
 int8 EfhEngine::sub16B08(int16 monsterId) {
 	// Simplified version compared to the original
 	int16 maxSize = _largeMapFlag ? 63 : 23;
@@ -3189,29 +2852,6 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
-Common::KeyCode EfhEngine::getInputBlocking() {
-	// The original checks for the joystick input
-	Common::Event event;
-	_system->getEventManager()->pollEvent(event);
-	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-
-	uint32 lastMs = _system->getMillis();
-	while (retVal == Common::KEYCODE_INVALID) {
-		if (event.type == Common::EVENT_KEYUP) {
-			retVal = event.kbd.keycode;
-		}
-
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 220) {
-			lastMs = newMs;
-			unkFct_anim();
-		}
-	}
-	return retVal;
-}
-
 void EfhEngine::sub22AA8(int16 arg0) {
 	int16 var8, varA, varC, varE;
 	var8 = varA = varC = varE = 0;
@@ -3541,16 +3181,6 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 	return level;
 }
 
-void EfhEngine::displayChar(char character) {
-	char buffer[2];
-	buffer[0] = character;
-	buffer[1] = 0;
-
-	drawString(buffer, _textPosX, _textPosY, _textColor);
-	_textPosX += getStringWidth(buffer) + 1;
-	setNextCharacterPos();
-}
-
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	char buffer1[40];
 	char buffer2[40];
@@ -3743,19 +3373,6 @@ void EfhEngine::unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine,
 		displayFctFullScreen();
 }
 
-void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest) {
-	if (buffer == nullptr) {
-		warning("Target Buffer Not Defined...DCImage!"); // That's the original message... And yes, it's wrong: it's checking the source buffer :)
-		return;
-	}
-
-	// Only MCGA handled, the rest is skipped
-	uncompressBuffer(buffer, dest);
-	displayRawDataAtPos(dest, posX, posY);
-	displayFctFullScreen();
-	displayRawDataAtPos(dest, posX, posY);
-}
-
 void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
 	for (int counter = 0; counter < 2; ++counter) {
 		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
@@ -3832,20 +3449,616 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 	}
 }
 
-int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
-	warning("STUB: sub19E2E");
+void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
+	int16 monsterId;
+	if (groupFl) {
+		monsterId = _teamMonsterIdArray[id];
+	} else {
+		monsterId = id;
+	}
 
-	return -1;
+	_mapMonsters[monsterId]._field_8 &= 0xF0;
+	_mapMonsters[monsterId]._field_8 |= mask;
 }
 
-bool EfhEngine::getValidationFromUser() {
-	Common::KeyCode input = handleAndMapInput(true);
-	if (input == Common::KEYCODE_y) // or if joystick button 1
+bool EfhEngine::sub1BA9B(int16 groupId, int16 id) {
+	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _stru32686[groupId]._field0[id] == 0)
 		return true;
-
 	return false;
 }
 
+int16 EfhEngine::sub15538(int16 mapPosX, int16 mapPosY) {
+	int16 mapTileInfo = getMapTileInfo(mapPosX, mapPosY);
+	int16 imageSetId = mapTileInfo / 72;
+
+	return (_currentTileBankImageSetId[imageSetId] * 72) + (mapTileInfo % 72);
+}
+
+void EfhEngine::setCharacterObjectToBroken(int16 charId, int16 objectId) {
+	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
+}
+
+Common::KeyCode EfhEngine::selectOtherCharFromTeam() {
+	Common::KeyCode maxVal = (Common::KeyCode) (Common::KEYCODE_0 + _teamSize);
+	Common::KeyCode input = Common::KEYCODE_INVALID; 
+	for (;;) {
+		input = waitForKey();
+		if (input == Common::KEYCODE_ESCAPE || (input >= Common::KEYCODE_0 && input <= maxVal))
+			break;
+	}
+
+	return input;
+}
+
+int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
+	char buffer1[80];
+	char buffer2[80];
+
+	int16 varA6 = 0;
+	int16 varA4 = 0;
+
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+	switch (_items[itemId].field_16 - 1) {
+	case 0:
+		if (argA == 2) {
+			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 varAE = 0;
+			strcat((char *)_messageToBePrinted, "  The item emits a low droning hum...");
+			if (getRandom(100) < 50) {
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (sub1BA9B(windowId, varA8)) {
+						++varAE;
+						_stru32686[windowId]._field0[varA8] = 1;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			} else {
+				int16 varAC = getRandom(9);
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (varAC == 0)
+						break;
+
+					if (sub1BA9B(windowId, varA8)) {
+						++varAE;
+						--varAC;
+						_stru32686[windowId]._field0[varA8] = 1;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			}
+			// The original was duplicating this code in each branch of the previous random check. 
+			if (varAE > 1) {
+				sprintf(buffer1, "%d %ss fall asleep!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			} else {
+				sprintf(buffer1, "%d %s falls asleep!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			}
+			strcat((char *)_messageToBePrinted, buffer1);
+		}
+
+		varA6 = -1;
+		break;
+	case 1:
+		if (argA == 2) {
+			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, "  The item emits a blue beam...");
+			int16 varAE = 0;
+			if (getRandom(100) < 50) {
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (sub1BA9B(windowId, varA8)) {
+						++varAE;
+						_stru32686[windowId]._field0[varA8] = 2;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			} else {
+				int16 varAC = getRandom(9);
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (varAC == 0)
+						break;
+
+					if (sub1BA9B(windowId, varA8)) {
+						++varAE;
+						--varAC;
+						_stru32686[windowId]._field0[varA8] = 2;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			}
+			// <CHECKME>: This part is only present in the original in the case < 50, but for me
+			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
+			if (varAE > 1) {
+				sprintf(buffer1, "%d %ss are frozen in place!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			} else {
+				sprintf(buffer1, "%d %s is frozen in place!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			}
+			strcat((char *)_messageToBePrinted, buffer1);
+			// </CHECKME>
+		}
+
+		varA6 = -1;
+		break;
+	case 2:
+		if (argA == 2) {
+			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, "  The combat pauses...as there is a moment of forgiveness...");
+			_unkArray2C8AA[0] = 0;
+		}
+
+		varA6 = -1;
+		break;
+	case 4:
+		if (argA == 2) {
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!");
+			if (getRandom(100) < 50) {
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (getRandom(100) < 50) {
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+					}
+				}
+			} else {
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (sub1BA9B(windowId, varA8)) {
+						if (getRandom(100) < 50) {
+							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+						}
+						break;
+					}
+				}				
+			}
+		}
+		varA6 = -1;
+		break;
+	case 5:
+		if (argA == 2) {
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			if (getRandom(100) < 50) {
+				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!");
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+				}
+			} else {
+				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!");
+				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+					if (sub1BA9B(windowId, varA8)) {
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+					}
+				}				
+			}
+		}
+
+		varA6 = -1;
+		break;
+	case 12:
+		if (argA == 2) {
+			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, "  The magic sparkles brilliant hues in the air!");
+			sub1E028(windowId, _items[itemId].field17_attackTypeDefense, true);
+		}
+		varA6 = -1;
+		break;
+	case 14: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+
+		if (varAA != 0x1B) {
+			strcpy(buffer1, "  The magic makes the user as quick and agile as a bird!");
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+			}
+			_word32482[varAA] -= 50;
+			if (_word32482[varAA] < 0)
+				_word32482[varAA] = 0;
+		}
+		
+		varA6 = -1;
+		}
+		break;
+	case 15: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+
+		if (varAA != 0x1B) {
+			strcpy(buffer1, "  The magic makes the user invisible!");
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine); 
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+			}
+
+			_word32680[varAA] -= 50;
+			if (_word32680[varAA] < 0)
+				_word32680[varAA] = 0;
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 16: {
+		int16 varAC = _mapPosX;
+		int16 varAA = _mapPosY;
+		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
+		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
+		int16 varAE = sub15538(_mapPosX, _mapPosY);
+
+		if (_tileFact[2 * varAE] == 0) {
+			totalPartyKill();
+			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+				varA4 = -1;
+			}
+			// emptyFunction(2);
+		} else {
+			if (varAE == 0 || varAE == 0x48) {
+				strcpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!");
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					strcat((char *)_messageToBePrinted, buffer1);
+					varA4 = -1;
+				}
+			} else {
+				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					strcat((char *)_messageToBePrinted, buffer1);
+					varA4 = -1;
+				}
+			}
+		}
+
+		varA6 = -1;		
+		}
+		break;
+	case 17: {
+		_mapPosX = _items[itemId].field_19;
+		_mapPosY = _items[itemId].field_1A;
+		int16 varAE = sub15538(_mapPosX, _mapPosY);
+		if (_tileFact[2 * varAE] == 0) {
+			totalPartyKill();
+			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+				varA4 = -1;
+			}
+			// emptyFunction(2);
+		} else {
+			if (varAE == 0 || varAE == 0x48) {
+				strcpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!");
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					strcat((char *)_messageToBePrinted, buffer1);
+					varA4 = -1;
+				}
+			} else {
+				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					strcat((char *)_messageToBePrinted, buffer1);
+					varA4 = -1;
+				}
+			}
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 18:
+		if (argA == 2) {
+			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 varAA = windowId;
+			if (varAA != 0x1B) {
+				if (_teamCharStatus[varAA]._status == 2) { // frozen
+					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
+					_teamCharStatus[varAA]._status = 0;
+					_teamCharStatus[varAA]._duration = 0;
+				} else {
+					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
+				}
+			}
+		}
+
+		varA6 = -1;
+		break;
+	case 19:
+		strcpy(buffer1, "  * The item breaks!");
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, buffer1);
+		}
+		setCharacterObjectToBroken(charId, objectId);
+		varA6 = -1;
+		break;
+	case 23:
+		copyString(_items[itemId]._name, buffer2);
+		sprintf(buffer1, "The %s says, '", buffer2);
+		if (_items[itemId].field_19 < _mapPosX) {
+			if (_items[itemId].field_1A < _mapPosY) {
+				strcat(buffer1, "North West!");
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				strcat(buffer1, "South West!");
+			} else {
+				strcat(buffer1, "West!");
+			}
+		} else if (_items[itemId].field_19 > _mapPosX) {
+			if (_items[itemId].field_1A < _mapPosY) {
+				strcat(buffer1, "North East!");
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				strcat(buffer1, "South East!");
+			} else {
+				strcat(buffer1, "East!");
+			}
+		} else { // equals _mapPosX
+			if (_items[itemId].field_1A < _mapPosY) {
+				strcat(buffer1, "North!");
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				strcat(buffer1, "South!");
+			} else {
+				strcat(buffer1, "Here!!!");
+			}
+		}
+		strcat(buffer1, "'");
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, buffer1);
+			varA4 = -1;
+		}
+
+		varA6 = -1;
+		break;
+	case 24: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else
+			varAA = windowId;
+
+		if (varAA != 0x1B) {
+			uint8 varAE = _items[itemId].field17_attackTypeDefense;
+			uint8 varAC = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[varAA]]._activeScore[varAE] += varAC;
+			if (_npcBuf[_teamCharId[varAA]]._activeScore[varAE] > 20) {
+				_npcBuf[_teamCharId[varAA]]._activeScore[varAE] = 20;
+			}
+			if (varAC > 1)
+				sprintf(buffer1, "%s increased %d points!", kSkillArray[varAE], varAC);
+			else
+				sprintf(buffer1, "%s increased 1 point!", kSkillArray[varAE]);
+
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+				varA4 = -1;
+			}
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 25: {
+			int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else
+			varAA = windowId;
+
+		if (varAA != 0x1B) {
+			uint8 varAE = _items[itemId].field17_attackTypeDefense;
+			uint8 varAC = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[varAA]]._activeScore[varAE] -= varAC;
+			if (_npcBuf[_teamCharId[varAA]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[varAA]]._activeScore[varAE] < 0) {
+				_npcBuf[_teamCharId[varAA]]._activeScore[varAE] = 1;
+			}
+			if (varAC > 1)
+				sprintf(buffer1, "%s lowered %d points!", kSkillArray[varAE], varAC);
+			else
+				sprintf(buffer1, "%s lowered 1 point!", kSkillArray[varAE]);
+
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+				varA4 = -1;
+			}
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 26:
+		strcpy(buffer1, "The entire party collapses, dead!!!");
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, buffer1);
+			varA4 = -1;
+		}
+		totalPartyKill();
+		// emptyFunction(2);
+		varA6 = -1;
+		break;
+	case 27: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+
+		if (varAA != 0x1B) {
+			_npcBuf[_teamCharId[varAA]]._hitPoints = 0;
+			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+			sprintf(buffer1, "%s collapses, dead!!!", buffer2);
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				strcat((char *)_messageToBePrinted, buffer1);
+				varA4 = -1;
+			}
+			// emptyFunction(2);
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 28:
+		if (argA == 2) {
+			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 varAA = windowId;
+			if (varAA != 0x1B) {
+				if (_teamCharStatus[varAA]._status == 0) {
+					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
+					_teamCharStatus[varAA]._status = 0;
+					_teamCharStatus[varAA]._duration = 0; 
+				} else {
+					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
+				}
+			}
+		}
+
+		varA6 = -1;
+		break;
+	case 29: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+		
+		if (varAA != 0x1B) {
+			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[varA4]]._hitPoints += varAE;
+			if (_npcBuf[_teamCharId[varA4]]._hitPoints > _npcBuf[_teamCharId[varA4]]._maxHP)
+				_npcBuf[_teamCharId[varA4]]._hitPoints = _npcBuf[_teamCharId[varA4]]._maxHP;
+
+			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+			if (varAE > 1)
+				sprintf(buffer1, "%s is healed %d points!", buffer2, varAE);
+			else
+				sprintf(buffer1, "%s is healed 1 point!", buffer2);
+		}
+
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, buffer1);
+			varA4 = -1;
+		}
+
+		varA6 = -1;
+		}
+		break;
+	case 30: {
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+
+		if (varAA != 0x1B) {
+			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[varA4]]._hitPoints -= varAE;
+			if (_npcBuf[_teamCharId[varA4]]._hitPoints < 0)
+				_npcBuf[_teamCharId[varA4]]._hitPoints = 0;
+
+			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+			if (varAE > 1)
+				sprintf(buffer1, "%s is harmed for %d points!", buffer2, varAE);
+			else
+				sprintf(buffer1, "%s is harmed for 1 point!", buffer2);
+		}
+
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			strcat((char *)_messageToBePrinted, buffer1);
+			varA4 = -1;
+		}
+
+		varA6 = -1;
+		
+		}
+		break;
+	case 3:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 13:
+	case 20:
+	case 21:
+	case 22:
+	default:
+		break;
+	}
+
+	if (varA6 != 0) {
+		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
+			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
+			if (varA1 <= 0) {
+				strcpy(buffer1, "  * The item breaks!");
+				if (argA == 2) {
+					Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					strcat((char *)_messageToBePrinted, buffer1);
+				}
+				setCharacterObjectToBroken(charId, objectId);
+			} else {
+				_npcBuf[charId]._inventory[objectId]._stat1 &= 0x80;
+				_npcBuf[charId]._inventory[objectId]._stat1 |= 0xA1;
+			}
+		}
+
+		if (argA == 2) {
+			Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
+			sub18E80(charId, windowId, menuId, curMenuLine);
+		}
+	}
+
+	return varA4;
+}
+
 int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	int16 menuId = 9;
 	int16 var16 = -1;
@@ -4403,204 +4616,12 @@ void EfhEngine::loadGame() {
 	loadPlacesFile(_fullPlaceId, true);
 }
 
-uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
-	if (compressedBuf == nullptr || destBuf == nullptr)
-		error("uncompressBuffer - Invalid pointer used in parameter list");
-
-	uint8 *curPtrDest = destBuf;
-
-	uint16 compSize = READ_LE_UINT16(compressedBuf) + 1;	
-	uint8 *curPtrCompressed = compressedBuf + 2;
-
-	// Not in the original. This has been added for debug purposes (the original function doesn't return a value)
-	uint32 decompSize = 0;
-
-	for (;;) {
-		uint8 next = *curPtrCompressed++;
-		if (--compSize <= 0)
-			break;
-
-		if (next != 0xC3) {
-			*curPtrDest++ = next;
-			++decompSize;
-			continue;
-		}
-
-		next = *curPtrCompressed++;
-		if (--compSize <= 0)
-			break;
-
-		if (next == 0) {
-			*curPtrDest++ = 0xC3;
-			++decompSize;
-			continue;
-		}
-			
-		uint8 loopVal = next;
-		next = *curPtrCompressed++;
-
-		for (int i = 0; i < loopVal; ++i) {
-			*curPtrDest++ = next;
-			++decompSize;
-		}
-		
-		--compSize;
-		if (compSize == 0)
-			break;
-	}
-
-	curPtrDest[0] = curPtrDest[1] = 0;
-	decompSize += 2;
-
-	return decompSize;
-}
-
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
-	int size = _largeMapFlag ? 32 : 24;
+	int size = _largeMapFlag ? 64 : 24;
 
 	return _mapGameMapPtr[mapPosX * size + mapPosY];
 }
 
-void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
-	if (minY > maxY)
-		SWAP(minY, maxY);
-
-	if (minX > maxX)
-		SWAP(minX, maxX);
-	
-	// warning("drawRect - _graphicsStruct x %d -> %d, y %d -> %d", _graphicsStruct->_area.left, _graphicsStruct->_area.right, _graphicsStruct->_area.top, _graphicsStruct->_area.bottom);
-
-	minX = CLIP(minX, 0, 319);
-	maxX = CLIP(maxX, 0, 319);
-	minY = CLIP(minY, 0, 199);
-	maxY = CLIP(maxY, 0, 199);
-	
-	int deltaY = 1 + maxY - minY;
-	int deltaX = 1 + maxX - minX;
-
-	uint8 color = _defaultBoxColor & 0xF;
-	bool xorColor = (_defaultBoxColor & 0x40) != 0;
-	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(minX, minY);
-	
-	for (int line = 0; line < deltaY; ++line) {
-		for (int col = 0; col < deltaX; ++col) {
-			if (xorColor)
-				destPtr[320 * line + col] ^= color;
-			else
-				destPtr[320 * line + col] = color;
-		}
-	}
-	
-}
-
-void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int color) {
-	uint8 oldValue = _defaultBoxColor;
-	_defaultBoxColor = color;
-	drawRect(minX, minY, maxX, maxY);
-	_defaultBoxColor = oldValue;
-}
-
-void EfhEngine::clearScreen(int color) {
-	drawColoredRect(0, 0, 320, 200, color);
-}
-
-Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
-	// The original checks for the joystick input
-	Common::Event event;
-	_system->getEventManager()->pollEvent(event);
-	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-	if (event.type == Common::EVENT_KEYUP) {
-		retVal = event.kbd.keycode;
-	} 	
-
-	if (animFl) {
-		warning("STUB - handleAndMapInput - animFl");
-	}
-	return retVal;
-}
-
-Common::KeyCode EfhEngine::waitForKey() {
-	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-	Common::Event event;
-
-	uint32 lastMs = _system->getMillis();
-	while (retVal == Common::KEYCODE_INVALID) { // TODO: Check shouldquit()
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 200) {
-			lastMs = newMs;
-			unkFct_anim();
-		}
-
-		_system->getEventManager()->pollEvent(event);
-		if (event.type == Common::EVENT_KEYUP) {
-			retVal = event.kbd.keycode;
-		} 	
-	}
-
-	return retVal;
-}
-
-Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
-	// Original is doing:
-	// if input < a or > z : return input
-	// else return (input + 0xE0)
-	// ex: 'a' = 0x61 + 0xE0 = 0x0141, but it's a uint8 so it's 0x41 which is 'A'.
-	// So basically the original works with uppercase letters and do not alter the other inputs.
-	// => no implementation needed.
-	return input;
-}
-
-Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
-	if (delay == 0)
-		return Common::KEYCODE_INVALID;
-
-	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
-
-	uint32 lastMs = _system->getMillis();
-	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 200) {
-			lastMs = newMs;
-			--delay;
-			unkFct_anim();
-		}
-
-		lastChar = handleAndMapInput(false);
-	}
-
-	return lastChar;
-}
-
-Common::KeyCode EfhEngine::getInput(int16 delay) {
-	if (delay == 0)
-		return Common::KEYCODE_INVALID;
-
-	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
-	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-
-	uint32 lastMs = _system->getMillis();
-	while (delay > 0) {
-		_system->delayMillis(20);
-		uint32 newMs = _system->getMillis();
-
-		if (newMs - lastMs >= 200) {
-			lastMs = newMs;
-			--delay;
-			unkFct_anim();
-		}
-
-		lastChar = handleAndMapInput(false);
-		if (lastChar != Common::KEYCODE_INVALID)
-			retVal = lastChar;
-	}
-
-	return retVal;
-}
-
 void EfhEngine::displayNextAnimFrame() {
 	if (++_unkAnimRelatedIndex >= 15)
 		_unkAnimRelatedIndex = 0;
@@ -4643,17 +4664,4 @@ void EfhEngine::copyCurrentPlaceToBuffer(int id) {
 	memcpy(_curPlace, placesPtr, 24 * 24);
 }
 
-void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
-	uint16 height = READ_LE_INT16(imagePtr);
-	uint16 width = READ_LE_INT16(imagePtr + 2);
-	uint8 *imageData = imagePtr + 4;
-
-	_imageDataPtr._lineDataSize = width;
-	_imageDataPtr._dataPtr = imageData;
-	_imageDataPtr._height = height;
-	_imageDataPtr._width = width * 2; // 2 pixels per byte
-	_imageDataPtr._startX = _imageDataPtr._startY = 0;
-	
-	displayBufferBmAtPos(&_imageDataPtr, posX, posY);
-}
 } // End of namespace Efh
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index cb33cdc8cf4..60a4407ea2b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -214,6 +214,13 @@ struct MapMonster {
 	int16 _pictureRef[9];
 };
 
+struct Stru32686 {
+	int16 _field0[9];
+	int16 _field2[9];
+
+	void init();
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -252,9 +259,7 @@ private:
 	GameType _gameType;
 	Common::Platform _platform;
 
-	void initPalette();
 	void initialize();
-	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void readAnimInfo();
 	void findMapFile(int16 mapId);
 	void loadNewPortrait();
@@ -262,17 +267,11 @@ private:
 	void loadHistory();
 	void loadTechMapImp(int16 fileId);
 	void loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl);
-	void drawLeftCenterBox();
-	void displayAnimFrame();
-	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
 	void readTileFact();
 	void readItems();
 	void loadNPCS();
-	void setDefaultNoteDuration();
 	Common::KeyCode playSong(uint8 *buffer);
-	void decryptImpFile(bool techMapFl);
 	void readImpFile(int16 id, bool techMapFl);
-	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
 	void playIntro();
 	void initEngine();
 	void initMapMonsters();
@@ -281,68 +280,40 @@ private:
 	int16 getEquipmentDefense(int16 charId, bool flag);
 	uint16 sub1C80A(int16 charId, int field18, bool flag);
 	void displayLowStatusScreen(bool flag);
-	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
-	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
-	void displayFctFullScreen();
-	void copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY);
-	void copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
 	void restoreAnimImageSetId();
 	void checkProtection();
 	void loadGame();
-	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	void copyCurrentPlaceToBuffer(int id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
-	void drawRect(int minX, int minY, int maxX, int maxY);
-	void drawColoredRect(int minX, int minY, int maxX, int maxY, int color);
-	void clearScreen(int color);
-	Common::KeyCode handleAndMapInput(bool animFl);
 	void displayNextAnimFrame();
 	void writeTechAndMapFiles();
 	uint16 getStringWidth(const char *buffer);
 	void setTextPos(int16 textPosX, int16 textPosY);
-
 	void sub15150(bool flag);
 	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl);
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
 	void redrawScreen();
-	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
-	void displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY);
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
 	void removeObject(int16 charId, int16 objectId);
 	void totalPartyKill();
-	int16 getRandom(int16 maxVal);
 	void removeCharacterFromTeam(int16 teamMemberId);
-	void emptyFunction(int i);
 	void refreshTeamSize();
 	bool isCharacterATeamMember(int16 id);
 	bool isTPK();
-	Common::KeyCode getInput(int16 delay);
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
-	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
-	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
-	void drawMapWindow();
-	void copyString(char *srcStr, char *destStr);
 	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
 	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
-	void displayGameScreen();
 	void sub221FA(uint8 *impArray, bool flag);
-	void drawUpperLeftBorders();
-	void drawUpperRightBorders();
-	void drawBottomBorders();
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
-	void drawChar(uint8 curChar, int16 posX, int posY);
-	void setTextColorWhite();
-	void setTextColorRed();
-	void setTextColorGrey();
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
 	void goNorth();
@@ -354,13 +325,8 @@ private:
 	void goSouthWest();
 	void handleNewRoundEffects();
 	bool handleDeathMenu();
-
-	void setNumLock();
 	void computeMapAnimation();
 	void unkFct_anim();
-	void setNextCharacterPos();
-	void displayStringAtTextPos(const char *message);
-	void unkFct_displayMenuBox_2(int16 color);
 	int8 sub16B08(int16 monsterId);
 	bool moveMonsterAwayFromTeam(int16 monsterId);
 	bool moveMonsterTowardsTeam(int16 monsterId);
@@ -379,7 +345,6 @@ private:
 	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
 	void sub221D2(int16 monsterId);
-	Common::KeyCode getInputBlocking();
 	void sub22AA8(int16 arg0);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
@@ -388,24 +353,73 @@ private:
 	void displayStatusMenu(int16 windowId);
 	void countRightWindowItems(int16 menuId, int16 charId);
 	int16 getXPLevel(int32 xp);
-	void displayChar(char character);
 	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
 	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
 	void unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
-	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 displayString_3(const char * str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 _objectId);
 	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	void sub1E028(int16 id, uint8 mask, int16 groupFl);
+	bool sub1BA9B(int16 groupId, int16 id);
+	int16 sub15538(int16 mapPosX, int16 mapPosY);
+	void setCharacterObjectToBroken(int16 charId, int16 objectId);
+	Common::KeyCode selectOtherCharFromTeam();
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
-	bool getValidationFromUser();
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
+	bool sub16E14();
+
+	// Graphics
+	void initPalette();
+	void drawLeftCenterBox();
+	void displayAnimFrame();
+	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
+	void displayFctFullScreen();
+	void copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY);
+	void copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
+	void displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY);
+	void drawRect(int minX, int minY, int maxX, int maxY);
+	void drawColoredRect(int minX, int minY, int maxX, int maxY, int color);
+	void clearScreen(int color);
+	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
+	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
+	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
+	void drawMapWindow();
+	void displayGameScreen();
+	void drawUpperLeftBorders();
+	void drawUpperRightBorders();
+	void drawBottomBorders();
+	void drawChar(uint8 curChar, int16 posX, int posY);
+	void setTextColorWhite();
+	void setTextColorRed();
+	void setTextColorGrey();
+	void displayStringAtTextPos(const char *message);
+	void unkFct_displayMenuBox_2(int16 color);
+	void setNextCharacterPos();
+	void displayChar(char character);
+	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
+
+	// Utils
+	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
+	void setDefaultNoteDuration();
+	void decryptImpFile(bool techMapFl);
+	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
+	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);	
+	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
+	int16 getRandom(int16 maxVal);
+	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
+	Common::KeyCode getInput(int16 delay);
 	Common::KeyCode waitForKey();
 	Common::KeyCode mapInputCode(Common::KeyCode input);
-	bool sub16E14();
+	Common::KeyCode handleAndMapInput(bool animFl);
+	Common::KeyCode getInputBlocking();
+	void setNumLock();
+	void copyString(char *srcStr, char *destStr);
+	bool getValidationFromUser();
+
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
@@ -502,8 +516,11 @@ private:
 	bool _word2C8D2;
 	int16 _menuDepth;
 	int16 _word2D0BA;
+	int16 _word32680[3];
+	int16 _word32482[3];
 
 	int16 _word3273A[15];
+	Stru32686 _stru32686[5];
 };
 
 } // End of namespace Efh
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
new file mode 100644
index 00000000000..47a81e7c019
--- /dev/null
+++ b/engines/efh/graphics.cpp
@@ -0,0 +1,346 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "efh/efh.h"
+#include "graphics/palette.h"
+#include "common/system.h"
+
+namespace Efh {
+
+void EfhEngine::initPalette() {
+	// Strangerke - values from a tool I wrote in 2008. I can't remember if it's guess work or not.
+	const uint8 pal[3 * 16] = {
+		0, 0, 0,
+		0, 0, 170,
+		0, 170, 0,
+		0, 170, 170,
+		170, 0, 0,
+		170, 0, 170,
+		170, 85, 0,
+		170, 170, 170,
+		85, 85, 85,
+		85, 85, 255,
+		1, 1, 1,
+		85, 255, 255,
+		255, 85, 85,
+		255, 85, 255,
+		255, 255, 85,
+		255, 255, 255
+	};
+
+	_system->getPaletteManager()->setPalette(pal, 0, 16);
+	_system->updateScreen();
+}
+
+void EfhEngine::drawLeftCenterBox() {
+	drawColoredRect(16, 8, 111, 135, 0);
+}
+
+void EfhEngine::displayAnimFrame() {
+	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
+
+	if (_animImageSetId == 0xFF)
+		return;
+
+	if (_animImageSetId == 0xFE) {
+		displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
+		return;
+	}
+
+	displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
+	for (int i = 0; i < 4; ++i) {
+		int16 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex].field0;
+		if (var2 == 0xFF)
+			continue;
+		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
+	}
+}
+
+void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
+	if (animId == 0xFF)
+		return;
+
+	_animImageSetId = animId;
+	if (_animImageSetId == 0xFE)
+		loadNewPortrait();
+	else
+		loadAnimImageSet();
+
+	if (!displayMenuBoxFl)
+		return;
+
+	for (int i = 0; i < 2; ++i) {
+		drawLeftCenterBox();
+		displayAnimFrame();
+
+		if (i == 0)
+			displayFctFullScreen();
+	}
+}
+
+void EfhEngine::displayFctFullScreen() {
+	// CHECKME: 319 is in the original but looks suspicious.
+	// copyDirtyRect(0, 0, 319, 200);
+
+	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+	_system->updateScreen();
+}
+
+void EfhEngine::copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
+	_graphicsStruct->copy(_vgaGraphicsStruct2);
+	_initRect = Common::Rect(minX, minY, maxX, maxY);
+	copyGraphicBufferFromTo(_vgaGraphicsStruct2, _vgaGraphicsStruct1, _initRect, minX, minY);
+}
+
+void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y) {
+	warning("STUB - copyGraphicBufferFromTo");
+}
+
+void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY) {
+	// TODO: Quick code to display stuff, may require to really reverse the actual function
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
+	// warning("%d %d - startX %d startY %d width %d height %d lineDataSize %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_lineDataSize, bufferBM->_fieldD);
+	int counter = 0;
+	for (int line = 0; line < bufferBM->_height; ++line) {
+		for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
+			destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
+			destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
+			++counter;
+		}
+	}
+
+	//	_system->copyRectToScreen((uint8 *)_mainSurface->getPixels(), 320, 0, 0, 320, 200);
+	//	_system->updateScreen();
+}
+
+void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
+	if (minY > maxY)
+		SWAP(minY, maxY);
+
+	if (minX > maxX)
+		SWAP(minX, maxX);
+
+	// warning("drawRect - _graphicsStruct x %d -> %d, y %d -> %d", _graphicsStruct->_area.left, _graphicsStruct->_area.right, _graphicsStruct->_area.top, _graphicsStruct->_area.bottom);
+
+	minX = CLIP(minX, 0, 319);
+	maxX = CLIP(maxX, 0, 319);
+	minY = CLIP(minY, 0, 199);
+	maxY = CLIP(maxY, 0, 199);
+
+	int deltaY = 1 + maxY - minY;
+	int deltaX = 1 + maxX - minX;
+
+	uint8 color = _defaultBoxColor & 0xF;
+	bool xorColor = (_defaultBoxColor & 0x40) != 0;
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(minX, minY);
+
+	for (int line = 0; line < deltaY; ++line) {
+		for (int col = 0; col < deltaX; ++col) {
+			if (xorColor)
+				destPtr[320 * line + col] ^= color;
+			else
+				destPtr[320 * line + col] = color;
+		}
+	}
+}
+
+void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int color) {
+	uint8 oldValue = _defaultBoxColor;
+	_defaultBoxColor = color;
+	drawRect(minX, minY, maxX, maxY);
+	_defaultBoxColor = oldValue;
+}
+
+void EfhEngine::clearScreen(int color) {
+	drawColoredRect(0, 0, 320, 200, color);
+}
+
+void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
+	uint16 height = READ_LE_INT16(imagePtr);
+	uint16 width = READ_LE_INT16(imagePtr + 2);
+	uint8 *imageData = imagePtr + 4;
+
+	_imageDataPtr._lineDataSize = width;
+	_imageDataPtr._dataPtr = imageData;
+	_imageDataPtr._height = height;
+	_imageDataPtr._width = width * 2; // 2 pixels per byte
+	_imageDataPtr._startX = _imageDataPtr._startY = 0;
+
+	displayBufferBmAtPos(&_imageDataPtr, posX, posY);
+}
+
+void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 unkFl) {
+	uint8 *curPtr = (uint8 *)str;
+	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
+	_unk_sub26437_flag = unkFl & 0x3FFF;
+	int16 minX = startX;
+	int16 minY = startY;                                 // Used in case 0x8000
+	int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
+
+	if (unkFl & 0x8000) {
+		warning("STUB - drawString - 0x8000");
+	}
+
+	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
+		if (curChar == 0x0A) {
+			startX = minX;
+			startY += lineHeight;
+			continue;
+		}
+
+		if (curChar < 0x20)
+			continue;
+
+		uint16 characterId = (curChar + 0xE0) & 0xFF;
+		uint8 charWidth = _fontDescr._widthArray[characterId];
+
+		if (startX + charWidth >= 319) {
+			startX = minX;
+			startY += lineHeight;
+		}
+
+		uint8 varC = _fontDescr._extraLines[characterId];
+		drawChar(curChar, startX, startY + varC);
+		startX += charWidth + _fontDescr._extraHorizontalSpace;
+	}
+}
+
+void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY) {
+	uint16 length = getStringWidth(str);
+	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
+	drawString(str, startCenteredDisplayX, posY, _textColor);
+}
+
+void EfhEngine::drawMapWindow() {
+	drawColoredRect(128, 8, 303, 135, 0);
+}
+
+void EfhEngine::displayGameScreen() {
+	clearScreen(0);
+	drawUpperLeftBorders();
+	drawUpperRightBorders();
+	drawBottomBorders();
+	displayAnimFrame();
+	displayLowStatusScreen(false);
+}
+
+void EfhEngine::drawUpperLeftBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[1], 112, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[3], 16, 0);
+}
+
+void EfhEngine::drawUpperRightBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[2], 304, 0);
+	displayRawDataAtPos(_circleImageSubFileArray[4], 128, 0);
+}
+
+void EfhEngine::drawBottomBorders() {
+	displayRawDataAtPos(_circleImageSubFileArray[7], 16, 136);
+	displayRawDataAtPos(_circleImageSubFileArray[8], 16, 192);
+	displayRawDataAtPos(_circleImageSubFileArray[5], 0, 136);
+	displayRawDataAtPos(_circleImageSubFileArray[6], 304, 136);
+}
+
+void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
+	// Quick hacked display, may require rework
+	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
+
+	int16 charId = curChar - 0x20;
+	uint8 width = _fontDescr._widthArray[charId];
+
+	for (int16 line = 0; line < 8; ++line) {
+		int16 x = 0;
+		for (int i = 7; i >= 7 - width; --i) {
+			if (_fontDescr._fontData[charId]._lines[line] & (1 << i))
+				destPtr[320 * line + x] = _textColor;
+			++x;
+		}
+	}
+}
+
+void EfhEngine::setTextColorWhite() {
+	if (_videoMode == 8) // CGA
+		_textColor = 0x3;
+	else
+		_textColor = 0xF;
+}
+
+void EfhEngine::setTextColorRed() {
+	if (_videoMode == 8) // CGA
+		_textColor = 0x2;
+	else
+		_textColor = 0xC;
+}
+
+void EfhEngine::setTextColorGrey() {
+	if (_videoMode == 8) // CGA
+		_textColor = 0x1;
+	else
+		_textColor = 0x8;
+}
+
+void EfhEngine::displayStringAtTextPos(const char *message) {
+	drawString(message, _textPosX, _textPosY, _textColor);
+	_textPosX += getStringWidth(message) + 1;
+	setNextCharacterPos();
+}
+
+void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
+	drawColoredRect(16, 152, 302, 189, color);
+}
+
+void EfhEngine::setNextCharacterPos() {
+	if (_textPosX <= 311)
+		return;
+
+	_textPosX = 0;
+	_textPosY += 8;
+
+	if (_textPosY > 191)
+		_textPosY = 0;
+}
+
+void EfhEngine::displayChar(char character) {
+	char buffer[2];
+	buffer[0] = character;
+	buffer[1] = 0;
+
+	drawString(buffer, _textPosX, _textPosY, _textColor);
+	_textPosX += getStringWidth(buffer) + 1;
+	setNextCharacterPos();
+}
+
+void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest) {
+	if (buffer == nullptr) {
+		warning("Target Buffer Not Defined...DCImage!"); // That's the original message... And yes, it's wrong: it's checking the source buffer :)
+		return;
+	}
+
+	// Only MCGA handled, the rest is skipped
+	uncompressBuffer(buffer, dest);
+	displayRawDataAtPos(dest, posX, posY);
+	displayFctFullScreen();
+	displayRawDataAtPos(dest, posX, posY);
+}
+
+} // End of namespace Efh
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index cd1d0983a97..158d389f1c3 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -3,6 +3,8 @@ MODULE := engines/efh
 MODULE_OBJS = \
 	constants.o \
 	efh.o \
+	graphics.o \
+	utils.o \
 	metaengine.o
 
 MODULE_DIRS += \
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
new file mode 100644
index 00000000000..e8b99457842
--- /dev/null
+++ b/engines/efh/utils.cpp
@@ -0,0 +1,318 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "efh/efh.h"
+#include "common/system.h"
+#include "common/random.h"
+
+namespace Efh {
+
+int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
+	Common::File f;
+	if (!f.open(filename))
+		error("Unable to find file %s", filename.c_str());
+
+	int size = f.size();
+
+	return f.read(destBuffer, size);
+}
+
+void EfhEngine::setDefaultNoteDuration() {
+	// Original implementation is based on the int1C, which is triggered at 18.2065Hz.
+	// Every 4 times, it sets a flag (thus, approx every 220ms)
+	// The function was checking the keyboard in a loop, incrementing a counter and setting the last character read
+	// The "_defaultNoteDuration" was then set to 7 times this counter
+	//
+	// No implementation required in ScummVM
+}
+
+void EfhEngine::decryptImpFile(bool techMapFl) {
+	uint16 counter = 0;
+	uint16 target;
+	uint8 *curPtr;
+
+	if (!techMapFl) {
+		_imp2PtrArray[counter++] = curPtr = _imp2;
+		target = 431;
+	} else {
+		_imp2PtrArray[counter++] = curPtr = _imp1;
+		target = 99;
+	}
+
+	do {
+		*curPtr = (*curPtr - 3) ^ 0xD7;
+		if (*curPtr == 0x40) {
+			curPtr += 3;
+			if (!techMapFl)
+				_imp2PtrArray[counter++] = curPtr;
+			else
+				_imp1PtrArray[counter++] = curPtr;
+		} else
+			++curPtr;
+	} while (*curPtr != 0x60 && counter <= target);
+
+// TODO: remove the dump part
+	Common::DumpFile dump;
+	if (!techMapFl) {
+		dump.open("imp2_unc.dump");
+		dump.write(_imp2, curPtr - _imp2);
+	} else {
+		dump.open("imp1_unc.dump");
+		dump.write(_imp1, curPtr - _imp1);
+	}
+	dump.flush();
+	dump.close();
+}
+
+void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
+	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
+	rImageFile(fileName, buffer, subFilesArray, destBuffer);
+}
+
+void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
+	readFileToBuffer(filename, packedBuffer);
+	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
+	// TODO: Keep this dump for debug purposes only
+	Common::DumpFile dump;
+	dump.open(filename + ".dump");
+	dump.write(targetBuffer, size);
+	dump.flush();
+	dump.close();
+	// End of dump
+
+	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
+	// => Write a class to handle that more properly
+	uint8 *ptr = targetBuffer;
+	uint16 counter = 0;
+	while (READ_LE_INT16(ptr) != 0) {
+		subFilesArray[counter] = ptr;
+		++counter;
+		int16 imageWidth = READ_LE_INT16(ptr);
+		ptr += 2;
+		int16 imageHeight = READ_LE_INT16(ptr);
+		ptr += 2;
+		ptr += (imageWidth * imageHeight);
+	}
+}
+
+uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
+	if (compressedBuf == nullptr || destBuf == nullptr)
+		error("uncompressBuffer - Invalid pointer used in parameter list");
+
+	uint8 *curPtrDest = destBuf;
+
+	uint16 compSize = READ_LE_UINT16(compressedBuf) + 1;
+	uint8 *curPtrCompressed = compressedBuf + 2;
+
+	// Not in the original. This has been added for debug purposes (the original function doesn't return a value)
+	uint32 decompSize = 0;
+
+	for (;;) {
+		uint8 next = *curPtrCompressed++;
+		if (--compSize <= 0)
+			break;
+
+		if (next != 0xC3) {
+			*curPtrDest++ = next;
+			++decompSize;
+			continue;
+		}
+
+		next = *curPtrCompressed++;
+		if (--compSize <= 0)
+			break;
+
+		if (next == 0) {
+			*curPtrDest++ = 0xC3;
+			++decompSize;
+			continue;
+		}
+
+		uint8 loopVal = next;
+		next = *curPtrCompressed++;
+
+		for (int i = 0; i < loopVal; ++i) {
+			*curPtrDest++ = next;
+			++decompSize;
+		}
+
+		--compSize;
+		if (compSize == 0)
+			break;
+	}
+
+	curPtrDest[0] = curPtrDest[1] = 0;
+	decompSize += 2;
+
+	return decompSize;
+}
+
+int16 EfhEngine::getRandom(int16 maxVal) {
+	if (maxVal == 0)
+		return 0;
+
+	return 1 + _rnd->getRandomNumber(maxVal - 1);
+}
+
+Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0 && lastChar == Common::KEYCODE_INVALID) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+	}
+
+	return lastChar;
+}
+
+Common::KeyCode EfhEngine::getInput(int16 delay) {
+	if (delay == 0)
+		return Common::KEYCODE_INVALID;
+
+	Common::KeyCode lastChar = Common::KEYCODE_INVALID;
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (delay > 0) {
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			--delay;
+			unkFct_anim();
+		}
+
+		lastChar = handleAndMapInput(false);
+		if (lastChar != Common::KEYCODE_INVALID)
+			retVal = lastChar;
+	}
+
+	return retVal;
+}
+
+Common::KeyCode EfhEngine::waitForKey() {
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+	Common::Event event;
+
+	uint32 lastMs = _system->getMillis();
+	while (retVal == Common::KEYCODE_INVALID) { // TODO: Check shouldquit()
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 200) {
+			lastMs = newMs;
+			unkFct_anim();
+		}
+
+		_system->getEventManager()->pollEvent(event);
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = event.kbd.keycode;
+		}
+	}
+
+	return retVal;
+}
+
+Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
+	// Original is doing:
+	// if input < a or > z : return input
+	// else return (input + 0xE0)
+	// ex: 'a' = 0x61 + 0xE0 = 0x0141, but it's a uint8 so it's 0x41 which is 'A'.
+	// So basically the original works with uppercase letters and do not alter the other inputs.
+	// => no implementation needed.
+	return input;
+}
+
+Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
+	// The original checks for the joystick input
+	Common::Event event;
+	_system->getEventManager()->pollEvent(event);
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+	if (event.type == Common::EVENT_KEYUP) {
+		retVal = event.kbd.keycode;
+	}
+
+	if (animFl) {
+		warning("STUB - handleAndMapInput - animFl");
+	}
+	return retVal;
+}
+
+Common::KeyCode EfhEngine::getInputBlocking() {
+	// The original checks for the joystick input
+	Common::Event event;
+	_system->getEventManager()->pollEvent(event);
+	Common::KeyCode retVal = Common::KEYCODE_INVALID;
+
+	uint32 lastMs = _system->getMillis();
+	while (retVal == Common::KEYCODE_INVALID) {
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = event.kbd.keycode;
+		}
+
+		_system->delayMillis(20);
+		uint32 newMs = _system->getMillis();
+
+		if (newMs - lastMs >= 220) {
+			lastMs = newMs;
+			unkFct_anim();
+		}
+	}
+	return retVal;
+}
+
+void EfhEngine::setNumLock() {
+	// No implementation in ScummVM
+}
+
+void EfhEngine::copyString(char *srcStr, char *destStr) {
+	char lastChar = 1;
+	int16 idx = 0;
+
+	while (lastChar != 0) {
+		lastChar = destStr[idx] = srcStr[idx];
+		++idx;
+	}
+}
+
+bool EfhEngine::getValidationFromUser() {
+	Common::KeyCode input = handleAndMapInput(true);
+	if (input == Common::KEYCODE_y) // or if joystick button 1
+		return true;
+
+	return false;
+}
+
+} // End of namespace Efh


Commit: 6cc1cc1a25ba79de6fb59653fa648515a3968f87
    https://github.com/scummvm/scummvm/commit/6cc1cc1a25ba79de6fb59653fa648515a3968f87
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
Fix selectOtherCharFromTeam()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2dde75fa0b3..ac758755e41 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3478,7 +3478,7 @@ void EfhEngine::setCharacterObjectToBroken(int16 charId, int16 objectId) {
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 }
 
-Common::KeyCode EfhEngine::selectOtherCharFromTeam() {
+int16 EfhEngine::selectOtherCharFromTeam() {
 	Common::KeyCode maxVal = (Common::KeyCode) (Common::KEYCODE_0 + _teamSize);
 	Common::KeyCode input = Common::KEYCODE_INVALID; 
 	for (;;) {
@@ -3487,7 +3487,10 @@ Common::KeyCode EfhEngine::selectOtherCharFromTeam() {
 			break;
 	}
 
-	return input;
+	if (input == Common::KEYCODE_ESCAPE)
+		return 0x1B;
+
+	return (int16)input - (int16)Common::KEYCODE_0;
 }
 
 int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 60a4407ea2b..89844c5566b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -367,7 +367,7 @@ private:
 	bool sub1BA9B(int16 groupId, int16 id);
 	int16 sub15538(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
-	Common::KeyCode selectOtherCharFromTeam();
+	int16 selectOtherCharFromTeam();
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	bool sub16E14();


Commit: 36744e2dd3d88e147de93baad26752122d3b5ad6
    https://github.com/scummvm/scummvm/commit/36744e2dd3d88e147de93baad26752122d3b5ad6
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:34+01:00

Commit Message:
EFH: Some renaming, fix a couple of issues

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ac758755e41..b3ff1f702ad 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3384,7 +3384,7 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 }
 
 int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	int16 var2 = 0;
+	int16 retVal = 0;
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
 		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
@@ -3394,7 +3394,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 			script_parse((uint8 *)str, 28, 122, 105, 166, 0);
 			displayFctFullScreen();
 		} else {
-			var2 = script_parse((uint8 *)str, 28, 122, 105, 166, -1);
+			retVal = script_parse((uint8 *)str, 28, 122, 105, 166, -1);
 		}
 	}
 
@@ -3403,7 +3403,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 		sub18E80(charId, windowId, menuId, curMenuLine);
 	}
 	
-	return var2;
+	return retVal;
 }
 
 bool EfhEngine::isItemCursed(int16 itemId) {
@@ -3497,8 +3497,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	char buffer1[80];
 	char buffer2[80];
 
-	int16 varA6 = 0;
-	int16 varA4 = 0;
+	bool varA6 = false;
+	bool retVal = false;
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 	switch (_items[itemId].field_16 - 1) {
@@ -3506,51 +3506,51 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			int16 varAE = 0;
+			int16 victims = 0;
 			strcat((char *)_messageToBePrinted, "  The item emits a low droning hum...");
 			if (getRandom(100) < 50) {
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					if (sub1BA9B(windowId, varA8)) {
-						++varAE;
-						_stru32686[windowId]._field0[varA8] = 1;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
+				for (int16 counter = 0; counter < 9; ++counter) {
+					if (sub1BA9B(windowId, counter)) {
+						++victims;
+						_stru32686[windowId]._field0[counter] = 1;
+						_stru32686[windowId]._field2[counter] = getRandom(8);
 					}
 				}
 			} else {
-				int16 varAC = getRandom(9);
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					if (varAC == 0)
+				int16 NumberOfTargets = getRandom(9);
+				for (int16 counter = 0; counter < 9; ++counter) {
+					if (NumberOfTargets == 0)
 						break;
 
-					if (sub1BA9B(windowId, varA8)) {
-						++varAE;
-						--varAC;
-						_stru32686[windowId]._field0[varA8] = 1;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					if (sub1BA9B(windowId, counter)) {
+						++victims;
+						--NumberOfTargets;
+						_stru32686[windowId]._field0[counter] = 1;
+						_stru32686[windowId]._field2[counter] = getRandom(8);
 					}
 				}
 			}
 			// The original was duplicating this code in each branch of the previous random check. 
-			if (varAE > 1) {
-				sprintf(buffer1, "%d %ss fall asleep!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			if (victims > 1) {
+				sprintf(buffer1, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s falls asleep!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
 			}
 			strcat((char *)_messageToBePrinted, buffer1);
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 1:
 		if (argA == 2) {
 			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			strcat((char *)_messageToBePrinted, "  The item emits a blue beam...");
-			int16 varAE = 0;
+			int16 victim = 0;
 			if (getRandom(100) < 50) {
 				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
 					if (sub1BA9B(windowId, varA8)) {
-						++varAE;
+						++victim;
 						_stru32686[windowId]._field0[varA8] = 2;
 						_stru32686[windowId]._field2[varA8] = getRandom(8);
 					}
@@ -3562,7 +3562,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 						break;
 
 					if (sub1BA9B(windowId, varA8)) {
-						++varAE;
+						++victim;
 						--varAC;
 						_stru32686[windowId]._field0[varA8] = 2;
 						_stru32686[windowId]._field2[varA8] = getRandom(8);
@@ -3571,16 +3571,16 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			}
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
-			if (varAE > 1) {
-				sprintf(buffer1, "%d %ss are frozen in place!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+			if (victim > 1) {
+				sprintf(buffer1, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s is frozen in place!", varAE, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
 			}
 			strcat((char *)_messageToBePrinted, buffer1);
 			// </CHECKME>
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 2:
 		if (argA == 2) {
@@ -3590,7 +3590,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			_unkArray2C8AA[0] = 0;
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 4:
 		if (argA == 2) {
@@ -3598,23 +3598,23 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		} else {
 			strcat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!");
 			if (getRandom(100) < 50) {
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+				for (int16 counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
 				}
 			} else {
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					if (sub1BA9B(windowId, varA8)) {
+				for (int16 counter = 0; counter < 9; ++counter) {
+					if (sub1BA9B(windowId, counter)) {
 						if (getRandom(100) < 50) {
-							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 						}
 						break;
 					}
 				}				
 			}
 		}
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 5:
 		if (argA == 2) {
@@ -3622,20 +3622,20 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		} else {
 			if (getRandom(100) < 50) {
 				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!");
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+				for (int16 counter = 0; counter < 9; ++counter) {
+					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 				}
 			} else {
 				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!");
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					if (sub1BA9B(windowId, varA8)) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[varA8] = 0;
+				for (int16 counter = 0; counter < 9; ++counter) {
+					if (sub1BA9B(windowId, counter)) {
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
 				}				
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 12:
 		if (argA == 2) {
@@ -3644,7 +3644,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			strcat((char *)_messageToBePrinted, "  The magic sparkles brilliant hues in the air!");
 			sub1E028(windowId, _items[itemId].field17_attackTypeDefense, true);
 		}
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 14: {
 		int16 varAA;
@@ -3667,19 +3667,19 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_word32482[varAA] = 0;
 		}
 		
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 15: {
-		int16 varAA;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else {
-			varAA = windowId;
+			teamCharId = windowId;
 		}
 
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) {
 			strcpy(buffer1, "  The magic makes the user invisible!");
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine); 
@@ -3687,12 +3687,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				strcat((char *)_messageToBePrinted, buffer1);
 			}
 
-			_word32680[varAA] -= 50;
-			if (_word32680[varAA] < 0)
-				_word32680[varAA] = 0;
+			_word32680[teamCharId] -= 50;
+			if (_word32680[teamCharId] < 0)
+				_word32680[teamCharId] = 0;
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 16: {
@@ -3709,7 +3709,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strcat((char *)_messageToBePrinted, buffer1);
-				varA4 = -1;
+				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
@@ -3719,7 +3719,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					strcat((char *)_messageToBePrinted, buffer1);
-					varA4 = -1;
+					retVal = true;
 				}
 			} else {
 				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
@@ -3727,12 +3727,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					strcat((char *)_messageToBePrinted, buffer1);
-					varA4 = -1;
+					retVal = true;
 				}
 			}
 		}
 
-		varA6 = -1;		
+		varA6 = true;		
 		}
 		break;
 	case 17: {
@@ -3746,7 +3746,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strcat((char *)_messageToBePrinted, buffer1);
-				varA4 = -1;
+				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
@@ -3756,7 +3756,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					strcat((char *)_messageToBePrinted, buffer1);
-					varA4 = -1;
+					retVal = true;
 				}
 			} else {
 				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
@@ -3764,31 +3764,31 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					strcat((char *)_messageToBePrinted, buffer1);
-					varA4 = -1;
+					retVal = true;
 				}
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 18:
 		if (argA == 2) {
 			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			int16 varAA = windowId;
-			if (varAA != 0x1B) {
-				if (_teamCharStatus[varAA]._status == 2) { // frozen
+			int16 teamCharId = windowId;
+			if (teamCharId != 0x1B) {
+				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
 					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
-					_teamCharStatus[varAA]._status = 0;
-					_teamCharStatus[varAA]._duration = 0;
+					_teamCharStatus[teamCharId]._status = 0;
+					_teamCharStatus[teamCharId]._duration = 0;
 				} else {
 					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
 				}
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 19:
 		strcpy(buffer1, "  * The item breaks!");
@@ -3798,7 +3798,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			strcat((char *)_messageToBePrinted, buffer1);
 		}
 		setCharacterObjectToBroken(charId, objectId);
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 23:
 		copyString(_items[itemId]._name, buffer2);
@@ -3833,28 +3833,28 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			strcat((char *)_messageToBePrinted, buffer1);
-			varA4 = -1;
+			retVal = true;
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 24: {
-		int16 varAA;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else
-			varAA = windowId;
+			teamCharId = windowId;
 
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 varAC = getRandom(_items[itemId].field_19);
-			_npcBuf[_teamCharId[varAA]]._activeScore[varAE] += varAC;
-			if (_npcBuf[_teamCharId[varAA]]._activeScore[varAE] > 20) {
-				_npcBuf[_teamCharId[varAA]]._activeScore[varAE] = 20;
+			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
+				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
 			}
-			if (varAC > 1)
-				sprintf(buffer1, "%s increased %d points!", kSkillArray[varAE], varAC);
+			if (effectPoints > 1)
+				sprintf(buffer1, "%s increased %d points!", kSkillArray[varAE], effectPoints);
 			else
 				sprintf(buffer1, "%s increased 1 point!", kSkillArray[varAE]);
 
@@ -3862,30 +3862,30 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strcat((char *)_messageToBePrinted, buffer1);
-				varA4 = -1;
+				retVal = true;
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 25: {
-			int16 varAA;
+			int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else
-			varAA = windowId;
+			teamCharId = windowId;
 
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 varAC = getRandom(_items[itemId].field_19);
-			_npcBuf[_teamCharId[varAA]]._activeScore[varAE] -= varAC;
-			if (_npcBuf[_teamCharId[varAA]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[varAA]]._activeScore[varAE] < 0) {
-				_npcBuf[_teamCharId[varAA]]._activeScore[varAE] = 1;
+			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
+				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
 			}
-			if (varAC > 1)
-				sprintf(buffer1, "%s lowered %d points!", kSkillArray[varAE], varAC);
+			if (effectPoints > 1)
+				sprintf(buffer1, "%s lowered %d points!", kSkillArray[varAE], effectPoints);
 			else
 				sprintf(buffer1, "%s lowered 1 point!", kSkillArray[varAE]);
 
@@ -3893,11 +3893,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strcat((char *)_messageToBePrinted, buffer1);
-				varA4 = -1;
+				retVal = true;
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 26:
@@ -3906,71 +3906,71 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			strcat((char *)_messageToBePrinted, buffer1);
-			varA4 = -1;
+			retVal = true;
 		}
 		totalPartyKill();
 		// emptyFunction(2);
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 27: {
-		int16 varAA;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else {
-			varAA = windowId;
+			teamCharId = windowId;
 		}
 
-		if (varAA != 0x1B) {
-			_npcBuf[_teamCharId[varAA]]._hitPoints = 0;
-			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+		if (teamCharId != 0x1B) {
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
+			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
 			sprintf(buffer1, "%s collapses, dead!!!", buffer2);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strcat((char *)_messageToBePrinted, buffer1);
-				varA4 = -1;
+				retVal = true;
 			}
 			// emptyFunction(2);
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 28:
 		if (argA == 2) {
 			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			int16 varAA = windowId;
-			if (varAA != 0x1B) {
-				if (_teamCharStatus[varAA]._status == 0) {
+			int16 teamCharId = windowId;
+			if (teamCharId != 0x1B) {
+				if (_teamCharStatus[teamCharId]._status == 0) {
 					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
-					_teamCharStatus[varAA]._status = 0;
-					_teamCharStatus[varAA]._duration = 0; 
+					_teamCharStatus[teamCharId]._status = 0;
+					_teamCharStatus[teamCharId]._duration = 0; 
 				} else {
 					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
 				}
 			}
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		break;
 	case 29: {
-		int16 varAA;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else {
-			varAA = windowId;
+			teamCharId = windowId;
 		}
 		
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) {
 			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[varA4]]._hitPoints += varAE;
-			if (_npcBuf[_teamCharId[varA4]]._hitPoints > _npcBuf[_teamCharId[varA4]]._maxHP)
-				_npcBuf[_teamCharId[varA4]]._hitPoints = _npcBuf[_teamCharId[varA4]]._maxHP;
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints += varAE;
+			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
+				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
 
-			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
 			if (varAE > 1)
 				sprintf(buffer1, "%s is healed %d points!", buffer2, varAE);
 			else
@@ -3981,28 +3981,28 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			strcat((char *)_messageToBePrinted, buffer1);
-			varA4 = -1;
+			retVal = true;
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		}
 		break;
 	case 30: {
-		int16 varAA;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else {
-			varAA = windowId;
+			teamCharId = windowId;
 		}
 
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) {
 			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[varA4]]._hitPoints -= varAE;
-			if (_npcBuf[_teamCharId[varA4]]._hitPoints < 0)
-				_npcBuf[_teamCharId[varA4]]._hitPoints = 0;
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= varAE;
+			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
+				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 
-			copyString(_npcBuf[_teamCharId[varAA]]._name, buffer2);
+			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
 			if (varAE > 1)
 				sprintf(buffer1, "%s is harmed for %d points!", buffer2, varAE);
 			else
@@ -4013,10 +4013,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			strcat((char *)_messageToBePrinted, buffer1);
-			varA4 = -1;
+			retVal = true;
 		}
 
-		varA6 = -1;
+		varA6 = true;
 		
 		}
 		break;
@@ -4035,7 +4035,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	}
 
-	if (varA6 != 0) {
+	if (varA6) {
 		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
 			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
 			if (varA1 <= 0) {
@@ -4059,7 +4059,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 	}
 
-	return varA4;
+	return retVal;
 }
 
 int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
@@ -4067,8 +4067,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	int16 var16 = -1;
 	int16 windowId = -1;
 	int16 curMenuLine = -1;
-	int16 var10 = 0;
-	int16 var2 = 0;
+	bool var10 = false;
+	bool var2 = false;
 
 	saveAnimImageSetId();
 
@@ -4151,7 +4151,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				if (_menuDepth == 0) {
 					menuId = windowId;
 					if (menuId > 7)
-						var10 = -1;
+						var10 = true;
 					else {
 						_menuDepth = 1;
 						curMenuLine = 0;
@@ -4164,7 +4164,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 					} else {
 						var16 = curMenuLine;
-						var10 = -1;
+						var10 = true;
 					}
 				}
 				break;
@@ -4212,6 +4212,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					}
 				}
 				break;
+			default:
+				break;
 			}
 
 			if (curMenuLine == -1)
@@ -4219,7 +4221,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			else
 				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 
-		} while (var10 == 0);
+		} while (!var10);
 
 		bool validationFl = true;
 
@@ -4290,17 +4292,17 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				sub18E80(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
-					int16 var6;
+					bool var6;
 					int16 var8;
 					do {
 						if (_teamCharId[2] != -1) {
 							var8 = displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
-							var2 = 0;
+							var2 = false;
 						} else if (_teamCharId[1]) {
 							var8 = 0x1A;
-							var2 = 0;
+							var2 = false;
 						} else {
-							var2 = -1;
+							var2 = true;
 							if (_teamCharId[0] == charId)
 								var8 = 1;
 							else
@@ -4309,7 +4311,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 						if (var8 != 0x1A && var8 != 0x1B) {
 							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
-							if (var6 == 0) {
+							if (!var6) {
 								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
 								getLastCharAfterAnimCount(_guessAnimationAmount);
 							}
@@ -4319,9 +4321,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 								getLastCharAfterAnimCount(_guessAnimationAmount);
 								var8 = 0x1B;
 							}
-							var6 = 0;
+							var6 = false;
 						}
-					} while (var6 == 0 && var2 == 0 && var8 != 0x1B);
+					} while (!var6 && !var2 && var8 != 0x1B);
 
 					if (var6) {
 						removeObject(charId, objectId);
@@ -4399,10 +4401,12 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				}
 			}
 			break;
+		default:
+			break;
 		}
 
 		if (menuId != 8) {
-			var10 = 0;
+			var10 = false;
 			_menuDepth = 0;
 			menuId = 9;
 			var16 = -1;
@@ -4465,7 +4469,7 @@ bool EfhEngine::sub16E14() {
 					sprintf(buffer, "with %d %s", var6A, dest);
 				} else if (var1 == 0x3E) {
 					strcpy(buffer, "(NOT DEFINED)");
-				} else if (var1 == 0x3F) { // Useless if, it's the last possible value
+				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
 					copyString(_npcBuf[_mapMonsters[monsterId]._MonsterRef]._name, dest);
 					sprintf(buffer, "with %s", dest);
 				}


Commit: 232e260453a3f858080cce3d67ec1874ad027c97
    https://github.com/scummvm/scummvm/commit/232e260453a3f858080cce3d67ec1874ad027c97
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Fix handleCharacterJoining, add chooseCharacterToReplace

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b3ff1f702ad..a0526edecf6 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -611,6 +611,8 @@ void EfhEngine::readItems() {
 		_items[i].field_18 = *curPtr++;
 		_items[i].field_19 = *curPtr++;
 		_items[i].field_1A = *curPtr++;
+
+		warning("%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
 	}
 }
 
@@ -1422,8 +1424,18 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
 }
 
 int16 EfhEngine::chooseCharacterToReplace() {
-	warning("STUB - chooseCharacterToReplace");
-	return 0x1B;
+	Common::KeyCode maxVal = (Common::KeyCode)(Common::KEYCODE_0 + _teamSize);
+	Common::KeyCode input = Common::KEYCODE_INVALID;
+	for (;;) {
+		input = waitForKey();
+		if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0 || (input > Common::KEYCODE_1 && input <= maxVal))
+			break;
+	}
+
+	if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0)
+		return 0x1B;
+
+	return (int16)input - (int16)Common::KEYCODE_1;
 }
 
 int16 EfhEngine::handleCharacterJoining() {
@@ -3487,10 +3499,10 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 			break;
 	}
 
-	if (input == Common::KEYCODE_ESCAPE)
+	if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0)
 		return 0x1B;
 
-	return (int16)input - (int16)Common::KEYCODE_0;
+	return (int16)input - (int16)Common::KEYCODE_1;
 }
 
 int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {


Commit: 5f3c36217e09925953fc7c64ba07ef22533f3acb
    https://github.com/scummvm/scummvm/commit/5f3c36217e09925953fc7c64ba07ef22533f3acb
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Implement some more stubs

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a0526edecf6..d294bdad7ca 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1942,7 +1942,35 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 }
 
 void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
-	warning("STUB: sub15A28");
+	_drawHeroOnMapFl = false;
+	int16 varE = arg0 - 11;
+	int16 varC = arg2 - 11;
+
+	if (varE < 0)
+		varE = 0;
+	if (varC < 0)
+		varC = 0;
+
+	for (int16 counter = 0; counter <= 23; counter += 2) {
+		for (int16 var8 = 0; var8 <= 23; ++var8) {
+			int16 var4 = counter + varE;
+			int16 var2 = var8 + varC;
+			_mapGameMapPtr[var2 + 64 * var4] = _curPlace[var8 + counter * 24];
+		}
+		redrawScreen();
+	}
+
+	for (int16 counter = 1; counter <= 23; counter += 2) {
+		for (int16 var8 = 0; var8 <= 23; ++var8) {
+			int16 var4 = counter + varE;
+			int16 var2 = var8 + varC;
+			_mapGameMapPtr[var2 + 64 * var4] = _curPlace[var8 + counter * 24];
+		}
+		redrawScreen();
+	}
+
+	getLastCharAfterAnimCount(3);
+	_drawHeroOnMapFl = true;
 }
 
 void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
@@ -2208,7 +2236,63 @@ void EfhEngine::handleNewRoundEffects() {
 }
 
 bool EfhEngine::handleDeathMenu() {
-	warning("STUB: handleDeathMenu");
+	displayAnimFrames(20, true);
+	_imageSetSubFilesIdx = 213;
+	redrawScreen();
+
+	for (int16 counter = 0; counter < 2; ++counter) {
+		unkFct_displayMenuBox_2(0);
+		displayCenteredString("Darkness Prevails...Death Has Taken You!", 24, 296, 153);
+		setTextPos(100, 162);
+		setTextColorWhite();
+		displayCharAtTextPos('L');
+		setTextColorRed();
+		displayStringAtTextPos("oad last saved game");
+		setTextPos(100, 171);
+		setTextColorWhite();
+		displayCharAtTextPos('R');
+		setTextColorRed();
+		displayStringAtTextPos("estart from beginning");
+		setTextPos(100, 180);
+		setTextColorWhite();
+		displayCharAtTextPos('Q');
+		setTextColorRed();
+		displayStringAtTextPos("uit for now");
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+
+	bool found;
+	for (found = false; !found;) {
+		Common::KeyCode input = waitForKey();
+		switch (input) {
+		case Common::KEYCODE_l:
+			loadGame();
+			found = true;
+			break;
+		case Common::KEYCODE_q:
+			return true;
+			break;
+		case Common::KEYCODE_r:
+			loadGame();
+			loadTechMapImp(0);
+			_largeMapFlag = true;
+			_oldMapPosX = _mapPosX = 31;
+			_oldMapPosY = _mapPosY = 31;
+			_unkRelatedToAnimImageSetId = 0;
+			*_unkArray2C8AA = 0;
+			found = true;
+			break;
+		case Common::KEYCODE_x:
+			if (!_word2C8D7)
+				found = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	displayAnimFrames(0xFE, true);
 	return false;
 }
 
@@ -3245,7 +3329,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 		if (itemId != 0x7FFF) {
 			if (_npcBuf[npcId]._inventory[_word3273A[counter]]._stat1 & 0x80) {
 				setTextPos(146, textPosY);
-				displayChar('E');
+				displayCharAtTextPos('E');
 			}
 		}
 
@@ -4636,9 +4720,10 @@ void EfhEngine::loadGame() {
 }
 
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
-	int size = _largeMapFlag ? 64 : 24;
+	if (_largeMapFlag)
+		return _mapGameMapPtr[mapPosX * 64 + mapPosY];
 
-	return _mapGameMapPtr[mapPosX * size + mapPosY];
+	return _curPlace[mapPosX * 24 + mapPosY];
 }
 
 void EfhEngine::displayNextAnimFrame() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 89844c5566b..898569f33ed 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -399,7 +399,7 @@ private:
 	void displayStringAtTextPos(const char *message);
 	void unkFct_displayMenuBox_2(int16 color);
 	void setNextCharacterPos();
-	void displayChar(char character);
+	void displayCharAtTextPos(char character);
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 
 	// Utils
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 47a81e7c019..1ba34542533 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -320,7 +320,7 @@ void EfhEngine::setNextCharacterPos() {
 		_textPosY = 0;
 }
 
-void EfhEngine::displayChar(char character) {
+void EfhEngine::displayCharAtTextPos(char character) {
 	char buffer[2];
 	buffer[0] = character;
 	buffer[1] = 0;


Commit: c8ee5e07dd8ed98cd5e611ceecfe4e64328fdc57
    https://github.com/scummvm/scummvm/commit/c8ee5e07dd8ed98cd5e611ceecfe4e64328fdc57
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Fix issue in sub221FA()

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d294bdad7ca..5ef6cd2fbe6 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1937,6 +1937,8 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 				_dword2C856 = impArray;
 				sub133E5(impArray, 17, 115, 110, 133, 0);
 			}
+			if (counter == 0 && flag)
+				displayFctFullScreen();
 		}
 	}
 }


Commit: 468aeeaa272a69f91c5cb8b1d1e33e8a7c7da5f2
    https://github.com/scummvm/scummvm/commit/468aeeaa272a69f91c5cb8b1d1e33e8a7c7da5f2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Add 3 missing key mapped in main loop (some more are still missing)

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 5ef6cd2fbe6..6256376fbe5 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -400,7 +400,30 @@ Common::Error EfhEngine::run() {
 			goNorthWest();
 			_imageSetSubFilesIdx = 147;
 			break;
-
+		case Common::KEYCODE_F1:
+			if (_teamCharId[0] != -1) {
+				handleStatusMenu(1, _teamCharId[0]);
+				_dword2C856 = nullptr;
+				sub15150(true);
+				_redrawNeededFl = true;
+			}
+			break;
+		case Common::KEYCODE_F2:
+			if (_teamCharId[1] != -1) {
+				handleStatusMenu(1, _teamCharId[1]);
+				_dword2C856 = nullptr;
+				sub15150(true);
+				_redrawNeededFl = true;
+			}
+			break;
+		case Common::KEYCODE_F3:
+			if (_teamCharId[2] != -1) {
+				handleStatusMenu(1, _teamCharId[2]);
+				_dword2C856 = nullptr;
+				sub15150(true);
+				_redrawNeededFl = true;
+			}
+			break;
 		default:
 			if (retVal != Common::KEYCODE_INVALID)
 				warning("Main Loop: Unhandled input %d", retVal);


Commit: 2cf05c04326ff7d5de2ce1f28fbcfafe96e3180e
    https://github.com/scummvm/scummvm/commit/2cf05c04326ff7d5de2ce1f28fbcfafe96e3180e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Add keyboard mapping for save and load game

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6256376fbe5..c36a7c8975a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -424,6 +424,51 @@ Common::Error EfhEngine::run() {
 				_redrawNeededFl = true;
 			}
 			break;
+		case Common::KEYCODE_F5: { // Original is using CTRL-S
+			for (int16 counter = 0; counter < 2; ++counter) {
+				unkFct_displayMenuBox_2(0);
+				displayCenteredString("Are You Sure You Want To Save?", 24, 296, 160);
+				if (counter == 0)
+					displayFctFullScreen();
+			}
+			Common::KeyCode input = waitForKey();
+			if (input = Common::KEYCODE_y) {
+				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
+				getInput(2);
+				saveEfhGame();
+				unkFct_displayBox(0);
+				displayLowStatusScreen(true);
+			} else {
+				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
+				getInput(2);
+				unkFct_displayBox(0);
+				displayLowStatusScreen(true);
+			}
+			
+			}			
+			break;
+		case Common::KEYCODE_F7: { // Original is using CTRL-S
+			for (int16 counter = 0; counter < 2; ++counter) {
+				unkFct_displayMenuBox_2(0);
+				displayCenteredString("Are You Sure You Want To Load?", 24, 296, 160);
+				if (counter == 0)
+					displayFctFullScreen();
+			}
+			Common::KeyCode input = waitForKey();
+			if (input = Common::KEYCODE_y) {
+				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
+				getInput(2);
+				loadEfhGame();
+				unkFct_displayBox(0);
+				displayLowStatusScreen(true);
+			} else {
+				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
+				getInput(2);
+				unkFct_displayBox(0);
+				displayLowStatusScreen(true);
+			}
+
+		} break;
 		default:
 			if (retVal != Common::KEYCODE_INVALID)
 				warning("Main Loop: Unhandled input %d", retVal);
@@ -588,7 +633,6 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 }
 
 void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
-	//TODO : Remove unused parameter when all the calls are implemented
 	if (fullPlaceId == 0xFF)
 		return;
 
@@ -930,7 +974,7 @@ void EfhEngine::initEngine() {
 	// Note: The original at this point saves int 24h and sets a new int24 to handle fatal failure
 
 	checkProtection();
-	loadGame();
+	loadEfhGame();
 	_engineInitPending = false;
 }
 
@@ -2292,14 +2336,14 @@ bool EfhEngine::handleDeathMenu() {
 		Common::KeyCode input = waitForKey();
 		switch (input) {
 		case Common::KEYCODE_l:
-			loadGame();
+			loadEfhGame();
 			found = true;
 			break;
 		case Common::KEYCODE_q:
 			return true;
 			break;
 		case Common::KEYCODE_r:
-			loadGame();
+			loadEfhGame();
 			loadTechMapImp(0);
 			_largeMapFlag = true;
 			_oldMapPosX = _mapPosX = 31;
@@ -3189,6 +3233,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 
 bool EfhEngine::handleFight(int16 monsterId) {
 	warning("STUB - handleFight");
+	
 	return false;
 }
 
@@ -4691,7 +4736,7 @@ void EfhEngine::checkProtection() {
 	sub15150(true);	
 }
 
-void EfhEngine::loadGame() {
+void EfhEngine::loadEfhGame() {
 	// The original used a loop to check for the presence of the savegame on the current floppy.
 	// When the savegame wasn't found, it was displaying a screen asking for Disk 1 and was setting a flag used
 	// to call a function after loading right before returning.
@@ -4744,6 +4789,10 @@ void EfhEngine::loadGame() {
 	loadPlacesFile(_fullPlaceId, true);
 }
 
+void EfhEngine::saveEfhGame() {
+	warning("STUB - saveEfhGame");
+}
+
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	if (_largeMapFlag)
 		return _mapGameMapPtr[mapPosX * 64 + mapPosY];
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 898569f33ed..ab5338cc6bc 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -249,6 +249,7 @@ public:
 protected:
 	Common::EventManager *_eventMan;
 	int _lastTime;
+	void saveGame();
 	// Engine APIs
 	Common::Error run() override;
 	void handleMenu();
@@ -283,7 +284,8 @@ private:
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
 	void restoreAnimImageSetId();
 	void checkProtection();
-	void loadGame();
+	void loadEfhGame();
+	void saveEfhGame();
 	void copyCurrentPlaceToBuffer(int id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
 	void displayNextAnimFrame();
@@ -387,6 +389,7 @@ private:
 	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
 	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
 	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
+	void displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int posY);
 	void drawMapWindow();
 	void displayGameScreen();
 	void drawUpperLeftBorders();
@@ -401,6 +404,8 @@ private:
 	void setNextCharacterPos();
 	void displayCharAtTextPos(char character);
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
+	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
+	void unkFct_displayBox(int16 color);
 
 	// Utils
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 1ba34542533..2ef7f03015e 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -230,6 +230,12 @@ void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, i
 	drawString(str, startCenteredDisplayX, posY, _textColor);
 }
 
+void EfhEngine::displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int posY) {
+	displayCenteredString(str, minX, maxX, posY);
+	displayFctFullScreen();
+	displayCenteredString(str, minX, maxX, posY);
+}
+
 void EfhEngine::drawMapWindow() {
 	drawColoredRect(128, 8, 303, 135, 0);
 }
@@ -343,4 +349,14 @@ void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest
 	displayRawDataAtPos(dest, posX, posY);
 }
 
+void EfhEngine::displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color) {
+	drawColoredRect(minX, minY, maxX, maxY, color);
+	displayFctFullScreen();
+	drawColoredRect(minX, minY, maxX, maxY, color);
+}
+
+void EfhEngine::unkFct_displayBox(int16 color) {
+	displayColoredMenuBox(16, 152, 302, 189, color);
+}
+
 } // End of namespace Efh


Commit: 13e6100ec77b79e3948b3e21705ba4cd7ce8f5aa
    https://github.com/scummvm/scummvm/commit/13e6100ec77b79e3948b3e21705ba4cd7ce8f5aa
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Start working on handleFight

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 0e94b67c90f..6bc0bf44f5c 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -393,4 +393,6 @@ const uint8 kByte2C7D0[60] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
+const char kPossessive[3][4] = { 'his', 'her', 'its'};
+
 } // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 4112f4ee424..6aa94ee2af5 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -46,6 +46,7 @@ extern const Font kFontData[96];
 extern const Encounter kEncounters[];
 extern const char kSkillArray[37][20];
 extern const uint8 kByte2C7D0[60];
+extern const char kPossessive[3][4];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c36a7c8975a..80328350420 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -165,6 +165,11 @@ void Stru32686::init() {
 	}
 }
 
+void Stru3244C::init() {
+	_field0 = 0;
+	_field2 = 0;
+}
+
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 
@@ -224,11 +229,15 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	for (int i = 0; i < 20; ++i) {
 		_portraitSubFilesArray[i] = nullptr;
-		_ennemyNamePt2[i] = 0;
-		_characterNamePt2[i] = 0;
-		_nameBuffer[i] = 0;
 	}
 
+	memset(_characterNamePt1, 0, 5);
+	memset(_characterNamePt2, 0, 20);
+	memset(_enemyNamePt1, 0, 5);
+	memset(_enemyNamePt2, 0, 20);
+	memset(_nameBuffer, 0, 20);
+	memset(_attackBuffer, 0, 20);
+
 	for (int i = 0; i < 100; ++i) {
 		_imp1PtrArray[i] = nullptr;
 		_mapUnknown[i].init();
@@ -255,6 +264,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_unkArray2C8AA[i] = 0;
 		_word32680[i] = 0;
 		_word32482[i] = 0;
+		_word3267A[i] = -1;
+		_teamLastAction[i] = 0;
 	}
 
 	for (int i = 0; i < 5; ++i) {
@@ -298,6 +309,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	}
 
 	memset(_messageToBePrinted, 0, 400);
+	for (int i = 0; i < 8; ++i)
+		_stru3244C[i].init();
 }
 
 EfhEngine::~EfhEngine() {
@@ -1871,9 +1884,9 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
-					copyString(_npcBuf[_teamCharId[counter]]._name, _ennemyNamePt2);
+					copyString(_npcBuf[_teamCharId[counter]]._name, _enemyNamePt2);
 					copyString(_items[var110]._name, _nameBuffer);
-					sprintf(dest, "%s finds a %s!", _ennemyNamePt2, _nameBuffer);
+					sprintf(dest, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
@@ -2959,9 +2972,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		for (int16 counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
-				copyString(_npcBuf[var58]._name, _ennemyNamePt2);
+				copyString(_npcBuf[var58]._name, _enemyNamePt2);
 				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
-				sprintf(buffer, "%s asks that %s leave your party.", _ennemyNamePt2, _characterNamePt2);
+				sprintf(buffer, "%s asks that %s leave your party.", _enemyNamePt2, _characterNamePt2);
 				for (int16 i = 0; i < 2; ++i) {
 					unkFct_displayMenuBox_2(0);
 					_textColor = 0xE;
@@ -3231,10 +3244,442 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return _tileFact[imageSetId * 2];
 }
 
+void EfhEngine::sub1BCA7(int16 monsterId) {
+	warning("STUB: sub1BE89");
+}
+
+void EfhEngine::reset_stru32686() {
+	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
+		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+			_stru32686[counter1]._field0[counter2] = 0;
+			_stru32686[counter1]._field2[counter2] = 0;
+		}
+	}
+}
+
+void EfhEngine::sub1BE89(int16 monsterId) {
+	sub1BCA7(monsterId);
+	reset_stru32686();
+}
+
+void EfhEngine::resetTeamMonsterIdArray() {
+	for (int i = 0; i < 5; ++i) {
+		_teamMonsterIdArray[i] = -1;
+	}
+}
+
+bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
+	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
+		return true;
+
+	return false;
+}
+
+void EfhEngine::sub1CDFA() {
+	warning("STUB: sub1CDFA");
+}
+
+bool EfhEngine::sub1CB27() {
+	warning("STUB: sub1CB27");
+
+	return false;
+}
+
+void EfhEngine::sub1BE9A(int16 monsterId) {
+	warning("STUB sub1BE9A");
+}
+
+int16 EfhEngine::getTeamMonsterAnimId() {
+	int16 retVal = 0xFF;
+	for (int16 counter = 0; counter < 5; ++counter) {
+		int16 monsterGroupId = _teamMonsterIdArray[counter];
+		if (monsterGroupId == -1)
+			continue;
+
+		if (!unkFct_checkMonsterField8(monsterGroupId, false))
+			continue;
+
+		retVal = kEncounters[_mapMonsters[monsterGroupId]._MonsterRef]._animId;
+		break;
+	}
+
+	if (retVal == 0xFF)
+		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._MonsterRef]._animId;
+
+	return retVal;
+}
+
+void EfhEngine::sub1C4CA(bool WhiteFl) {
+	warning("STUB: sub1C4CA");
+}
+
+void EfhEngine::displayCombatMenu(int16 charId) {
+	char buffer[80];
+	copyString(_npcBuf[charId]._name, buffer);
+	strcat(buffer, ":");
+	setTextColorWhite();
+	setTextPos(144, 7);
+	displayStringAtTextPos(buffer);
+	setTextPos(152, 79);
+	displayStringAtTextPos("A");
+	setTextColorRed();
+	displayStringAtTextPos("ttack");
+	setTextPos(195, 79);
+	setTextColorWhite();
+	displayStringAtTextPos("H");
+	setTextColorRed();
+	displayStringAtTextPos("ide");
+	setTextPos(152, 88);
+	setTextColorWhite();
+	displayStringAtTextPos("D");
+	setTextColorRed();
+	displayStringAtTextPos("efend");
+	setTextPos(195, 88);
+	setTextColorWhite();
+	displayStringAtTextPos("R");
+	setTextColorRed();
+	displayStringAtTextPos("un");
+	setTextPos(152, 97);
+	setTextColorWhite();
+	displayStringAtTextPos("S");
+	setTextColorRed();
+	displayStringAtTextPos("tatus");
+}
+
+void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
+	for (int16 counter = 0; counter < 2; ++counter) {
+		if (counter == 0 || forceDrawFl) {
+			drawMapWindow();
+			displayCenteredString("Combat", 128, 303, 9);
+			drawColoredRect(200, 112, 278, 132, 0);
+			displayCenteredString("'T' for Terrain", 128, 303, 117);
+			sub1C219(nullptr, 1, 0, false);
+			sub1C4CA(whiteFl);
+			displayCombatMenu(charId);
+			displayLowStatusScreen(false);
+		}
+
+		if (counter == 0 && forceDrawFl)
+			displayFctFullScreen();
+	}
+}
+
+void EfhEngine::handleFight_checkEndEffect(int16 charId) {
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+	if (_teamCharStatus[charId]._status == 0)
+		return;
+	if (--_teamCharStatus[charId]._duration != 0)
+		return;
+
+	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
+	copyString(_npcBuf[_teamCharId[charId]]._name, _enemyNamePt2);
+	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
+		strcpy(_enemyNamePt1, "The ");
+	} else {
+		_enemyNamePt1[0] = 0;
+	}
+
+	// End of effect message depends on the type of effect
+	switch (_teamCharStatus[charId]._status) {
+	case 1:
+		sprintf((char *)_messageToBePrinted, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+		break;
+	case 2:
+		sprintf((char *)_messageToBePrinted, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+		break;
+	default:
+		sprintf((char *)_messageToBePrinted, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+		break;
+	}
+
+	// The character status is back to normal
+	_teamCharStatus[charId]._status = 0;
+
+	// Finally, display the message
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+int16 EfhEngine::sub1DEC8(int16 groupNumber) {
+	warning("STUB: sub1DEC8");
+	return -1;
+}
+
+int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
+	warning("STUB - getCharacterScore");
+	return 90;
+}
+
+bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
+	switch(_techData[_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
+	case 1:
+		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
+			return true;
+		return false;
+	case 2:
+		if ((itemId < 0x61 || itemId > 0x63) && (itemId < 0x74 || itemId > 0x76) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x5B || itemId > 0x5E) && (itemId < 0x66 || itemId > 0x68) && (itemId != 0x8C))
+			return true;
+		return false;
+	default:
+		return true;
+	}
+}
+
+void EfhEngine::generateSound(int16 soundType) {
+	warning("STUB: generateSound");
+}
+
+void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
+	if (repeatCount <= 0)
+		return;
+
+	switch (soundType) {
+	case 0:
+	case 1:
+	case 2:
+		generateSound(5);
+		break;
+	case 3:
+	case 4:
+	case 6:
+		generateSound(9);
+		break;
+	case 5:
+	case 7:
+		generateSound(13);
+		break;
+	case 8:
+	case 9:
+	case 10:
+		generateSound(10);
+		generateSound(9);
+		break;
+	case 14:
+		generateSound(14);
+		break;
+	case 11:
+	case 12:
+	case 13:
+		for (int16 counter = 0; counter < repeatCount; ++counter) {
+			generateSound(17);
+		}
+		break;
+	case 15:
+		generateSound(16);
+	default:
+		break;
+	}
+}
+
+void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+
+	int16 unk_monsterField5_itemId = sub1C80A(_teamCharId[teamCharId], 9, true);
+	if (unk_monsterField5_itemId == 0x7FFF)
+		unk_monsterField5_itemId = 0x3F;
+	int16 monsterGroupNumber = _word3267A[teamCharId];
+	if (monsterGroupNumber == 0x64)
+		monsterGroupNumber = 0;
+
+	if (monsterGroupNumber == -1)
+		return;
+	int16 var58;
+	if (_items[unk_monsterField5_itemId]._range == 4)
+		var58 = 5;
+	else
+		var58 = monsterGroupNumber + 1;
+
+	int16 var54;
+	int16 teamMemberId;
+	if (_items[unk_monsterField5_itemId]._range < 3) {
+		teamMemberId = sub1DEC8(monsterGroupNumber);
+		var54 = teamMemberId + 1;
+	} else {
+		teamMemberId = 0;
+		var54 = 9;
+	}
+
+	if (teamMemberId != -1) {
+		bool var6E = true;
+		for (int16 groupId = monsterGroupNumber; groupId < var58; ++groupId) {
+			if (_teamMonsterIdArray[groupId] == -1)
+				continue;
+
+			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
+				if (sub1BA9B(groupId, var7E) && var6E) {
+					int16 var5C;
+					if (unkFct_checkMonsterField8(groupId, true)) {
+						sub1E028(groupId, 9, true);
+						*_unkArray2C8AA += 500;
+						var5C = -1;
+					} else
+						var5C = 0;
+
+					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
+					int16 varInt = _teamCharId[teamCharId];
+					int16 var51 = _npcBuf[varInt]._possessivePronounSHL6;
+					var51 >>= 6;
+					int16 var70 = var51;
+					varInt = _teamMonsterIdArray[groupId];
+					int16 var5E = kEncounters[_mapMonsters[varInt]._MonsterRef]._nameArticle;
+					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
+					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
+					int16 var62 = 0;
+					int16 hitPoints = 0;
+					int16 originalDamage = 0;
+					int16 damagePointsAbsorbed = 0;
+					int16 var64 = _items[unk_monsterField5_itemId]._attacks *_npcBuf[_teamCharId[teamCharId]]._speed;
+
+					warning("STUB: handleFight - Action A - Loop var84");
+
+					if (originalDamage < 0)
+						originalDamage = 0;
+
+					hitPoints = originalDamage + damagePointsAbsorbed;
+					
+					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+						var62 = 0;
+
+					if (var62 > 0) {
+						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
+						if (var62 > 1) {
+							sprintf(_attackBuffer, "%d times ", var62);
+						} else {
+							*_attackBuffer = 0;
+						}
+					}
+					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+					int16 var6A = getRandom(3) - 1;
+					if (var5E == 2) {
+						strcpy(_characterNamePt1, "The ");
+					} else {
+						*_characterNamePt1 = 0;
+					}
+
+					if (var70 == 2) {
+						strcpy(_enemyNamePt1, "The ");
+					} else {
+						*_enemyNamePt1 = 0;
+					}
+
+					strcpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._MonsterRef]._name);
+					copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+					copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+						warning("STUB: handleFight - Action A - Check degats");
+						warning("STUB: handleFight - Action A - Shitload of checks in cascade");
+						warning("STUB: handleFight - Action A - Second Shitload of checks in cascade");
+						if (var5C)
+							strcat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...");
+
+						warning("STUB: handleFight - Action A - Check if item broke");
+						warning("STUB: handleFight - Action A - Check effect");						
+					} else {
+						sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn',27h,'t work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+					}
+
+					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+					sub1C219(_messageToBePrinted, 1, 2, true);
+				}
+			}
+		}
+	}
+}
+
 bool EfhEngine::handleFight(int16 monsterId) {
 	warning("STUB - handleFight");
-	
-	return false;
+
+	int16 var8C = 0;
+
+	sub1BE89(monsterId);
+
+	if (_teamMonsterIdArray[0] == -1) {
+		resetTeamMonsterIdArray();
+		_word2D0BC = false;
+		displayAnimFrames(0xFE, true);
+		return true;
+	}
+
+	drawCombatScreen(0, false, true);
+
+	for (bool mainLoopCond = false; !mainLoopCond;) {
+		if (isTPK()) {
+			resetTeamMonsterIdArray();
+			_word2D0BC = false;
+			displayAnimFrames(0xFE, true);
+			return false;
+		}
+
+		if (_teamMonsterIdArray[0] == -1) {
+			resetTeamMonsterIdArray();
+			_word2D0BC = false;
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+
+		int16 varInt = getTeamMonsterAnimId();
+		displayAnimFrames(varInt, true);
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			_word32680[counter] = 100;
+			_word32482[counter] = 65;
+		}
+
+		if (!sub1CB27()) {
+			resetTeamMonsterIdArray();
+			_word2D0BC = false;
+			totalPartyKill();
+			displayAnimFrames(0xFE, true);
+			return false;
+		}
+
+		for (int16 counter = 0; counter < _teamSize; ++counter) {
+			if (_teamLastAction[counter] == 0x52)
+				mainLoopCond = true;
+		}
+
+		sub1CDFA();
+		sub1C219(nullptr, 2, 1, false);
+
+		for (int16 counter = 0; counter < 8; ++counter) {
+			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
+			if (monsterGroupIdOrMonsterId == -1)
+				continue;
+			if (monsterGroupIdOrMonsterId > 999) {
+				monsterGroupIdOrMonsterId -= 1000;
+				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
+					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
+				} else {
+					switch (_teamLastAction[monsterGroupIdOrMonsterId]) {
+					case 0x41:// 'A'ttack
+						handleFight_lastAction_A(monsterGroupIdOrMonsterId);
+						break;
+					case 0x44: // 'D'efend
+						warning("STUB: handlefight - last action == 44h");
+						break;
+					case 0x48: // 'H'ide
+						warning("STUB: handlefight - last action == 48h");
+						break;
+					case 0x55: // 'U'
+						warning("STUB: handlefight - last action == 55h");
+						break;
+					default:
+						break;
+					}
+				}
+			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
+				warning("STUB - handleFight - loop var86");
+			}
+		}
+
+		sub174A0();
+		sub1BE9A(monsterId);
+	}
+
+	resetTeamMonsterIdArray();
+	_word2D0BC = false;
+	displayAnimFrames(0xFE, true);
+	return true;
 }
 
 void EfhEngine::displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index ab5338cc6bc..89b42d96127 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -221,6 +221,13 @@ struct Stru32686 {
 	void init();
 };
 
+struct Stru3244C {
+	int16 _field0;
+	int16 _field2;
+
+	void init();
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -350,6 +357,25 @@ private:
 	void sub22AA8(int16 arg0);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
+	void sub1BCA7(int16 monsterId);
+	void reset_stru32686();
+	void sub1BE89(int16 monsterId);
+	void resetTeamMonsterIdArray();
+	bool isTeamMemberStatusNormal(int16 id);
+	void sub1CDFA();
+	bool sub1CB27();
+	void sub1BE9A(int16 monsterId);
+	int16 getTeamMonsterAnimId();
+	void sub1C4CA(bool WhiteFl);
+	void displayCombatMenu(int16 charId);
+	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
+	void handleFight_checkEndEffect(int16 charId);
+	int16 sub1DEC8(int16 groupNumber);
+	int16 getCharacterScore(int16 charId, int16 itemId);
+	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
+	void generateSound(int16 soundType);
+	void genericGenerateSound(int16 soundType, int16 repeatCount);
+	void handleFight_lastAction_A(int16 teamCharId);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
 	void displayStatusMenu(int16 windowId);
@@ -451,9 +477,12 @@ private:
 	AnimInfo _animInfo[100];
 	uint8 _history[256];
 	uint8 _techData[4096];
-	char _ennemyNamePt2[20];
+	char _enemyNamePt1[5];
+	char _enemyNamePt2[20];
+	char _characterNamePt1[5];
 	char _characterNamePt2[20];
 	char _nameBuffer[20];
+	char _attackBuffer[20];
 	uint8 _messageToBePrinted[400];
 	
 	uint8 *_mapBitmapRef;
@@ -495,6 +524,7 @@ private:
 	int16 _teamMonsterIdArray[5];
 	CharStatus _teamCharStatus[3];
 	int16 _unkArray2C8AA[3];
+	int16 _teamLastAction[3];
 	int16 _teamSize;
 	int16 _word2C872;
 	bool _word2C880;
@@ -523,9 +553,11 @@ private:
 	int16 _word2D0BA;
 	int16 _word32680[3];
 	int16 _word32482[3];
+	int16 _word3267A[3];
 
 	int16 _word3273A[15];
 	Stru32686 _stru32686[5];
+	Stru3244C _stru3244C[8];
 };
 
 } // End of namespace Efh


Commit: c164d4854e66a222c6a96b00c962848466754d90
    https://github.com/scummvm/scummvm/commit/c164d4854e66a222c6a96b00c962848466754d90
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: More work on handleFight / Action A

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 6bc0bf44f5c..3416107495b 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -393,6 +393,59 @@ const uint8 kByte2C7D0[60] = {
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 
-const char kPossessive[3][4] = { 'his', 'her', 'its'};
+const char kPossessive[3][4] = { "his", "her", "its"};
 
+const char kAttackVerbs[51][20] = {
+	"hits",
+	"strikes",
+	"hits",
+	"slashes",
+	"hacks",
+	"slashes",
+	"stabs",
+	"sticks",
+	"pokes",
+	"pounds",
+	"bashes",
+	"hammers",
+	"blasts",
+	"blasts",
+	"roasts",
+	"blasts",
+	"chills",
+	"zaps",
+	"zaps",
+	"zaps",
+	"zaps",
+	"shoots",
+	"hits",
+	"strikes",
+	"zaps",
+	"zaps",
+	"zaps",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"blasts",
+	"shoots",
+	"shoots",
+	"blasts",
+	"shoots",
+	"shoots",
+	"blasts",
+	"shoots",
+	"shoots",
+	"gases",
+	"sprays",
+	"fumigates",
+	"shoots",
+	"shoots",
+	"shoots"
+};
 } // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 6aa94ee2af5..a9d65f4c9fb 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -47,6 +47,7 @@ extern const Encounter kEncounters[];
 extern const char kSkillArray[37][20];
 extern const uint8 kByte2C7D0[60];
 extern const char kPossessive[3][4];
+extern const char kAttackVerbs[51][20];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 80328350420..a0c45a1ff09 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3471,6 +3471,23 @@ void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
 	}
 }
 
+bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
+	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
+	
+	if (_items[itemId].field_16 != 0)
+		return false;
+
+	return _items[itemId].field17_attackTypeDefense == attackType;
+}
+
+void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
+	warning("STUB - getDeathTypeDescription");
+}
+
+void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {
+	warning("STUB - getXPAndSearchCorpse");
+}
+
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -3532,7 +3549,24 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var64 = _items[unk_monsterField5_itemId]._attacks *_npcBuf[_teamCharId[teamCharId]]._speed;
 
 					warning("STUB: handleFight - Action A - Loop var84");
-
+					// Action A - Loop var84 - Start
+					for (int16 var84 = 0; var84 < var64; ++var84) {
+						if (getRandom(100) < charScore) {
+							++var62;
+							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[unk_monsterField5_itemId]._attackType)) {
+								int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+								varInt = var7C - var76;
+								if (varInt > 0) {
+									originalDamage += varInt;
+									damagePointsAbsorbed += var76;
+								} else {
+									damagePointsAbsorbed += var7C;
+								}
+							}
+						}
+					}
+					// Action A - Loop var84 - End
+					
 					if (originalDamage < 0)
 						originalDamage = 0;
 
@@ -3567,7 +3601,29 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
 					copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
-						warning("STUB: handleFight - Action A - Check degats");
+						// Action A - Check damages - Start
+						if (var62 == 0) {
+							sprintf((char *)_messageToBePrinted, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+						} else if (hitPoints <= 0){
+							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+						} else if (hitPoints == 1) {
+							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+								getDeathTypeDescription(groupId, teamCharId + 1000);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+							} else {
+								strcat((char *)_messageToBePrinted, "!");
+							}
+						} else {
+							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+								getDeathTypeDescription(groupId, teamCharId + 1000);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+							} else {
+								strcat((char *)_messageToBePrinted, "!");
+							}
+						}
+						// Action A - Check damages - End
 						warning("STUB: handleFight - Action A - Shitload of checks in cascade");
 						warning("STUB: handleFight - Action A - Second Shitload of checks in cascade");
 						if (var5C)
@@ -3576,7 +3632,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						warning("STUB: handleFight - Action A - Check if item broke");
 						warning("STUB: handleFight - Action A - Check effect");						
 					} else {
-						sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn',27h,'t work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+						sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 89b42d96127..9b59535c7f4 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -375,6 +375,9 @@ private:
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	void generateSound(int16 soundType);
 	void genericGenerateSound(int16 soundType, int16 repeatCount);
+	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
+	void getDeathTypeDescription(int16 attackerId, int16 victimId);
+	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
 	void handleFight_lastAction_A(int16 teamCharId);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);


Commit: f3c3f6307610ac4ab51e00440b1dc2d38dc77d3d
    https://github.com/scummvm/scummvm/commit/f3c3f6307610ac4ab51e00440b1dc2d38dc77d3d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: More work on handleFight / Action A (2)

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a0c45a1ff09..2ccfd67cc55 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3488,6 +3488,124 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2,
 	warning("STUB - getXPAndSearchCorpse");
 }
 
+void EfhEngine::addReactionText(int16 id) {
+	int16 rand3 = getRandom(3);
+	char buffer[80];
+	memset(buffer, 0, 80);
+
+	switch (id) {
+	case 0:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 1:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 2:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 3:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 4:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s screams!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s bellows!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s shrills!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 5:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s chortles!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 6:
+		switch (rand3) {
+		case 1:
+			sprintf(buffer, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 2:
+			sprintf(buffer, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2);
+			break;
+		case 3:
+			sprintf(buffer, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2);
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+
+	strcat((char *)_messageToBePrinted, buffer);
+}
+
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -3624,8 +3742,41 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							}
 						}
 						// Action A - Check damages - End
-						warning("STUB: handleFight - Action A - Shitload of checks in cascade");
-						warning("STUB: handleFight - Action A - Second Shitload of checks in cascade");
+
+						// Action A - Add reaction text - Start
+						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] - 5 <= originalDamage) {
+								addReactionText(0);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 8) {
+								addReactionText(1);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 4) {
+								addReactionText(2);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 2) {
+								addReactionText(3);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 3) {
+								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+								addReactionText(4);
+							} else if (var80 / 8 >= originalDamage) {
+								addReactionText(5);
+							} else if (originalDamage == 0 && getRandom(100) < 35) {
+								addReactionText(6);
+							}
+						}
+						// Action A - Add reaction text - End
+
+						// Action A - Add armor absorb text - Start
+						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							char buffer[80];
+							memset(buffer, 0, 80);
+							if (damagePointsAbsorbed <= 1)
+								sprintf(buffer, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+							else
+								sprintf(buffer, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+
+							strcat((char *)_messageToBePrinted, buffer);
+						}
+						// Action A - Add armor absorb text - End
+
 						if (var5C)
 							strcat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...");
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 9b59535c7f4..ba7ac6d9a87 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -378,6 +378,7 @@ private:
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
+	void addReactionText(int16 id);
 	void handleFight_lastAction_A(int16 teamCharId);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);


Commit: 790f00cb9db6947876ec2110d5a3d02006651d25
    https://github.com/scummvm/scummvm/commit/790f00cb9db6947876ec2110d5a3d02006651d25
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Finish the implementation of handleFight / Action A

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2ccfd67cc55..43b8fc9e7cc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3780,8 +3780,44 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						if (var5C)
 							strcat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...");
 
-						warning("STUB: handleFight - Action A - Check if item broke");
-						warning("STUB: handleFight - Action A - Check effect");						
+						// Action A - Check item durability - Start
+						varInt = _teamCharId[teamCharId];
+						var64 = sub1C80A(varInt, 9, false);
+						if (var64 != 0x7FFF && (_npcBuf[varInt]._inventory[var64]._stat1 & 0x7F) != 0x7F) {
+							var51 = _npcBuf[varInt]._inventory[var64]._stat1 & 0x7F;
+							--var51;
+							if (var51 <= 0) {
+								char buffer[80];
+								memset(buffer, 0, 80);
+								sprintf(buffer, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer);
+								strcat((char *)_messageToBePrinted, buffer);
+								setCharacterObjectToBroken(varInt, var64);
+								var6E = false;
+							} else {
+								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + var51;
+							}
+						}
+						// Action A - Check item durability - End
+
+						// Action A - Check effect - Start
+						if (_items[unk_monsterField5_itemId].field_16 == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							if (getRandom(100) < 35) {
+								_stru32686[var7E]._field0[groupId] = 1;
+								_stru32686[var7E]._field2[groupId] = getRandom(10);
+								char buffer[80];
+								memset(buffer, 0, 80);
+								sprintf(buffer, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+								strcat((char *)_messageToBePrinted, buffer);
+							}
+						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							_stru32686[var7E]._field0[groupId] = 2;
+							_stru32686[var7E]._field2[groupId] = getRandom(10);
+							char buffer[80];
+							memset(buffer, 0, 80);
+							sprintf(buffer, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+							strcat((char *)_messageToBePrinted, buffer);
+						}
+						// Action A - Check effect - End
 					} else {
 						sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 					}


Commit: f63a39055d729c85906b67a91f2fbaf29cc93f6e
    https://github.com/scummvm/scummvm/commit/f63a39055d729c85906b67a91f2fbaf29cc93f6e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Implement handlefight - lastAction D, H and U

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 3416107495b..2deb3ec0782 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -394,6 +394,7 @@ const uint8 kByte2C7D0[60] = {
 };
 
 const char kPossessive[3][4] = { "his", "her", "its"};
+const char kPersonal[3][4] = {"him", "her", "it"};
 
 const char kAttackVerbs[51][20] = {
 	"hits",
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index a9d65f4c9fb..0fced1a00fa 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -47,6 +47,7 @@ extern const Encounter kEncounters[];
 extern const char kSkillArray[37][20];
 extern const uint8 kByte2C7D0[60];
 extern const char kPossessive[3][4];
+extern const char kPersonal[3][4];
 extern const char kAttackVerbs[51][20];
 
 } // End of namespace Efh
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 43b8fc9e7cc..a3792792979 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -265,6 +265,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_word32680[i] = 0;
 		_word32482[i] = 0;
 		_word3267A[i] = -1;
+		_word31780[i] = 0;
 		_teamLastAction[i] = 0;
 	}
 
@@ -3830,6 +3831,51 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	}
 }
 
+void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
+	_word32482[teamCharId] -= 40;
+	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+
+	if (var70 == 2)
+		strcpy(_enemyNamePt1, "The ");
+	else
+		*_enemyNamePt1 = 0;
+
+	sprintf((char *)_messageToBePrinted, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+
+	_word32680[teamCharId] -= 50;
+	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+
+	if (var70 == 2)
+		strcpy(_enemyNamePt1, "The ");
+	else
+		*_enemyNamePt1 = 0;
+
+	sprintf((char *)_messageToBePrinted, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
+	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
+	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+	copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+	if (var70 == 2)
+		strcpy(_enemyNamePt1, "The ");
+	else
+		*_enemyNamePt1 = 0;
+
+	sprintf((char *)_messageToBePrinted, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
 bool EfhEngine::handleFight(int16 monsterId) {
 	warning("STUB - handleFight");
 
@@ -3877,7 +3923,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		}
 
 		for (int16 counter = 0; counter < _teamSize; ++counter) {
-			if (_teamLastAction[counter] == 0x52)
+			if (_teamLastAction[counter] == 0x52) // 'R'
 				mainLoopCond = true;
 		}
 
@@ -3898,13 +3944,13 @@ bool EfhEngine::handleFight(int16 monsterId) {
 						handleFight_lastAction_A(monsterGroupIdOrMonsterId);
 						break;
 					case 0x44: // 'D'efend
-						warning("STUB: handlefight - last action == 44h");
+						handleFight_lastAction_D(monsterGroupIdOrMonsterId);
 						break;
 					case 0x48: // 'H'ide
-						warning("STUB: handlefight - last action == 48h");
+						handleFight_lastAction_H(monsterGroupIdOrMonsterId);
 						break;
-					case 0x55: // 'U'
-						warning("STUB: handlefight - last action == 55h");
+					case 0x55: // 'U'se
+						handleFight_lastAction_U(monsterGroupIdOrMonsterId);
 						break;
 					default:
 						break;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index ba7ac6d9a87..e6ce39afb15 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -380,6 +380,9 @@ private:
 	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
 	void addReactionText(int16 id);
 	void handleFight_lastAction_A(int16 teamCharId);
+	void handleFight_lastAction_D(int16 teamCharId);
+	void handleFight_lastAction_H(int16 teamCharId);
+	void handleFight_lastAction_U(int16 teamCharId);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
 	void displayStatusMenu(int16 windowId);
@@ -558,6 +561,7 @@ private:
 	int16 _word32680[3];
 	int16 _word32482[3];
 	int16 _word3267A[3];
+	int16 _word31780[3];
 
 	int16 _word3273A[15];
 	Stru32686 _stru32686[5];


Commit: 4b7e91feade3378bb5af9cd21b76fe12c62c840c
    https://github.com/scummvm/scummvm/commit/4b7e91feade3378bb5af9cd21b76fe12c62c840c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: More work on handleFight

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a3792792979..fd8de7242a5 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3863,6 +3863,8 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
 	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
 	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
 	copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
@@ -3877,8 +3879,6 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 }
 
 bool EfhEngine::handleFight(int16 monsterId) {
-	warning("STUB - handleFight");
-
 	int16 var8C = 0;
 
 	sub1BE89(monsterId);
@@ -3957,7 +3957,117 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					}
 				}
 			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
-				warning("STUB - handleFight - loop var86");
+				// handleFight - Loop on var86 - Start
+				for (int16 var86 = 0; var86 < 9; ++var86) {
+					if (sub1BA9B(monsterGroupIdOrMonsterId, var86)) {
+						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
+						if (unk_monsterField5_itemId == 0xFF)
+							unk_monsterField5_itemId = 0x3F;
+						int16 teamMemberId = -1;
+						int16 var54;
+						if (_items[unk_monsterField5_itemId]._range < 3) {
+							for (int16 var84 = 0; var84 < 10; ++var84) {
+								teamMemberId = getRandom(_teamSize) - 1;
+								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _word32680[teamMemberId]) {
+									break;
+								}
+								teamMemberId = -1;
+							}
+							var54 = teamMemberId + 1;
+						} else {
+							teamMemberId = 0;
+							var54 = _teamSize;
+						}
+						if (teamMemberId != -1) {
+							// handleFight - Loop on var7E - Start
+							for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
+								if (_teamCharId[var7E] == -1 || !isTeamMemberStatusNormal(var7E))
+									continue;
+
+								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
+								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
+								int16 var70 = kEncounters[_mapMonsters[varInt]._MonsterRef]._nameArticle;
+								int16 var5E = _npcBuf[_teamCharId[var7E]]._possessivePronounSHL6 >> 6;
+								varInt = _items[unk_monsterField5_itemId].field_13;
+								_word32482[var7E] += (varInt * 5);
+								int16 var62 = 0;
+								int16 hitPoints = 0;
+								int16 originalDamage = 0;
+								int16 damagePointsAbsorbed = 0;
+								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
+								for (int16 var84 = 0; var84 < var64; ++var84)
+									warning("STUB: handleFight - Loop on var64");
+
+								if (originalDamage < 0)
+									originalDamage = 0;
+
+								hitPoints = originalDamage + damagePointsAbsorbed;
+								if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+									var62 = 0;
+
+								if (var62 > 0) {
+									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
+									if (var62 > 1)
+										sprintf(_attackBuffer, "%d times ", var62);
+									else
+										*_attackBuffer = 0;
+								}
+
+								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+								int16 var6A = getRandom(3);
+								if (var5E == 2)
+									sprintf(_characterNamePt1, "The ");
+								else
+									*_characterNamePt1 = 0;
+
+								if (var7E == 2)
+									sprintf(_enemyNamePt1, "The ");
+								else
+									*_enemyNamePt1 = 0;
+
+								strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._name);
+								copyString(_npcBuf[_teamCharId[var7E]]._name, _characterNamePt2);
+								copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+									warning("STUB: handleFight - check Damages");
+									warning("STUB: handleFight - Cascade of checks");
+									warning("STUB: handleFight - check armor");
+									warning("STUB: handleFight - check effect");
+								} else {
+									sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+								}
+								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+								sub1C219(_messageToBePrinted, 1, 2, true);
+							}
+							// handleFight - Loop on var7E - End
+						}
+					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
+						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
+						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
+							strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._name);
+							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._nameArticle;
+							if (var70 == 2)
+								strcpy(_enemyNamePt1, "The ");
+							else
+								*_enemyNamePt1 = 0;
+
+							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
+							case 1:
+								sprintf((char *)_messageToBePrinted, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+								break;
+							case 2:
+								sprintf((char *)_messageToBePrinted, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+								break;
+							default:
+								sprintf((char *)_messageToBePrinted, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+								break;
+							}
+							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
+							sub1C219(_messageToBePrinted, 1, 2, true);
+						}
+					}
+				}
+				// handleFight - Loop on var86 - End
 			}
 		}
 


Commit: 706496f1bd246a95abbe22bb70b02a47fa182111
    https://github.com/scummvm/scummvm/commit/706496f1bd246a95abbe22bb70b02a47fa182111
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Implement 3 more stubs in handleFight

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index fd8de7242a5..d40df381fe0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3481,6 +3481,23 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	return _items[itemId].field17_attackTypeDefense == attackType;
 }
 
+bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
+	int16 itemId = _npcBuf[charId]._unkItemId;
+
+	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+		return true;
+
+	for (int16 counter = 0; counter < 10; ++counter) {
+		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || _npcBuf[charId]._inventory[counter]._stat1 == 0x80)
+			continue;
+
+		itemId = _npcBuf[charId]._inventory[counter]._ref;
+		if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+			return true;
+	}
+	return false;
+}
+
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	warning("STUB - getDeathTypeDescription");
 }
@@ -3995,8 +4012,27 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 originalDamage = 0;
 								int16 damagePointsAbsorbed = 0;
 								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
-								for (int16 var84 = 0; var84 < var64; ++var84)
-									warning("STUB: handleFight - Loop on var64");
+								for (int16 var84 = 0; var84 < var64; ++var84) {
+									// handleFight - Loop var84 on var64 (objectId) - Start
+									if (getRandom(100) > _word32482[var7E])
+										continue;
+
+									++var62;
+
+									if (hasAdequateDefense_2(_teamCharId[var7E], _items[unk_monsterField5_itemId]._attackType))
+										continue;
+
+									int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+									varInt = var7C - var76;
+
+									if (varInt > 0) {
+										damagePointsAbsorbed += var76;
+										originalDamage += varInt;
+									} else {
+										damagePointsAbsorbed += var7C;
+									}
+									// handleFight - Loop var84 on var64 (objectId) - End
+								}
 
 								if (originalDamage < 0)
 									originalDamage = 0;
@@ -4029,8 +4065,47 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								copyString(_npcBuf[_teamCharId[var7E]]._name, _characterNamePt2);
 								copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
-									warning("STUB: handleFight - check Damages");
-									warning("STUB: handleFight - Cascade of checks");
+									// handleFight - check damages - Start
+									if (var62 == 0) {
+										sprintf((char *)_messageToBePrinted, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+									} else if (hitPoints <= 0) {
+										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+									} else if (hitPoints == 1) {
+										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
+											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
+										else
+											strcat((char *)_messageToBePrinted, "!");
+									} else {
+										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
+											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
+										else
+											strcat((char *)_messageToBePrinted, "!");
+									}
+									// handleFight - check damages - End
+
+									// handleFight - Add reaction text - start
+									if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints - 5 <= originalDamage) {
+											addReactionText(0);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 8) {
+											addReactionText(1);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 4) {
+											addReactionText(2);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
+											addReactionText(3);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
+											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+											addReactionText(4);
+										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
+											addReactionText(5);
+										} else if (originalDamage == 0 && getRandom(100) < 35) {
+											addReactionText(6);
+										}
+									}
+									// handleFight - Add reaction text - end
+
 									warning("STUB: handleFight - check armor");
 									warning("STUB: handleFight - check effect");
 								} else {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e6ce39afb15..9c13ac6aa2a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -376,6 +376,7 @@ private:
 	void generateSound(int16 soundType);
 	void genericGenerateSound(int16 soundType, int16 repeatCount);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
+	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
 	void addReactionText(int16 id);


Commit: 73d6cf6b0a1e4bae702156f522725e91e9ea177d
    https://github.com/scummvm/scummvm/commit/73d6cf6b0a1e4bae702156f522725e91e9ea177d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:35+01:00

Commit Message:
EFH: Implement 2 more stubs in handleFight

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d40df381fe0..37bfeac18d4 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3895,6 +3895,68 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
+char EfhEngine::getFightMessageLastCharacter(char *message) {
+	char *ptr = message;
+
+	if (ptr == nullptr || *ptr == 0)
+		return 0;
+
+	char lastChar = *ptr;
+	while (*ptr != 0) {
+		lastChar = *ptr++;
+	}
+
+	return lastChar;
+}
+
+void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
+	int16 var42 = 0;
+	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
+	char buffer[40];
+	char buffer2[20];
+
+	if (var40 > 2) {
+		var40 = 2;
+	}
+
+	if (damage > 50)
+		damage = 50;
+
+	for (int16 objectId = 0; objectId < 10; ++objectId) {
+		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || (_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0 && _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
+			continue;
+
+		int16 var44 = damage - _npcBuf[charId]._inventory[objectId]._stat2;
+		_npcBuf[charId]._inventory[objectId]._stat2 -= damage;
+
+		if (_npcBuf[charId]._inventory[objectId]._stat2 <= 0) {
+			copyString(_items[_npcBuf[charId]._inventory[objectId]._ref]._name, buffer2);
+			removeObject(charId, objectId);
+
+			if (var42 == 0) {
+				var42 = 1;
+				sprintf(buffer, ", but %s %s", kPossessive[var40], buffer2);
+				strcat((char *)_messageToBePrinted, buffer);
+			} else {
+				++var42;
+				sprintf(buffer, ", %s", buffer2);
+				strcat((char *)_messageToBePrinted, buffer);
+			}
+		}
+
+		if (var44 > 0)
+			damage = var44;
+	}
+
+	if (var42 == 0) {
+		strcat((char *)_messageToBePrinted, "!");
+	} else if (var42 > 1 || getFightMessageLastCharacter((char *)_messageToBePrinted) == 's' || getFightMessageLastCharacter((char *)_messageToBePrinted) == 'S') {
+		strcat((char *)_messageToBePrinted, " are destroyed!");
+	} else {
+		strcat((char *)_messageToBePrinted, " is destroyed!");
+	}
+}
+
 bool EfhEngine::handleFight(int16 monsterId) {
 	int16 var8C = 0;
 
@@ -4106,8 +4168,53 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									}
 									// handleFight - Add reaction text - end
 
-									warning("STUB: handleFight - check armor");
-									warning("STUB: handleFight - check effect");
+									// handleFight - Check armor - start
+									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
+										char buffer[80];
+										memset(buffer, 0, 80);
+										if (damagePointsAbsorbed <= 1)
+											sprintf(buffer, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+										else
+											sprintf(buffer, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+
+										strcat((char *)_messageToBePrinted, buffer);
+										varInt = (originalDamage + damagePointsAbsorbed) / 10;
+										sub1D8C2(_teamCharId[var7E], varInt);
+									}
+									// handleFight - Check armor - end
+
+									// handleFight - Check effect - start
+									char buffer[80];
+									memset(buffer, 0, 80);
+									switch (_items[unk_monsterField5_itemId].field_16) {
+									case 1:
+										if (getRandom(100) < 20) {
+											_teamCharStatus[var7E]._status = 1;
+											_teamCharStatus[var7E]._duration = getRandom(10);
+											sprintf(buffer, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+											strcat((char *)_messageToBePrinted, buffer);
+										}
+										break;
+									case 2:
+										if (getRandom(100) < 20) {
+											_teamCharStatus[var7E]._status = 2;
+											_teamCharStatus[var7E]._duration = getRandom(10);
+											sprintf(buffer, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+											strcat((char *)_messageToBePrinted, buffer);
+										}
+										break;
+									case 5:
+									case 6:
+										if (getRandom(100) < 20) {
+											sprintf(buffer, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2);
+											strcat((char *)_messageToBePrinted, buffer);
+											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
+										}
+										break;
+									default:
+										break;
+									} 
+									// handleFight - Check effect - end
 								} else {
 									sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 								}
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 9c13ac6aa2a..63cd7ca2b13 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -384,6 +384,8 @@ private:
 	void handleFight_lastAction_D(int16 teamCharId);
 	void handleFight_lastAction_H(int16 teamCharId);
 	void handleFight_lastAction_U(int16 teamCharId);
+	char getFightMessageLastCharacter(char *message);
+	void sub1D8C2(int16 charId, int16 damage);
 	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
 	void displayStatusMenu(int16 windowId);


Commit: 70127ffe6d12733b094ea5c4dd739dab3aaf260c
    https://github.com/scummvm/scummvm/commit/70127ffe6d12733b094ea5c4dd739dab3aaf260c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement 1 stubs

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 37bfeac18d4..83e43bef327 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3246,7 +3246,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 }
 
 void EfhEngine::sub1BCA7(int16 monsterId) {
-	warning("STUB: sub1BE89");
+	warning("STUB: sub1BCA7");
 }
 
 void EfhEngine::reset_stru32686() {
@@ -3280,10 +3280,131 @@ void EfhEngine::sub1CDFA() {
 	warning("STUB: sub1CDFA");
 }
 
+void EfhEngine::sub1CAFD() {
+	for (int16 counter = 0; counter < 2; ++counter) {
+		redrawScreen();
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+}
+
+int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
+	warning("STUB: sub1C956");
+	return 0;
+}
+
+void EfhEngine::sub1CAB6(int16 charId) {
+	for (int16 counter = 0; counter < 2; ++counter) {
+		sub15150(false);
+		displayLowStatusScreen(false);
+		drawCombatScreen(charId, false, false);
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+}
+
 bool EfhEngine::sub1CB27() {
-	warning("STUB: sub1CB27");
+	int16 var4 = false;
+	for (int16 counter1 = 0; counter1 < _teamSize; ++counter1) {
+		_teamLastAction[counter1] = 0;
+		if (!isTeamMemberStatusNormal(counter1))
+			continue;
 
-	return false;
+		var4 = true;
+		do {
+			drawCombatScreen(_teamCharId[counter1], false, true);
+			Common::KeyCode var1 = handleAndMapInput(true);
+			switch (var1) {
+			case Common::KEYCODE_a:
+				_teamLastAction[counter1] = 'A';
+				_word3267A[counter1] = sub1C956(_teamCharId[counter1], 9, true);
+				if (_word3267A[counter1] == -1)
+					_teamLastAction[counter1] = 0;
+				break;
+			case Common::KEYCODE_d:
+				_teamLastAction[counter1] = 'D';
+				break;
+			case Common::KEYCODE_h:
+				_teamLastAction[counter1] = 'H';
+				break;
+			case Common::KEYCODE_r:
+				for (int16 counter2 = 0; counter2 < _teamSize; ++counter2) {
+					_teamLastAction[counter2] = 'R';
+				}
+				return true;
+			case Common::KEYCODE_s: {
+				int16 var8 = handleStatusMenu(2, _teamCharId[counter1]);
+				sub1CAB6(_teamCharId[counter1]);
+				if (var8 > 999) {
+					if (var8 == 0x7D00)
+						_teamLastAction[counter1] = 'S';
+				} else {
+					_teamLastAction[counter1] = 'U';
+					_word31780[counter1] = var8;
+					int16 var6 = _npcBuf[_teamCharId[counter1]]._inventory[var8]._ref;
+					switch (var6 - 1) {
+					case 0:
+					case 1:
+					case 2:
+					case 3:
+					case 4:
+					case 5:
+					case 6:
+					case 7:
+					case 8:
+					case 10:
+					case 12:
+					case 13:
+						_word3267A[counter1] = sub1C956(_teamCharId[counter1], 9, false);
+						break;
+
+					case 9:
+					case 11:
+					case 14:
+					case 15:
+					case 18:
+					case 24:
+					case 25:
+					case 27:
+					case 28:
+					case 29:
+					case 30:
+						sub1C219((uint8 *)"Select Character:", 3, 1, false);
+						_word3267A[counter1] = selectOtherCharFromTeam();
+						break;
+
+					case 16:
+					case 17:
+					case 26:
+						_word3267A[counter1] = 0xC8;
+						break;
+						
+					case 19:
+					case 20:
+					case 21:
+					case 22:
+					case 23:
+					default:
+						break;
+					}
+					
+				}
+				
+				}
+				break;
+			case Common::KEYCODE_t:
+				sub1CAFD();
+				getInputBlocking();
+				drawCombatScreen(_teamCharId[counter1], false, true);
+				break;
+			default:
+				break;
+			}
+		} while (_teamLastAction[counter1] == 0);
+
+	}
+
+	return var4;
 }
 
 void EfhEngine::sub1BE9A(int16 monsterId) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 63cd7ca2b13..be921fbad96 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -363,6 +363,9 @@ private:
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
 	void sub1CDFA();
+	void sub1CAFD();
+	int16 sub1C956(int16 charId, int16 unkFied18Val, int16 arg4);
+	void sub1CAB6(int16 charId);
 	bool sub1CB27();
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();


Commit: 668b33d2d9917526f5fa2d0aae3ac2bfe9861443
    https://github.com/scummvm/scummvm/commit/668b33d2d9917526f5fa2d0aae3ac2bfe9861443
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement getDeathTypeDescription

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 83e43bef327..e88f2b65709 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3620,7 +3620,227 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 }
 
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
-	warning("STUB - getDeathTypeDescription");
+	int16 charId;
+	int16 possessivePronoun;
+
+	if (attackerId > 999) {
+		charId = _teamCharId[attackerId - 1000];
+		possessivePronoun = _npcBuf[charId]._possessivePronounSHL6 >> 6;
+	} else {
+		charId = _teamMonsterIdArray[attackerId];
+		possessivePronoun = _mapMonsters[attackerId]._possessivePronounSHL6 >> 6;
+	}
+
+	if (possessivePronoun > 2)
+		possessivePronoun = 2;
+
+	int16 deathType;
+	if (getRandom(100) < 20) {
+		deathType = 0;
+	} else {
+		if (victimId >= 1000) {
+			charId = _teamCharId[victimId - 1000];
+			if (charId == -1)
+				deathType = 0;
+			else {
+				int16 var6 = sub1C80A(charId, 9, true);
+				if (var6 == 0x7FFF)
+					deathType = 0;
+				else
+					deathType = _items[var6]._attackType + 1;
+			}
+		} else if (_teamMonsterIdArray[victimId] == -1)
+			deathType = 0;
+		else {
+			charId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
+			deathType = _items[charId]._attackType;
+		}
+	}
+
+	int16 rndDescrForDeathType = getRandom((3)) - 1;
+	char buffer[80];
+	memset(buffer, 0, 80);
+	sprintf(buffer, "DUDE IS TOAST!");
+	switch (deathType) {
+	case 0:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", killing %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", slaughtering %s!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", annihilating %s!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 1:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", cutting %s in two!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", dicing %s into small cubes!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 2:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", popping %s like a zit!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 3:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 4:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", totally incinerating %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", leaving a blistered mass of flesh behind!");
+			break;
+		}
+		break;
+	case 5:
+		switch (rndDescrForDeathType) {
+		case 0:
+			// The original has a typo: popscicle
+			sprintf(buffer, ", turning %s into a popsicle!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", shattering %s into shards!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 6:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", leaving pudding for brains");
+			break;
+		case 1:
+			sprintf(buffer, ", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 7:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 8:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", sucking %s into eternity!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 9:
+	case 10:
+	case 11:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", completely disintegrating %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 12:
+	case 13:
+	case 14:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", blowing %s brains out!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 15:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", choking %s to death!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", melting %s lungs!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	case 16:
+		switch (rndDescrForDeathType) {
+		case 0:
+			sprintf(buffer, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			sprintf(buffer, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			sprintf(buffer, ", impaling %s brain!", kPersonal[possessivePronoun]);
+			break;
+		}
+		break;
+	default:
+		break;
+	}	
+
+	strcat((char *)_messageToBePrinted, buffer);
 }
 
 void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {


Commit: 7f389610512f5dbe43df42549df147f3959542d7
    https://github.com/scummvm/scummvm/commit/7f389610512f5dbe43df42549df147f3959542d7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Fix issue in getDeathTypeDescription, some renaming

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e88f2b65709..a475a54c8de 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3620,15 +3620,14 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 }
 
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
-	int16 charId;
 	int16 possessivePronoun;
 
 	if (attackerId > 999) {
-		charId = _teamCharId[attackerId - 1000];
+		int16 charId = _teamCharId[attackerId - 1000];
 		possessivePronoun = _npcBuf[charId]._possessivePronounSHL6 >> 6;
 	} else {
-		charId = _teamMonsterIdArray[attackerId];
-		possessivePronoun = _mapMonsters[attackerId]._possessivePronounSHL6 >> 6;
+		int16 charId = _teamMonsterIdArray[attackerId];
+		possessivePronoun = _mapMonsters[charId]._possessivePronounSHL6 >> 6;
 	}
 
 	if (possessivePronoun > 2)
@@ -3639,7 +3638,7 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		deathType = 0;
 	} else {
 		if (victimId >= 1000) {
-			charId = _teamCharId[victimId - 1000];
+			int16 charId = _teamCharId[victimId - 1000];
 			if (charId == -1)
 				deathType = 0;
 			else {
@@ -3652,8 +3651,8 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		} else if (_teamMonsterIdArray[victimId] == -1)
 			deathType = 0;
 		else {
-			charId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
-			deathType = _items[charId]._attackType;
+			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
+			deathType = _items[itemId]._attackType;
 		}
 	}
 


Commit: 9b34c6766aa7f6315534e44a4aed370af58ea522
    https://github.com/scummvm/scummvm/commit/9b34c6766aa7f6315534e44a4aed370af58ea522
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement getXPAndSearchCorpse

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a475a54c8de..4f6e1ee72f3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1483,7 +1483,7 @@ void EfhEngine::handleWinSequence() {
 	free(winSeqBuf4);
 }
 
-bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int altCharId) {
+bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
 	for (int16 newObjectId = 0; newObjectId < 10; ++newObjectId) {
 		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
 			continue;
@@ -3842,8 +3842,47 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	strcat((char *)_messageToBePrinted, buffer);
 }
 
+bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
+	int16 rndVal = getRandom(100);
+	if (kEncounters[_mapMonsters[monsterId]._MonsterRef]._dropOccurrencePct < rndVal)
+		return false;
+
+	rndVal = getRandom(5) - 1;
+	int16 itemId = kEncounters[_mapMonsters[monsterId]._MonsterRef]._dropItemId[rndVal];
+	if (itemId == -1)
+		return false;
+
+	if (!giveItemTo(charId, itemId, 0xFF))
+		return false;
+
+	char tmpString[20];
+	copyString(_items[itemId]._name, tmpString);
+	char buffer[80];
+	sprintf(buffer, " and finds a %s!", tmpString);
+	strcat((char *)_messageToBePrinted, buffer);
+	return true;
+}
+
 void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {
-	warning("STUB - getXPAndSearchCorpse");
+	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
+	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._MonsterRef]._xpGiven;
+	char buffer[80];
+	sprintf(buffer, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._MonsterRef]._xpGiven);
+	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
+		generateSound(15);
+		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
+		_npcBuf[charId]._hitPoints += var2;
+		_npcBuf[charId]._maxHP += var2;
+		_npcBuf[charId]._infoScore[0] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[1] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[2] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
+	}
+	strcat((char *)_messageToBePrinted, buffer);
+	if (!characterSearchesMonsterCorpse(charId, monsterId))
+		strcat((char *)_messageToBePrinted, "!");
+	
 }
 
 void EfhEngine::addReactionText(int16 id) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index be921fbad96..68eebc5129f 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -313,7 +313,7 @@ private:
 	bool isCharacterATeamMember(int16 id);
 	bool isTPK();
 	void handleWinSequence();
-	bool giveItemTo(int16 charId, int16 objectId, int altCharId);
+	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
@@ -381,6 +381,7 @@ private:
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
+	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
 	void addReactionText(int16 id);
 	void handleFight_lastAction_A(int16 teamCharId);


Commit: 2584221af284d6cd6fb9921d9ff3116fbfd8bdbc
    https://github.com/scummvm/scummvm/commit/2584221af284d6cd6fb9921d9ff3116fbfd8bdbc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement 4 more functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4f6e1ee72f3..d70ce45d701 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -360,8 +360,7 @@ Common::Error EfhEngine::run() {
 		return Common::kNoError;
 
 	uint32 lastMs = _system->getMillis();
-	warning("STUB - Main loop");
-	for (;;) {
+	while(!_shouldQuit) {
 		_system->delayMillis(20);
 		uint32 newMs = _system->getMillis();
 
@@ -536,9 +535,7 @@ Common::Error EfhEngine::run() {
 			if (handleDeathMenu())
 				_shouldQuit = true;
 		}
-		
-		warning("Main loop - missing implementation");
-		
+
 		displayFctFullScreen();
 	}
 	return Common::kNoError;
@@ -3245,8 +3242,58 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return _tileFact[imageSetId * 2];
 }
 
-void EfhEngine::sub1BCA7(int16 monsterId) {
-	warning("STUB: sub1BCA7");
+bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
+	for (int16 counter = 0; counter < teamMonsterId; ++counter) {
+		if (_teamMonsterIdArray[counter] == monsterId)
+			return true;
+	}
+	return false;
+}
+
+void EfhEngine::sub1BCA7(int16 monsterTeamId) {
+	int16 counter = 0;
+	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false)) {
+		counter = 1;
+		_teamMonsterIdArray[0] = monsterTeamId;
+	}
+
+	for (int16 counter2 = 1; counter2 <= 3; ++counter2) {
+		if (counter >= 5)
+			break;
+
+		for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
+			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+				continue;
+
+			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+				continue;
+
+			if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+				continue;
+
+			bool var6 = false;
+			for (int16 counter3 = 0; counter3 < 9; ++counter3) {
+				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
+					var6 = true;
+					break;
+				}
+			}
+
+			if (var6) {
+				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
+					_teamMonsterIdArray[counter] = monsterId;
+					if (++counter >= 5)
+						break;
+				}
+			}
+		}
+	}
+
+	if (counter > 4)
+		return;
+
+	for (int16 id = counter; id < 5; ++id)
+		_teamMonsterIdArray[id] = -1;
 }
 
 void EfhEngine::reset_stru32686() {
@@ -3277,7 +3324,35 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 }
 
 void EfhEngine::sub1CDFA() {
-	warning("STUB: sub1CDFA");
+	for (int16 counter = 0; counter < 3; ++counter) {
+		if (_teamCharId[counter] != -1 && counter < _teamSize) {
+			_stru3244C[counter]._field0 = counter + 1000;
+			_stru3244C[counter]._field2 = _npcBuf[_teamCharId[counter]]._infoScore[3];
+		} else {
+			_stru3244C[counter]._field0 = -1;
+			_stru3244C[counter]._field2 = -1;
+		}
+	}
+
+	for (int16 counter = 0; counter < 5; ++counter) {
+		if (_teamMonsterIdArray[counter] == -1) {
+			_stru3244C[counter + 3]._field0 = -1;
+			_stru3244C[counter + 3]._field2 = -1;
+		} else {
+			_stru3244C[counter + 3]._field0 = counter;
+			_stru3244C[counter + 3]._field2 = _mapMonsters[_teamMonsterIdArray[counter]]._field_1 + getRandom(20);
+		}
+	}
+
+	for (int16 counter = 0; counter < 8; ++counter) {
+		for (int16 counter2 = 0; counter2 < 8; ++counter2) {
+			if (_stru3244C[counter]._field2 >= _stru3244C[counter2]._field2)
+				continue;
+
+			SWAP(_stru3244C[counter]._field0, _stru3244C[counter2]._field0);
+			SWAP(_stru3244C[counter]._field2, _stru3244C[counter2]._field2);			
+		}
+	}
 }
 
 void EfhEngine::sub1CAFD() {
@@ -3431,8 +3506,75 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 	return retVal;
 }
 
-void EfhEngine::sub1C4CA(bool WhiteFl) {
-	warning("STUB: sub1C4CA");
+int16 EfhEngine::sub1BAF9(int16 monsterGroup) {
+	int16 var2 = 0;
+	for (int16 counter = 0; counter < 9; ++counter) {
+		if (sub1BA9B(monsterGroup, counter))
+			++var2;
+	}
+
+	return var2;
+}
+
+void EfhEngine::sub1C4CA(bool whiteFl) {
+	int16 textPosY = 20;
+	for (int16 counter = 0; counter < 5; ++counter) {
+		if (_teamMonsterIdArray[counter] == -1)
+			continue;
+
+		int16 var6C = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
+		int16 var6E = sub1BAF9(counter);
+		if (whiteFl)
+			setTextColorWhite();
+		else
+			setTextColorGrey();
+
+		setTextPos(129, textPosY);
+		char buffer[80];
+		sprintf(buffer, "%c)", 'A' + counter);
+		displayStringAtTextPos(buffer);
+		setTextColorRed();
+		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
+		if (var1 <= 0x3D) {
+			sprintf(buffer, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._MonsterRef]._name);
+			displayStringAtTextPos(buffer);
+			if (var6E > 1)
+				displayStringAtTextPos("s");
+		} else if (var1 == 0x3E) {
+			displayStringAtTextPos("(NOT DEFINED)");
+		} else if (var1 == 0x3F) {
+			char stringToDisplay[20];
+			copyString(_npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name, stringToDisplay);
+			displayStringAtTextPos(stringToDisplay);
+		}
+
+		setTextPos(228, textPosY);
+		if (unkFct_checkMonsterField8(counter, true)) {
+			_textColor = 0xE;
+			displayStringAtTextPos("Hostile");
+		} else {
+			_textColor = 2;
+			displayStringAtTextPos("Friendly");
+		}
+
+		setTextColorRed();
+		switch (var6C) {
+		case 1:
+			displayCenteredString("S", 290, 302, textPosY);
+			break;
+		case 2:
+			displayCenteredString("M", 290, 302, textPosY);
+			break;
+		case 3:
+			displayCenteredString("L", 290, 302, textPosY);
+			break;
+		default:
+			displayCenteredString("?", 290, 302, textPosY);
+			break;
+		}
+
+		textPosY += 9;
+	}
 }
 
 void EfhEngine::displayCombatMenu(int16 charId) {
@@ -4063,7 +4205,6 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 damagePointsAbsorbed = 0;
 					int16 var64 = _items[unk_monsterField5_itemId]._attacks *_npcBuf[_teamCharId[teamCharId]]._speed;
 
-					warning("STUB: handleFight - Action A - Loop var84");
 					// Action A - Loop var84 - Start
 					for (int16 var84 = 0; var84 < var64; ++var84) {
 						if (getRandom(100) < charScore) {
@@ -6097,7 +6238,7 @@ bool EfhEngine::sub16E14() {
 				var68 = true;
 				break;
 			default:
-				warning("STUB: sub16E14 - Missing mapping ?");
+//				warning("STUB: sub16E14 - Missing mapping ?");
 				break;
 			}
 		} while (!var68);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 68eebc5129f..6ba22bfa1de 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -357,7 +357,8 @@ private:
 	void sub22AA8(int16 arg0);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
-	void sub1BCA7(int16 monsterId);
+	bool sub1BC74(int16 monsterId, int16 teamMonsterId);
+	void sub1BCA7(int16 monsterTeamId);
 	void reset_stru32686();
 	void sub1BE89(int16 monsterId);
 	void resetTeamMonsterIdArray();
@@ -369,6 +370,7 @@ private:
 	bool sub1CB27();
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
+	int16 sub1BAF9(int16 monsterGroup);
 	void sub1C4CA(bool WhiteFl);
 	void displayCombatMenu(int16 charId);
 	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);


Commit: 7ac43704a786c504bfca6a0214ed8a378de923e5
    https://github.com/scummvm/scummvm/commit/7ac43704a786c504bfca6a0214ed8a378de923e5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement one more stub

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d70ce45d701..b309276d8a5 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3355,7 +3355,7 @@ void EfhEngine::sub1CDFA() {
 	}
 }
 
-void EfhEngine::sub1CAFD() {
+void EfhEngine::redrawScreenForced() {
 	for (int16 counter = 0; counter < 2; ++counter) {
 		redrawScreen();
 		if (counter == 0)
@@ -3363,9 +3363,85 @@ void EfhEngine::sub1CAFD() {
 	}
 }
 
+int16 EfhEngine::selectMonsterGroup() {
+	int16 retVal = -1;
+
+	while (retVal == -1) {
+		Common::KeyCode input = handleAndMapInput(true);
+		switch (input) {
+		case Common::KEYCODE_ESCAPE:
+			retVal = 27;
+			break;
+		case Common::KEYCODE_a:
+		case Common::KEYCODE_b:
+		case Common::KEYCODE_c:
+		case Common::KEYCODE_d:
+		case Common::KEYCODE_e:
+			retVal = input - Common::KEYCODE_a;
+			if (_teamMonsterIdArray[retVal] == -1)
+				retVal = -1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return retVal;
+}
+
 int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
-	warning("STUB: sub1C956");
-	return 0;
+	int16 varE = -1;
+	
+	int16 var6 = sub1C80A(charId, unkFied18Val, true);
+	int16 range = 0;
+	if (var6 != 0x7FFF)
+		range = _items[var6]._range;
+
+	switch (range) {
+	case 3:
+	case 2:
+		++range;
+	case 1:
+		++range;
+	case 0:
+		++range;
+		break;
+	case 4:
+		return 100;
+	default:
+		return varE;
+	}
+
+	do {
+		for (int16 counter = 0; counter < 2; ++counter) {
+			drawCombatScreen(charId, true, false);
+			if (_teamMonsterIdArray[1] != -1)
+				sub1C219((uint8 *)"Select Monster Group:", 3, 0, false);
+
+			if (counter == 0)
+				displayFctFullScreen();
+		}
+
+		if (_teamMonsterIdArray[1] == -1)
+			varE = 0;
+		else
+			varE = selectMonsterGroup();
+
+		if (arg4 == 0) {
+			if (varE == 27)
+				varE = 0;
+		} else if (varE != 27) {
+			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[varE]);
+			if (monsterGroupDistance > range) {
+				varE = 27;
+			}
+		}
+	} while (varE != -1);
+
+	if (varE == 27)
+		varE = -1;
+	
+	return varE;
 }
 
 void EfhEngine::sub1CAB6(int16 charId) {
@@ -3468,7 +3544,7 @@ bool EfhEngine::sub1CB27() {
 				}
 				break;
 			case Common::KEYCODE_t:
-				sub1CAFD();
+				redrawScreenForced();
 				getInputBlocking();
 				drawCombatScreen(_teamCharId[counter1], false, true);
 				break;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 6ba22bfa1de..0521d12dae0 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -364,7 +364,8 @@ private:
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
 	void sub1CDFA();
-	void sub1CAFD();
+	void redrawScreenForced();
+	int16 selectMonsterGroup();
 	int16 sub1C956(int16 charId, int16 unkFied18Val, int16 arg4);
 	void sub1CAB6(int16 charId);
 	bool sub1CB27();


Commit: fd7b6755fbd7375e88953c42056cc84750724d28
    https://github.com/scummvm/scummvm/commit/fd7b6755fbd7375e88953c42056cc84750724d28
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement 2 more stubs, rename a function

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b309276d8a5..ddc7944d82c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3585,7 +3585,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 int16 EfhEngine::sub1BAF9(int16 monsterGroup) {
 	int16 var2 = 0;
 	for (int16 counter = 0; counter < 9; ++counter) {
-		if (sub1BA9B(monsterGroup, counter))
+		if (isMonsterActive(monsterGroup, counter))
 			++var2;
 	}
 
@@ -3741,13 +3741,114 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 }
 
 int16 EfhEngine::sub1DEC8(int16 groupNumber) {
-	warning("STUB: sub1DEC8");
-	return -1;
+	int16 var4 = -1;
+	int16 monsterId = _teamMonsterIdArray[groupNumber];
+
+	if (monsterId == -1)
+		return -1;
+
+	for (int16 counter = 0; counter < 9; ++counter) {
+		if (isMonsterActive(groupNumber, counter)) {
+			var4 = counter;
+			break;
+		}
+	}
+
+	for (int16 counter = var4 + 1; counter < 9; ++counter) {
+		if (!isMonsterActive(groupNumber, counter))
+			continue;
+
+		if (_mapMonsters[monsterId]._pictureRef[var4] > _mapMonsters[monsterId]._pictureRef[counter])
+			var4 = counter;
+	}
+
+	if (_mapMonsters[monsterId]._pictureRef[var4] <= 0)
+		return -1;
+
+	return var4;
 }
 
 int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
-	warning("STUB - getCharacterScore");
-	return 90;
+	int16 totalScore = 0;
+	switch (_items[itemId]._range) {
+	case 0:
+		totalScore = _npcBuf[charId]._passiveScore[5] + _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
+		totalScore += _npcBuf[charId]._infoScore[0] / 5;
+		totalScore += _npcBuf[charId]._infoScore[2] * 2,
+		totalScore += _npcBuf[charId]._infoScore[6] / 5;
+		totalScore += 2 * _npcBuf[charId]._infoScore[5] / 5;
+		break;
+	case 1:
+		totalScore = _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
+		totalScore += _npcBuf[charId]._infoScore[2] * 2;
+		totalScore += _npcBuf[charId]._infoScore[1] / 5;
+		totalScore += _npcBuf[charId]._infoScore[3] / 5;
+		break;
+	case 2:
+	case 3:
+	case 4:
+		totalScore = _npcBuf[charId]._passiveScore[1];
+		totalScore += _npcBuf[charId]._infoScore[2] * 2;
+		totalScore += _npcBuf[charId]._infoScore[1] / 5;
+		totalScore += _npcBuf[charId]._infoScore[3] / 5;
+		totalScore += _npcBuf[charId]._infoScore[8] / 5;
+	default:
+		break;
+	}
+
+	int16 extraScore = 0;
+	switch (_items[itemId]._attackType) {
+	case 0:
+	case 1:
+	case 2:
+		if (itemId == 0x3F)
+			extraScore = _npcBuf[charId]._passiveScore[2];
+		else if (itemId == 0x41 || itemId == 0x42 || itemId == 0x6A || itemId == 0x6C || itemId == 0x6D)
+			extraScore = _npcBuf[charId]._passiveScore[0];
+		break;
+	case 3:
+	case 4:
+	case 6:
+		extraScore = _npcBuf[charId]._infoScore[7];
+		break;
+	case 5:
+	case 7:
+		extraScore = _npcBuf[charId]._infoScore[9];
+		break;
+	case 8:
+	case 9:
+		extraScore = _npcBuf[charId]._activeScore[12];
+		break;
+	case 10:
+		extraScore = _npcBuf[charId]._passiveScore[10];
+		break;
+	case 11:
+		extraScore = _npcBuf[charId]._passiveScore[6];
+		break;
+	case 12:
+		extraScore = _npcBuf[charId]._passiveScore[7];
+		break;
+	case 13:
+		extraScore = _npcBuf[charId]._passiveScore[8];
+		break;
+	case 14:
+		extraScore = _npcBuf[charId]._activeScore[13];
+		break;
+	case 15:
+		extraScore = _npcBuf[charId]._passiveScore[9];
+		break;
+	default:
+		break;
+	}
+
+	extraScore += _items[itemId].field_13;
+
+	int16 grandTotalScore = totalScore + extraScore;
+	if (grandTotalScore > 60)
+		grandTotalScore = 60;
+
+	int16 retVal = CLIP(grandTotalScore + 30, 5, 90);
+	return retVal;
 }
 
 bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
@@ -4257,7 +4358,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				continue;
 
 			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
-				if (sub1BA9B(groupId, var7E) && var6E) {
+				if (isMonsterActive(groupId, var7E) && var6E) {
 					int16 var5C;
 					if (unkFct_checkMonsterField8(groupId, true)) {
 						sub1E028(groupId, 9, true);
@@ -4634,7 +4735,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
 				// handleFight - Loop on var86 - Start
 				for (int16 var86 = 0; var86 < 9; ++var86) {
-					if (sub1BA9B(monsterGroupIdOrMonsterId, var86)) {
+					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
 						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
 						if (unk_monsterField5_itemId == 0xFF)
 							unk_monsterField5_itemId = 0x3F;
@@ -5249,7 +5350,7 @@ void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
 	_mapMonsters[monsterId]._field_8 |= mask;
 }
 
-bool EfhEngine::sub1BA9B(int16 groupId, int16 id) {
+bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _stru32686[groupId]._field0[id] == 0)
 		return true;
 	return false;
@@ -5298,7 +5399,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			strcat((char *)_messageToBePrinted, "  The item emits a low droning hum...");
 			if (getRandom(100) < 50) {
 				for (int16 counter = 0; counter < 9; ++counter) {
-					if (sub1BA9B(windowId, counter)) {
+					if (isMonsterActive(windowId, counter)) {
 						++victims;
 						_stru32686[windowId]._field0[counter] = 1;
 						_stru32686[windowId]._field2[counter] = getRandom(8);
@@ -5310,7 +5411,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					if (NumberOfTargets == 0)
 						break;
 
-					if (sub1BA9B(windowId, counter)) {
+					if (isMonsterActive(windowId, counter)) {
 						++victims;
 						--NumberOfTargets;
 						_stru32686[windowId]._field0[counter] = 1;
@@ -5337,7 +5438,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 victim = 0;
 			if (getRandom(100) < 50) {
 				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
-					if (sub1BA9B(windowId, varA8)) {
+					if (isMonsterActive(windowId, varA8)) {
 						++victim;
 						_stru32686[windowId]._field0[varA8] = 2;
 						_stru32686[windowId]._field2[varA8] = getRandom(8);
@@ -5349,7 +5450,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					if (varAC == 0)
 						break;
 
-					if (sub1BA9B(windowId, varA8)) {
+					if (isMonsterActive(windowId, varA8)) {
 						++victim;
 						--varAC;
 						_stru32686[windowId]._field0[varA8] = 2;
@@ -5393,7 +5494,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				}
 			} else {
 				for (int16 counter = 0; counter < 9; ++counter) {
-					if (sub1BA9B(windowId, counter)) {
+					if (isMonsterActive(windowId, counter)) {
 						if (getRandom(100) < 50) {
 							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 						}
@@ -5416,7 +5517,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!");
 				for (int16 counter = 0; counter < 9; ++counter) {
-					if (sub1BA9B(windowId, counter)) {
+					if (isMonsterActive(windowId, counter)) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
 				}				
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0521d12dae0..494053a379b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -409,7 +409,7 @@ private:
 	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub1E028(int16 id, uint8 mask, int16 groupFl);
-	bool sub1BA9B(int16 groupId, int16 id);
+	bool isMonsterActive(int16 groupId, int16 id);
 	int16 sub15538(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
 	int16 selectOtherCharFromTeam();


Commit: e6e84a6c7e5b46742f14f2ea43601e58c05c6782
    https://github.com/scummvm/scummvm/commit/e6e84a6c7e5b46742f14f2ea43601e58c05c6782
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Implement sub1BE9A

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ddc7944d82c..a4d3b16e7c4 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3558,9 +3558,102 @@ bool EfhEngine::sub1CB27() {
 	return var4;
 }
 
+// The parameter isn't used in the original
 void EfhEngine::sub1BE9A(int16 monsterId) {
-	warning("STUB sub1BE9A");
-}
+	int16 var4 = 1;
+
+	// sub1BE9A - 1rst loop counter1_monsterId - Start
+	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
+		if (sub1BAF9(counter1))
+			continue;
+
+		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+			_mapMonsters[_teamMonsterIdArray[counter1]]._pictureRef[counter2] = 0;
+			_stru32686[counter1]._field0[counter2] = 0;
+			_stru32686[counter1]._field2[counter2] = 0;
+		}
+
+		_teamMonsterIdArray[counter1] = -1;
+		for (int16 counter2 = counter1 + 1; counter2 < 5; ++counter2) {
+			for (int16 var8 = 0; var8 < 9; ++var8) {
+				_stru32686[counter1]._field0[var8] = _stru32686[counter2]._field0[var8];
+				_stru32686[counter1]._field2[var8] = _stru32686[counter2]._field2[var8];
+			}
+			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
+		}
+		
+	}
+	// sub1BE9A - 1rst loop counter1_monsterId - End
+
+	var4 = -1;
+	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
+		if (_teamMonsterIdArray[counter1] == -1) {
+			var4 = counter1;
+			break;
+		}
+	}
+
+	if (var4 != -1) {
+		// sub1BE9A - loop var2 - Start
+		for (int16 var2 = 1; var2 < 3; ++var2) {
+			if (var4 >= 5)
+				break;
+
+			for (int16 counter1 = 0; counter1 < 64; ++counter1) {
+				if (_mapMonsters[counter1]._guess_fullPlaceId == 0xFF)
+					continue;
+				
+				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._field_1)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+					if (checkIfMonsterOnSameLargelMapPlace(counter1)) {
+						bool var6 = false;
+						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+							if (_mapMonsters[counter1]._pictureRef[counter2] > 0) {
+								var6 = true;
+								break;
+							}
+						}
+
+						if (!var6)
+							continue;
+
+						if (var2 > computeMonsterGroupDistance(counter1))
+							continue;
+
+						if (sub1BC74(counter1, var4))
+							continue;
+
+						_teamMonsterIdArray[var4] = counter1;
+
+						// The original at this point was doing a loop on counter1, which is not a good idea as
+						// it was resetting the counter1 to 9 whatever its value before the loop.
+						// Furthermore, it was accessing _stru32686[counter1]._field0[counter1] which doesn't make
+						// sense...
+						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
+						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+							_stru32686[counter1]._field0[counter2] = 0;
+						}
+						
+						if (++var4 >= 5)
+							break;
+					}
+				}
+			}			
+		}
+		// sub1BE9A - loop var2 - End
+	}
+
+	if (var4 == -1 || var4 > 4)
+		return;
+
+	// sub1BE9A - last loop counter1_monsterId - Start
+	for (int16 counter1 = var4; counter1 < 5; ++counter1) {
+		_teamMonsterIdArray[counter1] = -1;
+		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+			_stru32686[counter1]._field0[counter2] = 0x8000;
+		}
+	}
+	// sub1BE9A - last loop counter1_monsterId - End
+	}
 
 int16 EfhEngine::getTeamMonsterAnimId() {
 	int16 retVal = 0xFF;


Commit: f3bf1bfbc55d527f644e348afac9b94f345c0e52
    https://github.com/scummvm/scummvm/commit/f3bf1bfbc55d527f644e348afac9b94f345c0e52
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Add some debug traces, some renaming

Changed paths:
    engines/efh/detection.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/detection.cpp b/engines/efh/detection.cpp
index 7f570bd78e0..439f8c54b4d 100644
--- a/engines/efh/detection.cpp
+++ b/engines/efh/detection.cpp
@@ -25,6 +25,7 @@
 #include "common/textconsole.h"
 
 #include "efh/detection.h"
+#include "efh/efh.h"
 
 namespace Efh {
 
@@ -57,6 +58,12 @@ static const EfhGameDescription gameDescriptions[] = {
 	{AD_TABLE_END_MARKER, kGameTypeNone}
 };
 
+static const DebugChannelDef debugFlagList[] = {
+	{Efh::kDebugEngine, "engine", "Engine debug level"},
+	{Efh::kDebugUtils, "utils", "Utils debug level"},
+	{Efh::kDebugGraphics, "graphics", "Graphics debug level"},
+	DEBUG_CHANNEL_END};
+
 class EfhMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
 	EfhMetaEngineDetection() : AdvancedMetaEngineDetection(gameDescriptions, sizeof(EfhGameDescription), efhGames) {
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a4d3b16e7c4..c88075ab8ef 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -312,6 +312,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_messageToBePrinted, 0, 400);
 	for (int i = 0; i < 8; ++i)
 		_stru3244C[i].init();
+
 }
 
 EfhEngine::~EfhEngine() {
@@ -351,6 +352,7 @@ Common::Error EfhEngine::run() {
 	syncSoundSettings();
 	_soundHandler->init();
 */
+
 	initEngine();
 	sub15150(true);
 	redrawScreen();
@@ -439,7 +441,7 @@ Common::Error EfhEngine::run() {
 			break;
 		case Common::KEYCODE_F5: { // Original is using CTRL-S
 			for (int16 counter = 0; counter < 2; ++counter) {
-				unkFct_displayMenuBox_2(0);
+				clearBottomTextZone(0);
 				displayCenteredString("Are You Sure You Want To Save?", 24, 296, 160);
 				if (counter == 0)
 					displayFctFullScreen();
@@ -449,12 +451,12 @@ Common::Error EfhEngine::run() {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
 				saveEfhGame();
-				unkFct_displayBox(0);
+				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			} else {
 				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
 				getInput(2);
-				unkFct_displayBox(0);
+				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			}
 			
@@ -462,7 +464,7 @@ Common::Error EfhEngine::run() {
 			break;
 		case Common::KEYCODE_F7: { // Original is using CTRL-S
 			for (int16 counter = 0; counter < 2; ++counter) {
-				unkFct_displayMenuBox_2(0);
+				clearBottomTextZone(0);
 				displayCenteredString("Are You Sure You Want To Load?", 24, 296, 160);
 				if (counter == 0)
 					displayFctFullScreen();
@@ -472,12 +474,12 @@ Common::Error EfhEngine::run() {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
 				loadEfhGame();
-				unkFct_displayBox(0);
+				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			} else {
 				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
 				getInput(2);
-				unkFct_displayBox(0);
+				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			}
 
@@ -1261,7 +1263,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 	
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
-			unkFct_displayMenuBox_2(0);
+			clearBottomTextZone(0);
 			setTextColorWhite();
 			displayCenteredString(strName, 16, 88, 152);
 			displayCenteredString(strDef, 104, 128, 152);
@@ -2321,7 +2323,7 @@ bool EfhEngine::handleDeathMenu() {
 	redrawScreen();
 
 	for (int16 counter = 0; counter < 2; ++counter) {
-		unkFct_displayMenuBox_2(0);
+		clearBottomTextZone(0);
 		displayCenteredString("Darkness Prevails...Death Has Taken You!", 24, 296, 153);
 		setTextPos(100, 162);
 		setTextColorWhite();
@@ -2974,7 +2976,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
 				sprintf(buffer, "%s asks that %s leave your party.", _enemyNamePt2, _characterNamePt2);
 				for (int16 i = 0; i < 2; ++i) {
-					unkFct_displayMenuBox_2(0);
+					clearBottomTextZone(0);
 					_textColor = 0xE;
 					displayCenteredString(buffer, 24, 296, 161);
 					setTextPos(24, 169);
@@ -6456,7 +6458,7 @@ bool EfhEngine::sub16E14() {
 					sprintf(buffer, "with %s", dest);
 				}
 
-				unkFct_displayMenuBox_2(0);
+				clearBottomTextZone(0);
 				_textColor = 0xE;
 				displayCenteredString("Interaction", 24, 296, 152);
 				displayCenteredString(buffer, 24, 296, 161);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 494053a379b..eeaf9b259f7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -55,6 +55,12 @@ namespace Efh {
 
 static const int kSavegameVersion = 1;
 
+enum AccessDebugChannels {
+	kDebugEngine = 1 << 0,
+	kDebugUtils = 1 << 1,
+	kDebugGraphics = 1 << 2
+};
+
 struct EfhGameDescription;
 
 class EfhGraphicsStruct {
@@ -443,12 +449,12 @@ private:
 	void setTextColorRed();
 	void setTextColorGrey();
 	void displayStringAtTextPos(const char *message);
-	void unkFct_displayMenuBox_2(int16 color);
+	void clearBottomTextZone(int16 color);
+	void clearBottomTextZone_2(int16 color);
 	void setNextCharacterPos();
 	void displayCharAtTextPos(char character);
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
-	void unkFct_displayBox(int16 color);
 
 	// Utils
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 2ef7f03015e..19fdfe4b66d 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -28,7 +28,7 @@ namespace Efh {
 
 void EfhEngine::initPalette() {
 	// Strangerke - values from a tool I wrote in 2008. I can't remember if it's guess work or not.
-	const uint8 pal[3 * 16] = {
+	static const uint8 pal[3 * 16] = {
 		0, 0, 0,
 		0, 0, 170,
 		0, 170, 0,
@@ -47,15 +47,18 @@ void EfhEngine::initPalette() {
 		255, 255, 255
 	};
 
+	debugC(1, kDebugGraphics, "initPalette");
 	_system->getPaletteManager()->setPalette(pal, 0, 16);
 	_system->updateScreen();
 }
 
 void EfhEngine::drawLeftCenterBox() {
+	debugC(1, kDebugGraphics, "drawLeftCenterBox");
 	drawColoredRect(16, 8, 111, 135, 0);
 }
 
 void EfhEngine::displayAnimFrame() {
+	debugC(1, kDebugGraphics, "displayAnimFrame");
 	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
 
 	if (_animImageSetId == 0xFF)
@@ -76,6 +79,7 @@ void EfhEngine::displayAnimFrame() {
 }
 
 void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
+	debugC(1, kDebugGraphics, "displayAnimFrames %d %s", animId, displayMenuBoxFl ? "True" : "False");
 	if (animId == 0xFF)
 		return;
 
@@ -98,6 +102,8 @@ void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
 }
 
 void EfhEngine::displayFctFullScreen() {
+	debugC(1, kDebugGraphics, "displayFctFullScreen");
+	
 	// CHECKME: 319 is in the original but looks suspicious.
 	// copyDirtyRect(0, 0, 319, 200);
 
@@ -116,9 +122,9 @@ void EfhEngine::copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct,
 }
 
 void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY) {
-	// TODO: Quick code to display stuff, may require to really reverse the actual function
+	debugC(1, kDebugGraphics, "displayBufferBmAtPos %d %d", posX, posY);
+	// CHECKME: Quick code to display stuff, may require to really reverse the actual function
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
-	// warning("%d %d - startX %d startY %d width %d height %d lineDataSize %d fieldD %d", posX, posY, bufferBM->_startX, bufferBM->_startY, bufferBM->_width, bufferBM->_height, bufferBM->_lineDataSize, bufferBM->_fieldD);
 	int counter = 0;
 	for (int line = 0; line < bufferBM->_height; ++line) {
 		for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
@@ -133,14 +139,14 @@ void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY)
 }
 
 void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
+	debugC(1, kDebugGraphics, "drawRect %d %d %d %d", minX, minY, maxX, maxY);
+
 	if (minY > maxY)
 		SWAP(minY, maxY);
 
 	if (minX > maxX)
 		SWAP(minX, maxX);
 
-	// warning("drawRect - _graphicsStruct x %d -> %d, y %d -> %d", _graphicsStruct->_area.left, _graphicsStruct->_area.right, _graphicsStruct->_area.top, _graphicsStruct->_area.bottom);
-
 	minX = CLIP(minX, 0, 319);
 	maxX = CLIP(maxX, 0, 319);
 	minY = CLIP(minY, 0, 199);
@@ -164,6 +170,8 @@ void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
 }
 
 void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int color) {
+	debugC(1, kDebugGraphics, "drawColoredRect %d %d %d %d %d", minX, minY, maxX, maxY, color);
+
 	uint8 oldValue = _defaultBoxColor;
 	_defaultBoxColor = color;
 	drawRect(minX, minY, maxX, maxY);
@@ -171,10 +179,12 @@ void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int colo
 }
 
 void EfhEngine::clearScreen(int color) {
+	debugC(1, kDebugGraphics, "clearScreen %d", color);
 	drawColoredRect(0, 0, 320, 200, color);
 }
 
 void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
+	debugC(1, kDebugGraphics, "displayRawDataAtPos %d %d", posX, posY);
 	uint16 height = READ_LE_INT16(imagePtr);
 	uint16 width = READ_LE_INT16(imagePtr + 2);
 	uint8 *imageData = imagePtr + 4;
@@ -189,6 +199,7 @@ void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
 }
 
 void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 unkFl) {
+	debugC(1, kDebugGraphics, "drawString %s %d %d %d", str, startX, startY, unkFl);
 	uint8 *curPtr = (uint8 *)str;
 	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
 	_unk_sub26437_flag = unkFl & 0x3FFF;
@@ -225,22 +236,26 @@ void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 u
 }
 
 void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY) {
+	debugC(1, kDebugGraphics, "displayCenteredString %s %d-%d %d", str, minX, maxX, posY);
 	uint16 length = getStringWidth(str);
 	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
 	drawString(str, startCenteredDisplayX, posY, _textColor);
 }
 
 void EfhEngine::displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int posY) {
+	debugC(1, kDebugGraphics, "displayMenuAnswerString %s %d-%d %d", str, minX, maxX, posY);
 	displayCenteredString(str, minX, maxX, posY);
 	displayFctFullScreen();
 	displayCenteredString(str, minX, maxX, posY);
 }
 
 void EfhEngine::drawMapWindow() {
+	debugC(1, kDebugGraphics, "drawMapWindow");
 	drawColoredRect(128, 8, 303, 135, 0);
 }
 
 void EfhEngine::displayGameScreen() {
+	debugC(1, kDebugGraphics, "displayGameScreen");
 	clearScreen(0);
 	drawUpperLeftBorders();
 	drawUpperRightBorders();
@@ -250,17 +265,20 @@ void EfhEngine::displayGameScreen() {
 }
 
 void EfhEngine::drawUpperLeftBorders() {
+	debugC(1, kDebugGraphics, "drawUpperLeftBorders");
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayRawDataAtPos(_circleImageSubFileArray[1], 112, 0);
 	displayRawDataAtPos(_circleImageSubFileArray[3], 16, 0);
 }
 
 void EfhEngine::drawUpperRightBorders() {
+	debugC(1, kDebugGraphics, "drawUpperRightBorders");
 	displayRawDataAtPos(_circleImageSubFileArray[2], 304, 0);
 	displayRawDataAtPos(_circleImageSubFileArray[4], 128, 0);
 }
 
 void EfhEngine::drawBottomBorders() {
+	debugC(1, kDebugGraphics, "drawBottomBorders");
 	displayRawDataAtPos(_circleImageSubFileArray[7], 16, 136);
 	displayRawDataAtPos(_circleImageSubFileArray[8], 16, 192);
 	displayRawDataAtPos(_circleImageSubFileArray[5], 0, 136);
@@ -268,7 +286,9 @@ void EfhEngine::drawBottomBorders() {
 }
 
 void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
-	// Quick hacked display, may require rework
+	debugC(1, kDebugGraphics, "drawChar %c %d %d", curChar, posX, posY);
+
+	// CHECKME: Quick hacked display, may require rework
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
 
 	int16 charId = curChar - 0x20;
@@ -285,6 +305,8 @@ void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
 }
 
 void EfhEngine::setTextColorWhite() {
+	debugC(1, kDebugGraphics, "setTextColorWhite");
+
 	if (_videoMode == 8) // CGA
 		_textColor = 0x3;
 	else
@@ -292,6 +314,8 @@ void EfhEngine::setTextColorWhite() {
 }
 
 void EfhEngine::setTextColorRed() {
+	debugC(1, kDebugGraphics, "setTextColorRed");
+
 	if (_videoMode == 8) // CGA
 		_textColor = 0x2;
 	else
@@ -299,6 +323,8 @@ void EfhEngine::setTextColorRed() {
 }
 
 void EfhEngine::setTextColorGrey() {
+	debugC(1, kDebugGraphics, "setTextColorGrey");
+
 	if (_videoMode == 8) // CGA
 		_textColor = 0x1;
 	else
@@ -306,16 +332,28 @@ void EfhEngine::setTextColorGrey() {
 }
 
 void EfhEngine::displayStringAtTextPos(const char *message) {
+	debugC(1, kDebugGraphics, "displayStringAtTextPos %s", message);
+
 	drawString(message, _textPosX, _textPosY, _textColor);
 	_textPosX += getStringWidth(message) + 1;
 	setNextCharacterPos();
 }
 
-void EfhEngine::unkFct_displayMenuBox_2(int16 color) {
+void EfhEngine::clearBottomTextZone(int16 color) {
+	debugC(1, kDebugGraphics, "clearBottomTextZone %d", color);
+
 	drawColoredRect(16, 152, 302, 189, color);
 }
 
+void EfhEngine::clearBottomTextZone_2(int16 color) {
+	debugC(1, kDebugGraphics, "clearBottomTextZone_2 %d", color);
+
+	displayColoredMenuBox(16, 152, 302, 189, color);
+}
+
 void EfhEngine::setNextCharacterPos() {
+	debugC(1, kDebugGraphics, "setNextCharacterPos");
+
 	if (_textPosX <= 311)
 		return;
 
@@ -327,6 +365,8 @@ void EfhEngine::setNextCharacterPos() {
 }
 
 void EfhEngine::displayCharAtTextPos(char character) {
+	debugC(1, kDebugGraphics, "displayCharAtTextPos %c", character);
+
 	char buffer[2];
 	buffer[0] = character;
 	buffer[1] = 0;
@@ -337,6 +377,8 @@ void EfhEngine::displayCharAtTextPos(char character) {
 }
 
 void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest) {
+	debugC(1, kDebugGraphics, "displayWindow %d %d", posX, posY);
+
 	if (buffer == nullptr) {
 		warning("Target Buffer Not Defined...DCImage!"); // That's the original message... And yes, it's wrong: it's checking the source buffer :)
 		return;
@@ -350,13 +392,11 @@ void EfhEngine::displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest
 }
 
 void EfhEngine::displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color) {
+	debugC(1, kDebugGraphics, "displayColoredMenuBox %d %d -> %d %d %d", minX, minY, maxX, maxY, color);
+
 	drawColoredRect(minX, minY, maxX, maxY, color);
 	displayFctFullScreen();
 	drawColoredRect(minX, minY, maxX, maxY, color);
 }
 
-void EfhEngine::unkFct_displayBox(int16 color) {
-	displayColoredMenuBox(16, 152, 302, 189, color);
-}
-
 } // End of namespace Efh
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index e8b99457842..54941c938a5 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -27,6 +27,7 @@
 namespace Efh {
 
 int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
+	debugC(1, kDebugUtils, "readFileToBuffer %s", filename.c_str());
 	Common::File f;
 	if (!f.open(filename))
 		error("Unable to find file %s", filename.c_str());
@@ -46,6 +47,7 @@ void EfhEngine::setDefaultNoteDuration() {
 }
 
 void EfhEngine::decryptImpFile(bool techMapFl) {
+	debugC(1, kDebugUtils, "decryptImpFile %s", techMapFl ? "True" : "False");
 	uint16 counter = 0;
 	uint16 target;
 	uint8 *curPtr;
@@ -84,11 +86,13 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 }
 
 void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
+	debugC(1, kDebugUtils, "loadImageSet %d", imageSetId);
 	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
 	rImageFile(fileName, buffer, subFilesArray, destBuffer);
 }
 
 void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
+	debugC(1, kDebugUtils, "rImageFile %s", filename.c_str());
 	readFileToBuffer(filename, packedBuffer);
 	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
 	// TODO: Keep this dump for debug purposes only
@@ -115,6 +119,7 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 }
 
 uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
+	debugC(1, kDebugUtils, "uncompressBuffer");
 	if (compressedBuf == nullptr || destBuf == nullptr)
 		error("uncompressBuffer - Invalid pointer used in parameter list");
 
@@ -167,6 +172,7 @@ uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 }
 
 int16 EfhEngine::getRandom(int16 maxVal) {
+	debugC(1, kDebugUtils, "getRandom %d", maxVal);
 	if (maxVal == 0)
 		return 0;
 
@@ -174,6 +180,7 @@ int16 EfhEngine::getRandom(int16 maxVal) {
 }
 
 Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
+	debugC(1, kDebugUtils, "getLastCharAfterAnimCount %d", delay);
 	if (delay == 0)
 		return Common::KEYCODE_INVALID;
 
@@ -197,6 +204,7 @@ Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
 }
 
 Common::KeyCode EfhEngine::getInput(int16 delay) {
+	debugC(1, kDebugUtils, "getInput %d", delay);
 	if (delay == 0)
 		return Common::KEYCODE_INVALID;
 
@@ -223,6 +231,7 @@ Common::KeyCode EfhEngine::getInput(int16 delay) {
 }
 
 Common::KeyCode EfhEngine::waitForKey() {
+	debugC(1, kDebugUtils, "waitForKey");
 	Common::KeyCode retVal = Common::KEYCODE_INVALID;
 	Common::Event event;
 
@@ -256,6 +265,7 @@ Common::KeyCode EfhEngine::mapInputCode(Common::KeyCode input) {
 }
 
 Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
+	debugC(1, kDebugUtils, "handleAndMapInput %s", animFl ? "True" : "False");
 	// The original checks for the joystick input
 	Common::Event event;
 	_system->getEventManager()->pollEvent(event);
@@ -271,6 +281,7 @@ Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
 }
 
 Common::KeyCode EfhEngine::getInputBlocking() {
+	debugC(1, kDebugUtils, "getInputBlocking");
 	// The original checks for the joystick input
 	Common::Event event;
 	_system->getEventManager()->pollEvent(event);
@@ -298,6 +309,7 @@ void EfhEngine::setNumLock() {
 }
 
 void EfhEngine::copyString(char *srcStr, char *destStr) {
+	debugC(1, kDebugUtils, "copyString %s", srcStr);
 	char lastChar = 1;
 	int16 idx = 0;
 
@@ -308,6 +320,7 @@ void EfhEngine::copyString(char *srcStr, char *destStr) {
 }
 
 bool EfhEngine::getValidationFromUser() {
+	debugC(1, kDebugUtils, "getValidationFromUser");
 	Common::KeyCode input = handleAndMapInput(true);
 	if (input == Common::KEYCODE_y) // or if joystick button 1
 		return true;


Commit: 5cb54e592234c411dde985f8d2e0743e0d6a5e4a
    https://github.com/scummvm/scummvm/commit/5cb54e592234c411dde985f8d2e0743e0d6a5e4a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Small modification in NPCStruct, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c88075ab8ef..7d96c08af88 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -102,10 +102,8 @@ void ItemStruct::init() {
 }
 
 void NPCStruct::init() {
-	for (int i = 0; i < 9; ++i)
+	for (int i = 0; i < 11; ++i)
 		_name[i] =  0;
-	field_9 = 0;
-	field_A = 0;
 	field_B = 0;
 	field_C = 0;
 	field_D = 0;
@@ -703,10 +701,8 @@ void EfhEngine::loadNPCS() {
 	uint8 *curPtr = npcLoading;
 
 	for (int i = 0; i < 99; ++i) {
-		for (int idx = 0; idx < 9; ++idx)
+		for (int idx = 0; idx < 11; ++idx)
 			_npcBuf[i]._name[idx] = *curPtr++;
-		_npcBuf[i].field_9 = *curPtr++;
-		_npcBuf[i].field_A = *curPtr++;
 		_npcBuf[i].field_B = *curPtr++;
 		_npcBuf[i].field_C = *curPtr++;
 		_npcBuf[i].field_D = *curPtr++;
@@ -798,10 +794,10 @@ void EfhEngine::playIntro() {
 
 	// With GF on the bed
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -809,11 +805,11 @@ void EfhEngine::playIntro() {
 	// Poof
 	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -821,38 +817,38 @@ void EfhEngine::playIntro() {
 	// On the phone
 	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, 0);
+	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	getLastCharAfterAnimCount(80);
 }
 
@@ -910,7 +906,7 @@ void EfhEngine::initEngine() {
 		_mapMonsters[i]._posY = 0;
 		_mapMonsters[i]._itemId_Weapon = 0;
 		_mapMonsters[i]._field_6 = 0;
-		_mapMonsters[i]._MonsterRef = 0;
+		_mapMonsters[i]._monsterRef = 0;
 		_mapMonsters[i]._field_8 = 0;
 		_mapMonsters[i]._field_9 = 0;
 		_mapMonsters[i]._groupSize = 0;
@@ -1005,7 +1001,7 @@ void EfhEngine::initMapMonsters() {
 
 		for (uint8 counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
-			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._MonsterRef]._pictureRef;
+			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._monsterRef]._pictureRef;
 
 			if (rand100 <= 25) {
 				uint16 delta = getRandom(pictureRef / 2);
@@ -1043,7 +1039,7 @@ void EfhEngine::loadMapMonsters() {
 		_mapMonsters[i]._posY = mapMonstersPtr[29 * i + 4];
 		_mapMonsters[i]._itemId_Weapon = mapMonstersPtr[29 * i + 5];
 		_mapMonsters[i]._field_6 = mapMonstersPtr[29 * i + 6];
-		_mapMonsters[i]._MonsterRef = mapMonstersPtr[29 * i + 7];
+		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
 		_mapMonsters[i]._field_8 = mapMonstersPtr[29 * i + 8];
 		_mapMonsters[i]._field_9 = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
@@ -1202,7 +1198,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 				if (!var4)
 					continue;
 
-				var6 = 148 + kEncounters[_mapMonsters[var16]._MonsterRef]._animId;
+				var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
 				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
 
 				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._field_1))
@@ -1547,7 +1543,7 @@ int16 EfhEngine::handleCharacterJoining() {
 	return 2;
 }
 
-int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX, int maxY, int argC) {	
+int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {	
 	bool doneFlag = false;
 	int16 var_F2 = -1;
 	int16 var_F0 = 0xFF;
@@ -1617,7 +1613,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 		switch (var_108) {
 		case 0x00:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				if (_largeMapFlag) {
 					_largeMapFlag = false;
 					_techDataId_MapPosX = _mapPosX;
@@ -1631,7 +1627,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			}
 			break;
 		case 0x01:
-			if (argC != 0) {
+			if (flag) {
 				_largeMapFlag = true;
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
 				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
@@ -1641,7 +1637,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x02:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				if (_word2C8D7)
 					writeTechAndMapFiles();
 				_oldMapPosX = _mapPosX = scriptNumberArray[1];
@@ -1655,7 +1651,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x03:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[2] - scriptNumberArray[0];
 				int16 var10E = scriptNumberArray[3] - scriptNumberArray[1];
 
@@ -1667,7 +1663,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x04:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				_mapPosX = scriptNumberArray[0];
 				_mapPosY = scriptNumberArray[1];
 				_word2C880 = true;
@@ -1676,7 +1672,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x05:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				if (var110 != -1) {
 					int16 var10E = scriptNumberArray[1];
@@ -1687,7 +1683,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x06:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				if (var110 != -1) {
 					int16 var10E = scriptNumberArray[1];
@@ -1696,20 +1692,20 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			}
 			break;
 		case 0x07:
-			if (argC != 0) {
+			if (flag) {
 				totalPartyKill();
 				// emptyFunction(2);
 			}
 			break;
 		case 0x08:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0 && scriptNumberArray[0] != -1) {
+			if (flag && scriptNumberArray[0] != -1) {
 				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
 			}
 			break;		
 		case 0x09:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				if (var110 != -1) {
 					int16 var10E = getRandom(scriptNumberArray[1]);
@@ -1721,7 +1717,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0A:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				if (var110 != -1) {
 					_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
@@ -1730,7 +1726,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0B:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				if (var110 != -1) {
 					int16 var10E = getRandom(scriptNumberArray[1]);
@@ -1742,7 +1738,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0C:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				bool found = false;
 				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
@@ -1758,7 +1754,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0D:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = _teamCharId[scriptNumberArray[0]];
 				for (int16 counter = 0; counter < _teamSize; ++counter) {
 					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
@@ -1768,7 +1764,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0E:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				bool found = false;
 				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
@@ -1788,7 +1784,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x0F:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				if (isCharacterATeamMember(var110))
 					var_F0 = scriptNumberArray[1];
@@ -1798,16 +1794,16 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x10:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0)
+			if (flag)
 				var_F0 = scriptNumberArray[0];
 
 			break;
 		case 0x11:
-			if (argC != 0)
+			if (flag)
 				_unkArray2C8AA[0] = 0;
 			break;
 		case 0x12:
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1)
 					_mapUnknown[var110]._field1 = 0xFF;
@@ -1815,7 +1811,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x13:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0 && _largeMapFlag) {
+			if (flag && _largeMapFlag) {
 				_word2C87A = true;
 				loadPlacesFile(scriptNumberArray[0], false);
 				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
@@ -1825,7 +1821,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x14:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				if (!isCharacterATeamMember(var110))
 					var_EE = var110;
@@ -1834,7 +1830,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x15:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				_oldMapPosX = _mapPosX = scriptNumberArray[0];
 				_oldMapPosY = _mapPosY = scriptNumberArray[1];
 				_largeMapFlag = true;
@@ -1843,7 +1839,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x16:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
 				if (isCharacterATeamMember(var110)) {
@@ -1858,14 +1854,14 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x17:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				displayAnimFrames(var110, true);
 			}
 			break;
 		case 0x18:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = scriptNumberArray[1] - scriptNumberArray[0] + 1;
 				bool found = false;
 				var110 = getRandom(var110) + scriptNumberArray[0] - 1;
@@ -1903,7 +1899,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x19:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				if (_largeMapFlag) {
 					_mapGameMapPtr[scriptNumberArray[0] * 6 + scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				} else {
@@ -1913,7 +1909,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x1A:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
 					_mapUnknown[var110]._field1 = 0xFF;
@@ -1922,7 +1918,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x1B:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
 					_mapUnknown[var110]._field1 = 0xFF;
@@ -1933,19 +1929,19 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x1C:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				_history[scriptNumberArray[0]] = 0xFF;
 			}
 			break;
 		case 0x1D:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				_history[scriptNumberArray[0]] = 0;
 			}
 			break;
 		case 0x1E:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (argC != 0) {
+			if (flag) {
 				if (_history[scriptNumberArray[0]] == 0)
 					var_F0 = scriptNumberArray[2];
 				else
@@ -1954,12 +1950,12 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 			break;
 		case 0x1F:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (argC != 0)
+			if (flag)
 				_unkArray2C8AA[0] = scriptNumberArray[0];
 
 			break;
 		case 0x20:
-			if (argC != 0) {
+			if (flag) {
 				handleWinSequence();
 				_system->quit();
 			}
@@ -1983,7 +1979,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int posX, int posY, int maxX,
 	return var_F0;
 }
 
-void EfhEngine::sub133E5(uint8 *srcPtr, int posX, int posY, int maxX, int maxY, int argC) {
+void EfhEngine::sub133E5(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;
 	memset(_messageToBePrinted, 0, 200);
@@ -2005,7 +2001,7 @@ void EfhEngine::sub133E5(uint8 *srcPtr, int posX, int posY, int maxX, int maxY,
 		}
 	}
 
-	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, argC);
+	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, flag);
 }
 
 void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
@@ -2015,7 +2011,7 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 			if (impArray != nullptr) {
 				_word2C86E = 4;
 				_dword2C856 = impArray;
-				sub133E5(impArray, 17, 115, 110, 133, 0);
+				sub133E5(impArray, 17, 115, 110, 133, false);
 			}
 			if (counter == 0 && flag)
 				displayFctFullScreen();
@@ -2115,7 +2111,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWi
 
 	drawColoredRect(minX, maxX, minY, maxY, 0);
 	if (str)
-		varA = script_parse(str, minX, minY, maxX, maxY, -1);
+		varA = script_parse(str, minX, minY, maxX, maxY, true);
 
 	if (displayTeamWindowFl)
 		displayLowStatusScreen(false);
@@ -2127,7 +2123,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWi
 		else {
 			drawColoredRect(minX, maxX, minY, maxY, 0);
 			if (str)
-				int16 varC = script_parse(str, minX, minY, maxX, maxY, -1);
+				int16 varC = script_parse(str, minX, minY, maxX, maxY, true);
 		}
 
 		if (displayTeamWindowFl)
@@ -2832,7 +2828,7 @@ bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 }
 
 void EfhEngine::displayMonsterAnim(int16 monsterId) {
-	int16 animId = kEncounters[_mapMonsters[monsterId]._MonsterRef]._animId;
+	int16 animId = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
 	displayAnimFrames(animId, true);
 }
 
@@ -3651,7 +3647,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	for (int16 counter1 = var4; counter1 < 5; ++counter1) {
 		_teamMonsterIdArray[counter1] = -1;
 		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
-			_stru32686[counter1]._field0[counter2] = 0x8000;
+			_stru32686[counter1]._field0[counter2] = (int16)0x8000;
 		}
 	}
 	// sub1BE9A - last loop counter1_monsterId - End
@@ -3660,19 +3656,19 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 int16 EfhEngine::getTeamMonsterAnimId() {
 	int16 retVal = 0xFF;
 	for (int16 counter = 0; counter < 5; ++counter) {
-		int16 monsterGroupId = _teamMonsterIdArray[counter];
-		if (monsterGroupId == -1)
+		int16 monsterId = _teamMonsterIdArray[counter];
+		if (monsterId == -1)
 			continue;
 
-		if (!unkFct_checkMonsterField8(monsterGroupId, false))
+		if (!unkFct_checkMonsterField8(monsterId, false))
 			continue;
 
-		retVal = kEncounters[_mapMonsters[monsterGroupId]._MonsterRef]._animId;
+		retVal = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
 		break;
 	}
 
 	if (retVal == 0xFF)
-		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._MonsterRef]._animId;
+		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._monsterRef]._animId;
 
 	return retVal;
 }
@@ -3707,7 +3703,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		setTextColorRed();
 		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
 		if (var1 <= 0x3D) {
-			sprintf(buffer, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._MonsterRef]._name);
+			sprintf(buffer, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
 			displayStringAtTextPos(buffer);
 			if (var6E > 1)
 				displayStringAtTextPos("s");
@@ -4258,11 +4254,11 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	int16 rndVal = getRandom(100);
-	if (kEncounters[_mapMonsters[monsterId]._MonsterRef]._dropOccurrencePct < rndVal)
+	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
 		return false;
 
 	rndVal = getRandom(5) - 1;
-	int16 itemId = kEncounters[_mapMonsters[monsterId]._MonsterRef]._dropItemId[rndVal];
+	int16 itemId = kEncounters[_mapMonsters[monsterId]._monsterRef]._dropItemId[rndVal];
 	if (itemId == -1)
 		return false;
 
@@ -4279,9 +4275,9 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 
 void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {
 	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
-	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._MonsterRef]._xpGiven;
+	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 	char buffer[80];
-	sprintf(buffer, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._MonsterRef]._xpGiven);
+	sprintf(buffer, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
 	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
 		generateSound(15);
 		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
@@ -4468,7 +4464,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					var51 >>= 6;
 					int16 var70 = var51;
 					varInt = _teamMonsterIdArray[groupId];
-					int16 var5E = kEncounters[_mapMonsters[varInt]._MonsterRef]._nameArticle;
+					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
 					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
 					int16 var62 = 0;
@@ -4525,7 +4521,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						*_enemyNamePt1 = 0;
 					}
 
-					strcpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._MonsterRef]._name);
+					strcpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
 					copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
 					copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
@@ -4857,7 +4853,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
 								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
-								int16 var70 = kEncounters[_mapMonsters[varInt]._MonsterRef]._nameArticle;
+								int16 var70 = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 								int16 var5E = _npcBuf[_teamCharId[var7E]]._possessivePronounSHL6 >> 6;
 								varInt = _items[unk_monsterField5_itemId].field_13;
 								_word32482[var7E] += (varInt * 5);
@@ -4915,7 +4911,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								else
 									*_enemyNamePt1 = 0;
 
-								strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._name);
+								strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name);
 								copyString(_npcBuf[_teamCharId[var7E]]._name, _characterNamePt2);
 								copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
@@ -5018,8 +5014,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
 						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
-							strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._name);
-							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._MonsterRef]._nameArticle;
+							strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name);
+							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
 								strcpy(_enemyNamePt1, "The ");
 							else
@@ -5378,7 +5374,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 			script_parse((uint8 *)str, 28, 122, 105, 166, 0);
 			displayFctFullScreen();
 		} else {
-			retVal = script_parse((uint8 *)str, 28, 122, 105, 166, -1);
+			retVal = script_parse((uint8 *)str, 28, 122, 105, 166, true);
 		}
 	}
 
@@ -5516,9 +5512,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			}
 			// The original was duplicating this code in each branch of the previous random check. 
 			if (victims > 1) {
-				sprintf(buffer1, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
 			strcat((char *)_messageToBePrinted, buffer1);
 		}
@@ -5556,9 +5552,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				sprintf(buffer1, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._MonsterRef]._name);
+				sprintf(buffer1, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
 			strcat((char *)_messageToBePrinted, buffer1);
 			// </CHECKME>
@@ -6446,7 +6442,7 @@ bool EfhEngine::sub16E14() {
 			for (int16 var6C = 0; var6C < 2; ++var6C) {
 				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 				if (var1 <= 0x3D) {
-					strcpy(dest, kEncounters[_mapMonsters[monsterId]._MonsterRef]._name);
+					strcpy(dest, kEncounters[_mapMonsters[monsterId]._monsterRef]._name);
 					if (var6A > 1)
 						strcat(dest, " ");
 
@@ -6454,7 +6450,7 @@ bool EfhEngine::sub16E14() {
 				} else if (var1 == 0x3E) {
 					strcpy(buffer, "(NOT DEFINED)");
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
-					copyString(_npcBuf[_mapMonsters[monsterId]._MonsterRef]._name, dest);
+					copyString(_npcBuf[_mapMonsters[monsterId]._monsterRef]._name, dest);
 					sprintf(buffer, "with %s", dest);
 				}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index eeaf9b259f7..4be294d1e58 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -132,9 +132,7 @@ struct ItemStruct {
 };
 
 struct NPCStruct {
-	char _name[9];
-	uint8 field_9;
-	uint8 field_A;
+	char _name[11];
 	uint8 field_B;
 	uint8 field_C;
 	uint8 field_D;
@@ -213,7 +211,7 @@ struct MapMonster {
 	uint8 _posY;
 	uint8 _itemId_Weapon;
 	uint8 _field_6;
-	uint8 _MonsterRef;
+	uint8 _monsterRef;
 	uint8 _field_8;
 	uint8 _field_9;
 	uint8 _groupSize;
@@ -322,8 +320,8 @@ private:
 	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
-	int16 script_parse(uint8 *str, int posX, int posY, int maxX, int maxY, int argC);
-	void sub133E5(uint8 *impPtr, int posX, int posY, int maxX, int maxY, int argC);
+	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
+	void sub133E5(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 	void sub221FA(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);


Commit: 8cffee5e899d03ed5b501a6cd1e57f4eaf2e334e
    https://github.com/scummvm/scummvm/commit/8cffee5e899d03ed5b501a6cd1e57f4eaf2e334e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Turn _mapGameMap and _curPlace into arrays

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7d96c08af88..7cbaa1badaa 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -192,7 +192,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
 	_mapBitmapRef = nullptr;
-	_mapGameMapPtr = nullptr;
 
 	_defaultBoxColor = 0;
 
@@ -881,6 +880,7 @@ void EfhEngine::initEngine() {
 	memset(_map, 0, sizeof(_map));
 	memset(_places, 0, sizeof(_places));
 	memset(_curPlace, 0, sizeof(_curPlace));
+	memset(_mapGameMap, 0, sizeof(_mapGameMap));
 	memset(_npcBuf, 0, sizeof(_npcBuf));
 	memset(_imp1, 0, sizeof(_imp1));
 	memset(_imp2, 0, sizeof(_imp2));
@@ -914,7 +914,10 @@ void EfhEngine::initEngine() {
 			_mapMonsters[i]._pictureRef[j] = 0;
 	}
 	
-	_mapGameMapPtr = &_map[2758];
+	uint8 *_mapPtr = &_map[2758];
+	for (int i = 0; i < 64; ++i)
+		for (int j = 0; j < 64; ++j)
+			_mapGameMap[i][j] = *_mapPtr++;
 
 	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
 	_vgaGraphicsStruct2->_shiftValue = 0x2000;
@@ -1163,10 +1166,10 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 		int16 var12 = 128;
 		for (int16 var16 = minX; var16 <= maxX; ++var16) {
 			if (largeMapFl) {
-				int16 idx = _mapGameMapPtr[(var16 * 64) + counterY]; // 64 = large map size (square)
+				int16 idx = _mapGameMap[var16][counterY];
 				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
 			} else {
-				int16 idx = _curPlace[(var16 * 24) + counterY]; // 24 = small map size (square)
+				int16 idx = _curPlace[var16][counterY];
 				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
 			}
 			var12 += 16;
@@ -1901,9 +1904,9 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
 				if (_largeMapFlag) {
-					_mapGameMapPtr[scriptNumberArray[0] * 6 + scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+					_mapGameMap[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				} else {
-					_curPlace[scriptNumberArray[0] * 24 + scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+					_curPlace[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				}
 			}
 			break;
@@ -2033,7 +2036,7 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 		for (int16 var8 = 0; var8 <= 23; ++var8) {
 			int16 var4 = counter + varE;
 			int16 var2 = var8 + varC;
-			_mapGameMapPtr[var2 + 64 * var4] = _curPlace[var8 + counter * 24];
+			_mapGameMap[var4][var2] = _curPlace[counter][var8];
 		}
 		redrawScreen();
 	}
@@ -2042,7 +2045,7 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 		for (int16 var8 = 0; var8 <= 23; ++var8) {
 			int16 var4 = counter + varE;
 			int16 var2 = var8 + varC;
-			_mapGameMapPtr[var2 + 64 * var4] = _curPlace[var8 + counter * 24];
+			_mapGameMap[var4][var2] = _curPlace[counter][var8];
 		}
 		redrawScreen();
 	}
@@ -2398,24 +2401,24 @@ void EfhEngine::computeMapAnimation() {
 			if (_largeMapFlag) {
 				if (_currentTileBankImageSetId[0] != 0)
 					continue;
-				uint8 var4 = _mapGameMapPtr[counterX * 64 + counterY];
+				uint8 var4 = _mapGameMap[counterX][counterY];
 				if (var4 >= 1 && var4 <= 0xF) {
 					if (getRandom(100) < 50)
-						_mapGameMapPtr[counterX * 64 + counterY] += 0xC5;
+						_mapGameMap[counterX][counterY] += 0xC5;
 				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
 					if (getRandom(100) < 50)
-						_mapGameMapPtr[counterX * 64 + counterY] -= 0xC5;
+						_mapGameMap[counterX][counterY] -= 0xC5;
 				}
 			} else {
 				if (_currentTileBankImageSetId[0] != 0)
 					continue;
-				uint8 var4 = _curPlace[counterX * 24 + counterY];
+				uint8 var4 = _curPlace[counterX][counterY];
 				if (var4 >= 1 && var4 <= 0xF) {
 					if (getRandom(100) < 50)
-						_curPlace[counterX * 24 + counterY] += 0xC5;
+						_curPlace[counterX][counterY] += 0xC5;
 				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
 					if (getRandom(100) < 50)
-						_curPlace[counterX * 24 + counterY] -= 0xC5;
+						_curPlace[counterX][counterY] -= 0xC5;
 				}
 			}
 		}
@@ -3106,7 +3109,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 						if (var2 != 0xFF)
 							var4 = var2;
 						
-						if (var4 != 0xFFFF) {
+						if (var4 != -1) {
 							for (int16 counter = 0; counter < 2; ++counter) {
 								if (varA) {
 									displayCenteredString("[DONE]", 128, 303, 117);
@@ -3225,9 +3228,9 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	if (_tileFact[imageSetId * 2 + 1] != 0xFF && !_word2C8D5) {
 		if ((arg4 == 1 && _word2C8D7) || (arg4 == 0 && _word2C8D7 && imageSetId != 128 && imageSetId != 121)) {
 			if (_largeMapFlag) {
-				_mapGameMapPtr[mapPosX * 64 + mapPosY] = _tileFact[imageSetId * 2 + 1];
+				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId * 2 + 1];
 			} else {
-				_curPlace[mapPosX * 24 + mapPosY] = _tileFact[imageSetId * 2 + 1];
+				_curPlace[mapPosX][mapPosY] = _tileFact[imageSetId * 2 + 1];
 			}
 
 			_redrawNeededFl = true;
@@ -6609,9 +6612,9 @@ void EfhEngine::saveEfhGame() {
 
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	if (_largeMapFlag)
-		return _mapGameMapPtr[mapPosX * 64 + mapPosY];
+		return _mapGameMap[mapPosX][mapPosY];
 
-	return _curPlace[mapPosX * 24 + mapPosY];
+	return _curPlace[mapPosX][mapPosY];
 }
 
 void EfhEngine::displayNextAnimFrame() {
@@ -6650,10 +6653,14 @@ void EfhEngine::setTextPos(int16 textPosX, int16 textPosY) {
 }
 
 void EfhEngine::copyCurrentPlaceToBuffer(int id) {
+	// Note that 576 = 24 * 24
 	uint8 *placesPtr = &_places[576 * id];
 
-	// Note that 576 = 24 * 24
-	memcpy(_curPlace, placesPtr, 24 * 24);
+	for (int16 i = 0; i < 24; ++i) {
+		for (int16 j = 0; j < 24; ++j) {
+			_curPlace[i][j] = placesPtr[i * 24 + j];
+		}
+	}
 }
 
 } // End of namespace Efh
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4be294d1e58..e33705d3ca7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -488,7 +488,7 @@ private:
 	uint8 _windowWithBorderBuf[1500];
 	uint8 _map[7000];
 	uint8 _places[12000];
-	uint8 _curPlace[600];
+	uint8 _curPlace[24][24];
 	NPCStruct _npcBuf[100];
 	uint8 _imp1[13000];
 	uint8 _imp2[10000];
@@ -509,7 +509,7 @@ private:
 	uint8 *_mapBitmapRef;
 	UnkMapStruct _mapUnknown[100];
 	MapMonster _mapMonsters[64];
-	uint8 *_mapGameMapPtr;
+	uint8 _mapGameMap[64][64];
 
 	uint8 _defaultBoxColor;
 	FontDescr _fontDescr;


Commit: b32993001381d5485dc773bba5774d8a7e12f75c
    https://github.com/scummvm/scummvm/commit/b32993001381d5485dc773bba5774d8a7e12f75c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Turn _tileFact into an array of struct, add comments on object types in sub1BC74

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7cbaa1badaa..4a79fa49215 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -164,8 +164,11 @@ void Stru32686::init() {
 }
 
 void Stru3244C::init() {
-	_field0 = 0;
-	_field2 = 0;
+	_field0 = _field2 = 0;
+}
+
+void TileFactStruct::init() {
+	_field0 = _field1 = 0;
 }
 
 EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
@@ -662,7 +665,13 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 
 void EfhEngine::readTileFact() {
 	Common::String fileName = "tilefact";
-	readFileToBuffer(fileName, _tileFact);
+	uint8 tileFactBuff[864];
+	readFileToBuffer(fileName, tileFactBuff);
+	uint8 *curPtr = tileFactBuff;
+	for (int i = 0; i < 432; ++i) {
+		_tileFact[i]._field0 = *curPtr++;
+		_tileFact[i]._field1 = *curPtr++;
+	}
 }
 
 void EfhEngine::readItems() {
@@ -3225,22 +3234,22 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 		_word2C880 = false;
 		return -1;
 	}
-	if (_tileFact[imageSetId * 2 + 1] != 0xFF && !_word2C8D5) {
+	if (_tileFact[imageSetId]._field1 != 0xFF && !_word2C8D5) {
 		if ((arg4 == 1 && _word2C8D7) || (arg4 == 0 && _word2C8D7 && imageSetId != 128 && imageSetId != 121)) {
 			if (_largeMapFlag) {
-				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId * 2 + 1];
+				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
 			} else {
-				_curPlace[mapPosX][mapPosY] = _tileFact[imageSetId * 2 + 1];
+				_curPlace[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
 			}
 
 			_redrawNeededFl = true;
-			if (_tileFact[imageSetId * 2] == 0)
+			if (_tileFact[imageSetId]._field0 == 0)
 				return 2;
 			return 1;
 		}
 	}
 
-	return _tileFact[imageSetId * 2];
+	return _tileFact[imageSetId]._field0;
 }
 
 bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
@@ -5485,7 +5494,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 	switch (_items[itemId].field_16 - 1) {
-	case 0:
+	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
 		if (argA == 2) {
 			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5524,7 +5533,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		varA6 = true;
 		break;
-	case 1:
+	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
 		if (argA == 2) {
 			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5575,7 +5584,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		varA6 = true;
 		break;
-	case 4:
+	case 4: // "Unholy Sinwave", "Holy Water"
 		if (argA == 2) {
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5599,7 +5608,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		varA6 = true;
 		break;
-	case 5:
+	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
 		if (argA == 2) {
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5620,7 +5629,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		varA6 = true;
 		break;
-	case 12:
+	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
 		if (argA == 2) {
 			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5629,7 +5638,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		varA6 = true;
 		break;
-	case 14: {
+	case 14: { // "Feathered Cap"
 		int16 varAA;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
@@ -5653,7 +5662,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		}
 		break;
-	case 15: {
+	case 15: { // "Regal Crown"
 		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
@@ -5678,14 +5687,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		}
 		break;
-	case 16: {
+	case 16: { // Fairy Dust
 		int16 varAC = _mapPosX;
 		int16 varAA = _mapPosY;
 		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
 		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
 		int16 varAE = sub15538(_mapPosX, _mapPosY);
 
-		if (_tileFact[2 * varAE] == 0) {
+		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
 			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
 			if (argA == 2) {
@@ -5718,11 +5727,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;		
 		}
 		break;
-	case 17: {
+	case 17: { // "Devil Dust"
 		_mapPosX = _items[itemId].field_19;
 		_mapPosY = _items[itemId].field_1A;
 		int16 varAE = sub15538(_mapPosX, _mapPosY);
-		if (_tileFact[2 * varAE] == 0) {
+		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
 			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
 			if (argA == 2) {
@@ -5773,7 +5782,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		varA6 = true;
 		break;
-	case 19:
+	case 19: // "Junk"
 		strcpy(buffer1, "  * The item breaks!");
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
@@ -5783,7 +5792,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		setCharacterObjectToBroken(charId, objectId);
 		varA6 = true;
 		break;
-	case 23:
+	case 23: // "Divining Rod"
 		copyString(_items[itemId]._name, buffer2);
 		sprintf(buffer1, "The %s says, '", buffer2);
 		if (_items[itemId].field_19 < _mapPosX) {
@@ -5883,7 +5892,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		}
 		break;
-	case 26:
+	case 26: // "Black Sphere"
 		strcpy(buffer1, "The entire party collapses, dead!!!");
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
@@ -5895,7 +5904,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		// emptyFunction(2);
 		varA6 = true;
 		break;
-	case 27: {
+	case 27: { // "Magic Pyramid", "Razor Blade"
 		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
@@ -5920,7 +5929,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		}
 		break;
-	case 28:
+	case 28: // "Bugle"
 		if (argA == 2) {
 			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
 		} else {
@@ -5938,7 +5947,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		varA6 = true;
 		break;
-	case 29: {
+	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
 		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e33705d3ca7..b01bac7cc80 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -119,7 +119,7 @@ struct ItemStruct {
 	uint8 _defense;
 	uint8 _attacks;
 	uint8 _uses;
-	uint8 field_13;
+	int8 field_13; // data contains values from -8 to +8
 	uint8 _range;
 	uint8 _attackType;
 	uint8 field_16;
@@ -232,6 +232,13 @@ struct Stru3244C {
 	void init();
 };
 
+struct TileFactStruct {
+	uint8 _field0;
+	uint8 _field1;
+
+	void init();
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
@@ -494,7 +501,7 @@ private:
 	uint8 _imp2[10000];
 	uint8 _titleSong[1024];
 	ItemStruct _items[300];
-	uint8 _tileFact[864];
+	TileFactStruct _tileFact[432];
 	AnimInfo _animInfo[100];
 	uint8 _history[256];
 	uint8 _techData[4096];


Commit: 20b099c025535b49146cd88999b32e6472953a2c
    https://github.com/scummvm/scummvm/commit/20b099c025535b49146cd88999b32e6472953a2c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Fix loading of _mapGameMap (regression introduced 2 or 3 commits ago)

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4a79fa49215..cc9bb4114f7 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -633,8 +633,8 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _map);
 	// This is not present in the original.
-	// The purpose is to properly load the mapMonster data in an array of struct in order to use it without being a pain afterwards
-	loadMapMonsters();
+	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
+	loadMapArrays();
 
 	loadImageSetToTileBank(1, _mapBitmapRef[0] + 1);
 	loadImageSetToTileBank(2, _mapBitmapRef[1] + 1);
@@ -926,7 +926,7 @@ void EfhEngine::initEngine() {
 	uint8 *_mapPtr = &_map[2758];
 	for (int i = 0; i < 64; ++i)
 		for (int j = 0; j < 64; ++j)
-			_mapGameMap[i][j] = *_mapPtr++;
+			_mapGameMap[i][j] = 0;
 
 	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
 	_vgaGraphicsStruct2->_shiftValue = 0x2000;
@@ -1028,7 +1028,7 @@ void EfhEngine::initMapMonsters() {
 	}
 }
 
-void EfhEngine::loadMapMonsters() {
+void EfhEngine::loadMapArrays() {
 	uint8 *_mapUnknownPtr = &_map[2];
 
 	for (int i = 0; i < 100; ++i) {
@@ -1058,6 +1058,12 @@ void EfhEngine::loadMapMonsters() {
 		for (int j = 0; j < 9; ++j)
 			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
 	}
+
+	uint8 *mapPtr = &_map[2758];
+	for (int i = 0; i < 64; ++i) {
+		for (int j = 0; j < 64; ++j)
+			_mapGameMap[i][j] = *mapPtr++;
+	}
 }
 
 void EfhEngine::saveAnimImageSetId() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b01bac7cc80..d36c171e1eb 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -294,7 +294,7 @@ private:
 	void playIntro();
 	void initEngine();
 	void initMapMonsters();
-	void loadMapMonsters();
+	void loadMapArrays();
 	void saveAnimImageSetId();
 	int16 getEquipmentDefense(int16 charId, bool flag);
 	uint16 sub1C80A(int16 charId, int field18, bool flag);


Commit: d29e4ed7f05730bac4e1d4585cbc15915440a5f9
    https://github.com/scummvm/scummvm/commit/d29e4ed7f05730bac4e1d4585cbc15915440a5f9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:36+01:00

Commit Message:
EFH: Fix unitialized variables in constructor, remove initializations in initEngine()

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index cc9bb4114f7..0364f57c135 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -273,7 +273,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_teamMonsterIdArray[i] = -1;
 		_stru32686[i].init();
 	}
-	
+
 	_unkArray2C8AA[2] = 1;
 	_teamSize = 1;
 	_word2C872 = 0;
@@ -304,7 +304,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_menuDepth = 0;
 	_word2D0BA = 0;
 
-
 	for (int i = 0; i < 15; ++i) {
 		_word3273A[i] = 0;
 	}
@@ -313,6 +312,31 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	for (int i = 0; i < 8; ++i)
 		_stru3244C[i].init();
 
+	memset(_bufferCharBM, 0, ARRAYSIZE(_bufferCharBM));
+	for (int i = 0; i < 3; ++i)
+		memset(_tileBank[i], 0, ARRAYSIZE(_tileBank[i]));
+	memset(_circleImageBuf, 0, ARRAYSIZE(_circleImageBuf));
+	memset(_portraitBuf, 0, ARRAYSIZE(_portraitBuf));
+	memset(_hiResImageBuf, 0, ARRAYSIZE(_hiResImageBuf));
+	memset(_loResImageBuf, 0, ARRAYSIZE(_loResImageBuf));
+	memset(_menuBuf, 0, ARRAYSIZE(_menuBuf));
+	memset(_windowWithBorderBuf, 0, ARRAYSIZE(_windowWithBorderBuf));
+	memset(_map, 0, ARRAYSIZE(_map));
+	memset(_places, 0, ARRAYSIZE(_places));
+	for (int i = 0; i < 24; ++i)
+		memset(_curPlace[i], 0, ARRAYSIZE(_curPlace[i]));
+	memset(_npcBuf, 0, ARRAYSIZE(_npcBuf));
+	memset(_imp1, 0, ARRAYSIZE(_imp1));
+	memset(_imp2, 0, ARRAYSIZE(_imp2));
+	memset(_titleSong, 0, ARRAYSIZE(_titleSong));
+	memset(_items, 0, ARRAYSIZE(_items));
+	memset(_tileFact, 0, ARRAYSIZE(_tileFact));
+	memset(_animInfo, 0, ARRAYSIZE(_animInfo));
+	memset(_history, 0, ARRAYSIZE(_history));
+	memset(_techData, 0, ARRAYSIZE(_techData));
+	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
+	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
+	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
 }
 
 EfhEngine::~EfhEngine() {
@@ -872,62 +896,11 @@ Common::String EfhEngine::getSavegameFilename(int slot) {
 
 void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
-	memset(_bufferCharBM, 0, sizeof(_bufferCharBM));
 	_graphicsStruct = new EfhGraphicsStruct;
 	_graphicsStruct->copy(_vgaGraphicsStruct1);
 
-	for (int i = 0; i < 3; ++i) {
-		memset(_tileBank[i], 0, sizeof(_tileBank[i]));
-	}
-
-	memset(_circleImageBuf, 0, sizeof(_circleImageBuf));
-	memset(_portraitBuf, 0, sizeof(_portraitBuf));
-	memset(_hiResImageBuf, 0, sizeof(_hiResImageBuf));
-	memset(_loResImageBuf, 0, sizeof(_loResImageBuf));
-	memset(_menuBuf, 0, sizeof(_menuBuf));
-	memset(_windowWithBorderBuf, 0, sizeof(_windowWithBorderBuf));
-	memset(_map, 0, sizeof(_map));
-	memset(_places, 0, sizeof(_places));
-	memset(_curPlace, 0, sizeof(_curPlace));
-	memset(_mapGameMap, 0, sizeof(_mapGameMap));
-	memset(_npcBuf, 0, sizeof(_npcBuf));
-	memset(_imp1, 0, sizeof(_imp1));
-	memset(_imp2, 0, sizeof(_imp2));
-	memset(_titleSong, 0, sizeof(_titleSong));
-	for (int i = 0; i < 300; ++i)
-		_items[i].init();
-	memset(_tileFact, 0, sizeof(_tileFact));
-
-	for (int i = 0; i < 100; ++i)
-		_animInfo[i].init();
-
-	memset(_history, 0, sizeof(_history));
-	memset(_techData, 0, sizeof(_techData));
-
 	_mapBitmapRef = &_map[0];
 
-	// Replaces _mapMonstersPtr which was equal to &_map[902];
-	for (int i = 0; i < 64; ++i) {
-		_mapMonsters[i]._possessivePronounSHL6 = 0;
-		_mapMonsters[i]._field_1 = 0;
-		_mapMonsters[i]._guess_fullPlaceId = 0xFF;
-		_mapMonsters[i]._posX = 0;
-		_mapMonsters[i]._posY = 0;
-		_mapMonsters[i]._itemId_Weapon = 0;
-		_mapMonsters[i]._field_6 = 0;
-		_mapMonsters[i]._monsterRef = 0;
-		_mapMonsters[i]._field_8 = 0;
-		_mapMonsters[i]._field_9 = 0;
-		_mapMonsters[i]._groupSize = 0;
-		for (int j = 0; j < 9; ++j)
-			_mapMonsters[i]._pictureRef[j] = 0;
-	}
-	
-	uint8 *_mapPtr = &_map[2758];
-	for (int i = 0; i < 64; ++i)
-		for (int j = 0; j < 64; ++j)
-			_mapGameMap[i][j] = 0;
-
 	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
 	_vgaGraphicsStruct2->_shiftValue = 0x2000;
 


Commit: c5707c7046027d80ced80700ea426d511e395e71
    https://github.com/scummvm/scummvm/commit/c5707c7046027d80ced80700ea426d511e395e71
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Put debug traces everywhere

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0364f57c135..ad27c79c160 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -362,7 +362,18 @@ Common::Platform EfhEngine::getPlatform() const {
 	return _platform;
 }
 
+void EfhEngine::syncSoundSettings() {
+	Engine::syncSoundSettings();
+
+	//	_sound->syncVolume();
+}
+
+Common::String EfhEngine::getSavegameFilename(int slot) {
+	return _targetName + Common::String::format("-%02d.SAV", slot);
+}
+
 Common::Error EfhEngine::run() {
+	debug("run");
 	s_Engine = this;
 	initialize();
 	initGraphics(320, 200);
@@ -574,6 +585,8 @@ void EfhEngine::initialize() {
 }
 
 void EfhEngine::readAnimInfo() {
+	debug("readAnimInfo");
+	
 	Common::String fileName = "animinfo";
 	uint8 animInfoBuf[9000];
 	memset(animInfoBuf, 0, 9000);
@@ -599,6 +612,8 @@ void EfhEngine::readAnimInfo() {
 }
 
 void EfhEngine::findMapFile(int16 mapId) {
+	debug("findMapFile %d", mapId);
+	
 	if (!_word31E9E)
 		return;
 
@@ -612,7 +627,9 @@ void EfhEngine::findMapFile(int16 mapId) {
 }
 
 void EfhEngine::loadNewPortrait() {
-	static int16 unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
+	debug("loadNewPortrait");
+	
+	static int16 const unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
 	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
 
 	if (_currentAnimImageSetId == 200 + _unkRelatedToAnimImageSetId)
@@ -625,6 +642,8 @@ void EfhEngine::loadNewPortrait() {
 }
 
 void EfhEngine::loadAnimImageSet() {
+	debug("loadAnimImageSet");
+	
 	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
 		return;
 
@@ -638,11 +657,15 @@ void EfhEngine::loadAnimImageSet() {
 }
 
 void EfhEngine::loadHistory() {
+	debug("loadHistory");
+	
 	Common::String fileName = "history";
 	readFileToBuffer(fileName, _history);
 }
 
 void EfhEngine::loadTechMapImp(int16 fileId) {
+	debug("loadTechMapImp %d", fileId);
+	
 	if (fileId == 0xFF)
 		return;
 
@@ -670,6 +693,8 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 }
 
 void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
+	debug("loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
+	
 	if (fullPlaceId == 0xFF)
 		return;
 
@@ -688,6 +713,8 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 }
 
 void EfhEngine::readTileFact() {
+	debug("readTileFact");
+	
 	Common::String fileName = "tilefact";
 	uint8 tileFactBuff[864];
 	readFileToBuffer(fileName, tileFactBuff);
@@ -699,6 +726,8 @@ void EfhEngine::readTileFact() {
 }
 
 void EfhEngine::readItems() {
+	debug("readItems");
+	
 	Common::String fileName = "items";
 	uint8 itemBuff[8100];
 	readFileToBuffer(fileName, itemBuff);
@@ -727,6 +756,8 @@ void EfhEngine::readItems() {
 }
 
 void EfhEngine::loadNPCS() {
+	debug("loadNPCS");
+	
 	Common::String fileName = "npcs";
 	uint8 npcLoading[13400];
 	readFileToBuffer(fileName, npcLoading);
@@ -802,6 +833,8 @@ Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 }
 
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
+	debug("readImpFile %d %s", id, techMapFl ? "True" : "False");
+	
 	Common::String fileName = Common::String::format("imp.%d", id);
 
 	if (techMapFl)
@@ -813,6 +846,8 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 }
 
 void EfhEngine::playIntro() {
+	debug("playIntro");
+	
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
@@ -884,16 +919,6 @@ void EfhEngine::playIntro() {
 	getLastCharAfterAnimCount(80);
 }
 
-void EfhEngine::syncSoundSettings() {
-	Engine::syncSoundSettings();
-
-//	_sound->syncVolume();
-}
-
-Common::String EfhEngine::getSavegameFilename(int slot) {
-	return _targetName + Common::String::format("-%02d.SAV", slot);
-}
-
 void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
 	_graphicsStruct = new EfhGraphicsStruct;
@@ -973,6 +998,8 @@ void EfhEngine::initEngine() {
 }
 
 void EfhEngine::initMapMonsters() {
+	debug("initMapMonsters");
+	
 	for (uint8 monsterId = 0; monsterId < 64; ++monsterId) {
 		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 			continue;
@@ -1002,6 +1029,8 @@ void EfhEngine::initMapMonsters() {
 }
 
 void EfhEngine::loadMapArrays() {
+	debug("loadMapArrays");
+
 	uint8 *_mapUnknownPtr = &_map[2];
 
 	for (int i = 0; i < 100; ++i) {
@@ -1040,11 +1069,15 @@ void EfhEngine::loadMapArrays() {
 }
 
 void EfhEngine::saveAnimImageSetId() {
+	debug("saveAnimImageSetId");
+
 	_oldAnimImageSetId = _animImageSetId;
 	_animImageSetId = 255;
 }
 
 int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
+	debug("getEquipmentDefense %d %s", charId, flag ? "True" : "False");
+
 	int16 altDef = 0;
 	int16 totalDef = 0;
 	for (int i = 0; i < 10; ++i) {
@@ -1071,7 +1104,9 @@ int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
 	return altDef;
 }
 
-uint16 EfhEngine::sub1C80A(int16 charId, int field18, bool flag) {
+uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
+	debug("sub1C80A %d %d %s", charId, field18, flag ? "True" : "False");
+
 	for (int i = 0; i < 10; ++i) {
 		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
 			continue;
@@ -1091,6 +1126,8 @@ uint16 EfhEngine::sub1C80A(int16 charId, int field18, bool flag) {
 }
 
 void EfhEngine::sub15150(bool flag) {
+	debug("sub15150 %s", flag ? "True" : "False");
+
 	uint8 mapTileInfo = getMapTileInfo(_mapPosX, _mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[mapTileInfo / 72];
 
@@ -1115,7 +1152,9 @@ void EfhEngine::sub15150(bool flag) {
 	}
 }
 
-void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl) {
+void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl) {
+	debug("drawMap %s %d-%d %d %s %s", largeMapFl ? "True" : "False", mapPosX, mapPosY, mapSize, drawHeroFl ? "True" : "False", drawMonstersFl ? "True" : "False");
+	
 	int16 unkPosX = 5;
 	int16 unkPosY = 4;
 	int16 posX = 0;
@@ -1209,14 +1248,18 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSi
 }
 
 void EfhEngine::displaySmallMap(int16 posX, int16 posY) {
+	debugC(6, kDebugEngine, "displaySmallMap %d %d", posX, posY);
 	drawMap(false, posX, posY, 23, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
 void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
+	debugC(6, kDebugEngine, "displayLargeMap %d %d", posX, posY);
 	drawMap(true, posX, posY, 63, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
 void EfhEngine::redrawScreen() {
+	debug("redrawScreen");
+	
 	for (int16 counter = 0; counter < 2; ++counter) {
 		_redrawNeededFl = false;
 		if (!_largeMapFlag) {
@@ -1238,6 +1281,8 @@ void EfhEngine::redrawScreen() {
 }
 
 void EfhEngine::displayLowStatusScreen(bool flag) {
+	debug("displayLowStatusScreen %s", flag ? "True" : "False");
+	
 	static char strName[5] = "Name";
 	static char strDef[4] = "DEF";
 	static char strHp[3] = "HP";
@@ -1309,6 +1354,8 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 }
 
 uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
+	debug("script_readNumberArray");
+	
 	uint8 *buffer = srcBuffer;
 
 	for (int16 i = 0; i < destArraySize; ++i) {
@@ -1319,6 +1366,8 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 }
 
 uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
+	debug("script_getNumber");
+	
 	uint8 *buffer = srcBuffer; 
 	int16 var2 = 0;
 	for (;;) {
@@ -1332,12 +1381,15 @@ uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
 }
 
 void EfhEngine::removeObject(int16 charId, int16 objectId) {
+	debug("removeObject %d %d", charId, objectId);
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 	_npcBuf[charId]._inventory[objectId]._stat1 = 0;
 	_npcBuf[charId]._inventory[objectId]._stat2 = 0;
 }
 
 void EfhEngine::totalPartyKill() {
+	debug("totalPartyKill");
+
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
 			_npcBuf[counter]._hitPoints = 0;
@@ -1345,6 +1397,8 @@ void EfhEngine::totalPartyKill() {
 }
 
 void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
+	debug("removeCharacterFromTeam %d", teamMemberId);
+
 	int16 charId = _teamCharId[teamMemberId];
 	_npcBuf[charId].field_12 = _npcBuf[charId].field_B;
 	_npcBuf[charId].field_14 = _npcBuf[charId].field_E;
@@ -1364,6 +1418,8 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 }
 
 void EfhEngine::refreshTeamSize() {
+	debug("refreshTeamSize");
+	
 	_teamSize = 0;
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
@@ -1372,6 +1428,8 @@ void EfhEngine::refreshTeamSize() {
 }
 
 bool EfhEngine::isCharacterATeamMember(int16 id) {
+	debug("isCharacterATeamMember %d", id);
+
 	for (int16 counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharId[counter] == id)
 			return true;
@@ -1381,6 +1439,8 @@ bool EfhEngine::isCharacterATeamMember(int16 id) {
 }
 
 bool EfhEngine::isTPK() {
+	debug("isTPK");
+	
 	int16 zeroedChar = 0;
 	for (int16 counter = 0; counter < _teamSize; ++counter) {
 		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
@@ -1391,6 +1451,8 @@ bool EfhEngine::isTPK() {
 }
 
 void EfhEngine::handleWinSequence() {
+	debugC(1, kDebugEngine, "handleWinSequence");
+	
 	saveAnimImageSetId();
 	findMapFile(18);
 	// clearMemory();
@@ -1411,56 +1473,56 @@ void EfhEngine::handleWinSequence() {
 	}
 
 	getInput(12);
-	for (int16 counter2 = 1; counter2 < 8; ++counter2) {
+	for (int16 animId = 1; animId < 8; ++animId) {
 		for (int16 counter = 0; counter < 2; ++counter) {
 			displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
-			displayRawDataAtPos(winSeqSubFilesArray2[counter2], 136, 48);
+			displayRawDataAtPos(winSeqSubFilesArray2[animId], 136, 48);
 			if (counter == 0)
 				displayFctFullScreen();
 		}
 		getInput(1);
 	}
 
-	Common::KeyCode var59 = Common::KEYCODE_INVALID;
+	Common::KeyCode input = Common::KEYCODE_INVALID;
 
-	while(var59 != Common::KEYCODE_ESCAPE) {
+	while(input != Common::KEYCODE_ESCAPE) {
 		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
 		displayFctFullScreen();
 		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
-		var59 = getInput(32);
-		if (var59 != Common::KEYCODE_ESCAPE) {
+		input = getInput(32);
+		if (input != Common::KEYCODE_ESCAPE) {
 			displayRawDataAtPos(winSeqSubFilesArray2[10], 136, 72);
 			displayFctFullScreen();
 			displayRawDataAtPos(winSeqSubFilesArray2[10], 136, 72);
-			var59 = getInput(1);
+			input = getInput(1);
 		}
 
-		if (var59 != Common::KEYCODE_ESCAPE) {
+		if (input != Common::KEYCODE_ESCAPE) {
 			displayRawDataAtPos(winSeqSubFilesArray2[11], 136, 72);
 			displayFctFullScreen();
 			displayRawDataAtPos(winSeqSubFilesArray2[11], 136, 72);
-			var59 = getInput(1);
+			input = getInput(1);
 		}
 
-		if (var59 != Common::KEYCODE_ESCAPE) {
+		if (input != Common::KEYCODE_ESCAPE) {
 			displayRawDataAtPos(winSeqSubFilesArray2[12], 136, 72);
 			displayFctFullScreen();
 			displayRawDataAtPos(winSeqSubFilesArray2[12], 136, 72);
-			var59 = getInput(1);
+			input = getInput(1);
 		}
 
-		if (var59 != Common::KEYCODE_ESCAPE) {
+		if (input != Common::KEYCODE_ESCAPE) {
 			displayRawDataAtPos(winSeqSubFilesArray2[13], 136, 72);
 			displayFctFullScreen();
 			displayRawDataAtPos(winSeqSubFilesArray2[13], 136, 72);
-			var59 = getInput(1);
+			input = getInput(1);
 		}
 
-		if (var59 != Common::KEYCODE_ESCAPE) {
+		if (input != Common::KEYCODE_ESCAPE) {
 			displayRawDataAtPos(winSeqSubFilesArray2[14], 136, 72);
 			displayFctFullScreen();
 			displayRawDataAtPos(winSeqSubFilesArray2[14], 136, 72);
-			var59 = getInput(1);
+			input = getInput(1);
 		}
 	}
 	
@@ -1470,6 +1532,8 @@ void EfhEngine::handleWinSequence() {
 }
 
 bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
+	debug("giveItemTo %d %d %d", charId, objectId, altCharId);
+
 	for (int16 newObjectId = 0; newObjectId < 10; ++newObjectId) {
 		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
 			continue;
@@ -1491,6 +1555,8 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
 }
 
 int16 EfhEngine::chooseCharacterToReplace() {
+	debug("chooseCharacterToReplace");
+
 	Common::KeyCode maxVal = (Common::KeyCode)(Common::KEYCODE_0 + _teamSize);
 	Common::KeyCode input = Common::KEYCODE_INVALID;
 	for (;;) {
@@ -1506,6 +1572,8 @@ int16 EfhEngine::chooseCharacterToReplace() {
 }
 
 int16 EfhEngine::handleCharacterJoining() {
+	debug("handleCharacterJoining");
+	
 	static char strReplaceWho[13] = "Replace Who?";
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
@@ -1534,7 +1602,9 @@ int16 EfhEngine::handleCharacterJoining() {
 	return 2;
 }
 
-int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {	
+int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
+	debug("script_parse %s %d-%d %d-%d %s", (char *) stringBuffer, posX, posY, maxX, maxY, flag ? "True" : "False");
+
 	bool doneFlag = false;
 	int16 var_F2 = -1;
 	int16 var_F0 = 0xFF;
@@ -1971,6 +2041,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 }
 
 void EfhEngine::sub133E5(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
+	debug("sub133E5 %d-%d %d-%d %d", posX, posY, maxX, maxY, flag ? "True" : "False");
+
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;
 	memset(_messageToBePrinted, 0, 200);
@@ -1996,6 +2068,8 @@ void EfhEngine::sub133E5(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 }
 
 void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
+	debug("sub221FA %s %s", (char *)impArray, flag ? "True" : "False");
+	
 	for (uint8 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			drawColoredRect(16, 115, 111, 133, 0);
@@ -2011,6 +2085,8 @@ void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
 }
 
 void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
+	debug("sub15A28 %d %d", arg0, arg2);
+
 	_drawHeroOnMapFl = false;
 	int16 varE = arg0 - 11;
 	int16 varC = arg2 - 11;
@@ -2043,7 +2119,8 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 }
 
 void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
-	warning("TODO: sub2455E - check behavior");
+	debug("sub2455E %d %d %d", arg0, arg2, arg4);
+
 	uint8 varD = kByte2C7D0[arg0];
 	int16 varC = arg2 - 11;
 	int16 varA = arg4 - 11;
@@ -2064,7 +2141,9 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWindowFl) {
+int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl) {
+	debug("sub1C219 %s %c %c %s", (char *)str, menuType, arg4, displayTeamWindowFl ? "True" : "False");
+
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;
 	
@@ -2131,6 +2210,8 @@ int16 EfhEngine::sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWi
 }
 
 int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
+	debug("sub151FD %d %d", posX, posY);
+
 	if (_largeMapFlag) {
 		for (int16 counter = 0; counter < 100; ++counter) {
 			if (_mapUnknown[counter]._field1 == posX && _mapUnknown[counter]._field2 == posY && _mapUnknown[counter]._field0 == 0xFE)
@@ -2146,6 +2227,8 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 }
 
 bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
+	debug("isPosOutOfMap %d %d", mapPosX, mapPosY);
+
 	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
 	if (mapPosX == 0 && (mapPosY == 0 || mapPosY == maxMapBlocks))
@@ -2158,6 +2241,8 @@ bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
 }
 
 void EfhEngine::goSouth() {
+	debug("goSouth");
+
 	if (_largeMapFlag) {
 		if (++_mapPosY > 63)
 			_mapPosY = 63;
@@ -2173,6 +2258,8 @@ void EfhEngine::goSouth() {
 }
 
 void EfhEngine::goNorth() {
+	debug("goNorth");
+
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
 
@@ -2183,6 +2270,8 @@ void EfhEngine::goNorth() {
 }
 
 void EfhEngine::goEast() {
+	debug("goEast");
+
 	if (_largeMapFlag) {
 		if (++_mapPosX > 63)
 			_mapPosX = 63;
@@ -2198,6 +2287,8 @@ void EfhEngine::goEast() {
 }
 
 void EfhEngine::goWest() {
+	debug("goWest");
+
 	if (--_mapPosX < 0)
 		_mapPosX = 0;
 
@@ -2208,6 +2299,8 @@ void EfhEngine::goWest() {
 }
 
 void EfhEngine::goNorthEast() {
+	debug("goNorthEast");
+
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
 
@@ -2226,21 +2319,19 @@ void EfhEngine::goNorthEast() {
 }
 
 void EfhEngine::goSouthEast() {
+	debug("goSouthEast");
+
 	if (_largeMapFlag) {
 		if (++_mapPosX > 63)
 			_mapPosX = 63;
-	} else {
-		if (++_mapPosX > 23)
-			_mapPosX = 23;
-	}
+	} else if (++_mapPosX > 23)
+		_mapPosX = 23;
 
 	if (_largeMapFlag) {
 		if (++_mapPosY > 63)
 			_mapPosY = 63;
-	} else {
-		if (++_mapPosY > 23)
-			_mapPosY = 23;
-	}
+	} else if (++_mapPosY > 23)
+		_mapPosY = 23;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;
@@ -2249,6 +2340,8 @@ void EfhEngine::goSouthEast() {
 }
 
 void EfhEngine::goNorthWest() {
+	debug("goNorthWest");
+
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
 
@@ -2262,16 +2355,16 @@ void EfhEngine::goNorthWest() {
 }
 
 void EfhEngine::goSouthWest() {
+	debug("goSouthWest");
+
 	if (--_mapPosX < 0)
 		_mapPosX = 0;
 
 	if (_largeMapFlag) {
 		if (++_mapPosY > 63)
 			_mapPosY = 63;
-	} else {
-		if (++_mapPosY > 23)
-			_mapPosY = 23;
-	}
+	} else if (++_mapPosY > 23)
+		_mapPosY = 23;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;
@@ -2280,6 +2373,8 @@ void EfhEngine::goSouthWest() {
 }
 
 void EfhEngine::handleNewRoundEffects() {
+	debug("handleNewRoundEffects");
+
 	static int16 regenCounter = 0;
 
 	if (!_word2C8D7)
@@ -2305,6 +2400,8 @@ void EfhEngine::handleNewRoundEffects() {
 }
 
 bool EfhEngine::handleDeathMenu() {
+	debug("handleDeathMenu");
+
 	displayAnimFrames(20, true);
 	_imageSetSubFilesIdx = 213;
 	redrawScreen();
@@ -2366,6 +2463,8 @@ bool EfhEngine::handleDeathMenu() {
 }
 
 void EfhEngine::computeMapAnimation() {
+	debug("computeMapAnimation");
+
 	const int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
 	int16 minMapX = _mapPosX - 5;
@@ -2414,6 +2513,8 @@ void EfhEngine::computeMapAnimation() {
 }
 
 void EfhEngine::unkFct_anim() {
+	debug("unkFct_anim");
+
 	setNumLock();
 
 	if (_engineInitPending)
@@ -2429,6 +2530,8 @@ void EfhEngine::unkFct_anim() {
 }
 
 int8 EfhEngine::sub16B08(int16 monsterId) {
+	debug("sub16B08 %d", monsterId);
+
 	// Simplified version compared to the original
 	int16 maxSize = _largeMapFlag ? 63 : 23;
 	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
@@ -2454,6 +2557,8 @@ int8 EfhEngine::sub16B08(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
+	debug("moveMonsterAwayFromTeam %d", monsterId);
+
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		--_mapMonsters[monsterId]._posX;
 		if (_mapMonsters[monsterId]._posY < _mapPosY)
@@ -2486,6 +2591,8 @@ bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
+	debug("moveMonsterTowardsTeam %d", monsterId);
+
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		++_mapMonsters[monsterId]._posX;
 		if (_mapMonsters[monsterId]._posY < _mapPosY)
@@ -2518,7 +2625,8 @@ bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
-
+	debug("moveMonsterGroupOther %d %d", monsterId, direction);
+	
 	switch (direction - 1) {
 	case 0:
 		--_mapMonsters[monsterId]._posY;
@@ -2554,6 +2662,8 @@ bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 }
 
 bool EfhEngine::moveMonsterGroup(int16 monsterId) {
+	debug("moveMonsterGroup %d", monsterId);
+
 	int16 rand100 = getRandom(100);
 
 	if (rand100 < 30)
@@ -2566,7 +2676,9 @@ bool EfhEngine::moveMonsterGroup(int16 monsterId) {
 	return moveMonsterAwayFromTeam(monsterId);
 }
 
-int16 EfhEngine::computeMonsterGroupDistance(int monsterId) {
+int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
+	debug("computeMonsterGroupDistance %d", monsterId);
+	
 	int16 monsterPosX = _mapMonsters[monsterId]._posX;
 	int16 monsterPosY = _mapMonsters[monsterId]._posY;
 
@@ -2576,7 +2688,9 @@ int16 EfhEngine::computeMonsterGroupDistance(int monsterId) {
 	return (int16)sqrt(deltaX * deltaX + deltaY * deltaY);
 }
 
-bool EfhEngine::checkWeaponRange(int16 monsterId, int weaponId) {
+bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
+	debug("checkWeaponRange %d %d", monsterId, weaponId);
+	
 	static const int16 kRange[5] = {1, 2, 3, 3, 3};
 
 	assert(_items[weaponId]._range < 5);
@@ -2586,7 +2700,9 @@ bool EfhEngine::checkWeaponRange(int16 monsterId, int weaponId) {
 	return true;
 }
 
-bool EfhEngine::unkFct_checkMonsterField8(int id, bool teamFlag) {
+bool EfhEngine::unkFct_checkMonsterField8(int16 id, bool teamFlag) {
+	debug("unkFct_checkMonsterField8 %d %s", id, teamFlag ? "True" : "False");
+
 	int16 monsterId = id;
 	if (teamFlag)
 		monsterId = _teamMonsterIdArray[id];
@@ -2604,6 +2720,8 @@ bool EfhEngine::unkFct_checkMonsterField8(int id, bool teamFlag) {
 }
 
 bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
+	debug("checkTeamWeaponRange %d", monsterId);
+
 	if (!_word2D0BC)
 		return true;
 
@@ -2616,6 +2734,8 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 }
 
 bool EfhEngine::checkIfMonsterOnSameLargelMapPlace(int16 monsterId) {
+	debug("checkIfMonsterOnSameLargelMapPlace %d", monsterId);
+	
 	if (_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
 		return true;
 
@@ -2626,10 +2746,14 @@ bool EfhEngine::checkIfMonsterOnSameLargelMapPlace(int16 monsterId) {
 }
 
 bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
+	debug("checkMonsterWeaponRange %d", monsterId);
+	
 	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
 }
 
 void EfhEngine::sub174A0() {
+	debug("sub174A0");
+
 	static int16 sub174A0_monsterPosX = -1;
 	static int16 sub174A0_monsterPosY = -1;
 	
@@ -2807,6 +2931,8 @@ void EfhEngine::sub174A0() {
 }
 
 bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
+	debug("checkPictureRefAvailability %d", monsterId);
+	
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
@@ -2819,11 +2945,15 @@ bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 }
 
 void EfhEngine::displayMonsterAnim(int16 monsterId) {
+	debug("displayMonsterAnim %d", monsterId);
+
 	int16 animId = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
 	displayAnimFrames(animId, true);
 }
 
 int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
+	debug("countPictureRef %d %s", id, teamMemberFl ? "True" : "False");
+
 	int16 count = 0;
 	int16 monsterId;
 
@@ -2841,6 +2971,8 @@ int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
 }
 
 bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
+	debug("checkMonsterGroupDistance1OrLess %d", monsterId);
+
 	if (computeMonsterGroupDistance(monsterId) > 1)
 		return false;
 
@@ -2848,6 +2980,8 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 }
 
 bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
+	debug("sub21820 %d %d %d", monsterId, arg2, itemId);
+
 	char buffer[80];
 	memset(buffer, 0, 80);
 
@@ -3011,6 +3145,8 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 }
 
 void EfhEngine::sub221D2(int16 monsterId) {
+	debug("sub221D2 %d", monsterId);
+
 	if (monsterId != -1) {
 		_dword2C856 = nullptr;
 		sub21820(monsterId, 5, -1);
@@ -3018,6 +3154,8 @@ void EfhEngine::sub221D2(int16 monsterId) {
 }
 
 void EfhEngine::sub22AA8(int16 arg0) {
+	debug("sub22AA8 %d", arg0);
+
 	int16 var8, varA, varC, varE;
 	var8 = varA = varC = varE = 0;
 
@@ -3121,6 +3259,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 }
 
 bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
+	debug("sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
+	
 	int16 var8 = sub151FD(mapPosX, mapPosY);
 
 	if (var8 == -1) {
@@ -3200,6 +3340,8 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 }
 
 int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
+	debug("sub15581 %d-%d %d", mapPosX, mapPosY, arg4);
+	
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
 	imageSetId *= 72;
@@ -3232,6 +3374,8 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 }
 
 bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
+	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
+
 	for (int16 counter = 0; counter < teamMonsterId; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId)
 			return true;
@@ -3240,6 +3384,8 @@ bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
 }
 
 void EfhEngine::sub1BCA7(int16 monsterTeamId) {
+	debug("sub1BCA7 %d", monsterTeamId);
+
 	int16 counter = 0;
 	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false)) {
 		counter = 1;
@@ -3286,6 +3432,7 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 }
 
 void EfhEngine::reset_stru32686() {
+	debug("reset_stru32686");
 	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
 		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
 			_stru32686[counter1]._field0[counter2] = 0;
@@ -3295,17 +3442,22 @@ void EfhEngine::reset_stru32686() {
 }
 
 void EfhEngine::sub1BE89(int16 monsterId) {
+	debug("sub1BE89 %d", monsterId);
 	sub1BCA7(monsterId);
 	reset_stru32686();
 }
 
 void EfhEngine::resetTeamMonsterIdArray() {
+	debug("resetTeamMonsterIdArray");
+	
 	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
 	}
 }
 
 bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
+	debug("isTeamMemberStatusNormal %d", teamMemberId);
+	
 	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
 		return true;
 
@@ -3313,6 +3465,8 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 }
 
 void EfhEngine::sub1CDFA() {
+	debug("sub1CDFA");
+	
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
 			_stru3244C[counter]._field0 = counter + 1000;
@@ -3345,6 +3499,8 @@ void EfhEngine::sub1CDFA() {
 }
 
 void EfhEngine::redrawScreenForced() {
+	debug("redrawScreenForced");
+	
 	for (int16 counter = 0; counter < 2; ++counter) {
 		redrawScreen();
 		if (counter == 0)
@@ -3353,6 +3509,8 @@ void EfhEngine::redrawScreenForced() {
 }
 
 int16 EfhEngine::selectMonsterGroup() {
+	debug("selectMonsterGroup");
+	
 	int16 retVal = -1;
 
 	while (retVal == -1) {
@@ -3379,6 +3537,8 @@ int16 EfhEngine::selectMonsterGroup() {
 }
 
 int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
+	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
+	
 	int16 varE = -1;
 	
 	int16 var6 = sub1C80A(charId, unkFied18Val, true);
@@ -3434,6 +3594,8 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
 }
 
 void EfhEngine::sub1CAB6(int16 charId) {
+	debug("sub1CAB6 %d", charId);
+
 	for (int16 counter = 0; counter < 2; ++counter) {
 		sub15150(false);
 		displayLowStatusScreen(false);
@@ -3444,7 +3606,9 @@ void EfhEngine::sub1CAB6(int16 charId) {
 }
 
 bool EfhEngine::sub1CB27() {
-	int16 var4 = false;
+	debug("sub1CB27");
+
+	bool var4 = false;
 	for (int16 counter1 = 0; counter1 < _teamSize; ++counter1) {
 		_teamLastAction[counter1] = 0;
 		if (!isTeamMemberStatusNormal(counter1))
@@ -3549,6 +3713,8 @@ bool EfhEngine::sub1CB27() {
 
 // The parameter isn't used in the original
 void EfhEngine::sub1BE9A(int16 monsterId) {
+	debug("sub1BE9A %d", monsterId);
+
 	int16 var4 = 1;
 
 	// sub1BE9A - 1rst loop counter1_monsterId - Start
@@ -3645,6 +3811,8 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	}
 
 int16 EfhEngine::getTeamMonsterAnimId() {
+		debug("getTeamMonsterAnimId");
+
 	int16 retVal = 0xFF;
 	for (int16 counter = 0; counter < 5; ++counter) {
 		int16 monsterId = _teamMonsterIdArray[counter];
@@ -3665,6 +3833,8 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 }
 
 int16 EfhEngine::sub1BAF9(int16 monsterGroup) {
+	debug("sub1BAF9 %d", monsterGroup);
+	
 	int16 var2 = 0;
 	for (int16 counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(monsterGroup, counter))
@@ -3675,6 +3845,8 @@ int16 EfhEngine::sub1BAF9(int16 monsterGroup) {
 }
 
 void EfhEngine::sub1C4CA(bool whiteFl) {
+	debug("sub1C4CA %s", whiteFl ? "True" : "False");
+
 	int16 textPosY = 20;
 	for (int16 counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == -1)
@@ -3736,6 +3908,8 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 }
 
 void EfhEngine::displayCombatMenu(int16 charId) {
+	debug("displayCombatMenu %d", charId);
+
 	char buffer[80];
 	copyString(_npcBuf[charId]._name, buffer);
 	strcat(buffer, ":");
@@ -3769,6 +3943,8 @@ void EfhEngine::displayCombatMenu(int16 charId) {
 }
 
 void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
+	debug("drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", forceDrawFl ? "True" : "False");
+
 	for (int16 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || forceDrawFl) {
 			drawMapWindow();
@@ -3787,6 +3963,8 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 }
 
 void EfhEngine::handleFight_checkEndEffect(int16 charId) {
+	debug("handleFight_checkEndEffect %d", charId);
+	
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	if (_teamCharStatus[charId]._status == 0)
@@ -3823,6 +4001,8 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 }
 
 int16 EfhEngine::sub1DEC8(int16 groupNumber) {
+	debug("sub1DEC8 %d", groupNumber);
+	
 	int16 var4 = -1;
 	int16 monsterId = _teamMonsterIdArray[groupNumber];
 
@@ -3851,6 +4031,8 @@ int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 }
 
 int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
+	debug("getCharacterScore %d %d", charId, itemId);
+
 	int16 totalScore = 0;
 	switch (_items[itemId]._range) {
 	case 0:
@@ -3934,6 +4116,8 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 }
 
 bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
+	debug("checkSpecialItemsOnCurrentPlace %d", itemId);
+
 	switch(_techData[_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
 	case 1:
 		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
@@ -3995,6 +4179,8 @@ void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
 }
 
 bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
+	debug("hasAdequateDefense %d %d", monsterId, attackType);
+
 	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
 	
 	if (_items[itemId].field_16 != 0)
@@ -4004,6 +4190,8 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 }
 
 bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
+	debug("hasAdequateDefense_2 %d %d", charId, attackType);
+
 	int16 itemId = _npcBuf[charId]._unkItemId;
 
 	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
@@ -4021,6 +4209,8 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 }
 
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
+	debug("getDeathTypeDescription %d %d", attackerId, victimId);
+
 	int16 possessivePronoun;
 
 	if (attackerId > 999) {
@@ -4244,6 +4434,8 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 }
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
+	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
+	
 	int16 rndVal = getRandom(100);
 	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
 		return false;
@@ -4265,6 +4457,8 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 }
 
 void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {
+	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1, namePt2, monsterId);
+
 	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 	char buffer[80];
@@ -4287,6 +4481,8 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2,
 }
 
 void EfhEngine::addReactionText(int16 id) {
+	debug("addReactionText %d", id);
+	
 	int16 rand3 = getRandom(3);
 	char buffer[80];
 	memset(buffer, 0, 80);
@@ -4405,6 +4601,8 @@ void EfhEngine::addReactionText(int16 id) {
 }
 
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
+	debug("handleFight_lastAction_A %d", teamCharId);
+
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 
@@ -4628,6 +4826,8 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
+	debug("handleFight_lastAction_D %d", teamCharId);
+
 	_word32482[teamCharId] -= 40;
 	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
@@ -4642,6 +4842,8 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
+	debug("handleFight_lastAction_H %d", teamCharId);
+
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 
@@ -4659,6 +4861,8 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
+	debug("handleFight_lastAction_U %d", teamCharId);
+
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
@@ -4675,6 +4879,8 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 }
 
 char EfhEngine::getFightMessageLastCharacter(char *message) {
+	debug("getFightMessageLastCharacter %s", message);
+
 	char *ptr = message;
 
 	if (ptr == nullptr || *ptr == 0)
@@ -4689,6 +4895,8 @@ char EfhEngine::getFightMessageLastCharacter(char *message) {
 }
 
 void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
+	debug("sub1D8C2 %d %d", charId, damage);
+	
 	int16 var42 = 0;
 	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
 	char buffer[40];
@@ -4737,6 +4945,8 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 }
 
 bool EfhEngine::handleFight(int16 monsterId) {
+	debug("handleFight %d", monsterId);
+
 	int16 var8C = 0;
 
 	sub1BE89(monsterId);
@@ -5042,7 +5252,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	return true;
 }
 
-void EfhEngine::displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str) {
+void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
+	debug("displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
+
 	char buffer[20];
 	memset(buffer, 0, 20);
 
@@ -5066,6 +5278,8 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX,
 }
 
 void EfhEngine::displayStatusMenu(int16 windowId) {
+	debug("displayStatusMenu %d", windowId);
+
 	for (int16 counter = 0; counter < 9; ++counter) {
 		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
 	}
@@ -5087,6 +5301,8 @@ void EfhEngine::displayStatusMenu(int16 windowId) {
 }
 
 void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
+	debug("countRightWindowItems %d %d", menuId, charId);
+
 	int16 var2 = 0;
 	int16 var4 = 0;
 	_word2D0BA = 0;
@@ -5134,6 +5350,8 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 }
 
 int16 EfhEngine::getXPLevel(int32 xp) {
+	debug("getXPLevel %ld", xp);
+
 	int16 level = 0;
 	int16 var6 = 1500;
 
@@ -5153,6 +5371,8 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 }
 
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
+	debug("displayCharacterSummary %d %d", curMenuLine, npcId);
+
 	char buffer1[40];
 	char buffer2[40];
 	memset(buffer1, 0, 40);
@@ -5252,6 +5472,8 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 }
 
 void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
+	debug("displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
+	
 	char buffer[40];
 	memset(buffer, 0, 40);
 
@@ -5290,6 +5512,8 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 }
 
 void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
+	debug("displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
+	
 	drawColoredRect(144, 15, 310, 184, 0);
 	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
 	_textColor = 0x0E;
@@ -5335,6 +5559,8 @@ void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16
 }
 
 void EfhEngine::unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
+	debug("unk_StatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
+
 	displayStatusMenu(windowId);
 
 	countRightWindowItems(menuId, charId);
@@ -5345,6 +5571,8 @@ void EfhEngine::unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine,
 }
 
 void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("sub18E80 %d %d %d %d", charId, windowId, menuId, curMenuLine);
+
 	for (int counter = 0; counter < 2; ++counter) {
 		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
 		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
@@ -5355,6 +5583,8 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 }
 
 int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayString_3 % %s %d %d %d %d", str, animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+
 	int16 retVal = 0;
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
@@ -5378,20 +5608,25 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 }
 
 bool EfhEngine::isItemCursed(int16 itemId) {
+	debugC(6, kDebugEngine, "isItemCursed %d", itemId);
+
 	if (_items[itemId].field_16 == 21 || _items[itemId].field_16 == 22 || _items[itemId].field_16 == 23)
 		return true;
 
 	return false;
 }
 
-bool EfhEngine::hasObjectEquipped(int16 charId, int16 _objectId) {
-	if ((_npcBuf[charId]._inventory[_objectId]._stat1 & 0x80) == 0)
+bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
+	debug("hasObjectEquipped %d %d", charId, objectId);
+	if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0)
 		return false;
 
 	return true;
 }
 
 void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("equipCursedItem %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
 	if (isItemCursed(itemId)) {
@@ -5403,6 +5638,8 @@ void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, in
 }
 
 void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("sub191FF %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
 	if (hasObjectEquipped(charId, objectId)) {
@@ -5421,6 +5658,8 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 }
 
 void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
+	debug("sub1E028 %d 0x%X %d", id, mask, groupFl);
+
 	int16 monsterId;
 	if (groupFl) {
 		monsterId = _teamMonsterIdArray[id];
@@ -5433,12 +5672,16 @@ void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
+	debug("isMonsterActive %d %d", groupId, id);
+
 	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _stru32686[groupId]._field0[id] == 0)
 		return true;
 	return false;
 }
 
 int16 EfhEngine::sub15538(int16 mapPosX, int16 mapPosY) {
+	debug("sub15538 %d-%d", mapPosX, mapPosY);
+
 	int16 mapTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = mapTileInfo / 72;
 
@@ -5446,10 +5689,14 @@ int16 EfhEngine::sub15538(int16 mapPosX, int16 mapPosY) {
 }
 
 void EfhEngine::setCharacterObjectToBroken(int16 charId, int16 objectId) {
+	debug("setCharacterObjectToBroken %d %d", charId, objectId);
+
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 }
 
 int16 EfhEngine::selectOtherCharFromTeam() {
+	debug("selectOtherCharFromTeam");
+
 	Common::KeyCode maxVal = (Common::KeyCode) (Common::KEYCODE_0 + _teamSize);
 	Common::KeyCode input = Common::KEYCODE_INVALID; 
 	for (;;) {
@@ -5465,6 +5712,8 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 }
 
 int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
+	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine, argA);
+
 	char buffer1[80];
 	char buffer2[80];
 
@@ -6034,6 +6283,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 }
 
 int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
+	debug("handleStatusMenu %d %d", gameMode, charId);
+
 	int16 menuId = 9;
 	int16 var16 = -1;
 	int16 windowId = -1;
@@ -6395,6 +6646,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 }
 
 bool EfhEngine::sub16E14() {
+	debug("sub16E14");
+
 	int16 var68 = 0;
 	char dest[20];
 	char buffer[80];
@@ -6512,6 +6765,8 @@ bool EfhEngine::sub16E14() {
 }
 
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
+	debug("loadImageSetToTileBank %d %d", tileBankId, imageSetId);
+
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
 	int16 setId = imageSetId - 1;
@@ -6542,6 +6797,8 @@ void EfhEngine::checkProtection() {
 }
 
 void EfhEngine::loadEfhGame() {
+	debug("loadEfhGame");
+
 	// The original used a loop to check for the presence of the savegame on the current floppy.
 	// When the savegame wasn't found, it was displaying a screen asking for Disk 1 and was setting a flag used
 	// to call a function after loading right before returning.
@@ -6599,6 +6856,8 @@ void EfhEngine::saveEfhGame() {
 }
 
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
+	debug("getMapTileInfo %d-%d", mapPosX, mapPosY);
+
 	if (_largeMapFlag)
 		return _mapGameMap[mapPosX][mapPosY];
 
@@ -6606,6 +6865,8 @@ uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 }
 
 void EfhEngine::displayNextAnimFrame() {
+	debug("displayNextAnimFrame");
+
 	if (++_unkAnimRelatedIndex >= 15)
 		_unkAnimRelatedIndex = 0;
 
@@ -6617,6 +6878,8 @@ void EfhEngine::writeTechAndMapFiles() {
 }
 
 uint16 EfhEngine::getStringWidth(const char *buffer) {
+	debug("getStringWidth %s", buffer);
+
 	uint16 retVal = 0;
 
 	for (;;) {
@@ -6636,11 +6899,15 @@ uint16 EfhEngine::getStringWidth(const char *buffer) {
 }
 
 void EfhEngine::setTextPos(int16 textPosX, int16 textPosY) {
+	debugC(6, kDebugEngine, "setTextPos %d-%d", textPosX, textPosY);
+
 	_textPosX = textPosX;
 	_textPosY = textPosY;
 }
 
-void EfhEngine::copyCurrentPlaceToBuffer(int id) {
+void EfhEngine::copyCurrentPlaceToBuffer(int16 id) {
+	debug("copyCurrentPlaceToBuffer %d", id);
+
 	// Note that 576 = 24 * 24
 	uint8 *placesPtr = &_places[576 * id];
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index d36c171e1eb..4374f04d223 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -297,21 +297,21 @@ private:
 	void loadMapArrays();
 	void saveAnimImageSetId();
 	int16 getEquipmentDefense(int16 charId, bool flag);
-	uint16 sub1C80A(int16 charId, int field18, bool flag);
+	uint16 sub1C80A(int16 charId, int16 field18, bool flag);
 	void displayLowStatusScreen(bool flag);
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
 	void restoreAnimImageSetId();
 	void checkProtection();
 	void loadEfhGame();
 	void saveEfhGame();
-	void copyCurrentPlaceToBuffer(int id);
+	void copyCurrentPlaceToBuffer(int16 id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
 	void displayNextAnimFrame();
 	void writeTechAndMapFiles();
 	uint16 getStringWidth(const char *buffer);
 	void setTextPos(int16 textPosX, int16 textPosY);
 	void sub15150(bool flag);
-	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int mapSize, bool drawHeroFl, bool drawMonstersFl);
+	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl);
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
 	void redrawScreen();
@@ -332,7 +332,7 @@ private:
 	void sub221FA(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(uint8 *str, int menuType, int arg4, bool displayTeamWindowFl);
+	int16 sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
@@ -352,9 +352,9 @@ private:
 	bool moveMonsterTowardsTeam(int16 monsterId);
 	bool moveMonsterGroupOther(int16 monsterId, int16 direction);
 	bool moveMonsterGroup(int16 monsterId);
-	int16 computeMonsterGroupDistance(int monsterId);
-	bool checkWeaponRange(int16 monsterId, int weaponId);
-	bool unkFct_checkMonsterField8(int id, bool teamFlag);
+	int16 computeMonsterGroupDistance(int16 monsterId);
+	bool checkWeaponRange(int16 monsterId, int16 weaponId);
+	bool unkFct_checkMonsterField8(int16 id, bool teamFlag);
 	bool checkTeamWeaponRange(int16 monsterId);
 	bool checkIfMonsterOnSameLargelMapPlace(int16 monsterId);
 	bool checkMonsterWeaponRange(int16 monsterId);
@@ -405,7 +405,7 @@ private:
 	char getFightMessageLastCharacter(char *message);
 	void sub1D8C2(int16 charId, int16 damage);
 	bool handleFight(int16 monsterId);
-	void displayMenuItemString(int16 menuBoxId, int thisBoxId, int minX, int maxX, int minY, const char *str);
+	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
 	void displayStatusMenu(int16 windowId);
 	void countRightWindowItems(int16 menuId, int16 charId);
 	int16 getXPLevel(int32 xp);
@@ -416,7 +416,7 @@ private:
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
-	bool hasObjectEquipped(int16 charId, int16 _objectId);
+	bool hasObjectEquipped(int16 charId, int16 objectId);
 	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub1E028(int16 id, uint8 mask, int16 groupFl);
@@ -437,19 +437,19 @@ private:
 	void copyDirtyRect(int16 minX, int16 minY, int16 maxX, int16 maxY);
 	void copyGraphicBufferFromTo(EfhGraphicsStruct *efh_graphics_struct, EfhGraphicsStruct *efh_graphics_struct1, const Common::Rect &rect, int16 min_x, int16 min_y);
 	void displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY);
-	void drawRect(int minX, int minY, int maxX, int maxY);
-	void drawColoredRect(int minX, int minY, int maxX, int maxY, int color);
-	void clearScreen(int color);
+	void drawRect(int16 minX, int16 minY, int16 maxX, int16 maxY);
+	void drawColoredRect(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
+	void clearScreen(int16 color);
 	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
 	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
 	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
-	void displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int posY);
+	void displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int16 posY);
 	void drawMapWindow();
 	void displayGameScreen();
 	void drawUpperLeftBorders();
 	void drawUpperRightBorders();
 	void drawBottomBorders();
-	void drawChar(uint8 curChar, int16 posX, int posY);
+	void drawChar(uint8 curChar, int16 posX, int16 posY);
 	void setTextColorWhite();
 	void setTextColorRed();
 	void setTextColorGrey();
@@ -465,7 +465,7 @@ private:
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
-	void loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
+	void loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
 	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);	
 	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	int16 getRandom(int16 maxVal);
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 19fdfe4b66d..2bb1a426fe2 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -138,8 +138,8 @@ void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY)
 	//	_system->updateScreen();
 }
 
-void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
-	debugC(1, kDebugGraphics, "drawRect %d %d %d %d", minX, minY, maxX, maxY);
+void EfhEngine::drawRect(int16 minX, int16 minY, int16 maxX, int16 maxY) {
+	debugC(1, kDebugGraphics, "drawRect %d-%d %d-%d", minX, minY, maxX, maxY);
 
 	if (minY > maxY)
 		SWAP(minY, maxY);
@@ -147,10 +147,10 @@ void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
 	if (minX > maxX)
 		SWAP(minX, maxX);
 
-	minX = CLIP(minX, 0, 319);
-	maxX = CLIP(maxX, 0, 319);
-	minY = CLIP(minY, 0, 199);
-	maxY = CLIP(maxY, 0, 199);
+	minX = CLIP<int16>(minX, 0, 319);
+	maxX = CLIP<int16>(maxX, 0, 319);
+	minY = CLIP<int16>(minY, 0, 199);
+	maxY = CLIP<int16>(maxY, 0, 199);
 
 	int deltaY = 1 + maxY - minY;
 	int deltaX = 1 + maxX - minX;
@@ -169,8 +169,8 @@ void EfhEngine::drawRect(int minX, int minY, int maxX, int maxY) {
 	}
 }
 
-void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int color) {
-	debugC(1, kDebugGraphics, "drawColoredRect %d %d %d %d %d", minX, minY, maxX, maxY, color);
+void EfhEngine::drawColoredRect(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color) {
+	debugC(1, kDebugGraphics, "drawColoredRect %d-%d %d-%d %d", minX, minY, maxX, maxY, color);
 
 	uint8 oldValue = _defaultBoxColor;
 	_defaultBoxColor = color;
@@ -178,7 +178,7 @@ void EfhEngine::drawColoredRect(int minX, int minY, int maxX, int maxY, int colo
 	_defaultBoxColor = oldValue;
 }
 
-void EfhEngine::clearScreen(int color) {
+void EfhEngine::clearScreen(int16 color) {
 	debugC(1, kDebugGraphics, "clearScreen %d", color);
 	drawColoredRect(0, 0, 320, 200, color);
 }
@@ -242,7 +242,7 @@ void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, i
 	drawString(str, startCenteredDisplayX, posY, _textColor);
 }
 
-void EfhEngine::displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int posY) {
+void EfhEngine::displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int16 posY) {
 	debugC(1, kDebugGraphics, "displayMenuAnswerString %s %d-%d %d", str, minX, maxX, posY);
 	displayCenteredString(str, minX, maxX, posY);
 	displayFctFullScreen();
@@ -285,7 +285,7 @@ void EfhEngine::drawBottomBorders() {
 	displayRawDataAtPos(_circleImageSubFileArray[6], 304, 136);
 }
 
-void EfhEngine::drawChar(uint8 curChar, int16 posX, int posY) {
+void EfhEngine::drawChar(uint8 curChar, int16 posX, int16 posY) {
 	debugC(1, kDebugGraphics, "drawChar %c %d %d", curChar, posX, posY);
 
 	// CHECKME: Quick hacked display, may require rework
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index 54941c938a5..5f6393a4b99 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -85,7 +85,7 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 	dump.close();
 }
 
-void EfhEngine::loadImageSet(int imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
+void EfhEngine::loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
 	debugC(1, kDebugUtils, "loadImageSet %d", imageSetId);
 	Common::String fileName = Common::String::format("imageset.%d", imageSetId);
 	rImageFile(fileName, buffer, subFilesArray, destBuffer);


Commit: 902e1f06f2a8939f88fbe215045ee6d25c19b3da
    https://github.com/scummvm/scummvm/commit/902e1f06f2a8939f88fbe215045ee6d25c19b3da
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix an issue in displayAnimFrame, small refactoring, add some debug traces

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ad27c79c160..8bbf3431a0a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -70,7 +70,7 @@ void UnkMapStruct::init() {
 }
 
 void UnkAnimStruct::init() {
-	field0 = field1 = field2 = field3 = 0;
+	memset(_field, 0, 4);
 }
 
 void AnimInfo::init() {
@@ -206,7 +206,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	_word31E9E = false;
 	_oldAnimImageSetId = -1;
-	_animImageSetId = 254;
+	_animImageSetId = 0xFE;
 	_paletteTransformationConstant = 10;
 
 	for (int i = 0; i < 12; ++i)
@@ -585,29 +585,39 @@ void EfhEngine::initialize() {
 }
 
 void EfhEngine::readAnimInfo() {
-	debug("readAnimInfo");
+	debugC(6, kDebugEngine, "readAnimInfo");
 	
 	Common::String fileName = "animinfo";
 	uint8 animInfoBuf[9000];
 	memset(animInfoBuf, 0, 9000);
 	uint8 *curPtr = animInfoBuf;
-	
+
 	readFileToBuffer(fileName, animInfoBuf);
 	for (int i = 0; i < 100; ++i) {
 		for (int id = 0; id < 15; ++id) {
-			_animInfo[i]._unkAnimArray[id].field0 = *curPtr++;
-			_animInfo[i]._unkAnimArray[id].field1 = *curPtr++;
-			_animInfo[i]._unkAnimArray[id].field2 = *curPtr++;
-			_animInfo[i]._unkAnimArray[id].field3 = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[0] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[1] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[2] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[3] = *curPtr++;
+
+			debugC(6, kDebugEngine, "%d %d %d %d", _animInfo[i]._unkAnimArray[id]._field[0], _animInfo[i]._unkAnimArray[id]._field[1], _animInfo[i]._unkAnimArray[id]._field[2], _animInfo[i]._unkAnimArray[id]._field[3]);
 		}
 
-		for (int id = 0; id < 10; ++id)
+		Common::String debugStr = "";
+		for (int id = 0; id < 10; ++id) {
 			_animInfo[i]._field3C_startY[id] = *curPtr++;
+			debugStr += Common::String::format("%d ", _animInfo[i]._field3C_startY[id]);
+		}
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
 
+		debugStr = "";
 		for (int id = 0; id < 10; ++id) {
 			_animInfo[i]._field46_startX[id] = READ_LE_INT16(curPtr);
 			curPtr += 2;
+			debugStr += Common::String::format("%d ", _animInfo[i]._field46_startX[id]);
 		}
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
+		debugC(6, kDebugEngine, "---------");
 	}
 }
 
@@ -1069,10 +1079,10 @@ void EfhEngine::loadMapArrays() {
 }
 
 void EfhEngine::saveAnimImageSetId() {
-	debug("saveAnimImageSetId");
+	debugC(6, kDebugEngine, "saveAnimImageSetId");
 
 	_oldAnimImageSetId = _animImageSetId;
-	_animImageSetId = 255;
+	_animImageSetId = 0xFF;
 }
 
 int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
@@ -6765,7 +6775,7 @@ bool EfhEngine::sub16E14() {
 }
 
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
-	debug("loadImageSetToTileBank %d %d", tileBankId, imageSetId);
+	debugC(3, kDebugEngine, "loadImageSetToTileBank %d %d", tileBankId, imageSetId);
 
 	// TODO: all the values of titleBankId and imageSetId are hardcoded. When all the calls are implemented, fix the values to avoid to have to decrease them
 	int16 bankId = tileBankId - 1;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4374f04d223..cdeddbc228a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -98,10 +98,7 @@ struct UnkMapStruct {
 };
 
 struct UnkAnimStruct {
-	uint8 field0;
-	uint8 field1;
-	uint8 field2;
-	uint8 field3;
+	int8 _field[4];
 
 	void init();
 };
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 2bb1a426fe2..9566d95ffb8 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -71,8 +71,8 @@ void EfhEngine::displayAnimFrame() {
 
 	displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
 	for (int i = 0; i < 4; ++i) {
-		int16 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex].field0;
-		if (var2 == 0xFF)
+		int8 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex]._field[i];
+		if (var2 == -1)
 			continue;
 		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
 	}


Commit: 11c5a8989117d6e4774c263324903c635e742cbe
    https://github.com/scummvm/scummvm/commit/11c5a8989117d6e4774c263324903c635e742cbe
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix delay, fix a kind of collision

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8bbf3431a0a..c867b6760ec 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -401,7 +401,7 @@ Common::Error EfhEngine::run() {
 		_system->delayMillis(20);
 		uint32 newMs = _system->getMillis();
 
-		if (newMs - lastMs >= 200) {
+		if (newMs - lastMs >= 220) {
 			lastMs = newMs;
 			unkFct_anim();
 		}
@@ -527,7 +527,7 @@ Common::Error EfhEngine::run() {
 
 		if ((_mapPosX != _oldMapPosX || _mapPosY != _oldMapPosY) && !_shouldQuit) {
 			int16 var4 = sub16E14();
-			if (!_word2C8D5 || var4 != 0) {
+			if (_word2C8D5 != 0 || var4 != 0) {
 				_oldMapPosX = _mapPosX;
 				_oldMapPosY = _mapPosY;
 				_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;


Commit: f9471c12ed0e1c4851cffd543454540488ff431f
    https://github.com/scummvm/scummvm/commit/f9471c12ed0e1c4851cffd543454540488ff431f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c867b6760ec..a8885219aef 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -298,7 +298,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_word2C87A = false;
 	_unk_sub26437_flag = 0;
 	_word2C8D9 = false;
-	_word2C8D5 = false;
+	_dbgForceMonsterBlock = false;
 	_word2D0BC = false;
 	_word2C8D2 = false;
 	_menuDepth = 0;
@@ -526,8 +526,8 @@ Common::Error EfhEngine::run() {
 		}
 
 		if ((_mapPosX != _oldMapPosX || _mapPosY != _oldMapPosY) && !_shouldQuit) {
-			int16 var4 = sub16E14();
-			if (_word2C8D5 != 0 || var4 != 0) {
+			bool collisionFl = checkMonsterCollision();
+			if (_dbgForceMonsterBlock || collisionFl) {
 				_oldMapPosX = _mapPosX;
 				_oldMapPosY = _mapPosY;
 				_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
@@ -3365,7 +3365,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 		_word2C880 = false;
 		return -1;
 	}
-	if (_tileFact[imageSetId]._field1 != 0xFF && !_word2C8D5) {
+	if (_tileFact[imageSetId]._field1 != 0xFF && !_dbgForceMonsterBlock) {
 		if ((arg4 == 1 && _word2C8D7) || (arg4 == 0 && _word2C8D7 && imageSetId != 128 && imageSetId != 121)) {
 			if (_largeMapFlag) {
 				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
@@ -6655,8 +6655,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	return 0;
 }
 
-bool EfhEngine::sub16E14() {
-	debug("sub16E14");
+bool EfhEngine::checkMonsterCollision() {
+	debug("checkMonsterCollision");
 
 	int16 var68 = 0;
 	char dest[20];
@@ -6760,7 +6760,7 @@ bool EfhEngine::sub16E14() {
 				var68 = true;
 				break;
 			default:
-//				warning("STUB: sub16E14 - Missing mapping ?");
+//				warning("STUB: checkMonsterCollision - Missing mapping ?");
 				break;
 			}
 		} while (!var68);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index cdeddbc228a..3bfbf0e7a7d 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -423,7 +423,7 @@ private:
 	int16 selectOtherCharFromTeam();
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
-	bool sub16E14();
+	bool checkMonsterCollision();
 
 	// Graphics
 	void initPalette();
@@ -571,7 +571,7 @@ private:
 	uint16 _word2C86E;
 	uint8 *_dword2C856;
 	bool _word2C8D9;
-	bool _word2C8D5; // CHECKME: always 0?
+	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 	bool _word2D0BC;
 	bool _word2C8D2;
 	int16 _menuDepth;


Commit: 2435653bc8d7afbde49d2a93efa5a933417db55b
    https://github.com/scummvm/scummvm/commit/2435653bc8d7afbde49d2a93efa5a933417db55b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Some renaming, improve some comments

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a8885219aef..56534ef0d79 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -288,8 +288,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_textPosY = 0;
 
 	_lastMainPlaceId = 0;
-	_word2C86E = 0;
-	_dword2C856 = nullptr;
+	_tempTextDelay = 0;
+	_tempTextPtr = nullptr;
 	_word2C880 = false;
 	_redrawNeededFl = false;
 	_word2C8D7 = true;
@@ -453,7 +453,7 @@ Common::Error EfhEngine::run() {
 		case Common::KEYCODE_F1:
 			if (_teamCharId[0] != -1) {
 				handleStatusMenu(1, _teamCharId[0]);
-				_dword2C856 = nullptr;
+				_tempTextPtr = nullptr;
 				sub15150(true);
 				_redrawNeededFl = true;
 			}
@@ -461,7 +461,7 @@ Common::Error EfhEngine::run() {
 		case Common::KEYCODE_F2:
 			if (_teamCharId[1] != -1) {
 				handleStatusMenu(1, _teamCharId[1]);
-				_dword2C856 = nullptr;
+				_tempTextPtr = nullptr;
 				sub15150(true);
 				_redrawNeededFl = true;
 			}
@@ -469,7 +469,7 @@ Common::Error EfhEngine::run() {
 		case Common::KEYCODE_F3:
 			if (_teamCharId[2] != -1) {
 				handleStatusMenu(1, _teamCharId[2]);
-				_dword2C856 = nullptr;
+				_tempTextPtr = nullptr;
 				sub15150(true);
 				_redrawNeededFl = true;
 			}
@@ -558,9 +558,9 @@ Common::Error EfhEngine::run() {
 		if (!_shouldQuit) {
 			handleNewRoundEffects();
 
-			if (_word2C86E > 0) {
-				if (--_word2C86E == 0) {
-					sub221FA(nullptr, true);
+			if (_tempTextDelay > 0) {
+				if (--_tempTextDelay == 0) {
+					displayMiddleLeftTempText(nullptr, true);
 				}
 			}
 		}
@@ -871,10 +871,10 @@ void EfhEngine::playIntro() {
 
 	// With GF on the bed
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[0], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[0], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[0], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -882,11 +882,11 @@ void EfhEngine::playIntro() {
 	// Poof
 	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[1], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[1], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[1], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[1], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -894,38 +894,38 @@ void EfhEngine::playIntro() {
 	// On the phone
 	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[2], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[2], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[2], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[2], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[3], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[3], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[3], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[4], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[4], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[4], 6, 150, 268, 186, false);
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
-	sub133E5(_imp2PtrArray[5], 6, 150, 268, 186, false);
+	drawText(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	getLastCharAfterAnimCount(80);
 }
 
@@ -1147,12 +1147,12 @@ void EfhEngine::sub15150(bool flag) {
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			displayGameScreen();
-			// TODO: _word2C86E is some kind of counter
-			if (_word2C86E != 0) {
-				// TODO: _dword2C856 is most likely an "Imp" Array
+			// Redraw temp text if one is displayed currently
+			// _tempTextDelay determines whether a temp text is displayed in the middle-left zone
+			if (_tempTextDelay != 0) {
 				// Note: the original was doing the check in the opposite order, which looks really suspicious
-				if ((_dword2C856 != nullptr) && (_dword2C856[0] != 0x30)) {
-					sub221FA(_dword2C856, false);
+				if ((_tempTextPtr != nullptr) && (_tempTextPtr[0] != 0x30)) {
+					displayMiddleLeftTempText(_tempTextPtr, false);
 				}
 			}
 		}
@@ -2050,8 +2050,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 	return var_F0;
 }
 
-void EfhEngine::sub133E5(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("sub133E5 %d-%d %d-%d %d", posX, posY, maxX, maxY, flag ? "True" : "False");
+void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
+	debug("drawText %d-%d %d-%d %d", posX, posY, maxX, maxY, flag ? "True" : "False");
 
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;
@@ -2077,16 +2077,17 @@ void EfhEngine::sub133E5(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 	script_parse(_messageToBePrinted, posX, posY, maxX, maxY, flag);
 }
 
-void EfhEngine::sub221FA(uint8 *impArray, bool flag) {
-	debug("sub221FA %s %s", (char *)impArray, flag ? "True" : "False");
+void EfhEngine::displayMiddleLeftTempText(uint8 *impArray, bool flag) {
+	debugC(3, kDebugEngine, "displayMiddleLeftTempText %s %s", (char *)impArray, flag ? "True" : "False");
 	
 	for (uint8 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
+			// clear middle-left text area
 			drawColoredRect(16, 115, 111, 133, 0);
 			if (impArray != nullptr) {
-				_word2C86E = 4;
-				_dword2C856 = impArray;
-				sub133E5(impArray, 17, 115, 110, 133, false);
+				_tempTextDelay = 4;
+				_tempTextPtr = impArray;
+				drawText(impArray, 17, 115, 110, 133, false);
 			}
 			if (counter == 0 && flag)
 				displayFctFullScreen();
@@ -3158,7 +3159,7 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	debug("sub221D2 %d", monsterId);
 
 	if (monsterId != -1) {
-		_dword2C856 = nullptr;
+		_tempTextPtr = nullptr;
 		sub21820(monsterId, 5, -1);
 	}
 }
@@ -3170,9 +3171,9 @@ void EfhEngine::sub22AA8(int16 arg0) {
 	var8 = varA = varC = varE = 0;
 
 	if (arg0 <= 0xFE) {
-		if (_dword2C856) {
-			_dword2C856 = nullptr;
-			sub221FA(_dword2C856, true);
+		if (_tempTextPtr) {
+			_tempTextPtr = nullptr;
+			displayMiddleLeftTempText(_tempTextPtr, true);
 		}
 		if (_word2C8D2)
 			sub15150(true);
@@ -3275,7 +3276,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 
 	if (var8 == -1) {
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
-			sub221FA(_imp2PtrArray[imageSetId], true);
+			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (var8 == 0) {
 		if (_mapUnknown[var8]._field3 == 0xFF) {
 			sub22AA8(_mapUnknown[var8]._field5); // word!
@@ -6752,7 +6753,7 @@ bool EfhEngine::checkMonsterCollision() {
 			case Common::KEYCODE_s: // Status
 				var6A = handleStatusMenu(1, _teamCharId[0]);
 				var68 = true;
-				_dword2C856 = nullptr;
+				_tempTextPtr = nullptr;
 				sub15150(true);
 				break;
 			case Common::KEYCODE_t: // Talk
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 3bfbf0e7a7d..3662a7ceabd 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -325,8 +325,8 @@ private:
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
-	void sub133E5(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
-	void sub221FA(uint8 *impArray, bool flag);
+	void drawText(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
+	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl);
@@ -568,8 +568,8 @@ private:
 	int16 _techDataId_MapPosX, _techDataId_MapPosY;
 	uint16 _lastMainPlaceId;
 
-	uint16 _word2C86E;
-	uint8 *_dword2C856;
+	uint16 _tempTextDelay;
+	uint8 *_tempTextPtr;
 	bool _word2C8D9;
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 	bool _word2D0BC;


Commit: 6796634043eeb44dfdcfc5ca7217e641866c415b
    https://github.com/scummvm/scummvm/commit/6796634043eeb44dfdcfc5ca7217e641866c415b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: more renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 56534ef0d79..0c9b92d57b0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -297,10 +297,10 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_drawMonstersOnMapFl = true;
 	_word2C87A = false;
 	_unk_sub26437_flag = 0;
-	_word2C8D9 = false;
+	_dbgForceDisplayUpperRightBorder = false;
 	_dbgForceMonsterBlock = false;
 	_word2D0BC = false;
-	_word2C8D2 = false;
+	_statusMenuActive = false;
 	_menuDepth = 0;
 	_word2D0BA = 0;
 
@@ -389,8 +389,8 @@ Common::Error EfhEngine::run() {
 */
 
 	initEngine();
-	sub15150(true);
-	redrawScreen();
+	drawGameScreenAndTempText(true);
+	drawScreen();
 	displayLowStatusScreen(true);
 
 	if (!_protectionPassed)
@@ -454,7 +454,7 @@ Common::Error EfhEngine::run() {
 			if (_teamCharId[0] != -1) {
 				handleStatusMenu(1, _teamCharId[0]);
 				_tempTextPtr = nullptr;
-				sub15150(true);
+				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
 			}
 			break;
@@ -462,7 +462,7 @@ Common::Error EfhEngine::run() {
 			if (_teamCharId[1] != -1) {
 				handleStatusMenu(1, _teamCharId[1]);
 				_tempTextPtr = nullptr;
-				sub15150(true);
+				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
 			}
 			break;
@@ -470,7 +470,7 @@ Common::Error EfhEngine::run() {
 			if (_teamCharId[2] != -1) {
 				handleStatusMenu(1, _teamCharId[2]);
 				_tempTextPtr = nullptr;
-				sub15150(true);
+				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
 			}
 			break;
@@ -551,7 +551,7 @@ Common::Error EfhEngine::run() {
 		}
 
 		if (_redrawNeededFl && !_shouldQuit) {
-			redrawScreen();
+			drawScreen();
 			displayLowStatusScreen(true);
 		}
 
@@ -1135,14 +1135,16 @@ uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
 	return 0x7FFF;
 }
 
-void EfhEngine::sub15150(bool flag) {
-	debug("sub15150 %s", flag ? "True" : "False");
+void EfhEngine::drawGameScreenAndTempText(bool flag) {
+	debugC(2, kDebugEngine, "drawGameScreenAndTempText %s", flag ? "True" : "False");
 
+	#if 0
+	// This code is present in the original, but looks strictly useless.
 	uint8 mapTileInfo = getMapTileInfo(_mapPosX, _mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[mapTileInfo / 72];
 
 	int16 mapImageSetId = (imageSetId * 72) + (mapTileInfo % 72);
-	// CHECKME : Why do we compute this Id if we don't use it?
+	#endif
 	
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -1267,8 +1269,8 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 	drawMap(true, posX, posY, 63, _drawHeroOnMapFl, _drawMonstersOnMapFl);
 }
 
-void EfhEngine::redrawScreen() {
-	debug("redrawScreen");
+void EfhEngine::drawScreen() {
+	debug("drawScreen");
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
 		_redrawNeededFl = false;
@@ -1276,13 +1278,13 @@ void EfhEngine::redrawScreen() {
 			if (_fullPlaceId != 0xFF)
 				displaySmallMap(_mapPosX, _mapPosY);
 
-			if (_word2C8D9)
+			if (_dbgForceDisplayUpperRightBorder)
 				drawUpperRightBorders();
 		} else {
 			if (_techId != 0xFF)
 				displayLargeMap(_mapPosX, _mapPosY);
 			
-			if (_word2C8D9)
+			if (_dbgForceDisplayUpperRightBorder)
 				drawUpperRightBorders();
 		}
 		if (counter == 0)
@@ -2113,7 +2115,7 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 			int16 var2 = var8 + varC;
 			_mapGameMap[var4][var2] = _curPlace[counter][var8];
 		}
-		redrawScreen();
+		drawScreen();
 	}
 
 	for (int16 counter = 1; counter <= 23; counter += 2) {
@@ -2122,7 +2124,7 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 			int16 var2 = var8 + varC;
 			_mapGameMap[var4][var2] = _curPlace[counter][var8];
 		}
-		redrawScreen();
+		drawScreen();
 	}
 
 	getLastCharAfterAnimCount(3);
@@ -2415,7 +2417,7 @@ bool EfhEngine::handleDeathMenu() {
 
 	displayAnimFrames(20, true);
 	_imageSetSubFilesIdx = 213;
-	redrawScreen();
+	drawScreen();
 
 	for (int16 counter = 0; counter < 2; ++counter) {
 		clearBottomTextZone(0);
@@ -3175,8 +3177,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 			_tempTextPtr = nullptr;
 			displayMiddleLeftTempText(_tempTextPtr, true);
 		}
-		if (_word2C8D2)
-			sub15150(true);
+		if (_statusMenuActive)
+			drawGameScreenAndTempText(true);
 
 		int16 var4 = arg0;
 
@@ -3513,7 +3515,7 @@ void EfhEngine::redrawScreenForced() {
 	debug("redrawScreenForced");
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
-		redrawScreen();
+		drawScreen();
 		if (counter == 0)
 			displayFctFullScreen();
 	}
@@ -3608,7 +3610,7 @@ void EfhEngine::sub1CAB6(int16 charId) {
 	debug("sub1CAB6 %d", charId);
 
 	for (int16 counter = 0; counter < 2; ++counter) {
-		sub15150(false);
+		drawGameScreenAndTempText(false);
 		displayLowStatusScreen(false);
 		drawCombatScreen(charId, false, false);
 		if (counter == 0)
@@ -6305,7 +6307,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 	saveAnimImageSetId();
 
-	_word2C8D2 = true;
+	_statusMenuActive = true;
 	_menuDepth = 0;
 
 	sub18E80(charId, windowId, menuId, curMenuLine);
@@ -6467,7 +6469,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
 			if (gameMode == 2) {
 				restoreAnimImageSetId();
-				_word2C8D2 = false;
+				_statusMenuActive = false;
 				return 0x7D00;
 			}
 			break;
@@ -6476,11 +6478,11 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (gameMode == 2) {
 				restoreAnimImageSetId();
-				_word2C8D2 = false;
+				_statusMenuActive = false;
 				return objectId;
 			} else {
 				if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
-					_word2C8D2 = false;
+					_statusMenuActive = false;
 					return -1;
 				} else {
 					sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
@@ -6505,7 +6507,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						removeObject(charId, objectId);
 						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
 						if (var8 != 0) {
-							_word2C8D2 = false;
+							_statusMenuActive = false;
 							return -1;
 						}
 					}
@@ -6562,7 +6564,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						removeObject(charId, objectId);
 						if (gameMode == 2) {
 							restoreAnimImageSetId();
-							_word2C8D2 = false;
+							_statusMenuActive = false;
 							return 0x7D00;
 						}
 					}
@@ -6586,13 +6588,13 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					removeObject(charId, objectId);
 					if (gameMode == 2) {
 						restoreAnimImageSetId();
-						_word2C8D2 = false;
+						_statusMenuActive = false;
 						return 0x7D00;
 					}
 
 					bool var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1);
 					if (var8) {
-						_word2C8D2 = false;
+						_statusMenuActive = false;
 						return -1;
 					}
 				}
@@ -6605,7 +6607,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
-					_word2C8D2 = false;
+					_statusMenuActive = false;
 					return -1;
 				}
 			}
@@ -6617,7 +6619,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
-					_word2C8D2 = false;
+					_statusMenuActive = false;
 					return -1;
 				}
 			}
@@ -6629,7 +6631,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			} else {
 				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
 				if (var8) {
-					_word2C8D2 = false;
+					_statusMenuActive = false;
 					return -1;
 				}
 			}
@@ -6648,7 +6650,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 		if (menuId == 8) {
 			restoreAnimImageSetId();
-			_word2C8D2 = false;
+			_statusMenuActive = false;
 			return 0x7FFF;
 		}
 	}
@@ -6754,7 +6756,7 @@ bool EfhEngine::checkMonsterCollision() {
 				var6A = handleStatusMenu(1, _teamCharId[0]);
 				var68 = true;
 				_tempTextPtr = nullptr;
-				sub15150(true);
+				drawGameScreenAndTempText(true);
 				break;
 			case Common::KEYCODE_t: // Talk
 				sub221D2(monsterId);
@@ -6804,7 +6806,7 @@ void EfhEngine::checkProtection() {
 	//CHECKME : Well, yeah, some code may be missing there. Who knows.
 	
 	_protectionPassed = true;
-	sub15150(true);	
+	drawGameScreenAndTempText(true);	
 }
 
 void EfhEngine::loadEfhGame() {
@@ -6867,7 +6869,7 @@ void EfhEngine::saveEfhGame() {
 }
 
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
-	debug("getMapTileInfo %d-%d", mapPosX, mapPosY);
+	debugC(3, kDebugEngine, "getMapTileInfo %d-%d", mapPosX, mapPosY);
 
 	if (_largeMapFlag)
 		return _mapGameMap[mapPosX][mapPosY];
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 3662a7ceabd..5aaa306973b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -307,11 +307,11 @@ private:
 	void writeTechAndMapFiles();
 	uint16 getStringWidth(const char *buffer);
 	void setTextPos(int16 textPosX, int16 textPosY);
-	void sub15150(bool flag);
+	void drawGameScreenAndTempText(bool flag);
 	void drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl);
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
-	void redrawScreen();
+	void drawScreen();
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
 	void removeObject(int16 charId, int16 objectId);
@@ -554,7 +554,6 @@ private:
 	int16 _word2C872;
 	bool _word2C880;
 	bool _redrawNeededFl;
-	bool _word2C8D7;
 	bool _drawHeroOnMapFl;
 	bool _drawMonstersOnMapFl;
 	bool _word2C87A;
@@ -570,10 +569,11 @@ private:
 
 	uint16 _tempTextDelay;
 	uint8 *_tempTextPtr;
-	bool _word2C8D9;
+	bool _dbgForceDisplayUpperRightBorder; // Original debug flag? Always false.
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
+	bool _word2C8D7; // Original debug flag? Always true.
 	bool _word2D0BC;
-	bool _word2C8D2;
+	bool _statusMenuActive;
 	int16 _menuDepth;
 	int16 _word2D0BA;
 	int16 _word32680[3];


Commit: a651ff0b9dd3f4055e09b33a94d8fce9b72d37c7
    https://github.com/scummvm/scummvm/commit/a651ff0b9dd3f4055e09b33a94d8fce9b72d37c7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix missing initialization in handleFight

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0c9b92d57b0..aef7cd918ca 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -4961,6 +4961,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	debug("handleFight %d", monsterId);
 
 	int16 var8C = 0;
+	_word2D0BC = true;
 
 	sub1BE89(monsterId);
 


Commit: cadc61de7acf5294bc8b1e92f0d5be7d4e251f66
    https://github.com/scummvm/scummvm/commit/cadc61de7acf5294bc8b1e92f0d5be7d4e251f66
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix debug string for drawText

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index aef7cd918ca..9ea4e27cc43 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2053,7 +2053,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 }
 
 void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("drawText %d-%d %d-%d %d", posX, posY, maxX, maxY, flag ? "True" : "False");
+	debug("drawText %d-%d %d-%d %s", posX, posY, maxX, maxY, flag ? "True" : "False");
 
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;


Commit: c253ae5a54d8ec97d4ea42ab37175035db39ba7b
    https://github.com/scummvm/scummvm/commit/c253ae5a54d8ec97d4ea42ab37175035db39ba7b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix getStringWidth (fix 2nd text page in the intro)

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9ea4e27cc43..2d2d5b6035c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -6909,6 +6909,9 @@ uint16 EfhEngine::getStringWidth(const char *buffer) {
 		retVal += _fontDescr._widthArray[curChar - 0x20] + 1;
 	}
 
+	if (retVal)
+		retVal--;
+	
 	return retVal;
 }
 


Commit: 8f5128f1a3019ce24b96ce6390a42b413938f4c8
    https://github.com/scummvm/scummvm/commit/8f5128f1a3019ce24b96ce6390a42b413938f4c8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Some renaming in script_parse

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2d2d5b6035c..833d2bad133 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1621,24 +1621,23 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 	int16 var_F2 = -1;
 	int16 var_F0 = 0xFF;
 	int16 var_EE = 0xFF;
-	const char *stringToDisplay = " ";
-	uint16 curLine = 0;
+	uint16 curLineNb = 0;
 	int16 numbLines = (1 + maxY - posY) / 9;
 	int16 width = maxX - posX;
-	int16 var_114 = getStringWidth(stringToDisplay);
+	int16 spaceWidth = getStringWidth(" ");
 	uint8 *buffer = stringBuffer;
-	char var_EC[80];
-	char dest[150];
-	memset(var_EC, 0, sizeof(var_EC));
-	memset(dest, 0, sizeof(dest));
-	int16 var_116 = 0;
-	setTextPos(posX, curLine * 9 + posY);
+	char nextWord[80];
+	char curLine[150];
+	memset(nextWord, 0, sizeof(nextWord));
+	memset(curLine, 0, sizeof(curLine));
+	int16 curWordPos = 0;
+	setTextPos(posX, curLineNb * 9 + posY);
 
 	while (!doneFlag) {
 		uint8 curChar = *buffer;
 		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
 			var_F2 = 0;
-			var_EC[var_116++] = curChar;
+			nextWord[curWordPos++] = curChar;
 			++buffer;
 			continue;
 		}
@@ -1649,28 +1648,28 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			else if (curChar == 0x7C)
 				var_F2 = 0;
 
-			var_EC[var_116] = 0;
-			int16 var_11A = getStringWidth(var_EC);
-			int16 var_118 = var_114 + getStringWidth(dest);
+			nextWord[curWordPos] = 0;
+			int16 widthNextWord = getStringWidth(nextWord);
+			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine);
 
-			if (var_118 + var_11A > width || curChar == 0x7C) {
-				if (curLine >= numbLines) {
+			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) {
+				if (curLineNb >= numbLines) {
 					doneFlag = true;
 				} else {
 					if (var_F2 == 0)
-						displayStringAtTextPos(dest);
-
-					*dest = 0;
-					strcpy(dest, var_EC);
-					strcat(dest, " ");
-					++curLine;
-					setTextPos(posX, posY + curLine * 9);
-					var_116 = 0;
+						displayStringAtTextPos(curLine);
+
+					*curLine = 0;
+					strcpy(curLine, nextWord);
+					strcat(curLine, " ");
+					++curLineNb;
+					setTextPos(posX, posY + curLineNb * 9);
+					curWordPos = 0;
 				}
 			} else {
-				strcat(dest, var_EC);
-				strcat(dest, " ");
-				var_116 = 0;
+				strcat(curLine, nextWord);
+				strcat(curLine, " ");
+				curWordPos = 0;
 			}
 			++buffer;
 			continue;
@@ -1955,11 +1954,11 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 				} else {
 					copyString(_npcBuf[_teamCharId[counter]]._name, _enemyNamePt2);
 					copyString(_items[var110]._name, _nameBuffer);
-					sprintf(dest, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
+					sprintf(curLine, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219((uint8 *)dest, 1, 2, true);
+					var110 = sub1C219((uint8 *)curLine, 1, 2, true);
 					displayFctFullScreen();
 				}
 
@@ -2037,8 +2036,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 		}
 	}
 
-	if (*dest != 0 && curLine < numbLines && var_F2 == 0)
-		displayStringAtTextPos(dest);
+	if (*curLine != 0 && curLineNb < numbLines && var_F2 == 0)
+		displayStringAtTextPos(curLine);
 
 	if (var_EE != 0xFF) {
 		displayLowStatusScreen(true);
@@ -2441,8 +2440,7 @@ bool EfhEngine::handleDeathMenu() {
 			displayFctFullScreen();
 	}
 
-	bool found;
-	for (found = false; !found;) {
+	for (bool found = false; !found;) {
 		Common::KeyCode input = waitForKey();
 		switch (input) {
 		case Common::KEYCODE_l:
@@ -6892,7 +6890,7 @@ void EfhEngine::writeTechAndMapFiles() {
 }
 
 uint16 EfhEngine::getStringWidth(const char *buffer) {
-	debug("getStringWidth %s", buffer);
+	debugC(6, kDebugEngine, "getStringWidth %s", buffer);
 
 	uint16 retVal = 0;
 


Commit: 70147a0310ce49d37ac1c351128697dcc55e3e1e
    https://github.com/scummvm/scummvm/commit/70147a0310ce49d37ac1c351128697dcc55e3e1e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix display of the last part of the intro

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 833d2bad133..166c315a56b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -856,7 +856,7 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 }
 
 void EfhEngine::playIntro() {
-	debug("playIntro");
+	debugC(6, "playIntro");
 	
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
@@ -921,9 +921,11 @@ void EfhEngine::playIntro() {
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
 
+	displayRawDataAtPos(_circleImageSubFileArray[3], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	drawText(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	displayFctFullScreen();
+	displayRawDataAtPos(_circleImageSubFileArray[3], 110, 16);
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	drawText(_imp2PtrArray[5], 6, 150, 268, 186, false);
 	getLastCharAfterAnimCount(80);
@@ -2524,13 +2526,13 @@ void EfhEngine::computeMapAnimation() {
 }
 
 void EfhEngine::unkFct_anim() {
-	debug("unkFct_anim");
-
 	setNumLock();
 
 	if (_engineInitPending)
 		return;
 
+	debug("unkFct_anim");
+
 	if (_animImageSetId != 0xFF) {
 		displayNextAnimFrame();
 		displayFctFullScreen();


Commit: cbe49b22ce3dd9bf241f843c9a65e567cd48adb2
    https://github.com/scummvm/scummvm/commit/cbe49b22ce3dd9bf241f843c9a65e567cd48adb2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix getInputBlocking

Changed paths:
    engines/efh/utils.cpp


diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index 5f6393a4b99..b97acb13ad1 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -289,6 +289,8 @@ Common::KeyCode EfhEngine::getInputBlocking() {
 
 	uint32 lastMs = _system->getMillis();
 	while (retVal == Common::KEYCODE_INVALID) {
+		_system->getEventManager()->pollEvent(event);
+
 		if (event.type == Common::EVENT_KEYUP) {
 			retVal = event.kbd.keycode;
 		}


Commit: c66d0eee230983e6bf4481de569a13a937e602a2
    https://github.com/scummvm/scummvm/commit/c66d0eee230983e6bf4481de569a13a937e602a2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:37+01:00

Commit Message:
EFH: Fix opening dialog when using phone booth

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 166c315a56b..71bd83813cc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -65,7 +65,7 @@ void InvObject::init() {
 }
 
 void UnkMapStruct::init() {
-	_field0 = _field1 = _field2 = _field3 = _field4 = 0;
+	_placeId = _posX = _posY = _field3 = _field4 = 0;
 	_field5 = _field7 = 0;
 }
 
@@ -299,7 +299,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_unk_sub26437_flag = 0;
 	_dbgForceDisplayUpperRightBorder = false;
 	_dbgForceMonsterBlock = false;
-	_word2D0BC = false;
+	_ongoingFightFl = false;
 	_statusMenuActive = false;
 	_menuDepth = 0;
 	_word2D0BA = 0;
@@ -761,7 +761,7 @@ void EfhEngine::readItems() {
 		_items[i].field_19 = *curPtr++;
 		_items[i].field_1A = *curPtr++;
 
-		warning("%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
+//		warning("%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
 	}
 }
 
@@ -856,7 +856,7 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 }
 
 void EfhEngine::playIntro() {
-	debugC(6, "playIntro");
+	debugC(6, kDebugEngine, "playIntro");
 	
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
@@ -1046,9 +1046,9 @@ void EfhEngine::loadMapArrays() {
 	uint8 *_mapUnknownPtr = &_map[2];
 
 	for (int i = 0; i < 100; ++i) {
-		_mapUnknown[i]._field0 = _mapUnknownPtr[9 * i];
-		_mapUnknown[i]._field1 = _mapUnknownPtr[9 * i + 1];
-		_mapUnknown[i]._field2 = _mapUnknownPtr[9 * i + 2];
+		_mapUnknown[i]._placeId = _mapUnknownPtr[9 * i];
+		_mapUnknown[i]._posX = _mapUnknownPtr[9 * i + 1];
+		_mapUnknown[i]._posY = _mapUnknownPtr[9 * i + 2];
 		_mapUnknown[i]._field3 = _mapUnknownPtr[9 * i + 3];
 		_mapUnknown[i]._field4 = _mapUnknownPtr[9 * i + 4];
 		_mapUnknown[i]._field5 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
@@ -1167,7 +1167,7 @@ void EfhEngine::drawGameScreenAndTempText(bool flag) {
 }
 
 void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl) {
-	debug("drawMap %s %d-%d %d %s %s", largeMapFl ? "True" : "False", mapPosX, mapPosY, mapSize, drawHeroFl ? "True" : "False", drawMonstersFl ? "True" : "False");
+	debugC(6, kDebugEngine, "drawMap %s %d-%d %d %s %s", largeMapFl ? "True" : "False", mapPosX, mapPosY, mapSize, drawHeroFl ? "True" : "False", drawMonstersFl ? "True" : "False");
 	
 	int16 unkPosX = 5;
 	int16 unkPosY = 4;
@@ -1295,7 +1295,7 @@ void EfhEngine::drawScreen() {
 }
 
 void EfhEngine::displayLowStatusScreen(bool flag) {
-	debug("displayLowStatusScreen %s", flag ? "True" : "False");
+	debugC(6, kDebugEngine, "displayLowStatusScreen %s", flag ? "True" : "False");
 	
 	static char strName[5] = "Name";
 	static char strDef[4] = "DEF";
@@ -1880,7 +1880,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag) {
 				int16 var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1)
-					_mapUnknown[var110]._field1 = 0xFF;
+					_mapUnknown[var110]._posX = 0xFF;
 			}
 			break;
 		case 0x13:
@@ -1966,7 +1966,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 
 				var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1) {
-					_mapUnknown[var110]._field1 = 0xFF;
+					_mapUnknown[var110]._posX = 0xFF;
 				}
 				_redrawNeededFl = true;
 			}
@@ -1986,7 +1986,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
-					_mapUnknown[var110]._field1 = 0xFF;
+					_mapUnknown[var110]._posX = 0xFF;
 				}
 			}
 			break;
@@ -1995,10 +1995,10 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag) {
 				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
 				if (var110 != -1) {
-					_mapUnknown[var110]._field1 = 0xFF;
+					_mapUnknown[var110]._posX = 0xFF;
 				}
-				_mapUnknown[scriptNumberArray[2]]._field1 = scriptNumberArray[0];
-				_mapUnknown[scriptNumberArray[2]]._field2 = scriptNumberArray[1];
+				_mapUnknown[scriptNumberArray[2]]._posX = scriptNumberArray[0];
+				_mapUnknown[scriptNumberArray[2]]._posY = scriptNumberArray[1];
 			}
 			break;
 		case 0x1C:
@@ -2228,12 +2228,12 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 
 	if (_largeMapFlag) {
 		for (int16 counter = 0; counter < 100; ++counter) {
-			if (_mapUnknown[counter]._field1 == posX && _mapUnknown[counter]._field2 == posY && _mapUnknown[counter]._field0 == 0xFE)
+			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == 0xFE)
 				return counter;
 		}
 	} else {
 		for (int16 counter = 0; counter < 100; ++counter) {
-			if (_mapUnknown[counter]._field1 == posX && _mapUnknown[counter]._field2 == posY && _mapUnknown[counter]._field0 == _fullPlaceId)
+			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == _fullPlaceId)
 				return counter;
 		}
 	}
@@ -2702,7 +2702,7 @@ int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
 }
 
 bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
-	debug("checkWeaponRange %d %d", monsterId, weaponId);
+	debugC(6, kDebugEngine, "checkWeaponRange %d %d", monsterId, weaponId);
 	
 	static const int16 kRange[5] = {1, 2, 3, 3, 3};
 
@@ -2714,7 +2714,7 @@ bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
 }
 
 bool EfhEngine::unkFct_checkMonsterField8(int16 id, bool teamFlag) {
-	debug("unkFct_checkMonsterField8 %d %s", id, teamFlag ? "True" : "False");
+	debugC(6, kDebugEngine, "unkFct_checkMonsterField8 %d %s", id, teamFlag ? "True" : "False");
 
 	int16 monsterId = id;
 	if (teamFlag)
@@ -2733,9 +2733,9 @@ bool EfhEngine::unkFct_checkMonsterField8(int16 id, bool teamFlag) {
 }
 
 bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
-	debug("checkTeamWeaponRange %d", monsterId);
+	debugC(6, kDebugEngine, "checkTeamWeaponRange %d", monsterId);
 
-	if (!_word2D0BC)
+	if (!_ongoingFightFl)
 		return true;
 
 	for (int16 counter = 0; counter < 5; ++counter) {
@@ -2746,8 +2746,8 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 	return true;
 }
 
-bool EfhEngine::checkIfMonsterOnSameLargelMapPlace(int16 monsterId) {
-	debug("checkIfMonsterOnSameLargelMapPlace %d", monsterId);
+bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
+	debugC(6, kDebugEngine, "checkIfMonsterOnSameLargeMapPlace %d", monsterId);
 	
 	if (_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
 		return true;
@@ -2759,7 +2759,7 @@ bool EfhEngine::checkIfMonsterOnSameLargelMapPlace(int16 monsterId) {
 }
 
 bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
-	debug("checkMonsterWeaponRange %d", monsterId);
+	debugC(6, kDebugEngine, "checkMonsterWeaponRange %d", monsterId);
 	
 	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
 }
@@ -2787,7 +2787,7 @@ void EfhEngine::sub174A0() {
 		if (!checkTeamWeaponRange(monsterId))
 			continue;
 
-		if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+		if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 			continue;
 
 		int16 var4 = _mapMonsters[monsterId]._posX;
@@ -2944,7 +2944,7 @@ void EfhEngine::sub174A0() {
 }
 
 bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
-	debug("checkPictureRefAvailability %d", monsterId);
+	debugC(6, kDebugEngine, "checkPictureRefAvailability %d", monsterId);
 	
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
@@ -3005,7 +3005,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	if (countPictureRef(monsterId, false) < 1)
 		return false;
 
-	if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+	if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 		return false;
 
 	if (!checkMonsterGroupDistance1OrLess(monsterId))
@@ -3192,9 +3192,9 @@ void EfhEngine::sub22AA8(int16 arg0) {
 			if (var12 == nullptr)
 				break;
 
+			if (varE == 0)
+				memset(_messageToBePrinted, 0, 400);
 			do {
-				if (varE == 0)
-					memset(_messageToBePrinted, 0, 400);
 				switch (*var12) {
 				case 0x00:
 				case 0x0A:					
@@ -3223,6 +3223,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					var8 = -1;
 					break;
 				default:
+					_messageToBePrinted[varE++] = *var12;
+					varC++;
 				break;
 				}
 				var12 += 1;
@@ -3264,7 +3266,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					if (var2 != 0xFF)
 						var4 = var2;
 				}
-			} while (var4 != -1 && var4 != 0xFF);
+				
+			} while (varA == 0 && var4 != -1);
 		}
 	}
 
@@ -3279,7 +3282,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	if (var8 == -1) {
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
-	} else if (var8 == 0) {
+	} else if (arg8 == 0) {
 		if (_mapUnknown[var8]._field3 == 0xFF) {
 			sub22AA8(_mapUnknown[var8]._field5); // word!
 			return true;
@@ -3416,7 +3419,7 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
 				continue;
 
-			if (!checkIfMonsterOnSameLargelMapPlace(monsterId))
+			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 				continue;
 
 			bool var6 = false;
@@ -3732,7 +3735,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 
 	// sub1BE9A - 1rst loop counter1_monsterId - Start
 	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
-		if (sub1BAF9(counter1))
+		if (countMonsterGroupMembers(counter1))
 			continue;
 
 		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
@@ -3772,7 +3775,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 					continue;
 				
 				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._field_1)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
-					if (checkIfMonsterOnSameLargelMapPlace(counter1)) {
+					if (checkIfMonsterOnSameLargeMapPlace(counter1)) {
 						bool var6 = false;
 						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
 							if (_mapMonsters[counter1]._pictureRef[counter2] > 0) {
@@ -3845,16 +3848,16 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 	return retVal;
 }
 
-int16 EfhEngine::sub1BAF9(int16 monsterGroup) {
-	debug("sub1BAF9 %d", monsterGroup);
+int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
+	debugC(9, kDebugEngine, "countMonsterGroupMembers %d", monsterGroup);
 	
-	int16 var2 = 0;
+	int16 result = 0;
 	for (int16 counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(monsterGroup, counter))
-			++var2;
+			++result;
 	}
 
-	return var2;
+	return result;
 }
 
 void EfhEngine::sub1C4CA(bool whiteFl) {
@@ -3866,7 +3869,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 			continue;
 
 		int16 var6C = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
-		int16 var6E = sub1BAF9(counter);
+		int16 var6E = countMonsterGroupMembers(counter);
 		if (whiteFl)
 			setTextColorWhite();
 		else
@@ -4961,13 +4964,13 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	debug("handleFight %d", monsterId);
 
 	int16 var8C = 0;
-	_word2D0BC = true;
+	_ongoingFightFl = true;
 
 	sub1BE89(monsterId);
 
 	if (_teamMonsterIdArray[0] == -1) {
 		resetTeamMonsterIdArray();
-		_word2D0BC = false;
+		_ongoingFightFl = false;
 		displayAnimFrames(0xFE, true);
 		return true;
 	}
@@ -4977,14 +4980,14 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	for (bool mainLoopCond = false; !mainLoopCond;) {
 		if (isTPK()) {
 			resetTeamMonsterIdArray();
-			_word2D0BC = false;
+			_ongoingFightFl = false;
 			displayAnimFrames(0xFE, true);
 			return false;
 		}
 
 		if (_teamMonsterIdArray[0] == -1) {
 			resetTeamMonsterIdArray();
-			_word2D0BC = false;
+			_ongoingFightFl = false;
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -4998,7 +5001,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 		if (!sub1CB27()) {
 			resetTeamMonsterIdArray();
-			_word2D0BC = false;
+			_ongoingFightFl = false;
 			totalPartyKill();
 			displayAnimFrames(0xFE, true);
 			return false;
@@ -5261,7 +5264,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 	}
 
 	resetTeamMonsterIdArray();
-	_word2D0BC = false;
+	_ongoingFightFl = false;
 	displayAnimFrames(0xFE, true);
 	return true;
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 5aaa306973b..5e901c6264c 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -86,9 +86,9 @@ struct InvObject {
 };
 
 struct UnkMapStruct {
-	uint8 _field0;
-	uint8 _field1;
-	uint8 _field2;
+	uint8 _placeId;
+	uint8 _posX;
+	uint8 _posY;
 	uint8 _field3;
 	uint8 _field4;
 	uint16 _field5;
@@ -353,7 +353,7 @@ private:
 	bool checkWeaponRange(int16 monsterId, int16 weaponId);
 	bool unkFct_checkMonsterField8(int16 id, bool teamFlag);
 	bool checkTeamWeaponRange(int16 monsterId);
-	bool checkIfMonsterOnSameLargelMapPlace(int16 monsterId);
+	bool checkIfMonsterOnSameLargeMapPlace(int16 monsterId);
 	bool checkMonsterWeaponRange(int16 monsterId);
 	void sub174A0();
 	bool checkPictureRefAvailability(int16 monsterId);
@@ -379,7 +379,7 @@ private:
 	bool sub1CB27();
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
-	int16 sub1BAF9(int16 monsterGroup);
+	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1C4CA(bool WhiteFl);
 	void displayCombatMenu(int16 charId);
 	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
@@ -572,7 +572,7 @@ private:
 	bool _dbgForceDisplayUpperRightBorder; // Original debug flag? Always false.
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 	bool _word2C8D7; // Original debug flag? Always true.
-	bool _word2D0BC;
+	bool _ongoingFightFl;
 	bool _statusMenuActive;
 	int16 _menuDepth;
 	int16 _word2D0BA;


Commit: 0acc221f4f253246fc51c0b4205d37f3f9ab7280
    https://github.com/scummvm/scummvm/commit/0acc221f4f253246fc51c0b4205d37f3f9ab7280
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix the display of the gate first message and the board.

Changed paths:
    engines/efh/utils.cpp


diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index b97acb13ad1..58721a56459 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -56,7 +56,7 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 		_imp2PtrArray[counter++] = curPtr = _imp2;
 		target = 431;
 	} else {
-		_imp2PtrArray[counter++] = curPtr = _imp1;
+		_imp1PtrArray[counter++] = curPtr = _imp1;
 		target = 99;
 	}
 


Commit: 14bb81d797acf4473ce6fe7b2150cc0c38961e18
    https://github.com/scummvm/scummvm/commit/14bb81d797acf4473ce6fe7b2150cc0c38961e18
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix bugs in opcode 12 and 13, fix issues in readNumberArray and getNumber

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 71bd83813cc..52b918a682c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1371,7 +1371,7 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 	debug("script_readNumberArray");
 	
 	uint8 *buffer = srcBuffer;
-
+	buffer++;
 	for (int16 i = 0; i < destArraySize; ++i) {
 		buffer = script_getNumber(buffer, &destArray[i]);
 	}
@@ -1391,6 +1391,7 @@ uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
 			return buffer;
 		}
 		var2 = var2 * 10 + curChar - 0x30;
+		buffer++;
 	}
 }
 
@@ -1682,7 +1683,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 		int16 var_108 = 0;
 		buffer = script_getNumber(buffer, &var_108);
 		int16 scriptNumberArray[10];
-		memset(scriptNumberArray, 0, ARRAYSIZE(scriptNumberArray));
+		memset(scriptNumberArray, 0, sizeof(scriptNumberArray));
 
 		switch (var_108) {
 		case 0x00:
@@ -1813,7 +1814,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 		case 0x0C:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				int16 var110 = scriptNumberArray[0];
 				bool found = false;
 				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
 					for (int16 objectId = 0; objectId < 10; ++objectId) {
@@ -1829,7 +1830,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 		case 0x0D:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				int16 var110 = scriptNumberArray[0];
 				for (int16 counter = 0; counter < _teamSize; ++counter) {
 					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
 						break;
@@ -2156,7 +2157,7 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 }
 
 int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl) {
-	debug("sub1C219 %s %c %c %s", (char *)str, menuType, arg4, displayTeamWindowFl ? "True" : "False");
+	debug("sub1C219 %s %d %d %s", (char *)str, menuType, arg4, displayTeamWindowFl ? "True" : "False");
 
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;


Commit: d1acf3e1f78e8d725d6120564272b8724f76bcfc
    https://github.com/scummvm/scummvm/commit/d1acf3e1f78e8d725d6120564272b8724f76bcfc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix readNumberArray. It's now possible to teleport!! \o/

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 52b918a682c..838a70733ed 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1371,8 +1371,8 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 	debug("script_readNumberArray");
 	
 	uint8 *buffer = srcBuffer;
-	buffer++;
 	for (int16 i = 0; i < destArraySize; ++i) {
+		buffer++;
 		buffer = script_getNumber(buffer, &destArray[i]);
 	}
 


Commit: abfd4848ed67a8b223c595ecbcbb885fe8e83cef
    https://github.com/scummvm/scummvm/commit/abfd4848ed67a8b223c595ecbcbb885fe8e83cef
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix transparency

Changed paths:
    engines/efh/graphics.cpp


diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 9566d95ffb8..cd24bfcba95 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -39,7 +39,7 @@ void EfhEngine::initPalette() {
 		170, 170, 170,
 		85, 85, 85,
 		85, 85, 255,
-		1, 1, 1,
+		1, 1, 1, // Color 0xA is for transparency
 		85, 255, 255,
 		255, 85, 85,
 		255, 85, 255,
@@ -128,8 +128,10 @@ void EfhEngine::displayBufferBmAtPos(BufferBM *bufferBM, int16 posX, int16 posY)
 	int counter = 0;
 	for (int line = 0; line < bufferBM->_height; ++line) {
 		for (int col = 0; col < bufferBM->_lineDataSize; ++col) { // _lineDataSize = _width / 2
-			destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
-			destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
+			if (bufferBM->_dataPtr[counter] >> 4 != 0xA)
+				destPtr[320 * line + 2 * col] = bufferBM->_dataPtr[counter] >> 4;
+			if ((bufferBM->_dataPtr[counter] & 0xF) != 0xA)
+				destPtr[320 * line + 2 * col + 1] = bufferBM->_dataPtr[counter] & 0xF;
 			++counter;
 		}
 	}


Commit: fb064ef2233dcbe6fa2b6920135e6b07e7e42393
    https://github.com/scummvm/scummvm/commit/fb064ef2233dcbe6fa2b6920135e6b07e7e42393
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix DrawColorRect usage in sub1C219 (fix display when reading descriptions or dialogs)

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 838a70733ed..3cb751a8b59 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2194,7 +2194,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 		break;
 	}
 
-	drawColoredRect(minX, maxX, minY, maxY, 0);
+	drawColoredRect(minX, minY, maxX, maxY, 0);
 	if (str)
 		varA = script_parse(str, minX, minY, maxX, maxY, true);
 
@@ -2206,7 +2206,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 		if (_word2C87A != 0)
 			_word2C87A = 0;
 		else {
-			drawColoredRect(minX, maxX, minY, maxY, 0);
+			drawColoredRect(minX, minY, maxX, maxY, 0);
 			if (str)
 				int16 varC = script_parse(str, minX, minY, maxX, maxY, true);
 		}
@@ -2218,7 +2218,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 			int16 varC = getLastCharAfterAnimCount(_guessAnimationAmount);
 
 		if (arg4 == 3)
-			drawColoredRect(minX, maxX, minY, maxY, 0);
+			drawColoredRect(minX, minY, maxX, maxY, 0);
 	}
 
 	return varA;
@@ -3229,7 +3229,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 				break;
 				}
 				var12 += 1;
-				int16 var2;
+				int16 var2 = 0xFF ;
 				if (var8 != 0 || varA != 0) {
 					var8 = 0;
 					_messageToBePrinted[varE] = 0;


Commit: a3916952a6300b77d09fb6a6c4920a89c5dc55e7
    https://github.com/scummvm/scummvm/commit/a3916952a6300b77d09fb6a6c4920a89c5dc55e7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Some renaming, add a note in drawChar

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3cb751a8b59..94fe69a1ad1 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -296,7 +296,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
 	_word2C87A = false;
-	_unk_sub26437_flag = 0;
 	_dbgForceDisplayUpperRightBorder = false;
 	_dbgForceMonsterBlock = false;
 	_ongoingFightFl = false;
@@ -1680,12 +1679,12 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 
 		// At this point, curChar == 0x5E
 		++buffer;
-		int16 var_108 = 0;
-		buffer = script_getNumber(buffer, &var_108);
+		int16 opCode = 0;
+		buffer = script_getNumber(buffer, &opCode);
 		int16 scriptNumberArray[10];
 		memset(scriptNumberArray, 0, sizeof(scriptNumberArray));
 
-		switch (var_108) {
+		switch (opCode) {
 		case 0x00:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
@@ -2203,8 +2202,8 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 
 	if (arg4 != 0) {
 		displayFctFullScreen();
-		if (_word2C87A != 0)
-			_word2C87A = 0;
+		if (_word2C87A)
+			_word2C87A = false;
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 			if (str)
@@ -3900,7 +3899,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 			_textColor = 0xE;
 			displayStringAtTextPos("Hostile");
 		} else {
-			_textColor = 2;
+			_textColor = 0x2;
 			displayStringAtTextPos("Friendly");
 		}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 5e901c6264c..f67c48ce14a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -438,7 +438,7 @@ private:
 	void drawColoredRect(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 	void clearScreen(int16 color);
 	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
-	void drawString(const char *str, int16 startX, int16 startY, uint16 unkFl);
+	void drawString(const char *str, int16 startX, int16 startY, uint16 textColor);
 	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
 	void displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int16 posY);
 	void drawMapWindow();
@@ -557,7 +557,6 @@ private:
 	bool _drawHeroOnMapFl;
 	bool _drawMonstersOnMapFl;
 	bool _word2C87A;
-	int16 _unk_sub26437_flag;
 
 	int16 _imageSetSubFilesIdx;
 	int16 _oldImageSetSubFilesIdx;
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index cd24bfcba95..c31fdc61e38 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -200,17 +200,16 @@ void EfhEngine::displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY) {
 	displayBufferBmAtPos(&_imageDataPtr, posX, posY);
 }
 
-void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 unkFl) {
-	debugC(1, kDebugGraphics, "drawString %s %d %d %d", str, startX, startY, unkFl);
+void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 textColor) {
+	debugC(1, kDebugGraphics, "drawString %s %d %d %d", str, startX, startY, textColor);
 	uint8 *curPtr = (uint8 *)str;
 	uint16 lineHeight = _fontDescr._charHeight + _fontDescr._extraVerticalSpace;
-	_unk_sub26437_flag = unkFl & 0x3FFF;
 	int16 minX = startX;
-	int16 minY = startY;                                 // Used in case 0x8000
-	int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
 
-	if (unkFl & 0x8000) {
+	if (textColor & 0x8000) {
 		warning("STUB - drawString - 0x8000");
+		// int16 minY = startY;                                 // Used in case 0x8000
+		// int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
 	}
 
 	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
@@ -291,6 +290,11 @@ void EfhEngine::drawChar(uint8 curChar, int16 posX, int16 posY) {
 	debugC(1, kDebugGraphics, "drawChar %c %d %d", curChar, posX, posY);
 
 	// CHECKME: Quick hacked display, may require rework
+
+	// Note: The original is making of a variable which is set to _textColor & 0x3FFF
+	// It seems _textColor is always set to a small value and thus this variable
+	// has been removed.
+
 	uint8 *destPtr = (uint8 *)_mainSurface->getBasePtr(posX, posY);
 
 	int16 charId = curChar - 0x20;


Commit: 144819e53f0bc7d4a872d7ff8e02ded652f940ea
    https://github.com/scummvm/scummvm/commit/144819e53f0bc7d4a872d7ff8e02ded652f940ea
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix moonwalk occurring when getting close to the left and top border of the maps

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 94fe69a1ad1..d37ea2ea4cc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1177,12 +1177,12 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 	int16 minY = mapPosY - 4;
 
 	if (minX < 0) {
-		unkPosX -= minX;
+		unkPosX += minX;
 		minX = 0;
 	}
 
 	if (minY < 0) {
-		unkPosY -= minY;
+		unkPosY += minY;
 		minY = 0;
 	}
 


Commit: 309f10be4d05a71e268d7bba56c9b3e2fd870d3a
    https://github.com/scummvm/scummvm/commit/309f10be4d05a71e268d7bba56c9b3e2fd870d3a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Some renaming in drawMap

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d37ea2ea4cc..4d74f76b2ae 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1168,21 +1168,18 @@ void EfhEngine::drawGameScreenAndTempText(bool flag) {
 void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl) {
 	debugC(6, kDebugEngine, "drawMap %s %d-%d %d %s %s", largeMapFl ? "True" : "False", mapPosX, mapPosY, mapSize, drawHeroFl ? "True" : "False", drawMonstersFl ? "True" : "False");
 	
-	int16 unkPosX = 5;
-	int16 unkPosY = 4;
-	int16 posX = 0;
-	int16 posY = 0;
-	int16 var6 = 0;
+	int16 shiftPosX = 5;
+	int16 shiftPosY = 4;
 	int16 minX = mapPosX - 5;
 	int16 minY = mapPosY - 4;
 
 	if (minX < 0) {
-		unkPosX += minX;
+		shiftPosX += minX;
 		minX = 0;
 	}
 
 	if (minY < 0) {
-		unkPosY += minY;
+		shiftPosY += minY;
 		minY = 0;
 	}
 
@@ -1190,45 +1187,46 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 	int16 maxY = minY + 7;
 
 	if (maxX > mapSize) {
-		unkPosX += (maxX - mapSize);
+		shiftPosX += (maxX - mapSize);
 		maxX = mapSize;
 		minX = mapSize - 10;
 	}
 
 	if (maxY > mapSize) {
-		unkPosY += (maxY - mapSize);
+		shiftPosY += (maxY - mapSize);
 		maxY = mapSize;
 		minY = mapSize - 7;
 	}
 
-	int16 var10 = 8;
+	int16 drawPosY = 8;
 	for (int16 counterY = minY; counterY <= maxY; ++counterY) {
-		int16 var12 = 128;
-		for (int16 var16 = minX; var16 <= maxX; ++var16) {
+		int16 drawPosX = 128;
+		for (int16 counterX = minX; counterX <= maxX; ++counterX) {
 			if (largeMapFl) {
-				int16 idx = _mapGameMap[var16][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
+				int16 idx = _mapGameMap[counterX][counterY];
+				displayRawDataAtPos(_imageSetSubFilesArray[idx], drawPosX, drawPosY);
 			} else {
-				int16 idx = _curPlace[var16][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[idx], var12, var10);
+				int16 idx = _curPlace[counterX][counterY];
+				displayRawDataAtPos(_imageSetSubFilesArray[idx], drawPosX, drawPosY);
 			}
-			var12 += 16;
+			drawPosX += 16;
 		}
-		var10 += 16;
+		drawPosY += 16;
 	}
 
 	if (drawHeroFl) {
-		int16 var12 = 128 + unkPosX * 16;
-		var10 = 8 + unkPosY * 16;
-		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], var12, var10);
+		// Draw hero
+		int16 drawPosX = 128 + shiftPosX * 16;
+		drawPosY = 8 + shiftPosY * 16;
+		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], drawPosX, drawPosY);
 	}
 
 	if (drawMonstersFl) {
 		for (int16 var16 = 0; var16 < 64; ++var16) {
 			if ((_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == _fullPlaceId)){
 				bool var4 = false;
-				posX = _mapMonsters[var16]._posX;
-				posY = _mapMonsters[var16]._posY;
+				int16 posX = _mapMonsters[var16]._posX;
+				int16 posY = _mapMonsters[var16]._posY;
 
 				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
 					continue;
@@ -1241,15 +1239,15 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 				if (!var4)
 					continue;
 
-				var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
+				int16 var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
 				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
 
 				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._field_1))
 					continue;
 
-				int16 var12 = 128 + (posX - minX) * 16;
-				var10 = 8 + (posY - minY) * 16;
-				displayRawDataAtPos(_imageSetSubFilesArray[var6], var12, var10);
+				int16 drawPosX = 128 + (posX - minX) * 16;
+				drawPosY = 8 + (posY - minY) * 16;
+				displayRawDataAtPos(_imageSetSubFilesArray[var6], drawPosX, drawPosY);
 			}
 		}
 	}


Commit: 1071de9f8b45aa94af42a2c4f954fe9457c41427
    https://github.com/scummvm/scummvm/commit/1071de9f8b45aa94af42a2c4f954fe9457c41427
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Add some comments in the script parser, fix the display of conditional dialogs

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4d74f76b2ae..a11a9f8d734 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -718,7 +718,7 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 		readFileToBuffer(fileName, _hiResImageBuf);
 		uncompressBuffer(_hiResImageBuf, _places);
 	}
-	copyCurrentPlaceToBuffer(_fullPlaceId / 20);
+	copyCurrentPlaceToBuffer(_fullPlaceId % 20);
 }
 
 void EfhEngine::readTileFact() {
@@ -1684,6 +1684,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 
 		switch (opCode) {
 		case 0x00:
+			// Enter room { full Place Id, posX, posY }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
 				if (_largeMapFlag) {
@@ -1699,6 +1700,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			}
 			break;
 		case 0x01:
+			// Exit room { }
 			if (flag) {
 				_largeMapFlag = true;
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
@@ -1708,6 +1710,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			}
 			break;
 		case 0x02:
+			// Change map. { map number, posX, posY }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
 				if (_word2C8D7)
@@ -1825,6 +1828,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			}
 			break;
 		case 0x0D:
+			// Put item in inventory { objectId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
@@ -1875,6 +1879,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 				_unkArray2C8AA[0] = 0;
 			break;
 		case 0x12:
+			// Guess : disable special tile { }
 			if (flag) {
 				int16 var110 = sub151FD(_mapPosX, _mapPosY);
 				if (var110 != -1)
@@ -2012,6 +2017,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			}
 			break;
 		case 0x1E:
+			// Dialog with condition { historyId, dialogId1, dialogId2 }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
 				if (_history[scriptNumberArray[0]] == 0)
@@ -3266,6 +3272,10 @@ void EfhEngine::sub22AA8(int16 arg0) {
 				}
 				
 			} while (varA == 0 && var4 != -1);
+
+			varA = 0;
+			if (var4 == 0xFF || var4 == -1)
+				break;
 		}
 	}
 


Commit: 272b688b72981484bb9f89d2f5b1423350bbb3dc
    https://github.com/scummvm/scummvm/commit/272b688b72981484bb9f89d2f5b1423350bbb3dc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix crash when interacting with a special character

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a11a9f8d734..baa2a90a2aa 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -6719,7 +6719,8 @@ bool EfhEngine::checkMonsterCollision() {
 				} else if (var1 == 0x3E) {
 					strcpy(buffer, "(NOT DEFINED)");
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
-					copyString(_npcBuf[_mapMonsters[monsterId]._monsterRef]._name, dest);
+					// Special character name
+					copyString(_npcBuf[_mapMonsters[monsterId]._field_1]._name, dest);
 					sprintf(buffer, "with %s", dest);
 				}
 


Commit: 164b5825e9f2c998035f50da2e49858947183c8a
    https://github.com/scummvm/scummvm/commit/164b5825e9f2c998035f50da2e49858947183c8a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix double execution of opcodes, start fixing encounter of special characters

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index baa2a90a2aa..e532af339fc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2211,7 +2211,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 			if (str)
-				int16 varC = script_parse(str, minX, minY, maxX, maxY, true);
+				int16 varC = script_parse(str, minX, minY, maxX, maxY, false);
 		}
 
 		if (displayTeamWindowFl)
@@ -3002,7 +3002,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	char buffer[80];
 	memset(buffer, 0, 80);
 
-	int8 var51 = _mapMonsters[monsterId]._possessivePronounSHL6;
+	uint8 var51 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
@@ -5617,7 +5617,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
 
 		if (counter == 0) {
-			script_parse((uint8 *)str, 28, 122, 105, 166, 0);
+			script_parse((uint8 *)str, 28, 122, 105, 166, false);
 			displayFctFullScreen();
 		} else {
 			retVal = script_parse((uint8 *)str, 28, 122, 105, 166, true);


Commit: 024ba4e02df65de614a7abb08f50ebf73c0fa463
    https://github.com/scummvm/scummvm/commit/024ba4e02df65de614a7abb08f50ebf73c0fa463
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix another issue in sub21820

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e532af339fc..cae0cde1ad9 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3028,7 +3028,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	if (isCharacterATeamMember(_mapMonsters[monsterId]._field_1))
 		return false;
 
-	int16 var58 = isCharacterATeamMember(_mapMonsters[monsterId]._field_1);
+	int16 var58 = _mapMonsters[monsterId]._field_1;
 	switch (_npcBuf[var58].field_10 - 0xEE) {
 	case 0:
 		if (arg2 == 4 && _npcBuf[var58].field_11 == itemId) {
@@ -3149,6 +3149,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		displayAnimFrames(0xFE, true);
 		return true;
 	default:
+		
 		break;
 	}
 


Commit: f1d9b538c491e15f897b1673d98b9a4ff6390a2e
    https://github.com/scummvm/scummvm/commit/f1d9b538c491e15f897b1673d98b9a4ff6390a2e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Fix a couple of issues in the Y/N check related to save/load games, move some debug strings to debugC

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index cae0cde1ad9..a57e5a32264 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -481,7 +481,7 @@ Common::Error EfhEngine::run() {
 					displayFctFullScreen();
 			}
 			Common::KeyCode input = waitForKey();
-			if (input = Common::KEYCODE_y) {
+			if (input == Common::KEYCODE_y) {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
 				saveEfhGame();
@@ -496,7 +496,7 @@ Common::Error EfhEngine::run() {
 			
 			}			
 			break;
-		case Common::KEYCODE_F7: { // Original is using CTRL-S
+		case Common::KEYCODE_F7: { // Original is using CTRL-L
 			for (int16 counter = 0; counter < 2; ++counter) {
 				clearBottomTextZone(0);
 				displayCenteredString("Are You Sure You Want To Load?", 24, 296, 160);
@@ -504,7 +504,7 @@ Common::Error EfhEngine::run() {
 					displayFctFullScreen();
 			}
 			Common::KeyCode input = waitForKey();
-			if (input = Common::KEYCODE_y) {
+			if (input == Common::KEYCODE_y) {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
 				loadEfhGame();
@@ -621,7 +621,7 @@ void EfhEngine::readAnimInfo() {
 }
 
 void EfhEngine::findMapFile(int16 mapId) {
-	debug("findMapFile %d", mapId);
+	debugC(7, kDebugEngine, "findMapFile %d", mapId);
 	
 	if (!_word31E9E)
 		return;
@@ -636,7 +636,7 @@ void EfhEngine::findMapFile(int16 mapId) {
 }
 
 void EfhEngine::loadNewPortrait() {
-	debug("loadNewPortrait");
+	debugC(7, kDebugEngine, "loadNewPortrait");
 	
 	static int16 const unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
 	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
@@ -722,7 +722,7 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 }
 
 void EfhEngine::readTileFact() {
-	debug("readTileFact");
+	debugC(7, kDebugEngine, "readTileFact");
 	
 	Common::String fileName = "tilefact";
 	uint8 tileFactBuff[864];
@@ -735,7 +735,7 @@ void EfhEngine::readTileFact() {
 }
 
 void EfhEngine::readItems() {
-	debug("readItems");
+	debugC(7, kDebugEngine, "readItems");
 	
 	Common::String fileName = "items";
 	uint8 itemBuff[8100];
@@ -760,12 +760,12 @@ void EfhEngine::readItems() {
 		_items[i].field_19 = *curPtr++;
 		_items[i].field_1A = *curPtr++;
 
-//		warning("%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
 	}
 }
 
 void EfhEngine::loadNPCS() {
-	debug("loadNPCS");
+	debugC(7, kDebugEngine, "loadNPCS");
 	
 	Common::String fileName = "npcs";
 	uint8 npcLoading[13400];
@@ -874,6 +874,7 @@ void EfhEngine::playIntro() {
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	drawText(_imp2PtrArray[0], 6, 150, 268, 186, false);
+	
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -1897,6 +1898,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			}
 			break;
 		case 0x14:
+			// Add character to team { charId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
@@ -2058,7 +2060,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 }
 
 void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("drawText %d-%d %d-%d %s", posX, posY, maxX, maxY, flag ? "True" : "False");
+	debugC(7, kDebugEngine, "drawText %d-%d %d-%d %s", posX, posY, maxX, maxY, flag ? "True" : "False");
 
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;


Commit: 8082c472fe3cee2d53098f552059c3e59bfe6c3d
    https://github.com/scummvm/scummvm/commit/8082c472fe3cee2d53098f552059c3e59bfe6c3d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:38+01:00

Commit Message:
EFH: Change the safeguard in getRandom to make it more robust, change debug to debugC after proofreading the code, add some TODOs

Changed paths:
    engines/efh/efh.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a57e5a32264..523363f3c60 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1088,7 +1088,8 @@ void EfhEngine::saveAnimImageSetId() {
 }
 
 int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
-	debug("getEquipmentDefense %d %s", charId, flag ? "True" : "False");
+	debugC(2, kDebugGraphics, "getEquipmentDefense %d %s", charId, flag ? "True" : "False");
+	// TODO: flag is always false, remove it when refactoring
 
 	int16 altDef = 0;
 	int16 totalDef = 0;
@@ -1117,7 +1118,7 @@ int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
 }
 
 uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
-	debug("sub1C80A %d %d %s", charId, field18, flag ? "True" : "False");
+	debugC(2, kDebugEngine, "sub1C80A %d %d %s", charId, field18, flag ? "True" : "False");
 
 	for (int i = 0; i < 10; ++i) {
 		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
@@ -1270,7 +1271,7 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 }
 
 void EfhEngine::drawScreen() {
-	debug("drawScreen");
+	debugC(2, kDebugEngine, "drawScreen");
 	
 	for (int16 counter = 0; counter < 2; ++counter) {
 		_redrawNeededFl = false;
@@ -1278,12 +1279,14 @@ void EfhEngine::drawScreen() {
 			if (_fullPlaceId != 0xFF)
 				displaySmallMap(_mapPosX, _mapPosY);
 
+			// TODO: When refactoring : Always false, to be removed
 			if (_dbgForceDisplayUpperRightBorder)
 				drawUpperRightBorders();
 		} else {
 			if (_techId != 0xFF)
 				displayLargeMap(_mapPosX, _mapPosY);
-			
+
+			// TODO: When refactoring : Always false, to be removed
 			if (_dbgForceDisplayUpperRightBorder)
 				drawUpperRightBorders();
 		}
@@ -2465,7 +2468,7 @@ bool EfhEngine::handleDeathMenu() {
 			_oldMapPosX = _mapPosX = 31;
 			_oldMapPosY = _mapPosY = 31;
 			_unkRelatedToAnimImageSetId = 0;
-			*_unkArray2C8AA = 0;
+			_unkArray2C8AA[0] = 0;
 			found = true;
 			break;
 		case Common::KEYCODE_x:
@@ -2681,7 +2684,7 @@ bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 }
 
 bool EfhEngine::moveMonsterGroup(int16 monsterId) {
-	debug("moveMonsterGroup %d", monsterId);
+	debugC(2, kDebugEngine, "moveMonsterGroup %d", monsterId);
 
 	int16 rand100 = getRandom(100);
 
@@ -2696,7 +2699,7 @@ bool EfhEngine::moveMonsterGroup(int16 monsterId) {
 }
 
 int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
-	debug("computeMonsterGroupDistance %d", monsterId);
+	debugC(2, kDebugEngine, "computeMonsterGroupDistance %d", monsterId);
 	
 	int16 monsterPosX = _mapMonsters[monsterId]._posX;
 	int16 monsterPosY = _mapMonsters[monsterId]._posY;
@@ -4669,7 +4672,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var5C;
 					if (unkFct_checkMonsterField8(groupId, true)) {
 						sub1E028(groupId, 9, true);
-						*_unkArray2C8AA += 500;
+						_unkArray2C8AA[0] += 500;
 						var5C = -1;
 					} else
 						var5C = 0;
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index 58721a56459..f7f152064f3 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -173,7 +173,7 @@ uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 
 int16 EfhEngine::getRandom(int16 maxVal) {
 	debugC(1, kDebugUtils, "getRandom %d", maxVal);
-	if (maxVal == 0)
+	if (maxVal <= 0)
 		return 0;
 
 	return 1 + _rnd->getRandomNumber(maxVal - 1);


Commit: 73fabe7176a2bea09c0bb81647c89373564ec2fe
    https://github.com/scummvm/scummvm/commit/73fabe7176a2bea09c0bb81647c89373564ec2fe
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Fix a bug in the fight system, change the type of an argument to bool

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 523363f3c60..20cca5a946c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3566,7 +3566,7 @@ int16 EfhEngine::selectMonsterGroup() {
 	return retVal;
 }
 
-int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
+int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
 	
 	int16 varE = -1;
@@ -3606,8 +3606,8 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
 		else
 			varE = selectMonsterGroup();
 
-		if (arg4 == 0) {
-			if (varE == 27)
+		if (!arg4) {
+			if (varE == 27) // Esc
 				varE = 0;
 		} else if (varE != 27) {
 			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[varE]);
@@ -3615,7 +3615,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, int16 arg4) {
 				varE = 27;
 			}
 		}
-	} while (varE != -1);
+	} while (varE == -1);
 
 	if (varE == 27)
 		varE = -1;
@@ -6941,7 +6941,7 @@ void EfhEngine::setTextPos(int16 textPosX, int16 textPosY) {
 }
 
 void EfhEngine::copyCurrentPlaceToBuffer(int16 id) {
-	debug("copyCurrentPlaceToBuffer %d", id);
+	debugC(2, kDebugEngine, "copyCurrentPlaceToBuffer %d", id);
 
 	// Note that 576 = 24 * 24
 	uint8 *placesPtr = &_places[576 * id];
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index f67c48ce14a..8e5490ca840 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -374,7 +374,7 @@ private:
 	void sub1CDFA();
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
-	int16 sub1C956(int16 charId, int16 unkFied18Val, int16 arg4);
+	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
 	void sub1CAB6(int16 charId);
 	bool sub1CB27();
 	void sub1BE9A(int16 monsterId);


Commit: d88b4bce4dcca22c7587fdb702682700b907b31c
    https://github.com/scummvm/scummvm/commit/d88b4bce4dcca22c7587fdb702682700b907b31c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Add comments, fix a bug in handleFight_lastAction_A

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 20cca5a946c..110d7a56075 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3495,7 +3495,7 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 }
 
 void EfhEngine::sub1CDFA() {
-	debug("sub1CDFA");
+	debug("sub1CDFA"); // Initiatives
 	
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
@@ -3649,24 +3649,24 @@ bool EfhEngine::sub1CB27() {
 			drawCombatScreen(_teamCharId[counter1], false, true);
 			Common::KeyCode var1 = handleAndMapInput(true);
 			switch (var1) {
-			case Common::KEYCODE_a:
+			case Common::KEYCODE_a: // Attack
 				_teamLastAction[counter1] = 'A';
 				_word3267A[counter1] = sub1C956(_teamCharId[counter1], 9, true);
 				if (_word3267A[counter1] == -1)
 					_teamLastAction[counter1] = 0;
 				break;
-			case Common::KEYCODE_d:
+			case Common::KEYCODE_d: // Defend
 				_teamLastAction[counter1] = 'D';
 				break;
-			case Common::KEYCODE_h:
+			case Common::KEYCODE_h: // Hide
 				_teamLastAction[counter1] = 'H';
 				break;
-			case Common::KEYCODE_r:
+			case Common::KEYCODE_r: // Run
 				for (int16 counter2 = 0; counter2 < _teamSize; ++counter2) {
 					_teamLastAction[counter2] = 'R';
 				}
 				return true;
-			case Common::KEYCODE_s: {
+			case Common::KEYCODE_s: { // Status
 				int16 var8 = handleStatusMenu(2, _teamCharId[counter1]);
 				sub1CAB6(_teamCharId[counter1]);
 				if (var8 > 999) {
@@ -3726,7 +3726,7 @@ bool EfhEngine::sub1CB27() {
 				
 				}
 				break;
-			case Common::KEYCODE_t:
+			case Common::KEYCODE_t: // Terrain
 				redrawScreenForced();
 				getInputBlocking();
 				drawCombatScreen(_teamCharId[counter1], false, true);
@@ -4715,7 +4715,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 					hitPoints = originalDamage + damagePointsAbsorbed;
 					
-					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
 						var62 = 0;
 
 					if (var62 > 0) {
@@ -5033,7 +5033,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
 			if (monsterGroupIdOrMonsterId == -1)
 				continue;
-			if (monsterGroupIdOrMonsterId > 999) {
+			if (monsterGroupIdOrMonsterId > 999) { // Team Member
 				monsterGroupIdOrMonsterId -= 1000;
 				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
 					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);


Commit: 654b6ad17748828ea4d2f937f39ad87db4d10232
    https://github.com/scummvm/scummvm/commit/654b6ad17748828ea4d2f937f39ad87db4d10232
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: some renaming, fix a debug message

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 110d7a56075..726be2fe7ce 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -264,7 +264,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 		_unkArray2C8AA[i] = 0;
 		_word32680[i] = 0;
 		_word32482[i] = 0;
-		_word3267A[i] = -1;
+		_teamNextAttack[i] = -1;
 		_word31780[i] = 0;
 		_teamLastAction[i] = 0;
 	}
@@ -3417,7 +3417,7 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 	debug("sub1BCA7 %d", monsterTeamId);
 
 	int16 counter = 0;
-	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false)) {
+	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
 		counter = 1;
 		_teamMonsterIdArray[0] = monsterTeamId;
 	}
@@ -3651,8 +3651,8 @@ bool EfhEngine::sub1CB27() {
 			switch (var1) {
 			case Common::KEYCODE_a: // Attack
 				_teamLastAction[counter1] = 'A';
-				_word3267A[counter1] = sub1C956(_teamCharId[counter1], 9, true);
-				if (_word3267A[counter1] == -1)
+				_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, true);
+				if (_teamNextAttack[counter1] == -1)
 					_teamLastAction[counter1] = 0;
 				break;
 			case Common::KEYCODE_d: // Defend
@@ -3689,7 +3689,7 @@ bool EfhEngine::sub1CB27() {
 					case 10:
 					case 12:
 					case 13:
-						_word3267A[counter1] = sub1C956(_teamCharId[counter1], 9, false);
+						_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, false);
 						break;
 
 					case 9:
@@ -3704,13 +3704,13 @@ bool EfhEngine::sub1CB27() {
 					case 29:
 					case 30:
 						sub1C219((uint8 *)"Select Character:", 3, 1, false);
-						_word3267A[counter1] = selectOtherCharFromTeam();
+						_teamNextAttack[counter1] = selectOtherCharFromTeam();
 						break;
 
 					case 16:
 					case 17:
 					case 26:
-						_word3267A[counter1] = 0xC8;
+						_teamNextAttack[counter1] = 0xC8;
 						break;
 						
 					case 19:
@@ -4639,7 +4639,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	int16 unk_monsterField5_itemId = sub1C80A(_teamCharId[teamCharId], 9, true);
 	if (unk_monsterField5_itemId == 0x7FFF)
 		unk_monsterField5_itemId = 0x3F;
-	int16 monsterGroupNumber = _word3267A[teamCharId];
+	int16 monsterGroupNumber = _teamNextAttack[teamCharId];
 	if (monsterGroupNumber == 0x64)
 		monsterGroupNumber = 0;
 
@@ -5614,7 +5614,7 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 }
 
 int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayString_3 % %s %d %d %d %d", str, animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+	debug("displayString_3 %s %s %d %d %d %d", str, animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
 	
@@ -5648,7 +5648,7 @@ bool EfhEngine::isItemCursed(int16 itemId) {
 }
 
 bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
-	debug("hasObjectEquipped %d %d", charId, objectId);
+	debugC(6, kDebugEngine, "hasObjectEquipped %d %d", charId, objectId);
 	if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0)
 		return false;
 
@@ -5703,7 +5703,7 @@ void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
-	debug("isMonsterActive %d %d", groupId, id);
+	debugC(5, kDebugEngine, "isMonsterActive %d %d", groupId, id);
 
 	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _stru32686[groupId]._field0[id] == 0)
 		return true;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8e5490ca840..fd289b17f1b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -577,7 +577,7 @@ private:
 	int16 _word2D0BA;
 	int16 _word32680[3];
 	int16 _word32482[3];
-	int16 _word3267A[3];
+	int16 _teamNextAttack[3];
 	int16 _word31780[3];
 
 	int16 _word3273A[15];


Commit: b8f84a33f5d17c8ce6f8b8a0dd372b581ba1019c
    https://github.com/scummvm/scummvm/commit/b8f84a33f5d17c8ce6f8b8a0dd372b581ba1019c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Implement animFl in handleAndMapInput, fix a check in sub191FF, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 726be2fe7ce..abd0c4e3531 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -301,7 +301,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_ongoingFightFl = false;
 	_statusMenuActive = false;
 	_menuDepth = 0;
-	_word2D0BA = 0;
+	_menuItemCounter = 0;
 
 	for (int i = 0; i < 15; ++i) {
 		_word3273A[i] = 0;
@@ -5336,7 +5336,7 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 
 	int16 var2 = 0;
 	int16 var4 = 0;
-	_word2D0BA = 0;
+	_menuItemCounter = 0;
 
 	switch (menuId) {
 	case 0:
@@ -5361,20 +5361,20 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 		break;
 	default: // Case 8 + Default
 		var4 = -1;
-		_word2D0BA = 0;
+		_menuItemCounter = 0;
 		break;
 	}
 
 	if (var4 == -1) {
 		for (int16 counter = 0; counter < 10; ++counter) {
 			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
-				_word3273A[_word2D0BA++] = counter;
+				_word3273A[_menuItemCounter++] = counter;
 			}
 		}
 	} else {
 		for (int16 counter = var4; counter < var2; ++counter) {
 			if (_npcBuf[charId]._activeScore[counter] != 0) {
-				_word3273A[_word2D0BA++] = counter;
+				_word3273A[_menuItemCounter++] = counter;
 			}
 		}
 	}
@@ -5434,7 +5434,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	displayStringAtTextPos(buffer1);
 	displayCenteredString("Inventory", 144, 310, 72);
 
-	if (_word2D0BA == 0) {
+	if (_menuItemCounter == 0) {
 		if (curMenuLine != -1)
 			setTextColorWhite();
 
@@ -5443,7 +5443,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 		return;
 	}
 
-	for (int16 counter = 0; counter < _word2D0BA; ++counter) {
+	for (int16 counter = 0; counter < _menuItemCounter; ++counter) {
 		if (_menuDepth == 0)
 			setTextColorGrey();
 		else {
@@ -5513,7 +5513,7 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 	setTextPos(146, 27);
 	displayStringAtTextPos("Name: ");
 	displayStringAtTextPos(buffer);
-	if (_word2D0BA <= 0) {
+	if (_menuItemCounter <= 0) {
 		if (curMenuLine != -1)
 			setTextColorWhite();
 		displayCenteredString("No Skills To Select", 144, 310, 96);
@@ -5521,7 +5521,7 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 		return;
 	}
 
-	for (int16 counter = 0; counter < _word2D0BA; ++counter) {
+	for (int16 counter = 0; counter < _menuItemCounter; ++counter) {
 		if (counter == curMenuLine)
 			setTextColorWhite();
 		int16 textPosY = 38 + counter * 9;
@@ -5679,7 +5679,7 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 		int16 var2 = _items[itemId].field_18;
 		if (var2 != 4) {
 			for (int16 counter = 0; counter < 10; ++counter) {
-				if (var2 != _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
+				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
 					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
 			}
 		}
@@ -6317,7 +6317,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	debug("handleStatusMenu %d %d", gameMode, charId);
 
 	int16 menuId = 9;
-	int16 var16 = -1;
+	int16 selectedLine = -1;
 	int16 windowId = -1;
 	int16 curMenuLine = -1;
 	bool var10 = false;
@@ -6341,10 +6341,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			if (_menuDepth == 0) {
 				switch (var19) {
 				case Common::KEYCODE_ESCAPE:
-					if (_menuDepth == 0) { // ?? Useless case ?
-						windowId = 8;
-						var19 = Common::KEYCODE_RETURN;
-					}
+					windowId = 8;
+					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_a:
 					windowId = 7;
@@ -6388,9 +6386,10 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					break;
 				}
 			} else if (_menuDepth == 1) {
+				// in the sub-menus, only a list of selectable items is displayed
 				if (var19 >= Common::KEYCODE_a && var19 <= Common::KEYCODE_z) {
 					int16 var8 = var19 - Common::KEYCODE_a;
-					if (var8 < _word2D0BA) {
+					if (var8 < _menuItemCounter) {
 						curMenuLine = var8;
 						var19 = Common::KEYCODE_RETURN;
 					}
@@ -6410,13 +6409,13 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						curMenuLine = 0;
 					}
 				} else if (_menuDepth == 1) {
-					if (_word2D0BA == 0) {
+					if (_menuItemCounter == 0) {
 						_menuDepth = 0;
 						curMenuLine = -1;
 						menuId = 9;
 						unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 					} else {
-						var16 = curMenuLine;
+						selectedLine = curMenuLine;
 						var10 = true;
 					}
 				}
@@ -6439,9 +6438,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					if (++windowId > 8)
 						windowId = 0;
 				} else if (_menuDepth == 1) {
-					if (_word2D0BA != 0) {
+					if (_menuItemCounter != 0) {
 						++curMenuLine;
-						if (curMenuLine > _word2D0BA - 1)
+						if (curMenuLine > _menuItemCounter - 1)
 							curMenuLine = 0;
 					}
 				}
@@ -6458,10 +6457,10 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					if (--windowId < 0)
 						windowId = 8;
 				} else if (_menuDepth == 1) {
-					if (_word2D0BA != 0) {
+					if (_menuItemCounter != 0) {
 						--curMenuLine;
 						if (curMenuLine < 0)
-							curMenuLine = _word2D0BA - 1;
+							curMenuLine = _menuItemCounter - 1;
 					}
 				}
 				break;
@@ -6482,7 +6481,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		int16 itemId;
 		switch (menuId) {
 		case 0:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
 			if (gameMode == 2) {
@@ -6492,23 +6491,23 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 1:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (gameMode == 2) {
 				restoreAnimImageSetId();
 				_statusMenuActive = false;
 				return objectId;
-			} else {
-				if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
-					_statusMenuActive = false;
-					return -1;
-				} else {
-					sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
-				}
 			}
+
+			if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
+				_statusMenuActive = false;
+				return -1;
+			}
+
+			sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
 			break;
 		case 2:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -6534,7 +6533,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 			break;
 		case 3:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -6592,7 +6591,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 4:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -6619,7 +6618,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 5:
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
@@ -6631,7 +6630,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 6: // Identical to case 5?
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
@@ -6643,7 +6642,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 7: // Identical to case 5?
-			objectId = _word3273A[var16];
+			objectId = _word3273A[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
@@ -6662,7 +6661,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			var10 = false;
 			_menuDepth = 0;
 			menuId = 9;
-			var16 = -1;
+			selectedLine = -1;
 			curMenuLine = -1;
 		}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index fd289b17f1b..aeabc75f317 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -574,7 +574,7 @@ private:
 	bool _ongoingFightFl;
 	bool _statusMenuActive;
 	int16 _menuDepth;
-	int16 _word2D0BA;
+	int16 _menuItemCounter;
 	int16 _word32680[3];
 	int16 _word32482[3];
 	int16 _teamNextAttack[3];
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index f7f152064f3..ee23a0679e7 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -270,12 +270,25 @@ Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
 	Common::Event event;
 	_system->getEventManager()->pollEvent(event);
 	Common::KeyCode retVal = Common::KEYCODE_INVALID;
-	if (event.type == Common::EVENT_KEYUP) {
-		retVal = event.kbd.keycode;
-	}
 
-	if (animFl) {
-		warning("STUB - handleAndMapInput - animFl");
+	uint32 lastMs = _system->getMillis(); 
+	while (retVal == Common::KEYCODE_INVALID) {
+		_system->getEventManager()->pollEvent(event);
+
+		if (event.type == Common::EVENT_KEYUP) {
+			retVal = event.kbd.keycode;
+		}
+
+		if (animFl) {
+			_system->delayMillis(20);
+			uint32 newMs = _system->getMillis();
+
+			if (newMs - lastMs >= 200) {
+				lastMs = newMs;
+				unkFct_anim();
+			}
+		} else
+			break;
 	}
 	return retVal;
 }


Commit: 36a6700abf89fc8d992e6486ec7110890f0e0caf
    https://github.com/scummvm/scummvm/commit/36a6700abf89fc8d992e6486ec7110890f0e0caf
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Fix bug in combat system

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index abd0c4e3531..4d510eee043 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3801,7 +3801,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 						if (!var6)
 							continue;
 
-						if (var2 > computeMonsterGroupDistance(counter1))
+						if (computeMonsterGroupDistance(counter1) > var2)
 							continue;
 
 						if (sub1BC74(counter1, var4))


Commit: 43d189fd566dedc1a2ae8a6036ba265a933e97a2
    https://github.com/scummvm/scummvm/commit/43d189fd566dedc1a2ae8a6036ba265a933e97a2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Fix typo in the message about armor effect

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4d510eee043..79526ad3388 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -5195,7 +5195,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										if (damagePointsAbsorbed <= 1)
 											sprintf(buffer, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
 										else
-											sprintf(buffer, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+											sprintf(buffer, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
 
 										strcat((char *)_messageToBePrinted, buffer);
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;


Commit: c4c96555b48001f8f0f19c2729d1ffeb038c69af
    https://github.com/scummvm/scummvm/commit/c4c96555b48001f8f0f19c2729d1ffeb038c69af
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Add stubs for sound generation

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 79526ad3388..fa7445db21f 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -836,6 +836,9 @@ void EfhEngine::loadNPCS() {
 
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	warning("STUB: playSong");
+
+	
+	
 	_system->delayMillis(1000);
 	
 	return Common::KEYCODE_INVALID;
@@ -4162,8 +4165,59 @@ bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 	}
 }
 
+void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
+	warning("STUB: generateSound1 %d %d %d", arg0, arg2, duration);
+}
+
+void EfhEngine::generateSound2(int startFreq, int endFreq, int arg4) {
+	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, arg4);
+
+	// Arg4 doesn't seem to be used.
+}
+
+void EfhEngine::generateSound3() {
+	warning("STUB: generateSound3");
+}
+
+void EfhEngine::generateSound4(int arg0) {
+	warning("STUB: generateSound4 %d", arg0);
+}
+
+void EfhEngine::generateSound5(int arg0) {
+	warning("STUB: generateSound5 %d", arg0);
+}
+
 void EfhEngine::generateSound(int16 soundType) {
-	warning("STUB: generateSound");
+	switch (soundType) {
+		case 5:
+			generateSound3();
+			break;
+		case 9:
+			generateSound1(20, 888, 3000);
+			generateSound1(20, 888, 3000);
+			break;
+		case 10:
+			generateSound5(1);
+			break;
+		case 13:
+			generateSound2(256, 4096, 18);
+			break;
+		case 14:
+			generateSound2(20, 400, 100);
+			break;
+		case 15:
+			generateSound2(100, 888, 88);
+			break;
+		case 16:
+			generateSound1(2000, 6096, 1500);
+			break;
+		case 17:
+			generateSound4(1);
+			break;
+		default:
+			// Not implemented because not used by the engine
+			break;
+	}
 }
 
 void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index aeabc75f317..40307895f4c 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -387,6 +387,11 @@ private:
 	int16 sub1DEC8(int16 groupNumber);
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
+	void generateSound1(int arg0, int arg2, int duration);
+	void generateSound2(int startFreq, int endFreq, int arg4);
+	void generateSound3();
+	void generateSound4(int arg0);
+	void generateSound5(int arg0);
 	void generateSound(int16 soundType);
 	void genericGenerateSound(int16 soundType, int16 repeatCount);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
@@ -585,6 +590,7 @@ private:
 	Stru3244C _stru3244C[8];
 };
 
+
 } // End of namespace Efh
 
 #endif


Commit: 7f2c54998323c6db150aac50c7ec1cbf769e15d5
    https://github.com/scummvm/scummvm/commit/7f2c54998323c6db150aac50c7ec1cbf769e15d5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Fix compilation

Changed paths:
    engines/efh/detection.cpp
    engines/efh/efh.cpp


diff --git a/engines/efh/detection.cpp b/engines/efh/detection.cpp
index 439f8c54b4d..e58602b5e1c 100644
--- a/engines/efh/detection.cpp
+++ b/engines/efh/detection.cpp
@@ -69,12 +69,12 @@ public:
 	EfhMetaEngineDetection() : AdvancedMetaEngineDetection(gameDescriptions, sizeof(EfhGameDescription), efhGames) {
 	}
 
-	const char *getEngineId() const override {
-		return "efh";
+	const char *getEngineName() const override {
+		return "Efh";
 	}
 
 	const char *getName() const override {
-		return "Efh";
+		return "efh";
 	}
 
 	const char *getOriginalCopyright() const override {
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index fa7445db21f..a63e613305e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1330,11 +1330,11 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				copyString(_npcBuf[charId]._name, buffer);
 				setTextPos(16, textPosY);
 				displayStringAtTextPos(buffer);
-				sprintf(buffer, "%d", getEquipmentDefense(charId, false));
+				snprintf(buffer, 80, "%d", getEquipmentDefense(charId, false));
 				displayCenteredString(buffer, 104, 128, textPosY);
-				sprintf(buffer, "%d", _npcBuf[charId]._hitPoints);
+				snprintf(buffer, 80, "%d", _npcBuf[charId]._hitPoints);
 				displayCenteredString(buffer, 144, 176, textPosY);
-				sprintf(buffer, "%d", _npcBuf[charId]._maxHP);
+				snprintf(buffer, 80, "%d", _npcBuf[charId]._maxHP);
 				displayCenteredString(buffer, 192, 224, textPosY);
 
 				if (_npcBuf[charId]._hitPoints <= 0) {
@@ -1346,19 +1346,19 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				case 0: {
 					uint16 var4 = sub1C80A(charId, 9, true);
 					if (var4 == 0x7FFF)
-						strcpy(_nameBuffer, "(NONE)");
+						strncpy(_nameBuffer, "(NONE)", 20);
 					else
 						copyString(_items[var4]._name, _nameBuffer);
 					}
 					break;				
 				case 1:
-					strcpy(_nameBuffer, "* ASLEEP *");
+						strncpy(_nameBuffer, "* ASLEEP *", 20);
 					break;
 				case 2:
-					strcpy(_nameBuffer, "* FROZEN *");
+					strncpy(_nameBuffer, "* FROZEN *", 20);
 					break;
 				default:
-					strcpy(_nameBuffer, "* DISABLED *");
+					strncpy(_nameBuffer, "* DISABLED *", 20);
 					break;
 				}
 
@@ -1667,15 +1667,15 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 						displayStringAtTextPos(curLine);
 
 					*curLine = 0;
-					strcpy(curLine, nextWord);
-					strcat(curLine, " ");
+					strncpy(curLine, nextWord, 80);
+					strncat(curLine, " ",2);
 					++curLineNb;
 					setTextPos(posX, posY + curLineNb * 9);
 					curWordPos = 0;
 				}
 			} else {
-				strcat(curLine, nextWord);
-				strcat(curLine, " ");
+				strncat(curLine, nextWord, 80);
+				strncat(curLine, " ", 2);
 				curWordPos = 0;
 			}
 			++buffer;
@@ -1967,7 +1967,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 				} else {
 					copyString(_npcBuf[_teamCharId[counter]]._name, _enemyNamePt2);
 					copyString(_items[var110]._name, _nameBuffer);
-					sprintf(curLine, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
+					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
@@ -3120,7 +3120,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				displayMonsterAnim(monsterId);
 				copyString(_npcBuf[var58]._name, _enemyNamePt2);
 				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
-				sprintf(buffer, "%s asks that %s leave your party.", _enemyNamePt2, _characterNamePt2);
+				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2, _characterNamePt2);
 				for (int16 i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
 					_textColor = 0xE;
@@ -3894,12 +3894,12 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 
 		setTextPos(129, textPosY);
 		char buffer[80];
-		sprintf(buffer, "%c)", 'A' + counter);
+		snprintf(buffer, 80, "%c)", 'A' + counter);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
 		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
 		if (var1 <= 0x3D) {
-			sprintf(buffer, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
+			snprintf(buffer, 80, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
 			displayStringAtTextPos(buffer);
 			if (var6E > 1)
 				displayStringAtTextPos("s");
@@ -3945,7 +3945,7 @@ void EfhEngine::displayCombatMenu(int16 charId) {
 
 	char buffer[80];
 	copyString(_npcBuf[charId]._name, buffer);
-	strcat(buffer, ":");
+	strncat(buffer, ":", 2);
 	setTextColorWhite();
 	setTextPos(144, 7);
 	displayStringAtTextPos(buffer);
@@ -4008,7 +4008,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
 	copyString(_npcBuf[_teamCharId[charId]]._name, _enemyNamePt2);
 	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
-		strcpy(_enemyNamePt1, "The ");
+		strncpy(_enemyNamePt1, "The ", 5);
 	} else {
 		_enemyNamePt1[0] = 0;
 	}
@@ -4016,13 +4016,13 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	// End of effect message depends on the type of effect
 	switch (_teamCharStatus[charId]._status) {
 	case 1:
-		sprintf((char *)_messageToBePrinted, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
 		break;
 	case 2:
-		sprintf((char *)_messageToBePrinted, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
 		break;
 	default:
-		sprintf((char *)_messageToBePrinted, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
 		break;
 	}
 
@@ -4334,70 +4334,80 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	int16 rndDescrForDeathType = getRandom((3)) - 1;
 	char buffer[80];
 	memset(buffer, 0, 80);
-	sprintf(buffer, "DUDE IS TOAST!");
+	snprintf(buffer, 80, "DUDE IS TOAST!");
 	switch (deathType) {
 	case 0:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", killing %s!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", killing %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", slaughtering %s!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", slaughtering %s!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", annihilating %s!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", annihilating %s!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 1:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", cutting %s in two!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", cutting %s in two!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", dicing %s into small cubes!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", dicing %s into small cubes!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 2:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", piercing %s heart!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", popping %s like a zit!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", popping %s like a zit!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 3:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 4:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", totally incinerating %s!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", totally incinerating %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", leaving a blistered mass of flesh behind!");
+			snprintf(buffer, 80, ", leaving a blistered mass of flesh behind!");
+			break;
+		default:
 			break;
 		}
 		break;
@@ -4405,52 +4415,60 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		switch (rndDescrForDeathType) {
 		case 0:
 			// The original has a typo: popscicle
-			sprintf(buffer, ", turning %s into a popsicle!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", turning %s into a popsicle!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", shattering %s into shards!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", shattering %s into shards!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 6:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", leaving pudding for brains");
+			snprintf(buffer, 80, ", leaving pudding for brains");
 			break;
 		case 1:
-			sprintf(buffer, ", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 7:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 8:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", sucking %s into eternity!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", sucking %s into eternity!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
@@ -4459,13 +4477,15 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 11:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", completely disintegrating %s!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", completely disintegrating %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
@@ -4474,39 +4494,45 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 14:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", blowing %s brains out!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", blowing %s brains out!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 15:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", choking %s to death!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", choking %s to death!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", melting %s lungs!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", melting %s lungs!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
 	case 16:
 		switch (rndDescrForDeathType) {
 		case 0:
-			sprintf(buffer, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			sprintf(buffer, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", piercing %s heart!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			sprintf(buffer, ", impaling %s brain!", kPersonal[possessivePronoun]);
+			snprintf(buffer, 80, ", impaling %s brain!", kPersonal[possessivePronoun]);
+			break;
+		default:
 			break;
 		}
 		break;
@@ -4514,7 +4540,7 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		break;
 	}	
 
-	strcat((char *)_messageToBePrinted, buffer);
+	strncat((char *)_messageToBePrinted, buffer, 80);
 }
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
@@ -4535,8 +4561,8 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	char tmpString[20];
 	copyString(_items[itemId]._name, tmpString);
 	char buffer[80];
-	sprintf(buffer, " and finds a %s!", tmpString);
-	strcat((char *)_messageToBePrinted, buffer);
+	snprintf(buffer, 80, " and finds a %s!", tmpString);
+	strncat((char *)_messageToBePrinted, buffer, 80);
 	return true;
 }
 
@@ -4546,7 +4572,7 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2,
 	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 	char buffer[80];
-	sprintf(buffer, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
+	snprintf(buffer, 80, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
 	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
 		generateSound(15);
 		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
@@ -4558,9 +4584,9 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2,
 		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
 		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
 	}
-	strcat((char *)_messageToBePrinted, buffer);
+	strncat((char *)_messageToBePrinted, buffer, 80);
 	if (!characterSearchesMonsterCorpse(charId, monsterId))
-		strcat((char *)_messageToBePrinted, "!");
+		strncat((char *)_messageToBePrinted, "!", 2);
 	
 }
 
@@ -4575,13 +4601,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 0:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4590,13 +4616,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 1:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4605,13 +4631,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 2:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4620,13 +4646,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 3:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4635,13 +4661,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 4:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s screams!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s screams!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s bellows!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s bellows!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s shrills!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s shrills!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4650,13 +4676,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 5:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s chortles!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s chortles!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4665,13 +4691,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 6:
 		switch (rand3) {
 		case 1:
-			sprintf(buffer, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 2:
-			sprintf(buffer, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2);
 			break;
 		case 3:
-			sprintf(buffer, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2);
 			break;
 		default:
 			break;
@@ -4681,7 +4707,7 @@ void EfhEngine::addReactionText(int16 id) {
 		break;
 	}
 
-	strcat((char *)_messageToBePrinted, buffer);
+	strncat((char *)_messageToBePrinted, buffer, 80);
 }
 
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
@@ -4775,7 +4801,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (var62 > 0) {
 						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
 						if (var62 > 1) {
-							sprintf(_attackBuffer, "%d times ", var62);
+							snprintf(_attackBuffer, 20, "%d times ", var62);
 						} else {
 							*_attackBuffer = 0;
 						}
@@ -4783,41 +4809,41 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 					int16 var6A = getRandom(3) - 1;
 					if (var5E == 2) {
-						strcpy(_characterNamePt1, "The ");
+						strncpy(_characterNamePt1, "The ", 5);
 					} else {
 						*_characterNamePt1 = 0;
 					}
 
 					if (var70 == 2) {
-						strcpy(_enemyNamePt1, "The ");
+						strncpy(_enemyNamePt1, "The ", 5);
 					} else {
 						*_enemyNamePt1 = 0;
 					}
 
-					strcpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
+					strncpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name, 14);
 					copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
 					copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							sprintf((char *)_messageToBePrinted, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
 						} else if (hitPoints <= 0){
-							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
 						} else if (hitPoints == 1) {
-							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
-								strcat((char *)_messageToBePrinted, "!");
+								strncat((char *)_messageToBePrinted, "!", 2);
 							}
 						} else {
-							sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
-								strcat((char *)_messageToBePrinted, "!");
+								strncat((char *)_messageToBePrinted, "!", 2);
 							}
 						}
 						// Action A - Check damages - End
@@ -4848,16 +4874,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							char buffer[80];
 							memset(buffer, 0, 80);
 							if (damagePointsAbsorbed <= 1)
-								sprintf(buffer, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
 							else
-								sprintf(buffer, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+								snprintf(buffer, 80, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
 
-							strcat((char *)_messageToBePrinted, buffer);
+							strncat((char *)_messageToBePrinted, buffer, 80);
 						}
 						// Action A - Add armor absorb text - End
 
 						if (var5C)
-							strcat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...");
+							strncat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...", 400);
 
 						// Action A - Check item durability - Start
 						varInt = _teamCharId[teamCharId];
@@ -4868,8 +4894,8 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (var51 <= 0) {
 								char buffer[80];
 								memset(buffer, 0, 80);
-								sprintf(buffer, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer);
-								strcat((char *)_messageToBePrinted, buffer);
+								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer);
+								strncat((char *)_messageToBePrinted, buffer, 80);
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
 							} else {
@@ -4885,20 +4911,20 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 								_stru32686[var7E]._field2[groupId] = getRandom(10);
 								char buffer[80];
 								memset(buffer, 0, 80);
-								sprintf(buffer, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
-								strcat((char *)_messageToBePrinted, buffer);
+								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+								strncat((char *)_messageToBePrinted, buffer, 80);
 							}
 						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
 							_stru32686[var7E]._field0[groupId] = 2;
 							_stru32686[var7E]._field2[groupId] = getRandom(10);
 							char buffer[80];
 							memset(buffer, 0, 80);
-							sprintf(buffer, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
-							strcat((char *)_messageToBePrinted, buffer);
+							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+							strncat((char *)_messageToBePrinted, buffer, 80);
 						}
 						// Action A - Check effect - End
 					} else {
-						sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
@@ -4917,11 +4943,11 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
-		strcpy(_enemyNamePt1, "The ");
+		strncpy(_enemyNamePt1, "The ", 5);
 	else
 		*_enemyNamePt1 = 0;
 
-	sprintf((char *)_messageToBePrinted, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4936,11 +4962,11 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
-		strcpy(_enemyNamePt1, "The ");
+		strncpy(_enemyNamePt1, "The ", 5);
 	else
 		*_enemyNamePt1 = 0;
 
-	sprintf((char *)_messageToBePrinted, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4954,11 +4980,11 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
-		strcpy(_enemyNamePt1, "The ");
+		strncpy(_enemyNamePt1, "The ", 5);
 	else
 		*_enemyNamePt1 = 0;
 
-	sprintf((char *)_messageToBePrinted, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -5006,12 +5032,12 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 
 			if (var42 == 0) {
 				var42 = 1;
-				sprintf(buffer, ", but %s %s", kPossessive[var40], buffer2);
-				strcat((char *)_messageToBePrinted, buffer);
+				snprintf(buffer, 40, ", but %s %s", kPossessive[var40], buffer2);
+				strncat((char *)_messageToBePrinted, buffer, 40);
 			} else {
 				++var42;
-				sprintf(buffer, ", %s", buffer2);
-				strcat((char *)_messageToBePrinted, buffer);
+				snprintf(buffer, 40, ", %s", buffer2);
+				strncat((char *)_messageToBePrinted, buffer, 40);
 			}
 		}
 
@@ -5020,11 +5046,11 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	}
 
 	if (var42 == 0) {
-		strcat((char *)_messageToBePrinted, "!");
+		strncat((char *)_messageToBePrinted, "!", 2);
 	} else if (var42 > 1 || getFightMessageLastCharacter((char *)_messageToBePrinted) == 's' || getFightMessageLastCharacter((char *)_messageToBePrinted) == 'S') {
-		strcat((char *)_messageToBePrinted, " are destroyed!");
+		strncat((char *)_messageToBePrinted, " are destroyed!", 17);
 	} else {
-		strcat((char *)_messageToBePrinted, " is destroyed!");
+		strncat((char *)_messageToBePrinted, " is destroyed!", 16);
 	}
 }
 
@@ -5180,7 +5206,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (var62 > 0) {
 									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
 									if (var62 > 1)
-										sprintf(_attackBuffer, "%d times ", var62);
+										snprintf(_attackBuffer, 20, "%d times ", var62);
 									else
 										*_attackBuffer = 0;
 								}
@@ -5188,36 +5214,36 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 								int16 var6A = getRandom(3);
 								if (var5E == 2)
-									sprintf(_characterNamePt1, "The ");
+									snprintf(_characterNamePt1, 5, "The ");
 								else
 									*_characterNamePt1 = 0;
 
 								if (var7E == 2)
-									sprintf(_enemyNamePt1, "The ");
+									snprintf(_enemyNamePt1, 5, "The ");
 								else
 									*_enemyNamePt1 = 0;
 
-								strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name);
+								strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
 								copyString(_npcBuf[_teamCharId[var7E]]._name, _characterNamePt2);
 								copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										sprintf((char *)_messageToBePrinted, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
 									} else if (hitPoints <= 0) {
-										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
 									} else if (hitPoints == 1) {
-										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
-											strcat((char *)_messageToBePrinted, "!");
+											strncat((char *)_messageToBePrinted, "!", 2);
 									} else {
-										sprintf((char *)_messageToBePrinted, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
-											strcat((char *)_messageToBePrinted, "!");
+											strncat((char *)_messageToBePrinted, "!", 2);
 									}
 									// handleFight - check damages - End
 
@@ -5247,11 +5273,11 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										char buffer[80];
 										memset(buffer, 0, 80);
 										if (damagePointsAbsorbed <= 1)
-											sprintf(buffer, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
 										else
-											sprintf(buffer, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
 
-										strcat((char *)_messageToBePrinted, buffer);
+										strncat((char *)_messageToBePrinted, buffer, 80);
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;
 										sub1D8C2(_teamCharId[var7E], varInt);
 									}
@@ -5265,23 +5291,23 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											sprintf(buffer, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
-											strcat((char *)_messageToBePrinted, buffer);
+											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+											strncat((char *)_messageToBePrinted, buffer, 80);
 										}
 										break;
 									case 2:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 2;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											sprintf(buffer, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
-											strcat((char *)_messageToBePrinted, buffer);
+											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+											strncat((char *)_messageToBePrinted, buffer, 80);
 										}
 										break;
 									case 5:
 									case 6:
 										if (getRandom(100) < 20) {
-											sprintf(buffer, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2);
-											strcat((char *)_messageToBePrinted, buffer);
+											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2);
+											strncat((char *)_messageToBePrinted, buffer, 80);
 											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
 										}
 										break;
@@ -5290,7 +5316,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									} 
 									// handleFight - Check effect - end
 								} else {
-									sprintf((char *)_messageToBePrinted, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
@@ -5300,22 +5326,22 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
 						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
-							strcpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name);
+							strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
 							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
-								strcpy(_enemyNamePt1, "The ");
+								strncpy(_enemyNamePt1, "The ", 5);
 							else
 								*_enemyNamePt1 = 0;
 
 							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 							case 1:
-								sprintf((char *)_messageToBePrinted, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
 								break;
 							case 2:
-								sprintf((char *)_messageToBePrinted, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
 								break;
 							default:
-								sprintf((char *)_messageToBePrinted, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
 								break;
 							}
 							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
@@ -5349,7 +5375,7 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 mi
 		else
 			setTextColorGrey();
 
-		sprintf(buffer, "> %s <", str);
+		snprintf(buffer, 20,"> %s <", str);
 		displayCenteredString(buffer, minX, maxX, minY);
 		setTextColorRed();
 	} else {
@@ -5468,22 +5494,22 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	setTextPos(146, 27);
 	displayStringAtTextPos("Name: ");
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "Level: %d", getXPLevel(_npcBuf[npcId]._xp));
+	snprintf(buffer1, 40, "Level: %d", getXPLevel(_npcBuf[npcId]._xp));
 	setTextPos(146, 36);
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "XP: %lu", _npcBuf[npcId]._xp);
+	snprintf(buffer1, 40, "XP: %lu", _npcBuf[npcId]._xp);
 	setTextPos(227, 36);
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "Speed: %d", _npcBuf[npcId]._speed);
+	snprintf(buffer1, 40, "Speed: %d", _npcBuf[npcId]._speed);
 	setTextPos(146, 45);
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "Defense: %d", getEquipmentDefense(npcId, false));
+	snprintf(buffer1, 40, "Defense: %d", getEquipmentDefense(npcId, false));
 	setTextPos(146, 54);
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "Hit Points: %d", _npcBuf[npcId]._hitPoints);
+	snprintf(buffer1, 40, "Hit Points: %d", _npcBuf[npcId]._hitPoints);
 	setTextPos(146, 63);
 	displayStringAtTextPos(buffer1);
-	sprintf(buffer1, "Max HP: %d", _npcBuf[npcId]._maxHP);
+	snprintf(buffer1, 40, "Max HP: %d", _npcBuf[npcId]._maxHP);
 	setTextPos(227, 63);
 	displayStringAtTextPos(buffer1);
 	displayCenteredString("Inventory", 144, 310, 72);
@@ -5515,16 +5541,16 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 
 		setTextPos(152, textPosY);
 		if (counter == curMenuLine) {
-			sprintf(buffer1, "%c>", 'A' + counter);
+			snprintf(buffer1, 40, "%c>", 'A' + counter);
 		} else {
-			sprintf(buffer1, "%c)", 'A' + counter);
+			snprintf(buffer1, 40, "%c)", 'A' + counter);
 		}
 		displayStringAtTextPos(buffer1);
 
 		if (itemId != 0x7FFF) {
 			setTextPos(168, textPosY);
 			copyString(_items[itemId]._name, buffer2);
-			sprintf(buffer1, "  %s", buffer2);
+			snprintf(buffer1, 40, "  %s", buffer2);
 			displayStringAtTextPos(buffer1);
 			setTextPos(262, textPosY);
 
@@ -5534,7 +5560,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 					// useless?
 					var54 = _items[_npcBuf[npcId]._inventory[_word3273A[counter]]._ref]._defense;
 				} else {
-					sprintf(buffer1, "%d", 1 + var54 / 8);
+					snprintf(buffer1, 40, "%d", 1 + var54 / 8);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					displayStringAtTextPos("Def");
@@ -5542,7 +5568,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 			} else if (_items[itemId]._uses != 0x7F) {
 				int16 var52 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat1;
 				if (var52 != 0x7F) {
-					sprintf(buffer1, "%d", var52);
+					snprintf(buffer1, 40, "%d", var52);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					if (var52 == 1)
@@ -5581,15 +5607,15 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 		int16 textPosY = 38 + counter * 9;
 		setTextPos(146, textPosY);
 		if (counter == curMenuLine) {
-			sprintf(buffer, "%c>", 'A' + counter);
+			snprintf(buffer, 40, "%c>", 'A' + counter);
 		} else {
-			sprintf(buffer, "%c)", 'A' + counter);
+			snprintf(buffer, 40, "%c)", 'A' + counter);
 		}
 
 		displayStringAtTextPos(buffer);
 		setTextPos(163, textPosY);
 		displayStringAtTextPos(kSkillArray[_word3273A[counter]]);
-		sprintf(buffer, "%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
+		snprintf(buffer, 40, "%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
 		setTextPos(278, textPosY);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
@@ -5812,7 +5838,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			int16 victims = 0;
-			strcat((char *)_messageToBePrinted, "  The item emits a low droning hum...");
+			strncat((char *)_messageToBePrinted, "  The item emits a low droning hum...", 400);
 			if (getRandom(100) < 50) {
 				for (int16 counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
@@ -5837,11 +5863,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			}
 			// The original was duplicating this code in each branch of the previous random check. 
 			if (victims > 1) {
-				sprintf(buffer1, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				snprintf(buffer1, 80, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				snprintf(buffer1, 80, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 400);
 		}
 
 		varA6 = true;
@@ -5850,7 +5876,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, "  The item emits a blue beam...");
+			strncat((char *)_messageToBePrinted, "  The item emits a blue beam...", 400);
 			int16 victim = 0;
 			if (getRandom(100) < 50) {
 				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
@@ -5877,11 +5903,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				sprintf(buffer1, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				snprintf(buffer1, 80, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				sprintf(buffer1, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				snprintf(buffer1, 80, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 			// </CHECKME>
 		}
 
@@ -5891,7 +5917,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, "  The combat pauses...as there is a moment of forgiveness...");
+			strncat((char *)_messageToBePrinted, "  The combat pauses...as there is a moment of forgiveness...", 400);
 			_unkArray2C8AA[0] = 0;
 		}
 
@@ -5901,7 +5927,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!");
+			strncat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!", 400);
 			if (getRandom(100) < 50) {
 				for (int16 counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
@@ -5926,12 +5952,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			if (getRandom(100) < 50) {
-				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!");
+				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!", 400);
 				for (int16 counter = 0; counter < 9; ++counter) {
 					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 				}
 			} else {
-				strcat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!");
+				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!", 400);
 				for (int16 counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
@@ -5946,7 +5972,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, "  The magic sparkles brilliant hues in the air!");
+			strncat((char *)_messageToBePrinted, "  The magic sparkles brilliant hues in the air!", 400);
 			sub1E028(windowId, _items[itemId].field17_attackTypeDefense, true);
 		}
 		varA6 = true;
@@ -5961,11 +5987,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (varAA != 0x1B) {
-			strcpy(buffer1, "  The magic makes the user as quick and agile as a bird!");
+			strncpy(buffer1, "  The magic makes the user as quick and agile as a bird!", 80);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 			}
 			_word32482[varAA] -= 50;
 			if (_word32482[varAA] < 0)
@@ -5985,11 +6011,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (teamCharId != 0x1B) {
-			strcpy(buffer1, "  The magic makes the user invisible!");
+			strncpy(buffer1, "  The magic makes the user invisible!", 80);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine); 
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 			}
 
 			_word32680[teamCharId] -= 50;
@@ -6009,29 +6035,29 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
-			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
+			strncpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !", 80);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
 			if (varAE == 0 || varAE == 0x48) {
-				strcpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!");
+				strncpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!", 80);
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strcat((char *)_messageToBePrinted, buffer1);
+					strncat((char *)_messageToBePrinted, buffer1, 80);
 					retVal = true;
 				}
 			} else {
-				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
+				strncpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!", 80);
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strcat((char *)_messageToBePrinted, buffer1);
+					strncat((char *)_messageToBePrinted, buffer1, 80);
 					retVal = true;
 				}
 			}
@@ -6046,29 +6072,29 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		int16 varAE = sub15538(_mapPosX, _mapPosY);
 		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
-			strcpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !");
+			strncpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !", 80);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
 			if (varAE == 0 || varAE == 0x48) {
-				strcpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!");
+				strncpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!", 80);
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strcat((char *)_messageToBePrinted, buffer1);
+					strncat((char *)_messageToBePrinted, buffer1, 80);
 					retVal = true;
 				}
 			} else {
-				strcpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!");
+				strncpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!",80);
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strcat((char *)_messageToBePrinted, buffer1);
+					strncat((char *)_messageToBePrinted, buffer1, 80);
 					retVal = true;
 				}
 			}
@@ -6084,11 +6110,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 teamCharId = windowId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
-					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
+					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!", 80);
 					_teamCharStatus[teamCharId]._status = 0;
 					_teamCharStatus[teamCharId]._duration = 0;
 				} else {
-					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
+					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!", 80);
 				}
 			}
 		}
@@ -6096,48 +6122,48 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		break;
 	case 19: // "Junk"
-		strcpy(buffer1, "  * The item breaks!");
+		strncpy(buffer1, "  * The item breaks!", 80);
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 		}
 		setCharacterObjectToBroken(charId, objectId);
 		varA6 = true;
 		break;
 	case 23: // "Divining Rod"
 		copyString(_items[itemId]._name, buffer2);
-		sprintf(buffer1, "The %s says, '", buffer2);
+		snprintf(buffer1, 80, "The %s says, '", buffer2);
 		if (_items[itemId].field_19 < _mapPosX) {
 			if (_items[itemId].field_1A < _mapPosY) {
-				strcat(buffer1, "North West!");
+				strncat(buffer1, "North West!", 80);
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strcat(buffer1, "South West!");
+				strncat(buffer1, "South West!", 80);
 			} else {
-				strcat(buffer1, "West!");
+				strncat(buffer1, "West!", 80);
 			}
 		} else if (_items[itemId].field_19 > _mapPosX) {
 			if (_items[itemId].field_1A < _mapPosY) {
-				strcat(buffer1, "North East!");
+				strncat(buffer1, "North East!", 80);
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strcat(buffer1, "South East!");
+				strncat(buffer1, "South East!", 80);
 			} else {
-				strcat(buffer1, "East!");
+				strncat(buffer1, "East!", 80);
 			}
 		} else { // equals _mapPosX
 			if (_items[itemId].field_1A < _mapPosY) {
-				strcat(buffer1, "North!");
+				strncat(buffer1, "North!", 80);
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strcat(buffer1, "South!");
+				strncat(buffer1, "South!", 80);
 			} else {
-				strcat(buffer1, "Here!!!");
+				strncat(buffer1, "Here!!!",80);
 			}
 		}
-		strcat(buffer1, "'");
+		strncat(buffer1, "'", 2);
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 			retVal = true;
 		}
 
@@ -6159,14 +6185,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
 			}
 			if (effectPoints > 1)
-				sprintf(buffer1, "%s increased %d points!", kSkillArray[varAE], effectPoints);
+				snprintf(buffer1, 80, "%s increased %d points!", kSkillArray[varAE], effectPoints);
 			else
-				sprintf(buffer1, "%s increased 1 point!", kSkillArray[varAE]);
+				snprintf(buffer1, 80, "%s increased 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 				retVal = true;
 			}
 		}
@@ -6190,14 +6216,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
 			}
 			if (effectPoints > 1)
-				sprintf(buffer1, "%s lowered %d points!", kSkillArray[varAE], effectPoints);
+				snprintf(buffer1, 80, "%s lowered %d points!", kSkillArray[varAE], effectPoints);
 			else
-				sprintf(buffer1, "%s lowered 1 point!", kSkillArray[varAE]);
+				snprintf(buffer1, 80, "%s lowered 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 				retVal = true;
 			}
 		}
@@ -6206,11 +6232,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		break;
 	case 26: // "Black Sphere"
-		strcpy(buffer1, "The entire party collapses, dead!!!");
+		strncpy(buffer1, "The entire party collapses, dead!!!", 80);
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 			retVal = true;
 		}
 		totalPartyKill();
@@ -6229,11 +6255,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (teamCharId != 0x1B) {
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
-			sprintf(buffer1, "%s collapses, dead!!!", buffer2);
+			snprintf(buffer1, 80, "%s collapses, dead!!!", buffer2);
 			if (argA == 2) {
 				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strcat((char *)_messageToBePrinted, buffer1);
+				strncat((char *)_messageToBePrinted, buffer1, 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
@@ -6249,11 +6275,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 teamCharId = windowId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 0) {
-					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!");
+					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!", 80);
 					_teamCharStatus[teamCharId]._status = 0;
 					_teamCharStatus[teamCharId]._duration = 0; 
 				} else {
-					strcat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!");
+					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!", 80);
 				}
 			}
 		}
@@ -6277,15 +6303,15 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
 			if (varAE > 1)
-				sprintf(buffer1, "%s is healed %d points!", buffer2, varAE);
+				snprintf(buffer1, 80, "%s is healed %d points!", buffer2, varAE);
 			else
-				sprintf(buffer1, "%s is healed 1 point!", buffer2);
+				snprintf(buffer1, 80, "%s is healed 1 point!", buffer2);
 		}
 
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 			retVal = true;
 		}
 
@@ -6309,15 +6335,15 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
 			if (varAE > 1)
-				sprintf(buffer1, "%s is harmed for %d points!", buffer2, varAE);
+				snprintf(buffer1, 80, "%s is harmed for %d points!", buffer2, varAE);
 			else
-				sprintf(buffer1, "%s is harmed for 1 point!", buffer2);
+				snprintf(buffer1, 80, "%s is harmed for 1 point!", buffer2);
 		}
 
 		if (argA == 2) {
 			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strcat((char *)_messageToBePrinted, buffer1);
+			strncat((char *)_messageToBePrinted, buffer1, 80);
 			retVal = true;
 		}
 
@@ -6344,12 +6370,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
 			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
 			if (varA1 <= 0) {
-				strcpy(buffer1, "  * The item breaks!");
+				strncpy(buffer1, "  * The item breaks!", 80);
 				if (argA == 2) {
 					Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strcat((char *)_messageToBePrinted, buffer1);
+					strncat((char *)_messageToBePrinted, buffer1, 80);
 				}
 				setCharacterObjectToBroken(charId, objectId);
 			} else {
@@ -6770,17 +6796,17 @@ bool EfhEngine::checkMonsterCollision() {
 			for (int16 var6C = 0; var6C < 2; ++var6C) {
 				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 				if (var1 <= 0x3D) {
-					strcpy(dest, kEncounters[_mapMonsters[monsterId]._monsterRef]._name);
+					strncpy(dest, kEncounters[_mapMonsters[monsterId]._monsterRef]._name, 80);
 					if (var6A > 1)
-						strcat(dest, " ");
+						strncat(dest, " ", 2);
 
-					sprintf(buffer, "with %d %s", var6A, dest);
+					snprintf(buffer, 80, "with %d %s", var6A, dest);
 				} else if (var1 == 0x3E) {
-					strcpy(buffer, "(NOT DEFINED)");
+					strncpy(buffer, "(NOT DEFINED)", 80);
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
 					// Special character name
 					copyString(_npcBuf[_mapMonsters[monsterId]._field_1]._name, dest);
-					sprintf(buffer, "with %s", dest);
+					snprintf(buffer, 80, "with %s", dest);
 				}
 
 				clearBottomTextZone(0);
@@ -6791,13 +6817,13 @@ bool EfhEngine::checkMonsterCollision() {
 				setTextColorWhite();
 				displayStringAtTextPos("T");
 				setTextColorRed();
-				sprintf(buffer, "alk to the %s", dest);
+				snprintf(buffer, 80, "alk to the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(24, 178);
 				setTextColorWhite();
 				displayStringAtTextPos("A");
 				setTextColorRed();
-				sprintf(buffer, "ttack the %s", dest);
+				snprintf(buffer, 80, "ttack the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(198, 169);
 				setTextColorWhite();


Commit: 1043a315a9c86fec58063d3214df96bd37305937
    https://github.com/scummvm/scummvm/commit/1043a315a9c86fec58063d3214df96bd37305937
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Turn _nameBuffer into a Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a63e613305e..6f02e819b02 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -235,7 +235,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_characterNamePt2, 0, 20);
 	memset(_enemyNamePt1, 0, 5);
 	memset(_enemyNamePt2, 0, 20);
-	memset(_nameBuffer, 0, 20);
+	_nameBuffer = "";
 	memset(_attackBuffer, 0, 20);
 
 	for (int i = 0; i < 100; ++i) {
@@ -1346,23 +1346,23 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				case 0: {
 					uint16 var4 = sub1C80A(charId, 9, true);
 					if (var4 == 0x7FFF)
-						strncpy(_nameBuffer, "(NONE)", 20);
+						_nameBuffer = "(NONE)";
 					else
-						copyString(_items[var4]._name, _nameBuffer);
+						snprintf(_items[var4]._name, 15, "%s", _nameBuffer.c_str());
 					}
 					break;				
 				case 1:
-						strncpy(_nameBuffer, "* ASLEEP *", 20);
+					_nameBuffer = "* ASLEEP *";
 					break;
 				case 2:
-					strncpy(_nameBuffer, "* FROZEN *", 20);
+					_nameBuffer = "* FROZEN *";
 					break;
 				default:
-					strncpy(_nameBuffer, "* DISABLED *", 20);
+					_nameBuffer = "* DISABLED *";
 					break;
 				}
 
-				displayCenteredString(_nameBuffer, 225, 302, textPosY);
+				displayCenteredString(_nameBuffer.c_str(), 225, 302, textPosY);
 			}
 		}
 
@@ -1965,9 +1965,9 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
-					copyString(_npcBuf[_teamCharId[counter]]._name, _enemyNamePt2);
-					copyString(_items[var110]._name, _nameBuffer);
-					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2, _nameBuffer);
+					snprintf(_npcBuf[_teamCharId[counter]]._name, 11, "%s", _enemyNamePt2);
+					snprintf(_items[var110]._name, 15, "%s", _nameBuffer.c_str());
+					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2, _nameBuffer.c_str());
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
@@ -4809,28 +4809,28 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 					int16 var6A = getRandom(3) - 1;
 					if (var5E == 2) {
-						strncpy(_characterNamePt1, "The ", 5);
+						snprintf(_characterNamePt1, 5, "The ");
 					} else {
 						*_characterNamePt1 = 0;
 					}
 
 					if (var70 == 2) {
-						strncpy(_enemyNamePt1, "The ", 5);
+						snprintf(_enemyNamePt1, 5, "The ");
 					} else {
 						*_enemyNamePt1 = 0;
 					}
 
-					strncpy(_characterNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name, 14);
-					copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
-					copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+					snprintf(_characterNamePt2, 20, "%s", kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
+					snprintf(_npcBuf[_teamCharId[teamCharId]]._name, 11, "%s", _enemyNamePt2);
+					snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0){
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -4838,7 +4838,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
 						} else {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -4894,7 +4894,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (var51 <= 0) {
 								char buffer[80];
 								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer);
+								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer.c_str());
 								strncat((char *)_messageToBePrinted, buffer, 80);
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
@@ -4924,7 +4924,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						}
 						// Action A - Check effect - End
 					} else {
-						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
@@ -4976,15 +4976,15 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
-	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
-	copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+	snprintf(_npcBuf[_teamCharId[teamCharId]]._name, 11, "%s", _enemyNamePt2);
+	snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
-		strncpy(_enemyNamePt1, "The ", 5);
+		snprintf(_enemyNamePt1, 5, "The ");
 	else
 		*_enemyNamePt1 = 0;
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -5224,22 +5224,22 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									*_enemyNamePt1 = 0;
 
 								strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
-								copyString(_npcBuf[_teamCharId[var7E]]._name, _characterNamePt2);
-								copyString(_items[unk_monsterField5_itemId]._name, _nameBuffer);
+								snprintf(_npcBuf[_teamCharId[var7E]]._name, 11, "%s", _characterNamePt2);
+								snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											strncat((char *)_messageToBePrinted, "!", 2);
 									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer, hitPoints);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -5316,7 +5316,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									} 
 									// handleFight - Check effect - end
 								} else {
-									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer);
+									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 40307895f4c..80941c2b3fb 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -511,7 +511,7 @@ private:
 	char _enemyNamePt2[20];
 	char _characterNamePt1[5];
 	char _characterNamePt2[20];
-	char _nameBuffer[20];
+	Common::String _nameBuffer;
 	char _attackBuffer[20];
 	uint8 _messageToBePrinted[400];
 	


Commit: 27b7beae68adb5b0428daa93fe0d209a9183f5fc
    https://github.com/scummvm/scummvm/commit/27b7beae68adb5b0428daa93fe0d209a9183f5fc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Fixa couple of previously usages of "copystring"

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6f02e819b02..d519e0ef4e5 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1348,7 +1348,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					if (var4 == 0x7FFF)
 						_nameBuffer = "(NONE)";
 					else
-						snprintf(_items[var4]._name, 15, "%s", _nameBuffer.c_str());
+						_nameBuffer = _items[var4]._name;
 					}
 					break;				
 				case 1:
@@ -1965,8 +1965,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
-					snprintf(_npcBuf[_teamCharId[counter]]._name, 11, "%s", _enemyNamePt2);
-					snprintf(_items[var110]._name, 15, "%s", _nameBuffer.c_str());
+					snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[counter]]._name);
+					_nameBuffer = _items[var110]._name;
 					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2, _nameBuffer.c_str());
 					drawMapWindow();
 					displayFctFullScreen();
@@ -4821,8 +4821,8 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					}
 
 					snprintf(_characterNamePt2, 20, "%s", kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
-					snprintf(_npcBuf[_teamCharId[teamCharId]]._name, 11, "%s", _enemyNamePt2);
-					snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
+					snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[teamCharId]]._name);
+					_nameBuffer = _items[unk_monsterField5_itemId]._name;
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
@@ -4976,8 +4976,8 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
-	snprintf(_npcBuf[_teamCharId[teamCharId]]._name, 11, "%s", _enemyNamePt2);
-	snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
+	snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[teamCharId]]._name);
+	_nameBuffer = _items[unk_monsterField5_itemId]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
 		snprintf(_enemyNamePt1, 5, "The ");
@@ -5224,8 +5224,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									*_enemyNamePt1 = 0;
 
 								strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
-								snprintf(_npcBuf[_teamCharId[var7E]]._name, 11, "%s", _characterNamePt2);
-								snprintf(_items[unk_monsterField5_itemId]._name, 15, "%s", _nameBuffer.c_str());
+								snprintf(_characterNamePt2, 11, "%s", _npcBuf[_teamCharId[var7E]]._name);
+								_nameBuffer = _items[unk_monsterField5_itemId]._name;
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {


Commit: c6bd02fb8ee86aaa79ff5a9bb1765c7324ef6b06
    https://github.com/scummvm/scummvm/commit/c6bd02fb8ee86aaa79ff5a9bb1765c7324ef6b06
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Turn _enemyNamePt2 into a Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d519e0ef4e5..aa99d22aa67 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -234,7 +234,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_characterNamePt1, 0, 5);
 	memset(_characterNamePt2, 0, 20);
 	memset(_enemyNamePt1, 0, 5);
-	memset(_enemyNamePt2, 0, 20);
+	_enemyNamePt2= "";
 	_nameBuffer = "";
 	memset(_attackBuffer, 0, 20);
 
@@ -1327,7 +1327,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					continue;
 				int16 charId = _teamCharId[i];
 				int16 textPosY = 161 + 9 * i;
-				copyString(_npcBuf[charId]._name, buffer);
+				snprintf(buffer, 11, "%s", _npcBuf[charId]._name);
 				setTextPos(16, textPosY);
 				displayStringAtTextPos(buffer);
 				snprintf(buffer, 80, "%d", getEquipmentDefense(charId, false));
@@ -1965,9 +1965,9 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
-					snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[counter]]._name);
+					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
 					_nameBuffer = _items[var110]._name;
-					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2, _nameBuffer.c_str());
+					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
@@ -3118,9 +3118,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		for (int16 counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
-				copyString(_npcBuf[var58]._name, _enemyNamePt2);
+				_enemyNamePt2 = _npcBuf[var58]._name;
 				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
-				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2, _characterNamePt2);
+				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2);
 				for (int16 i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
 					_textColor = 0xE;
@@ -4006,7 +4006,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 		return;
 
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
-	copyString(_npcBuf[_teamCharId[charId]]._name, _enemyNamePt2);
+	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
 	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
 		strncpy(_enemyNamePt1, "The ", 5);
 	} else {
@@ -4016,13 +4016,13 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	// End of effect message depends on the type of effect
 	switch (_teamCharStatus[charId]._status) {
 	case 1:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2.c_str());
 		break;
 	case 2:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2.c_str());
 		break;
 	default:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2.c_str());
 		break;
 	}
 
@@ -4821,19 +4821,19 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					}
 
 					snprintf(_characterNamePt2, 20, "%s", kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
-					snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[teamCharId]]._name);
+					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 					_nameBuffer = _items[unk_monsterField5_itemId]._name;
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0){
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
 							} else {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
@@ -4841,7 +4841,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
 							} else {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
@@ -4894,7 +4894,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (var51 <= 0) {
 								char buffer[80];
 								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2, _nameBuffer.c_str());
+								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2.c_str(), _nameBuffer.c_str());
 								strncat((char *)_messageToBePrinted, buffer, 80);
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
@@ -4924,7 +4924,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						}
 						// Action A - Check effect - End
 					} else {
-						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
+						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
@@ -4939,7 +4939,7 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	debug("handleFight_lastAction_D %d", teamCharId);
 
 	_word32482[teamCharId] -= 40;
-	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
@@ -4947,7 +4947,7 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	else
 		*_enemyNamePt1 = 0;
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4958,7 +4958,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	// It has been split for readability purposes.
 
 	_word32680[teamCharId] -= 50;
-	copyString(_npcBuf[_teamCharId[teamCharId]]._name, _enemyNamePt2);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
@@ -4966,7 +4966,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	else
 		*_enemyNamePt1 = 0;
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2, kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4976,7 +4976,7 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
-	snprintf(_enemyNamePt2, 11, "%s", _npcBuf[_teamCharId[teamCharId]]._name);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	_nameBuffer = _items[unk_monsterField5_itemId]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
@@ -4984,7 +4984,7 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	else
 		*_enemyNamePt1 = 0;
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
+	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -5223,23 +5223,23 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								else
 									*_enemyNamePt1 = 0;
 
-								strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
+								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 								snprintf(_characterNamePt2, 11, "%s", _npcBuf[_teamCharId[var7E]]._name);
 								_nameBuffer = _items[unk_monsterField5_itemId]._name;
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											strncat((char *)_messageToBePrinted, "!", 2);
 									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -5316,7 +5316,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									} 
 									// handleFight - Check effect - end
 								} else {
-									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2, kPossessive[var70], _nameBuffer.c_str());
+									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
@@ -5326,7 +5326,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
 						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
-							strncpy(_enemyNamePt2, kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name, 20);
+							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
 								strncpy(_enemyNamePt1, "The ", 5);
@@ -5335,13 +5335,13 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 							case 1:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2.c_str());
 								break;
 							case 2:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2.c_str());
 								break;
 							default:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2);
+								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2.c_str());
 								break;
 							}
 							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 80941c2b3fb..77bcf1b1e71 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -464,6 +464,9 @@ private:
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 
 	// Utils
+	#if true
+	void copyString(char *srcStr, char *destStr);
+	#endif
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
@@ -478,7 +481,6 @@ private:
 	Common::KeyCode handleAndMapInput(bool animFl);
 	Common::KeyCode getInputBlocking();
 	void setNumLock();
-	void copyString(char *srcStr, char *destStr);
 	bool getValidationFromUser();
 
 
@@ -508,7 +510,7 @@ private:
 	uint8 _history[256];
 	uint8 _techData[4096];
 	char _enemyNamePt1[5];
-	char _enemyNamePt2[20];
+	Common::String _enemyNamePt2;
 	char _characterNamePt1[5];
 	char _characterNamePt2[20];
 	Common::String _nameBuffer;


Commit: 3ca7a67c1ea82302825d0b6cd4578c3dd5b0ca7b
    https://github.com/scummvm/scummvm/commit/3ca7a67c1ea82302825d0b6cd4578c3dd5b0ca7b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Turn _characterNamePt2 into a Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index aa99d22aa67..b0690260577 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -232,7 +232,7 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	}
 
 	memset(_characterNamePt1, 0, 5);
-	memset(_characterNamePt2, 0, 20);
+	_characterNamePt2 = "";
 	memset(_enemyNamePt1, 0, 5);
 	_enemyNamePt2= "";
 	_nameBuffer = "";
@@ -3119,8 +3119,8 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[var58]._name;
-				copyString(_npcBuf[_teamCharId[counter]]._name, _characterNamePt2);
-				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2);
+				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
+				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
 				for (int16 i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
 					_textColor = 0xE;
@@ -4601,13 +4601,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 0:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4616,13 +4616,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 1:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4631,13 +4631,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 2:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4646,13 +4646,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 3:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4661,13 +4661,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 4:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s screams!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s screams!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s bellows!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s bellows!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s shrills!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s shrills!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4676,13 +4676,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 5:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s chortles!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s chortles!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4691,13 +4691,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 6:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2);
+			snprintf(buffer, 80, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -4820,17 +4820,17 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						*_enemyNamePt1 = 0;
 					}
 
-					snprintf(_characterNamePt2, 20, "%s", kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name);
+					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
 					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 					_nameBuffer = _items[unk_monsterField5_itemId]._name;
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0){
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
@@ -4838,7 +4838,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
 						} else {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2, kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
@@ -4874,9 +4874,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							char buffer[80];
 							memset(buffer, 0, 80);
 							if (damagePointsAbsorbed <= 1)
-								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
 							else
-								snprintf(buffer, 80, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+								snprintf(buffer, 80, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 							strncat((char *)_messageToBePrinted, buffer, 80);
 						}
@@ -4911,7 +4911,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 								_stru32686[var7E]._field2[groupId] = getRandom(10);
 								char buffer[80];
 								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
 								strncat((char *)_messageToBePrinted, buffer, 80);
 							}
 						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
@@ -4919,7 +4919,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							_stru32686[var7E]._field2[groupId] = getRandom(10);
 							char buffer[80];
 							memset(buffer, 0, 80);
-							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
 							strncat((char *)_messageToBePrinted, buffer, 80);
 						}
 						// Action A - Check effect - End
@@ -5224,22 +5224,22 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									*_enemyNamePt1 = 0;
 
 								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-								snprintf(_characterNamePt2, 11, "%s", _npcBuf[_teamCharId[var7E]]._name);
+								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
 								_nameBuffer = _items[unk_monsterField5_itemId]._name;
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											strncat((char *)_messageToBePrinted, "!", 2);
 									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2, _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -5273,9 +5273,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										char buffer[80];
 										memset(buffer, 0, 80);
 										if (damagePointsAbsorbed <= 1)
-											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2);
+											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
 										else
-											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2, damagePointsAbsorbed);
+											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 										strncat((char *)_messageToBePrinted, buffer, 80);
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;
@@ -5291,7 +5291,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2);
+											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
 											strncat((char *)_messageToBePrinted, buffer, 80);
 										}
 										break;
@@ -5299,14 +5299,14 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 2;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2);
+											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
 											strncat((char *)_messageToBePrinted, buffer, 80);
 										}
 										break;
 									case 5:
 									case 6:
 										if (getRandom(100) < 20) {
-											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2);
+											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
 											strncat((char *)_messageToBePrinted, buffer, 80);
 											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
 										}
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 77bcf1b1e71..9d237900a39 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -512,7 +512,7 @@ private:
 	char _enemyNamePt1[5];
 	Common::String _enemyNamePt2;
 	char _characterNamePt1[5];
-	char _characterNamePt2[20];
+	Common::String _characterNamePt2;
 	Common::String _nameBuffer;
 	char _attackBuffer[20];
 	uint8 _messageToBePrinted[400];


Commit: 8008d096bcbfcb29fa4ee61617c4b1eafb411c2f
    https://github.com/scummvm/scummvm/commit/8008d096bcbfcb29fa4ee61617c4b1eafb411c2f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:39+01:00

Commit Message:
EFH: Turn _characterNamePt1 into a Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b0690260577..252977caa22 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -233,8 +233,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	memset(_characterNamePt1, 0, 5);
 	_characterNamePt2 = "";
-	memset(_enemyNamePt1, 0, 5);
-	_enemyNamePt2= "";
+	_enemyNamePt1 = "";
+	_enemyNamePt2 = "";
 	_nameBuffer = "";
 	memset(_attackBuffer, 0, 20);
 
@@ -4008,21 +4008,21 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
 	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
 	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
-		strncpy(_enemyNamePt1, "The ", 5);
+		_enemyNamePt1 = "The ";
 	} else {
-		_enemyNamePt1[0] = 0;
+		_enemyNamePt1 = "";
 	}
 
 	// End of effect message depends on the type of effect
 	switch (_teamCharStatus[charId]._status) {
 	case 1:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2.c_str());
+		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	case 2:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2.c_str());
+		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	default:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2.c_str());
+		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	}
 
@@ -4566,13 +4566,13 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	return true;
 }
 
-void EfhEngine::getXPAndSearchCorpse(int16 charId, char *namePt1, char *namePt2, int16 monsterId) {
-	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1, namePt2, monsterId);
+void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
+	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
 
 	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 	char buffer[80];
-	snprintf(buffer, 80, "  %s%s gains %d experience", namePt1, namePt2, kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
+	snprintf(buffer, 80, "  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
 	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
 		generateSound(15);
 		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
@@ -4815,9 +4815,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					}
 
 					if (var70 == 2) {
-						snprintf(_enemyNamePt1, 5, "The ");
+						_enemyNamePt1 = "The ";
 					} else {
-						*_enemyNamePt1 = 0;
+						_enemyNamePt1 = "";
 					}
 
 					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
@@ -4826,22 +4826,22 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0){
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
 						} else {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, (char *)_enemyNamePt2.c_str(), _teamMonsterIdArray[groupId]);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
 								strncat((char *)_messageToBePrinted, "!", 2);
 							}
@@ -4894,7 +4894,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (var51 <= 0) {
 								char buffer[80];
 								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1, _enemyNamePt2.c_str(), _nameBuffer.c_str());
+								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
 								strncat((char *)_messageToBePrinted, buffer, 80);
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
@@ -4924,7 +4924,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						}
 						// Action A - Check effect - End
 					} else {
-						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
@@ -4943,11 +4943,11 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
-		strncpy(_enemyNamePt1, "The ", 5);
+		_enemyNamePt1 = "The ";
 	else
-		*_enemyNamePt1 = 0;
+		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1, _enemyNamePt2.c_str(), kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4962,11 +4962,11 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
 	if (var70 == 2)
-		strncpy(_enemyNamePt1, "The ", 5);
+		_enemyNamePt1 = "The ";
 	else
-		*_enemyNamePt1 = 0;
+		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1, _enemyNamePt2.c_str(), kPersonal[var70]);
+	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -4980,11 +4980,11 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	_nameBuffer = _items[unk_monsterField5_itemId]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
-		snprintf(_enemyNamePt1, 5, "The ");
+		_enemyNamePt1 = "The ";
 	else
-		*_enemyNamePt1 = 0;
+		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -5219,9 +5219,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									*_characterNamePt1 = 0;
 
 								if (var7E == 2)
-									snprintf(_enemyNamePt1, 5, "The ");
+									_enemyNamePt1 = "The ";
 								else
-									*_enemyNamePt1 = 0;
+									_enemyNamePt1 = "";
 
 								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
@@ -5229,17 +5229,17 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											strncat((char *)_messageToBePrinted, "!", 2);
 									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1, _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -5316,7 +5316,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									} 
 									// handleFight - Check effect - end
 								} else {
-									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1, _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
@@ -5329,19 +5329,19 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
-								strncpy(_enemyNamePt1, "The ", 5);
+								_enemyNamePt1 = "The ";
 							else
-								*_enemyNamePt1 = 0;
+								_enemyNamePt1 = "";
 
 							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 							case 1:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1, _enemyNamePt2.c_str());
+								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							case 2:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1, _enemyNamePt2.c_str());
+								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							default:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1, _enemyNamePt2.c_str());
+								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							}
 							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 9d237900a39..e789a232866 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -398,7 +398,7 @@ private:
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
-	void getXPAndSearchCorpse(int16 charId, char* namePt1, char* namePt2, int16 monsterId);
+	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	void addReactionText(int16 id);
 	void handleFight_lastAction_A(int16 teamCharId);
 	void handleFight_lastAction_D(int16 teamCharId);
@@ -509,7 +509,7 @@ private:
 	AnimInfo _animInfo[100];
 	uint8 _history[256];
 	uint8 _techData[4096];
-	char _enemyNamePt1[5];
+	Common::String _enemyNamePt1;
 	Common::String _enemyNamePt2;
 	char _characterNamePt1[5];
 	Common::String _characterNamePt2;


Commit: cf5dd14c7a1ac8fa898748924fd296291bfadc64
    https://github.com/scummvm/scummvm/commit/cf5dd14c7a1ac8fa898748924fd296291bfadc64
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: More conversions from char [] to Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 252977caa22..01505e5b03c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1307,9 +1307,6 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 	static char strMaxHp[7] = "Max HP";
 	static char strWeapon[7] = "Weapon";
 	static char strDead[9] = "* DEAD *";
-
-	char buffer[80];
-	memset(buffer, 0, 80);
 	
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -1327,15 +1324,15 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					continue;
 				int16 charId = _teamCharId[i];
 				int16 textPosY = 161 + 9 * i;
-				snprintf(buffer, 11, "%s", _npcBuf[charId]._name);
+				Common::String buffer = _npcBuf[charId]._name;
 				setTextPos(16, textPosY);
 				displayStringAtTextPos(buffer);
-				snprintf(buffer, 80, "%d", getEquipmentDefense(charId, false));
-				displayCenteredString(buffer, 104, 128, textPosY);
-				snprintf(buffer, 80, "%d", _npcBuf[charId]._hitPoints);
-				displayCenteredString(buffer, 144, 176, textPosY);
-				snprintf(buffer, 80, "%d", _npcBuf[charId]._maxHP);
-				displayCenteredString(buffer, 192, 224, textPosY);
+				buffer = Common::String::format("%d", getEquipmentDefense(charId, false));
+				displayCenteredString(buffer.c_str(), 104, 128, textPosY);
+				buffer = Common::String::format("%d", _npcBuf[charId]._hitPoints);
+				displayCenteredString(buffer.c_str(), 144, 176, textPosY);
+				buffer = Common::String::format("%d", _npcBuf[charId]._maxHP);
+				displayCenteredString(buffer.c_str(), 192, 224, textPosY);
 
 				if (_npcBuf[charId]._hitPoints <= 0) {
 					displayCenteredString(strDead, 225, 302, textPosY);
@@ -3943,9 +3940,8 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 void EfhEngine::displayCombatMenu(int16 charId) {
 	debug("displayCombatMenu %d", charId);
 
-	char buffer[80];
-	copyString(_npcBuf[charId]._name, buffer);
-	strncat(buffer, ":", 2);
+	Common::String buffer = _npcBuf[charId]._name;
+	buffer += ":";
 	setTextColorWhite();
 	setTextPos(144, 7);
 	displayStringAtTextPos(buffer);
@@ -5484,32 +5480,30 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	debug("displayCharacterSummary %d %d", curMenuLine, npcId);
 
-	char buffer1[40];
 	char buffer2[40];
-	memset(buffer1, 0, 40);
 	memset(buffer2, 0, 40);
 	
 	setTextColorRed();
-	copyString(_npcBuf[npcId]._name, buffer1);
+	Common::String buffer1 = _npcBuf[npcId]._name;
 	setTextPos(146, 27);
 	displayStringAtTextPos("Name: ");
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "Level: %d", getXPLevel(_npcBuf[npcId]._xp));
+	buffer1 = Common::String::format("Level: %d", getXPLevel(_npcBuf[npcId]._xp));
 	setTextPos(146, 36);
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "XP: %lu", _npcBuf[npcId]._xp);
+	buffer1 = Common::String::format("XP: %lu", _npcBuf[npcId]._xp);
 	setTextPos(227, 36);
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "Speed: %d", _npcBuf[npcId]._speed);
+	buffer1 = Common::String::format("Speed: %d", _npcBuf[npcId]._speed);
 	setTextPos(146, 45);
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "Defense: %d", getEquipmentDefense(npcId, false));
+	buffer1 = Common::String::format("Defense: %d", getEquipmentDefense(npcId, false));
 	setTextPos(146, 54);
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "Hit Points: %d", _npcBuf[npcId]._hitPoints);
+	buffer1 = Common::String::format("Hit Points: %d", _npcBuf[npcId]._hitPoints);
 	setTextPos(146, 63);
 	displayStringAtTextPos(buffer1);
-	snprintf(buffer1, 40, "Max HP: %d", _npcBuf[npcId]._maxHP);
+	buffer1 = Common::String::format("Max HP: %d", _npcBuf[npcId]._maxHP);
 	setTextPos(227, 63);
 	displayStringAtTextPos(buffer1);
 	displayCenteredString("Inventory", 144, 310, 72);
@@ -5541,16 +5535,16 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 
 		setTextPos(152, textPosY);
 		if (counter == curMenuLine) {
-			snprintf(buffer1, 40, "%c>", 'A' + counter);
+			buffer1 = Common::String::format("%c>", 'A' + counter);
 		} else {
-			snprintf(buffer1, 40, "%c)", 'A' + counter);
+			buffer1 = Common::String::format("%c)", 'A' + counter);
 		}
 		displayStringAtTextPos(buffer1);
 
 		if (itemId != 0x7FFF) {
 			setTextPos(168, textPosY);
 			copyString(_items[itemId]._name, buffer2);
-			snprintf(buffer1, 40, "  %s", buffer2);
+			buffer1 = Common::String::format("  %s", buffer2);
 			displayStringAtTextPos(buffer1);
 			setTextPos(262, textPosY);
 
@@ -5560,7 +5554,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 					// useless?
 					var54 = _items[_npcBuf[npcId]._inventory[_word3273A[counter]]._ref]._defense;
 				} else {
-					snprintf(buffer1, 40, "%d", 1 + var54 / 8);
+					buffer1 = Common::String::format("%d", 1 + var54 / 8);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					displayStringAtTextPos("Def");
@@ -5568,7 +5562,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 			} else if (_items[itemId]._uses != 0x7F) {
 				int16 var52 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat1;
 				if (var52 != 0x7F) {
-					snprintf(buffer1, 40, "%d", var52);
+					buffer1 = Common::String::format("%d", var52);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					if (var52 == 1)
@@ -5585,11 +5579,8 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
 	debug("displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
 	
-	char buffer[40];
-	memset(buffer, 0, 40);
-
 	setTextColorRed();
-	copyString(_npcBuf[charId]._name, buffer);
+	Common::String buffer = _npcBuf[charId]._name;
 	setTextPos(146, 27);
 	displayStringAtTextPos("Name: ");
 	displayStringAtTextPos(buffer);
@@ -5607,15 +5598,15 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 		int16 textPosY = 38 + counter * 9;
 		setTextPos(146, textPosY);
 		if (counter == curMenuLine) {
-			snprintf(buffer, 40, "%c>", 'A' + counter);
+			buffer = Common::String::format("%c>", 'A' + counter);
 		} else {
-			snprintf(buffer, 40, "%c)", 'A' + counter);
+			buffer = Common::String::format("%c)", 'A' + counter);
 		}
 
 		displayStringAtTextPos(buffer);
 		setTextPos(163, textPosY);
 		displayStringAtTextPos(kSkillArray[_word3273A[counter]]);
-		snprintf(buffer, 40, "%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
+		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
 		setTextPos(278, textPosY);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
@@ -6760,7 +6751,6 @@ bool EfhEngine::checkMonsterCollision() {
 
 	int16 var68 = 0;
 	char dest[20];
-	char buffer[80];
 	
 	int16 monsterId;
 	for (monsterId = 0; monsterId < 64; ++monsterId) {
@@ -6792,6 +6782,7 @@ bool EfhEngine::checkMonsterCollision() {
 				++var6A;
 		}
 
+		Common::String buffer = "";
 		do {
 			for (int16 var6C = 0; var6C < 2; ++var6C) {
 				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
@@ -6800,30 +6791,30 @@ bool EfhEngine::checkMonsterCollision() {
 					if (var6A > 1)
 						strncat(dest, " ", 2);
 
-					snprintf(buffer, 80, "with %d %s", var6A, dest);
+					buffer = Common::String::format("with %d %s", var6A, dest);
 				} else if (var1 == 0x3E) {
-					strncpy(buffer, "(NOT DEFINED)", 80);
+					buffer = "(NOT DEFINED)";
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
 					// Special character name
 					copyString(_npcBuf[_mapMonsters[monsterId]._field_1]._name, dest);
-					snprintf(buffer, 80, "with %s", dest);
+					buffer = Common::String::format("with %s", dest);
 				}
 
 				clearBottomTextZone(0);
 				_textColor = 0xE;
 				displayCenteredString("Interaction", 24, 296, 152);
-				displayCenteredString(buffer, 24, 296, 161);
+				displayCenteredString(buffer.c_str(), 24, 296, 161);
 				setTextPos(24, 169);
 				setTextColorWhite();
 				displayStringAtTextPos("T");
 				setTextColorRed();
-				snprintf(buffer, 80, "alk to the %s", dest);
+				buffer = Common::String::format("alk to the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(24, 178);
 				setTextColorWhite();
 				displayStringAtTextPos("A");
 				setTextColorRed();
-				snprintf(buffer, 80, "ttack the %s", dest);
+				buffer = Common::String::format("ttack the %s", dest);
 				displayStringAtTextPos(buffer);
 				setTextPos(198, 169);
 				setTextColorWhite();
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e789a232866..a299e7421a7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -455,7 +455,7 @@ private:
 	void setTextColorWhite();
 	void setTextColorRed();
 	void setTextColorGrey();
-	void displayStringAtTextPos(const char *message);
+	void displayStringAtTextPos(Common::String message);
 	void clearBottomTextZone(int16 color);
 	void clearBottomTextZone_2(int16 color);
 	void setNextCharacterPos();
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index c31fdc61e38..486fd75ecdc 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -337,11 +337,11 @@ void EfhEngine::setTextColorGrey() {
 		_textColor = 0x8;
 }
 
-void EfhEngine::displayStringAtTextPos(const char *message) {
-	debugC(1, kDebugGraphics, "displayStringAtTextPos %s", message);
+void EfhEngine::displayStringAtTextPos(Common::String message) {
+	debugC(1, kDebugGraphics, "displayStringAtTextPos %s", message.c_str());
 
-	drawString(message, _textPosX, _textPosY, _textColor);
-	_textPosX += getStringWidth(message) + 1;
+	drawString(message.c_str(), _textPosX, _textPosY, _textColor);
+	_textPosX += getStringWidth(message.c_str()) + 1;
 	setNextCharacterPos();
 }
 


Commit: 0258f7009fbd322f1218fefea3350668a0cd81d3
    https://github.com/scummvm/scummvm/commit/0258f7009fbd322f1218fefea3350668a0cd81d3
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: more work on Common::String, somehow fix a crash in dialogs

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 01505e5b03c..494a118c351 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -3903,8 +3903,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		} else if (var1 == 0x3E) {
 			displayStringAtTextPos("(NOT DEFINED)");
 		} else if (var1 == 0x3F) {
-			char stringToDisplay[20];
-			copyString(_npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name, stringToDisplay);
+			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name;
 			displayStringAtTextPos(stringToDisplay);
 		}
 
@@ -4554,11 +4553,8 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	if (!giveItemTo(charId, itemId, 0xFF))
 		return false;
 
-	char tmpString[20];
-	copyString(_items[itemId]._name, tmpString);
-	char buffer[80];
-	snprintf(buffer, 80, " and finds a %s!", tmpString);
-	strncat((char *)_messageToBePrinted, buffer, 80);
+	Common::String buffer = Common::String::format(" and finds a %s!", _items[itemId]._name);
+	strncat((char *)_messageToBePrinted, buffer.c_str(), buffer.size() + 1);
 	return true;
 }
 
@@ -5005,8 +5001,6 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	
 	int16 var42 = 0;
 	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
-	char buffer[40];
-	char buffer2[20];
 
 	if (var40 > 2) {
 		var40 = 2;
@@ -5023,17 +5017,17 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 		_npcBuf[charId]._inventory[objectId]._stat2 -= damage;
 
 		if (_npcBuf[charId]._inventory[objectId]._stat2 <= 0) {
-			copyString(_items[_npcBuf[charId]._inventory[objectId]._ref]._name, buffer2);
+			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
 			removeObject(charId, objectId);
 
 			if (var42 == 0) {
 				var42 = 1;
-				snprintf(buffer, 40, ", but %s %s", kPossessive[var40], buffer2);
-				strncat((char *)_messageToBePrinted, buffer, 40);
+				Common::String buffer = Common::String::format(", but %s ", kPossessive[var40]) + buffer2;
+				strncat((char *)_messageToBePrinted, buffer.c_str(), 40);
 			} else {
 				++var42;
-				snprintf(buffer, 40, ", %s", buffer2);
-				strncat((char *)_messageToBePrinted, buffer, 40);
+				Common::String buffer = Common::String(", ") + buffer2;
+				strncat((char *)_messageToBePrinted, buffer.c_str(), 40);
 			}
 		}
 
@@ -5480,9 +5474,6 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	debug("displayCharacterSummary %d %d", curMenuLine, npcId);
 
-	char buffer2[40];
-	memset(buffer2, 0, 40);
-	
 	setTextColorRed();
 	Common::String buffer1 = _npcBuf[npcId]._name;
 	setTextPos(146, 27);
@@ -5543,8 +5534,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 
 		if (itemId != 0x7FFF) {
 			setTextPos(168, textPosY);
-			copyString(_items[itemId]._name, buffer2);
-			buffer1 = Common::String::format("  %s", buffer2);
+			buffer1 = Common::String::format("  %s", _items[itemId]._name);
 			displayStringAtTextPos(buffer1);
 			setTextPos(262, textPosY);
 
@@ -5816,8 +5806,7 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
 	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine, argA);
 
-	char buffer1[80];
-	char buffer2[80];
+	Common::String buffer1 = "";
 
 	bool varA6 = false;
 	bool retVal = false;
@@ -5854,11 +5843,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			}
 			// The original was duplicating this code in each branch of the previous random check. 
 			if (victims > 1) {
-				snprintf(buffer1, 80, "%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				snprintf(buffer1, 80, "%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strncat((char *)_messageToBePrinted, buffer1, 400);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 400);
 		}
 
 		varA6 = true;
@@ -5894,11 +5883,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				snprintf(buffer1, 80, "%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
-				snprintf(buffer1, 80, "%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			// </CHECKME>
 		}
 
@@ -5978,11 +5967,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (varAA != 0x1B) {
-			strncpy(buffer1, "  The magic makes the user as quick and agile as a bird!", 80);
+			buffer1 = "  The magic makes the user as quick and agile as a bird!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			}
 			_word32482[varAA] -= 50;
 			if (_word32482[varAA] < 0)
@@ -6002,11 +5991,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (teamCharId != 0x1B) {
-			strncpy(buffer1, "  The magic makes the user invisible!", 80);
+			buffer1 = "  The magic makes the user invisible!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine); 
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine); 
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			}
 
 			_word32680[teamCharId] -= 50;
@@ -6026,29 +6015,29 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
-			strncpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !", 80);
+			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
 			if (varAE == 0 || varAE == 0x48) {
-				strncpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!", 80);
+				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1, 80);
+					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 					retVal = true;
 				}
 			} else {
-				strncpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!", 80);
+				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1, 80);
+					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 					retVal = true;
 				}
 			}
@@ -6063,29 +6052,29 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		int16 varAE = sub15538(_mapPosX, _mapPosY);
 		if (_tileFact[varAE]._field0 == 0) {
 			totalPartyKill();
-			strncpy(buffer1, "The entire party vanishes in a flash... only to appear in stone !", 80);
+			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
 		} else {
 			if (varAE == 0 || varAE == 0x48) {
-				strncpy(buffer1, "The entire party vanishes in a flash...but re-appears, as if nothing happened!", 80);
+				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1, 80);
+					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 					retVal = true;
 				}
 			} else {
-				strncpy(buffer1, "The entire party vanishes in a flash...only to appear elsewhere!",80);
+				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1, 80);
+					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 					retVal = true;
 				}
 			}
@@ -6113,48 +6102,47 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		varA6 = true;
 		break;
 	case 19: // "Junk"
-		strncpy(buffer1, "  * The item breaks!", 80);
+		buffer1 = "  * The item breaks!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 		}
 		setCharacterObjectToBroken(charId, objectId);
 		varA6 = true;
 		break;
 	case 23: // "Divining Rod"
-		copyString(_items[itemId]._name, buffer2);
-		snprintf(buffer1, 80, "The %s says, '", buffer2);
+		buffer1 = Common::String::format("The %s says, '", _items[itemId]._name);
 		if (_items[itemId].field_19 < _mapPosX) {
 			if (_items[itemId].field_1A < _mapPosY) {
-				strncat(buffer1, "North West!", 80);
+				buffer1 += "North West!";
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strncat(buffer1, "South West!", 80);
+				buffer1 += "South West!";
 			} else {
-				strncat(buffer1, "West!", 80);
+				buffer1 += "West!";
 			}
 		} else if (_items[itemId].field_19 > _mapPosX) {
 			if (_items[itemId].field_1A < _mapPosY) {
-				strncat(buffer1, "North East!", 80);
+				buffer1 += "North East!";
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strncat(buffer1, "South East!", 80);
+				buffer1 += "South East!";
 			} else {
-				strncat(buffer1, "East!", 80);
+				buffer1 += "East!";
 			}
 		} else { // equals _mapPosX
 			if (_items[itemId].field_1A < _mapPosY) {
-				strncat(buffer1, "North!", 80);
+				buffer1 += "North!";
 			} else if (_items[itemId].field_1A > _mapPosY) {
-				strncat(buffer1, "South!", 80);
+				buffer1 += "South!";
 			} else {
-				strncat(buffer1, "Here!!!",80);
+				buffer1 += "Here!!!";
 			}
 		}
-		strncat(buffer1, "'", 2);
+		buffer1 += "'";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			retVal = true;
 		}
 
@@ -6176,14 +6164,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
 			}
 			if (effectPoints > 1)
-				snprintf(buffer1, 80, "%s increased %d points!", kSkillArray[varAE], effectPoints);
+				buffer1 = Common::String::format("%s increased %d points!", kSkillArray[varAE], effectPoints);
 			else
-				snprintf(buffer1, 80, "%s increased 1 point!", kSkillArray[varAE]);
+				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				retVal = true;
 			}
 		}
@@ -6207,14 +6195,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
 			}
 			if (effectPoints > 1)
-				snprintf(buffer1, 80, "%s lowered %d points!", kSkillArray[varAE], effectPoints);
+				buffer1 = Common::String::format("%s lowered %d points!", kSkillArray[varAE], effectPoints);
 			else
-				snprintf(buffer1, 80, "%s lowered 1 point!", kSkillArray[varAE]);
+				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				retVal = true;
 			}
 		}
@@ -6223,11 +6211,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		break;
 	case 26: // "Black Sphere"
-		strncpy(buffer1, "The entire party collapses, dead!!!", 80);
+		buffer1 = "The entire party collapses, dead!!!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			retVal = true;
 		}
 		totalPartyKill();
@@ -6245,12 +6233,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		if (teamCharId != 0x1B) {
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
-			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
-			snprintf(buffer1, 80, "%s collapses, dead!!!", buffer2);
+			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1, 80);
+				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				retVal = true;
 			}
 			// emptyFunction(2);
@@ -6287,22 +6274,21 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		
 		if (teamCharId != 0x1B) {
-			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints += varAE;
+			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
 				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
 
-			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
-			if (varAE > 1)
-				snprintf(buffer1, 80, "%s is healed %d points!", buffer2, varAE);
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
 			else
-				snprintf(buffer1, 80, "%s is healed 1 point!", buffer2);
+				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			retVal = true;
 		}
 
@@ -6319,22 +6305,21 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (teamCharId != 0x1B) {
-			int16 varAE = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= varAE;
+			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
 				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 
-			copyString(_npcBuf[_teamCharId[teamCharId]]._name, buffer2);
-			if (varAE > 1)
-				snprintf(buffer1, 80, "%s is harmed for %d points!", buffer2, varAE);
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
 			else
-				snprintf(buffer1, 80, "%s is harmed for 1 point!", buffer2);
+				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1, 80);
+			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			retVal = true;
 		}
 
@@ -6361,12 +6346,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
 			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
 			if (varA1 <= 0) {
-				strncpy(buffer1, "  * The item breaks!", 80);
+				buffer1 = "  * The item breaks!";
 				if (argA == 2) {
 					Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1, 80);
+					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 				}
 				setCharacterObjectToBroken(charId, objectId);
 			} else {
@@ -6750,10 +6735,8 @@ bool EfhEngine::checkMonsterCollision() {
 	debug("checkMonsterCollision");
 
 	int16 var68 = 0;
-	char dest[20];
-	
-	int16 monsterId;
-	for (monsterId = 0; monsterId < 64; ++monsterId) {
+
+	for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
 		if (!checkPictureRefAvailability(monsterId))
 			continue;
 
@@ -6786,18 +6769,20 @@ bool EfhEngine::checkMonsterCollision() {
 		do {
 			for (int16 var6C = 0; var6C < 2; ++var6C) {
 				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
+				Common::String dest;
 				if (var1 <= 0x3D) {
-					strncpy(dest, kEncounters[_mapMonsters[monsterId]._monsterRef]._name, 80);
+					dest = kEncounters[_mapMonsters[monsterId]._monsterRef]._name;
 					if (var6A > 1)
-						strncat(dest, " ", 2);
+						dest += "s";
 
-					buffer = Common::String::format("with %d %s", var6A, dest);
+					buffer = Common::String::format("with %d ", var6A) + dest;
 				} else if (var1 == 0x3E) {
 					buffer = "(NOT DEFINED)";
+					dest = "(NOT DEFINED)";
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
 					// Special character name
-					copyString(_npcBuf[_mapMonsters[monsterId]._field_1]._name, dest);
-					buffer = Common::String::format("with %s", dest);
+					dest = _npcBuf[_mapMonsters[monsterId]._field_1]._name;
+					buffer = Common::String("with ") + dest;
 				}
 
 				clearBottomTextZone(0);
@@ -6808,13 +6793,13 @@ bool EfhEngine::checkMonsterCollision() {
 				setTextColorWhite();
 				displayStringAtTextPos("T");
 				setTextColorRed();
-				buffer = Common::String::format("alk to the %s", dest);
+				buffer = Common::String("alk to the ") + dest;
 				displayStringAtTextPos(buffer);
 				setTextPos(24, 178);
 				setTextColorWhite();
 				displayStringAtTextPos("A");
 				setTextColorRed();
-				buffer = Common::String::format("ttack the %s", dest);
+				buffer = Common::String("ttack the ") + dest;
 				displayStringAtTextPos(buffer);
 				setTextPos(198, 169);
 				setTextColorWhite();


Commit: 2d6f4f7f17404111b9c4afa0aad6f6104be607e7
    https://github.com/scummvm/scummvm/commit/2d6f4f7f17404111b9c4afa0aad6f6104be607e7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: "Remove" copyString()

Changed paths:
    engines/efh/efh.h
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a299e7421a7..150347d05f6 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -464,7 +464,7 @@ private:
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 
 	// Utils
-	#if true
+	#if false
 	void copyString(char *srcStr, char *destStr);
 	#endif
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index ee23a0679e7..e621d91b37a 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -26,6 +26,20 @@
 
 namespace Efh {
 
+#if 0
+// Note : The original engine is using copyString(src, dest). It has been replaced either by a string assignment or a snprintf
+void EfhEngine::copyString(char *srcStr, char *destStr) {
+	debugC(1, kDebugUtils, "copyString %s", srcStr);
+	char lastChar = 1;
+	int16 idx = 0;
+
+	while (lastChar != 0) {
+		lastChar = destStr[idx] = srcStr[idx];
+		++idx;
+	}
+}
+#endif
+
 int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
 	debugC(1, kDebugUtils, "readFileToBuffer %s", filename.c_str());
 	Common::File f;
@@ -323,17 +337,6 @@ void EfhEngine::setNumLock() {
 	// No implementation in ScummVM
 }
 
-void EfhEngine::copyString(char *srcStr, char *destStr) {
-	debugC(1, kDebugUtils, "copyString %s", srcStr);
-	char lastChar = 1;
-	int16 idx = 0;
-
-	while (lastChar != 0) {
-		lastChar = destStr[idx] = srcStr[idx];
-		++idx;
-	}
-}
-
 bool EfhEngine::getValidationFromUser() {
 	debugC(1, kDebugUtils, "getValidationFromUser");
 	Common::KeyCode input = handleAndMapInput(true);


Commit: 8251081c093ecc0a6c3fb0c96c857a02db8cb4de
    https://github.com/scummvm/scummvm/commit/8251081c093ecc0a6c3fb0c96c857a02db8cb4de
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Start preparing TECH and MAP files for savegames

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 494a118c351..26983e13711 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -332,7 +332,8 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_tileFact, 0, ARRAYSIZE(_tileFact));
 	memset(_animInfo, 0, ARRAYSIZE(_animInfo));
 	memset(_history, 0, ARRAYSIZE(_history));
-	memset(_techData, 0, ARRAYSIZE(_techData));
+	for(int i = 0; i < 20; ++i)
+		memset(_techDataArr[i], 0, ARRAYSIZE(_techDataArr[i]));
 	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
 	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
 	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
@@ -681,11 +682,7 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	_techId = fileId;
 	findMapFile(_techId);
 
-	Common::String fileName = Common::String::format("tech.%d", _techId);
-	readFileToBuffer(fileName, _hiResImageBuf);
-	uncompressBuffer(_hiResImageBuf, _techData);
-
-	fileName = Common::String::format("map.%d", _techId);
+	Common::String fileName = Common::String::format("map.%d", _techId);
 	readFileToBuffer(fileName, _hiResImageBuf);
 	uncompressBuffer(_hiResImageBuf, _map);
 	// This is not present in the original.
@@ -934,6 +931,18 @@ void EfhEngine::playIntro() {
 	getLastCharAfterAnimCount(80);
 }
 
+/**
+ * Pre-Loads MAP and TECH files.
+ * This is required in order to implement a clean savegame feature
+ */
+void EfhEngine::preLoadMaps() {
+	for (int i = 0; i < 19; ++i) {
+		Common::String fileName = Common::String::format("tech.%d", _techId);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _techDataArr[_techId]);
+	}
+}
+
 void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
 	_graphicsStruct = new EfhGraphicsStruct;
@@ -957,6 +966,9 @@ void EfhEngine::initEngine() {
 	_fontDescr._extraHorizontalSpace = 1;
 	_word31E9E = false;
 
+	// Pre-load stuff required for savegames
+	preLoadMaps();
+	
 	saveAnimImageSetId();
 
 	// Load Title Screen
@@ -2159,7 +2171,7 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 
 	for (int16 var4 = varC; var4 <= var8; ++var4) {
 		for (int16 var2 = varA; var2 <= var6; ++var2) {
-			_techData[var2 + var4 * 64] = varD;
+			_techDataArr[_techId][var2 + var4 * 64] = varD;
 		}
 	}
 }
@@ -4146,7 +4158,7 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 	debug("checkSpecialItemsOnCurrentPlace %d", itemId);
 
-	switch(_techData[_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
+	switch(_techDataArr[_techId][_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
 	case 1:
 		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
 			return true;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 150347d05f6..1dedbf29610 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -289,6 +289,7 @@ private:
 	Common::KeyCode playSong(uint8 *buffer);
 	void readImpFile(int16 id, bool techMapFl);
 	void playIntro();
+	void preLoadMaps();
 	void initEngine();
 	void initMapMonsters();
 	void loadMapArrays();
@@ -508,7 +509,7 @@ private:
 	TileFactStruct _tileFact[432];
 	AnimInfo _animInfo[100];
 	uint8 _history[256];
-	uint8 _techData[4096];
+	uint8 _techDataArr[19][4100];
 	Common::String _enemyNamePt1;
 	Common::String _enemyNamePt2;
 	char _characterNamePt1[5];
@@ -575,9 +576,11 @@ private:
 
 	uint16 _tempTextDelay;
 	uint8 *_tempTextPtr;
+	// TODO: Remove those useless debug flags
 	bool _dbgForceDisplayUpperRightBorder; // Original debug flag? Always false.
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 	bool _word2C8D7; // Original debug flag? Always true.
+
 	bool _ongoingFightFl;
 	bool _statusMenuActive;
 	int16 _menuDepth;


Commit: 8acbbcafb0a2d02f41187e8cfef4c570078b98c2
    https://github.com/scummvm/scummvm/commit/8acbbcafb0a2d02f41187e8cfef4c570078b98c2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Fix typo in combats

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 26983e13711..9b2faba372e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -4880,7 +4880,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (damagePointsAbsorbed <= 1)
 								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
 							else
-								snprintf(buffer, 80, "  %s%s',27h,'s armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+								snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 							strncat((char *)_messageToBePrinted, buffer, 80);
 						}


Commit: b6291456274c0f78a418fcfa27f4c7b29605e315
    https://github.com/scummvm/scummvm/commit/b6291456274c0f78a418fcfa27f4c7b29605e315
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Preload maps

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9b2faba372e..f7e5249bcea 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -194,7 +194,9 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
-	_mapBitmapRef = nullptr;
+
+	for (int i = 0; i < 19; ++i)
+		_mapBitmapRefArr[i] = nullptr;
 
 	_defaultBoxColor = 0;
 
@@ -320,7 +322,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_loResImageBuf, 0, ARRAYSIZE(_loResImageBuf));
 	memset(_menuBuf, 0, ARRAYSIZE(_menuBuf));
 	memset(_windowWithBorderBuf, 0, ARRAYSIZE(_windowWithBorderBuf));
-	memset(_map, 0, ARRAYSIZE(_map));
 	memset(_places, 0, ARRAYSIZE(_places));
 	for (int i = 0; i < 24; ++i)
 		memset(_curPlace[i], 0, ARRAYSIZE(_curPlace[i]));
@@ -332,8 +333,10 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_tileFact, 0, ARRAYSIZE(_tileFact));
 	memset(_animInfo, 0, ARRAYSIZE(_animInfo));
 	memset(_history, 0, ARRAYSIZE(_history));
-	for(int i = 0; i < 20; ++i)
+	for (int i = 0; i < 19; ++i) {
 		memset(_techDataArr[i], 0, ARRAYSIZE(_techDataArr[i]));
+		memset(_mapArr[i], 0, ARRAYSIZE(_mapArr[i]));
+	}
 	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
 	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
 	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
@@ -682,15 +685,15 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	_techId = fileId;
 	findMapFile(_techId);
 
-	Common::String fileName = Common::String::format("map.%d", _techId);
-	readFileToBuffer(fileName, _hiResImageBuf);
-	uncompressBuffer(_hiResImageBuf, _map);
+	// The original was loading the specific tech.%d and map.%d files.
+	// This is gone in our implementation as we pre-load all the files to save them inside the savegames
+	
 	// This is not present in the original.
 	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
-	loadMapArrays();
-
-	loadImageSetToTileBank(1, _mapBitmapRef[0] + 1);
-	loadImageSetToTileBank(2, _mapBitmapRef[1] + 1);
+	loadMapArrays(_techId);
+	
+	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId][0] + 1);
+	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId][1] + 1);
 
 	initMapMonsters();
 	readImpFile(_techId, true);
@@ -937,9 +940,15 @@ void EfhEngine::playIntro() {
  */
 void EfhEngine::preLoadMaps() {
 	for (int i = 0; i < 19; ++i) {
-		Common::String fileName = Common::String::format("tech.%d", _techId);
+		Common::String fileName = Common::String::format("tech.%d", i);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _techDataArr[i]);
+
+		fileName = Common::String::format("map.%d", i);
 		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _techDataArr[_techId]);
+		uncompressBuffer(_hiResImageBuf, _mapArr[i]);
+
+		_mapBitmapRefArr[i] = &_mapArr[i][0];
 	}
 }
 
@@ -948,8 +957,6 @@ void EfhEngine::initEngine() {
 	_graphicsStruct = new EfhGraphicsStruct;
 	_graphicsStruct->copy(_vgaGraphicsStruct1);
 
-	_mapBitmapRef = &_map[0];
-
 	_vgaGraphicsStruct2->copy(_vgaGraphicsStruct1);
 	_vgaGraphicsStruct2->_shiftValue = 0x2000;
 
@@ -1055,10 +1062,10 @@ void EfhEngine::initMapMonsters() {
 	}
 }
 
-void EfhEngine::loadMapArrays() {
-	debug("loadMapArrays");
+void EfhEngine::loadMapArrays(int idx) {
+	debug("loadMapArrays %d", idx);
 
-	uint8 *_mapUnknownPtr = &_map[2];
+	uint8 *_mapUnknownPtr = &_mapArr[idx][2];
 
 	for (int i = 0; i < 100; ++i) {
 		_mapUnknown[i]._placeId = _mapUnknownPtr[9 * i];
@@ -1070,7 +1077,7 @@ void EfhEngine::loadMapArrays() {
 		_mapUnknown[i]._field7 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
 	}
 	
-	uint8 *mapMonstersPtr = &_map[902];
+	uint8 *mapMonstersPtr = &_mapArr[idx][902];
 
 	for (int i = 0; i < 64; ++i) {
 		_mapMonsters[i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
@@ -1088,7 +1095,7 @@ void EfhEngine::loadMapArrays() {
 			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
 	}
 
-	uint8 *mapPtr = &_map[2758];
+	uint8 *mapPtr = &_mapArr[idx][2758];
 	for (int i = 0; i < 64; ++i) {
 		for (int j = 0; j < 64; ++j)
 			_mapGameMap[i][j] = *mapPtr++;
@@ -6876,7 +6883,7 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	_currentTileBankImageSetId[bankId] = setId;
 
 	if (bankId == 0 || bankId == 1)
-		_mapBitmapRef[bankId] = setId;
+		_mapBitmapRefArr[_techId][bankId] = setId;
 
 	int16 ptrIndex = bankId * 72;
 	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _hiResImageBuf);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 1dedbf29610..223a2e435a8 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -292,7 +292,7 @@ private:
 	void preLoadMaps();
 	void initEngine();
 	void initMapMonsters();
-	void loadMapArrays();
+	void loadMapArrays(int idx);
 	void saveAnimImageSetId();
 	int16 getEquipmentDefense(int16 charId, bool flag);
 	uint16 sub1C80A(int16 charId, int16 field18, bool flag);
@@ -498,7 +498,7 @@ private:
 	uint8 _loResImageBuf[40100];
 	uint8 _menuBuf[12500];
 	uint8 _windowWithBorderBuf[1500];
-	uint8 _map[7000];
+	uint8 _mapArr[19][7000];
 	uint8 _places[12000];
 	uint8 _curPlace[24][24];
 	NPCStruct _npcBuf[100];
@@ -518,7 +518,7 @@ private:
 	char _attackBuffer[20];
 	uint8 _messageToBePrinted[400];
 	
-	uint8 *_mapBitmapRef;
+	uint8 *_mapBitmapRefArr[19];
 	UnkMapStruct _mapUnknown[100];
 	MapMonster _mapMonsters[64];
 	uint8 _mapGameMap[64][64];


Commit: d695ab34379799f37009e30ec8c0886ca8b60496
    https://github.com/scummvm/scummvm/commit/d695ab34379799f37009e30ec8c0886ca8b60496
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Partial implementation of savegames. Loading is missing.

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/metaengine.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index f7e5249bcea..512d2b75f5b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -26,6 +26,10 @@
 #include "common/config-manager.h"
 #include "common/events.h"
 #include "engines/util.h"
+#include "common/savefile.h"
+#include "graphics/palette.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
 
 #include "efh/efh.h"
 #include "efh/constants.h"
@@ -372,7 +376,75 @@ void EfhEngine::syncSoundSettings() {
 }
 
 Common::String EfhEngine::getSavegameFilename(int slot) {
-	return _targetName + Common::String::format("-%02d.SAV", slot);
+	return _targetName + Common::String::format("-%03d.SAV", slot);
+}
+
+bool EfhEngine::canLoadGameStateCurrently() {
+	return true;
+}
+
+bool EfhEngine::canSaveGameStateCurrently() {
+	return true;
+}
+
+Common::Error EfhEngine::loadGameState(int slot) {
+	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(getSaveStateName(slot));
+	if (!saveFile)
+		return Common::kReadingFailed;
+/*
+	Common::Serializer s(saveFile, nullptr);
+
+	uint32 signature;
+	s.syncAsUint32LE(signature);
+	uint8 version;
+	s.syncAsByte(version);
+	if (signature != EFH_SAVE_HEADER || version > kSavegameVersion)
+		error("Invalid savegame");
+	
+	// Load the thumbnail
+	Graphics::Surface *thumbnail;
+	Graphics::loadThumbnail(*srf, thumbnail)
+
+	synchronize(s);
+*/
+
+	delete saveFile;
+
+	return Common::kNoError;
+}
+
+Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+	Common::OutSaveFile *out = _system->getSavefileManager()->openForSaving(getSaveStateName(slot));
+	if (!out)
+		return Common::kCreatingFileFailed;
+
+	out->writeUint32LE(EFH_SAVE_HEADER);
+	out->writeByte(kSavegameVersion);
+
+	// Write savegame name
+	uint16 size = desc.size();
+	out->writeUint16LE(size);
+	for (int i = 0; i < size; ++i)
+		out->writeByte(desc.c_str()[i]);
+ 
+	// Get the active palette
+	uint8 thumbPalette[16 * 3];
+	_system->getPaletteManager()->grabPalette(thumbPalette, 0, 16);
+	// Create a thumbnail and save it
+	Graphics::Surface *thumb = new Graphics::Surface();
+	Graphics::Surface *sf = _mainSurface;
+	::createThumbnail(thumb, (const byte *)sf->getPixels(), 320, 200, thumbPalette);
+	Graphics::saveThumbnail(*out, *thumb);
+	thumb->free();
+	delete thumb; 
+
+	Common::Serializer s(nullptr, out);	
+	synchronize(s);
+
+	out->finalize();
+	delete out;
+
+	return Common::kNoError;
 }
 
 Common::Error EfhEngine::run() {
@@ -6870,6 +6942,104 @@ bool EfhEngine::checkMonsterCollision() {
 	return true;
 }
 
+void EfhEngine::synchronize(Common::Serializer &s) {
+	s.syncAsSint16LE(_techId);
+	s.syncAsUint16LE(_fullPlaceId);
+	s.syncAsSint16LE(_guessAnimationAmount);
+	s.syncAsUint16LE(_largeMapFlag);
+	s.syncAsSint16LE(_teamCharId[0]);
+	s.syncAsSint16LE(_teamCharId[1]);
+	s.syncAsSint16LE(_teamCharId[2]);
+
+	for (int i = 0; i < 3; ++i) {
+		s.syncAsSint16LE(_teamCharStatus[i]._status);
+		s.syncAsSint16LE(_teamCharStatus[i]._duration);
+	}
+
+	s.syncAsSint16LE(_teamSize);
+	s.syncAsSint16LE(_unkArray2C8AA[0]);
+	s.syncAsSint16LE(_word2C872);
+	s.syncAsSint16LE(_imageSetSubFilesIdx);
+	s.syncAsSint16LE(_mapPosX);
+	s.syncAsSint16LE(_mapPosY);
+	s.syncAsSint16LE(_techDataId_MapPosX);
+	s.syncAsSint16LE(_techDataId_MapPosY);
+
+	for (int i = 0; i < 19; ++i) {
+		int size = ARRAYSIZE(_techDataArr[i]);
+		for (int j = 0; j < size; ++j)
+			s.syncAsByte(_techDataArr[i][j]);
+
+		size = ARRAYSIZE(_mapArr[i]);
+		for (int j = 0; j < size; ++j)
+			s.syncAsByte(_mapArr[i][j]);
+
+		_mapBitmapRefArr[i] = &_mapArr[i][0];
+	}
+
+	// Dialog flags
+	for (int i = 0; i < 256; ++i)
+		s.syncAsByte(_history[i]);
+
+	// NPCs
+	for (int i = 0; i < 99; ++i) {
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._name[idx]);
+
+		s.syncAsByte(_npcBuf[i].field_B);
+		s.syncAsByte(_npcBuf[i].field_C);
+		s.syncAsByte(_npcBuf[i].field_D);
+		s.syncAsByte(_npcBuf[i].field_E);
+		s.syncAsByte(_npcBuf[i].field_F);
+		s.syncAsByte(_npcBuf[i].field_10);
+		s.syncAsByte(_npcBuf[i].field_11);
+		s.syncAsSint16LE(_npcBuf[i].field_12);
+		s.syncAsSint16LE(_npcBuf[i].field_14);
+		s.syncAsSint32LE(_npcBuf[i]._xp);
+		for (int idx = 0; idx < 15; ++idx)
+			s.syncAsByte(_npcBuf[i]._activeScore[idx]);
+
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._passiveScore[idx]);
+
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._infoScore[idx]);
+
+		s.syncAsByte(_npcBuf[i].field_3F);
+		s.syncAsByte(_npcBuf[i].field_40);
+		for (int idx = 0; idx < 10; ++idx) {
+			s.syncAsSint16LE(_npcBuf[i]._inventory[idx]._ref);
+			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat1);
+			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat2);
+		}
+		s.syncAsByte(_npcBuf[i]._possessivePronounSHL6);
+		s.syncAsByte(_npcBuf[i]._speed);
+		s.syncAsByte(_npcBuf[i].field_6B);
+		s.syncAsByte(_npcBuf[i].field_6C);
+		s.syncAsByte(_npcBuf[i].field_6D);
+		s.syncAsByte(_npcBuf[i]._unkItemId);
+		s.syncAsByte(_npcBuf[i].field_6F);
+		s.syncAsByte(_npcBuf[i].field_70);
+		s.syncAsByte(_npcBuf[i].field_71);
+		s.syncAsByte(_npcBuf[i].field_72);
+		s.syncAsByte(_npcBuf[i].field_73);
+		s.syncAsSint16LE(_npcBuf[i]._hitPoints);
+		s.syncAsSint16LE(_npcBuf[i]._maxHP);
+		s.syncAsByte(_npcBuf[i].field_78);
+		s.syncAsSint16LE(_npcBuf[i].field_79);
+		s.syncAsSint16LE(_npcBuf[i].field_7B);
+		s.syncAsByte(_npcBuf[i].field_7D);
+		s.syncAsByte(_npcBuf[i].field_7E);
+		s.syncAsByte(_npcBuf[i].field_7F);
+		s.syncAsByte(_npcBuf[i].field_80);
+		s.syncAsByte(_npcBuf[i].field_81);
+		s.syncAsByte(_npcBuf[i].field_82);
+		s.syncAsByte(_npcBuf[i].field_83);
+		s.syncAsByte(_npcBuf[i].field_84);
+		s.syncAsByte(_npcBuf[i].field_85);
+	}
+}
+
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	debugC(3, kDebugEngine, "loadImageSetToTileBank %d %d", tileBankId, imageSetId);
 
@@ -6959,6 +7129,7 @@ void EfhEngine::loadEfhGame() {
 
 void EfhEngine::saveEfhGame() {
 	warning("STUB - saveEfhGame");
+	openMainMenuDialog();
 }
 
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 223a2e435a8..ed9b7eaebe2 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -29,6 +29,7 @@
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/events.h"
+#include "common/serializer.h"
 
 #include "engines/engine.h"
 #include "graphics/surface.h"
@@ -42,18 +43,20 @@ class RandomSource;
  * This is the namespace of the Efh engine.
  *
  * Status of this engine:
- * - Skeletton
+ * - No savegames
+ * - No music in intro
+ * - No random PC speaker farts (aka sounds)
  *
  * Games using this engine:
  * - Escape From Hell
  * 
- * Escape From Hell is based on a modified Wasteland engine, so this engine could eventually, one day, also support:
- * - Wasteland
- * - Fountain of Dreams
+ * Note: Wasteland and Fountain of dreams *seem* to use the same engine, but it's not the case.
+ * This engine was written from scratch based on the visual look of the other
  */
 namespace Efh {
 
-static const int kSavegameVersion = 1;
+static const uint8 kSavegameVersion = 1;
+#define EFH_SAVE_HEADER MKTAG('E', 'F', 'H', 'S')
 
 enum AccessDebugChannels {
 	kDebugEngine = 1 << 0,
@@ -257,6 +260,12 @@ public:
 	const char *getCopyrightString() const;
 
 	Common::String getSavegameFilename(int slot);
+
+	bool canLoadGameStateCurrently() override;
+	bool canSaveGameStateCurrently() override;
+	Common::Error loadGameState(int slot) override;
+	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
+
 	void syncSoundSettings() override;
 
 	bool _shouldQuit;
@@ -264,10 +273,8 @@ public:
 protected:
 	Common::EventManager *_eventMan;
 	int _lastTime;
-	void saveGame();
 	// Engine APIs
 	Common::Error run() override;
-	void handleMenu();
 
 private:
 	static EfhEngine *s_Engine;
@@ -430,6 +437,7 @@ private:
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	bool checkMonsterCollision();
+	void synchronize(Common::Serializer &s);
 
 	// Graphics
 	void initPalette();
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index 9857fb0bee7..e2fca88a03a 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -83,7 +83,7 @@ SaveStateList EfhMetaEngine::listSaves(const char *target) const {
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
 	Common::StringArray filenames;
 	Common::String pattern = target;
-	pattern += "-##.SAV";
+	pattern += ".###";
 
 	filenames = saveFileMan->listSavefiles(pattern);
 
@@ -91,24 +91,25 @@ SaveStateList EfhMetaEngine::listSaves(const char *target) const {
 	char slot[3];
 	int slotNum = 0;
 	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
-		slot[0] = filename->c_str()[filename->size() - 6];
-		slot[1] = filename->c_str()[filename->size() - 5];
+		slot[0] = filename->c_str()[filename->size() - 2];
+		slot[1] = filename->c_str()[filename->size() - 1];
 		slot[2] = '\0';
 		// Obtain the last 2 digits of the filename (without extension), since they correspond to the save slot
 		slotNum = atoi(slot);
 		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
 			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
 			if (file) {
-				int saveVersion = file->readByte();
+				uint32 sign = file->readUint32LE();
+				uint8 saveVersion = file->readByte();
 
-				if (saveVersion != kSavegameVersion) {
-					warning("Savegame of incompatible version");
+				if (sign != EFH_SAVE_HEADER || saveVersion > kSavegameVersion) {
+					warning("Incompatible savegame");
 					delete file;
 					continue;
 				}
 
 				// read name
-				uint16 nameSize = file->readUint16BE();
+				uint16 nameSize = file->readUint16LE();
 				if (nameSize >= 255) {
 					delete file;
 					continue;
@@ -128,19 +129,20 @@ SaveStateList EfhMetaEngine::listSaves(const char *target) const {
 }
 
 SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
-	Common::String fileName = Common::String::format("%s-%02d.SAV", target, slot);
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
 	Common::InSaveFile *file = g_system->getSavefileManager()->openForLoading(fileName);
 
 	if (file) {
-		int saveVersion = file->readByte();
+		uint32 sign = file->readUint32LE();
+		uint8 saveVersion = file->readByte();
 
-		if (saveVersion != kSavegameVersion) {
-			warning("Savegame of incompatible version");
+		if (sign != EFH_SAVE_HEADER || saveVersion > kSavegameVersion) {
+			warning("Incompatible savegame");
 			delete file;
 			return SaveStateDescriptor();
 		}
 
-		uint32 saveNameLength = file->readUint16BE();
+		uint32 saveNameLength = file->readUint16LE();
 		Common::String saveName;
 		for (uint32 i = 0; i < saveNameLength; ++i) {
 			char curChr = file->readByte();
@@ -156,22 +158,6 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 		}
 		desc.setThumbnail(thumbnail);
 
-		desc.setDeletableFlag(true);
-		desc.setWriteProtectedFlag(false);
-
-		uint32 saveDate = file->readUint32BE();
-		uint16 saveTime = file->readUint16BE();
-
-		int day = (saveDate >> 24) & 0xFF;
-		int month = (saveDate >> 16) & 0xFF;
-		int year = saveDate & 0xFFFF;
-
-		desc.setSaveDate(year, month, day);
-
-		int hour = (saveTime >> 8) & 0xFF;
-		int minutes = saveTime & 0xFF;
-
-		desc.setSaveTime(hour, minutes);
 		desc.setDeletableFlag(slot != 0);
 		desc.setWriteProtectedFlag(slot == 0);
 
@@ -182,7 +168,7 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 }
 
 void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
-	Common::String fileName = Common::String::format("%s-%02d.SAV", target, slot);
+	Common::String fileName = Common::String::format("%s.%03d", target, slot);
 	g_system->getSavefileManager()->removeSavefile(fileName);
 }
 


Commit: 638696444dc3718cce69b496b49c12cc4bd55217
    https://github.com/scummvm/scummvm/commit/638696444dc3718cce69b496b49c12cc4bd55217
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Add save date & time

Changed paths:
    engines/efh/efh.cpp
    engines/efh/metaengine.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 512d2b75f5b..393fbc30991 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -438,6 +438,15 @@ Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, boo
 	thumb->free();
 	delete thumb; 
 
+	// Write out the save date/time
+	TimeDate td;
+	g_system->getTimeAndDate(td);
+	out->writeSint16LE(td.tm_year + 1900);
+	out->writeSint16LE(td.tm_mon + 1);
+	out->writeSint16LE(td.tm_mday);
+	out->writeSint16LE(td.tm_hour);
+	out->writeSint16LE(td.tm_min);
+
 	Common::Serializer s(nullptr, out);	
 	synchronize(s);
 
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index e2fca88a03a..a207dca55d2 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -157,7 +157,15 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 			return SaveStateDescriptor();
 		}
 		desc.setThumbnail(thumbnail);
-
+		// Read in save date/time
+		int16 year = file->readSint16LE();
+		int16 month = file->readSint16LE();
+		int16 day = file->readSint16LE();
+		int16 hour = file->readSint16LE();
+		int16 minute = file->readSint16LE();
+		desc.setSaveDate(year, month, day);
+		desc.setSaveTime(hour, minute);
+		
 		desc.setDeletableFlag(slot != 0);
 		desc.setWriteProtectedFlag(slot == 0);
 


Commit: e54b01d47493dbdce2a7ff1caf9a51cc3996cfd3
    https://github.com/scummvm/scummvm/commit/e54b01d47493dbdce2a7ff1caf9a51cc3996cfd3
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Partial loading code

Changed paths:
    engines/efh/efh.cpp
    engines/efh/metaengine.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 393fbc30991..6af0ddc5e94 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -391,22 +391,26 @@ Common::Error EfhEngine::loadGameState(int slot) {
 	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(getSaveStateName(slot));
 	if (!saveFile)
 		return Common::kReadingFailed;
-/*
-	Common::Serializer s(saveFile, nullptr);
 
-	uint32 signature;
-	s.syncAsUint32LE(signature);
-	uint8 version;
-	s.syncAsByte(version);
+	uint32 signature = saveFile->readUint32LE();
+	byte version = saveFile->readByte();
+
 	if (signature != EFH_SAVE_HEADER || version > kSavegameVersion)
 		error("Invalid savegame");
 	
-	// Load the thumbnail
+	// Skip savegame name
+	uint16 size = saveFile->readUint16BE();
+	saveFile->skip(size);
+
+	// Skip the thumbnail
 	Graphics::Surface *thumbnail;
-	Graphics::loadThumbnail(*srf, thumbnail)
+	Graphics::loadThumbnail(*saveFile, thumbnail, true);
 
+	// Skip the savegame date
+	saveFile->skip(10); // year, month, day, hours, minutes (all int16) 
+	
+	Common::Serializer s(saveFile, nullptr);
 	synchronize(s);
-*/
 
 	delete saveFile;
 
@@ -592,7 +596,8 @@ Common::Error EfhEngine::run() {
 			if (input == Common::KEYCODE_y) {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
-				loadEfhGame();
+//				loadEfhGame();
+				saveEfhGame();
 				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			} else {
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index a207dca55d2..01d76fb8264 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -81,21 +81,19 @@ int EfhMetaEngine::getMaximumSaveSlot() const {
 
 SaveStateList EfhMetaEngine::listSaves(const char *target) const {
 	Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
-	Common::StringArray filenames;
 	Common::String pattern = target;
 	pattern += ".###";
 
-	filenames = saveFileMan->listSavefiles(pattern);
+	Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
 
 	SaveStateList saveList;
 	char slot[3];
-	int slotNum = 0;
 	for (Common::StringArray::const_iterator filename = filenames.begin(); filename != filenames.end(); ++filename) {
 		slot[0] = filename->c_str()[filename->size() - 2];
 		slot[1] = filename->c_str()[filename->size() - 1];
 		slot[2] = '\0';
 		// Obtain the last 2 digits of the filename (without extension), since they correspond to the save slot
-		slotNum = atoi(slot);
+		int slotNum = atoi(slot);
 		if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
 			Common::InSaveFile *file = saveFileMan->openForLoading(*filename);
 			if (file) {
@@ -157,6 +155,7 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 			return SaveStateDescriptor();
 		}
 		desc.setThumbnail(thumbnail);
+		
 		// Read in save date/time
 		int16 year = file->readSint16LE();
 		int16 month = file->readSint16LE();


Commit: 0d158f15834bc58d3fed03ef226db240d26da4c8
    https://github.com/scummvm/scummvm/commit/0d158f15834bc58d3fed03ef226db240d26da4c8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Fix parsing of savegame

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6af0ddc5e94..dccfe84eb69 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -399,13 +399,14 @@ Common::Error EfhEngine::loadGameState(int slot) {
 		error("Invalid savegame");
 	
 	// Skip savegame name
-	uint16 size = saveFile->readUint16BE();
+	uint16 size = saveFile->readUint16LE();
 	saveFile->skip(size);
 
 	// Skip the thumbnail
 	Graphics::Surface *thumbnail;
-	Graphics::loadThumbnail(*saveFile, thumbnail, true);
-
+	Graphics::loadThumbnail(*saveFile, thumbnail);
+	delete (thumbnail);
+	
 	// Skip the savegame date
 	saveFile->skip(10); // year, month, day, hours, minutes (all int16) 
 	


Commit: df4ac48e9f46c7d768016fc15ff47086a325c787
    https://github.com/scummvm/scummvm/commit/df4ac48e9f46c7d768016fc15ff47086a325c787
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Fix loading (hopefully)

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index dccfe84eb69..dfc9634ad80 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -415,6 +415,14 @@ Common::Error EfhEngine::loadGameState(int slot) {
 
 	delete saveFile;
 
+	_oldMapPosX = _mapPosX;
+	_oldMapPosY = _mapPosY;
+	_unkRelatedToAnimImageSetId = 0;
+
+	loadTechMapImp(_techId);
+	_lastMainPlaceId = 0xFFFF;
+	loadPlacesFile(_fullPlaceId, true);
+
 	return Common::kNoError;
 }
 


Commit: 143c483bde9bd5f07bfd805df69949f8d0adeba8
    https://github.com/scummvm/scummvm/commit/143c483bde9bd5f07bfd805df69949f8d0adeba8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Load from launcher

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index dfc9634ad80..e6be0246dd3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -344,6 +344,14 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
 	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
 	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
+
+	// If requested, load a savegame instead of showing the intro
+	_loadSaveSlot = -1;
+	if (ConfMan.hasKey("save_slot")) {
+		int saveSlot = ConfMan.getInt("save_slot");
+		if (saveSlot >= 0 && saveSlot <= 999)
+			_loadSaveSlot = saveSlot;
+	}
 }
 
 EfhEngine::~EfhEngine() {
@@ -1073,12 +1081,14 @@ void EfhEngine::initEngine() {
 	
 	saveAnimImageSetId();
 
-	// Load Title Screen
+	// Load Title Screen, skip if loading a savegame from launcher
 	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
-	displayFctFullScreen();
-	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
-	displayFctFullScreen();
-	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
+	if (_loadSaveSlot == -1) {
+		displayFctFullScreen();
+		displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
+		displayFctFullScreen();
+		displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
+	}
 
 	// Load map tiles bitmaps
 	loadImageSetToTileBank(1, 1);
@@ -1110,7 +1120,7 @@ void EfhEngine::initEngine() {
 	setDefaultNoteDuration();
 	Common::KeyCode lastInput = playSong(_titleSong);
 
-	if (lastInput != Common::KEYCODE_ESCAPE) {
+	if (lastInput != Common::KEYCODE_ESCAPE && _loadSaveSlot == -1) {
 		playIntro();
 	}
 
@@ -1122,7 +1132,12 @@ void EfhEngine::initEngine() {
 	// Note: The original at this point saves int 24h and sets a new int24 to handle fatal failure
 
 	checkProtection();
-	loadEfhGame();
+	if (_loadSaveSlot == -1) {
+		loadEfhGame();
+	} else {
+		loadGameState(_loadSaveSlot);
+		_loadSaveSlot = -1;
+	}
 	_engineInitPending = false;
 }
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index ed9b7eaebe2..8e5211638e3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -43,15 +43,15 @@ class RandomSource;
  * This is the namespace of the Efh engine.
  *
  * Status of this engine:
- * - No savegames
  * - No music in intro
  * - No random PC speaker farts (aka sounds)
+ * - The rest is more or less working :)
  *
  * Games using this engine:
  * - Escape From Hell
  * 
  * Note: Wasteland and Fountain of dreams *seem* to use the same engine, but it's not the case.
- * This engine was written from scratch based on the visual look of the other
+ * Escape From Hell was written from scratch based on the visual look of the other
  */
 namespace Efh {
 
@@ -281,6 +281,7 @@ private:
 
 	GameType _gameType;
 	Common::Platform _platform;
+	int _loadSaveSlot;
 
 	void initialize();
 	void readAnimInfo();


Commit: a3046a0be0286964fd537c62800c885c3ab00c0a
    https://github.com/scummvm/scummvm/commit/a3046a0be0286964fd537c62800c885c3ab00c0a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:40+01:00

Commit Message:
EFH: Janitorial - Remove trailing spaces & tabs

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp
    engines/efh/metaengine.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e6be0246dd3..3068ab76f0f 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -132,7 +132,7 @@ void NPCStruct::init() {
 
 	for (int i = 0; i < 10; ++i)
 		_inventory[i].init();
-	
+
 	_possessivePronounSHL6 = 0;
 	_speed = 0;
 	field_6B = 0;
@@ -405,7 +405,7 @@ Common::Error EfhEngine::loadGameState(int slot) {
 
 	if (signature != EFH_SAVE_HEADER || version > kSavegameVersion)
 		error("Invalid savegame");
-	
+
 	// Skip savegame name
 	uint16 size = saveFile->readUint16LE();
 	saveFile->skip(size);
@@ -414,10 +414,10 @@ Common::Error EfhEngine::loadGameState(int slot) {
 	Graphics::Surface *thumbnail;
 	Graphics::loadThumbnail(*saveFile, thumbnail);
 	delete (thumbnail);
-	
+
 	// Skip the savegame date
-	saveFile->skip(10); // year, month, day, hours, minutes (all int16) 
-	
+	saveFile->skip(10); // year, month, day, hours, minutes (all int16)
+
 	Common::Serializer s(saveFile, nullptr);
 	synchronize(s);
 
@@ -447,7 +447,7 @@ Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, boo
 	out->writeUint16LE(size);
 	for (int i = 0; i < size; ++i)
 		out->writeByte(desc.c_str()[i]);
- 
+
 	// Get the active palette
 	uint8 thumbPalette[16 * 3];
 	_system->getPaletteManager()->grabPalette(thumbPalette, 0, 16);
@@ -457,7 +457,7 @@ Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, boo
 	::createThumbnail(thumb, (const byte *)sf->getPixels(), 320, 200, thumbPalette);
 	Graphics::saveThumbnail(*out, *thumb);
 	thumb->free();
-	delete thumb; 
+	delete thumb;
 
 	// Write out the save date/time
 	TimeDate td;
@@ -468,7 +468,7 @@ Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, boo
 	out->writeSint16LE(td.tm_hour);
 	out->writeSint16LE(td.tm_min);
 
-	Common::Serializer s(nullptr, out);	
+	Common::Serializer s(nullptr, out);
 	synchronize(s);
 
 	out->finalize();
@@ -599,8 +599,8 @@ Common::Error EfhEngine::run() {
 				clearBottomTextZone_2(0);
 				displayLowStatusScreen(true);
 			}
-			
-			}			
+
+			}
 			break;
 		case Common::KEYCODE_F7: { // Original is using CTRL-L
 			for (int16 counter = 0; counter < 2; ++counter) {
@@ -649,7 +649,7 @@ Common::Error EfhEngine::run() {
 			if (_largeMapFlag) {
 				_techDataId_MapPosX = _mapPosX;
 				_techDataId_MapPosY = _mapPosY;
-			}			
+			}
 		}
 
 		if (!_shouldQuit) {
@@ -692,7 +692,7 @@ void EfhEngine::initialize() {
 
 void EfhEngine::readAnimInfo() {
 	debugC(6, kDebugEngine, "readAnimInfo");
-	
+
 	Common::String fileName = "animinfo";
 	uint8 animInfoBuf[9000];
 	memset(animInfoBuf, 0, 9000);
@@ -729,7 +729,7 @@ void EfhEngine::readAnimInfo() {
 
 void EfhEngine::findMapFile(int16 mapId) {
 	debugC(7, kDebugEngine, "findMapFile %d", mapId);
-	
+
 	if (!_word31E9E)
 		return;
 
@@ -744,7 +744,7 @@ void EfhEngine::findMapFile(int16 mapId) {
 
 void EfhEngine::loadNewPortrait() {
 	debugC(7, kDebugEngine, "loadNewPortrait");
-	
+
 	static int16 const unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
 	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
 
@@ -759,7 +759,7 @@ void EfhEngine::loadNewPortrait() {
 
 void EfhEngine::loadAnimImageSet() {
 	debug("loadAnimImageSet");
-	
+
 	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
 		return;
 
@@ -774,14 +774,14 @@ void EfhEngine::loadAnimImageSet() {
 
 void EfhEngine::loadHistory() {
 	debug("loadHistory");
-	
+
 	Common::String fileName = "history";
 	readFileToBuffer(fileName, _history);
 }
 
 void EfhEngine::loadTechMapImp(int16 fileId) {
 	debug("loadTechMapImp %d", fileId);
-	
+
 	if (fileId == 0xFF)
 		return;
 
@@ -790,23 +790,23 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 
 	// The original was loading the specific tech.%d and map.%d files.
 	// This is gone in our implementation as we pre-load all the files to save them inside the savegames
-	
+
 	// This is not present in the original.
 	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
 	loadMapArrays(_techId);
-	
+
 	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId][0] + 1);
 	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId][1] + 1);
 
 	initMapMonsters();
 	readImpFile(_techId, true);
 	displayAnimFrames(0xFE, false);
-	
+
 }
 
 void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 	debug("loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
-	
+
 	if (fullPlaceId == 0xFF)
 		return;
 
@@ -826,7 +826,7 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 
 void EfhEngine::readTileFact() {
 	debugC(7, kDebugEngine, "readTileFact");
-	
+
 	Common::String fileName = "tilefact";
 	uint8 tileFactBuff[864];
 	readFileToBuffer(fileName, tileFactBuff);
@@ -839,7 +839,7 @@ void EfhEngine::readTileFact() {
 
 void EfhEngine::readItems() {
 	debugC(7, kDebugEngine, "readItems");
-	
+
 	Common::String fileName = "items";
 	uint8 itemBuff[8100];
 	readFileToBuffer(fileName, itemBuff);
@@ -849,7 +849,7 @@ void EfhEngine::readItems() {
 		for (int16 idx = 0; idx < 15; ++idx)
 			_items[i]._name[idx] = *curPtr++;
 
-		
+
 		_items[i]._damage = *curPtr++;
 		_items[i]._defense = *curPtr++;
 		_items[i]._attacks = *curPtr++;
@@ -869,7 +869,7 @@ void EfhEngine::readItems() {
 
 void EfhEngine::loadNPCS() {
 	debugC(7, kDebugEngine, "loadNPCS");
-	
+
 	Common::String fileName = "npcs";
 	uint8 npcLoading[13400];
 	readFileToBuffer(fileName, npcLoading);
@@ -940,16 +940,16 @@ void EfhEngine::loadNPCS() {
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	warning("STUB: playSong");
 
-	
-	
+
+
 	_system->delayMillis(1000);
-	
+
 	return Common::KEYCODE_INVALID;
 }
 
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 	debug("readImpFile %d %s", id, techMapFl ? "True" : "False");
-	
+
 	Common::String fileName = Common::String::format("imp.%d", id);
 
 	if (techMapFl)
@@ -962,7 +962,7 @@ void EfhEngine::readImpFile(int16 id, bool techMapFl) {
 
 void EfhEngine::playIntro() {
 	debugC(6, kDebugEngine, "playIntro");
-	
+
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
@@ -980,7 +980,7 @@ void EfhEngine::playIntro() {
 	displayFctFullScreen();
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 144);
 	drawText(_imp2PtrArray[0], 6, 150, 268, 186, false);
-	
+
 	lastInput = getLastCharAfterAnimCount(80);
 	if (lastInput == Common::KEYCODE_ESCAPE)
 		return;
@@ -1078,7 +1078,7 @@ void EfhEngine::initEngine() {
 
 	// Pre-load stuff required for savegames
 	preLoadMaps();
-	
+
 	saveAnimImageSetId();
 
 	// Load Title Screen, skip if loading a savegame from launcher
@@ -1115,7 +1115,7 @@ void EfhEngine::initEngine() {
 
 	// Load picture room with girlfriend
 	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
-	fileName = "titlsong"; 
+	fileName = "titlsong";
 	readFileToBuffer(fileName, _titleSong);
 	setDefaultNoteDuration();
 	Common::KeyCode lastInput = playSong(_titleSong);
@@ -1143,7 +1143,7 @@ void EfhEngine::initEngine() {
 
 void EfhEngine::initMapMonsters() {
 	debug("initMapMonsters");
-	
+
 	for (uint8 monsterId = 0; monsterId < 64; ++monsterId) {
 		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 			continue;
@@ -1168,7 +1168,7 @@ void EfhEngine::initMapMonsters() {
 				uint16 delta = getRandom(pictureRef / 2);
 				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef + delta;
 			}
-		}		
+		}
 	}
 }
 
@@ -1186,7 +1186,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapUnknown[i]._field5 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
 		_mapUnknown[i]._field7 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
 	}
-	
+
 	uint8 *mapMonstersPtr = &_mapArr[idx][902];
 
 	for (int i = 0; i < 64; ++i) {
@@ -1257,7 +1257,7 @@ uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
 			continue;
 
 		int16 itemId = _npcBuf[charId]._inventory[i]._ref;
-		
+
 		if (_items[itemId].field_18 != field18)
 			continue;
 
@@ -1280,7 +1280,7 @@ void EfhEngine::drawGameScreenAndTempText(bool flag) {
 
 	int16 mapImageSetId = (imageSetId * 72) + (mapTileInfo % 72);
 	#endif
-	
+
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			displayGameScreen();
@@ -1301,7 +1301,7 @@ void EfhEngine::drawGameScreenAndTempText(bool flag) {
 
 void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 mapSize, bool drawHeroFl, bool drawMonstersFl) {
 	debugC(6, kDebugEngine, "drawMap %s %d-%d %d %s %s", largeMapFl ? "True" : "False", mapPosX, mapPosY, mapSize, drawHeroFl ? "True" : "False", drawMonstersFl ? "True" : "False");
-	
+
 	int16 shiftPosX = 5;
 	int16 shiftPosY = 4;
 	int16 minX = mapPosX - 5;
@@ -1404,7 +1404,7 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 
 void EfhEngine::drawScreen() {
 	debugC(2, kDebugEngine, "drawScreen");
-	
+
 	for (int16 counter = 0; counter < 2; ++counter) {
 		_redrawNeededFl = false;
 		if (!_largeMapFlag) {
@@ -1429,14 +1429,14 @@ void EfhEngine::drawScreen() {
 
 void EfhEngine::displayLowStatusScreen(bool flag) {
 	debugC(6, kDebugEngine, "displayLowStatusScreen %s", flag ? "True" : "False");
-	
+
 	static char strName[5] = "Name";
 	static char strDef[4] = "DEF";
 	static char strHp[3] = "HP";
 	static char strMaxHp[7] = "Max HP";
 	static char strWeapon[7] = "Weapon";
 	static char strDead[9] = "* DEAD *";
-	
+
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			clearBottomTextZone(0);
@@ -1476,7 +1476,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					else
 						_nameBuffer = _items[var4]._name;
 					}
-					break;				
+					break;
 				case 1:
 					_nameBuffer = "* ASLEEP *";
 					break;
@@ -1499,7 +1499,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 
 uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
 	debug("script_readNumberArray");
-	
+
 	uint8 *buffer = srcBuffer;
 	for (int16 i = 0; i < destArraySize; ++i) {
 		buffer++;
@@ -1511,8 +1511,8 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 
 uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
 	debug("script_getNumber");
-	
-	uint8 *buffer = srcBuffer; 
+
+	uint8 *buffer = srcBuffer;
 	int16 var2 = 0;
 	for (;;) {
 		uint8 curChar = *buffer;
@@ -1564,7 +1564,7 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 
 void EfhEngine::refreshTeamSize() {
 	debug("refreshTeamSize");
-	
+
 	_teamSize = 0;
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
@@ -1585,7 +1585,7 @@ bool EfhEngine::isCharacterATeamMember(int16 id) {
 
 bool EfhEngine::isTPK() {
 	debug("isTPK");
-	
+
 	int16 zeroedChar = 0;
 	for (int16 counter = 0; counter < _teamSize; ++counter) {
 		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
@@ -1597,7 +1597,7 @@ bool EfhEngine::isTPK() {
 
 void EfhEngine::handleWinSequence() {
 	debugC(1, kDebugEngine, "handleWinSequence");
-	
+
 	saveAnimImageSetId();
 	findMapFile(18);
 	// clearMemory();
@@ -1670,7 +1670,7 @@ void EfhEngine::handleWinSequence() {
 			input = getInput(1);
 		}
 	}
-	
+
 	free(decompBuffer);
 	free(winSeqBuf3);
 	free(winSeqBuf4);
@@ -1718,7 +1718,7 @@ int16 EfhEngine::chooseCharacterToReplace() {
 
 int16 EfhEngine::handleCharacterJoining() {
 	debug("handleCharacterJoining");
-	
+
 	static char strReplaceWho[13] = "Replace Who?";
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
@@ -1910,7 +1910,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag && scriptNumberArray[0] != -1) {
 				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
 			}
-			break;		
+			break;
 		case 0x09:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
@@ -1955,7 +1955,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 							removeObject(_teamCharId[counter], objectId);
 							found = true;
 							break;
-						}						
+						}
 					}
 				}
 			}
@@ -1998,7 +1998,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 				if (isCharacterATeamMember(var110))
 					var_F0 = scriptNumberArray[1];
 				else
-					var_F0 = scriptNumberArray[2];	
+					var_F0 = scriptNumberArray[2];
 			}
 			break;
 		case 0x10:
@@ -2060,7 +2060,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 							break;
 						}
 					}
-				}				
+				}
 			}
 			break;
 		case 0x17:
@@ -2197,10 +2197,10 @@ void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;
 	memset(_messageToBePrinted, 0, 200);
-	
+
 	for (;;) {
 		uint8 curChar = *impPtr;
-		
+
 		if (curChar == 0 || curChar == 0x40 || curChar == 0x60)
 			break;
 
@@ -2220,7 +2220,7 @@ void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 
 void EfhEngine::displayMiddleLeftTempText(uint8 *impArray, bool flag) {
 	debugC(3, kDebugEngine, "displayMiddleLeftTempText %s %s", (char *)impArray, flag ? "True" : "False");
-	
+
 	for (uint8 counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			// clear middle-left text area
@@ -2298,7 +2298,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;
-	
+
 	switch (menuType) {
 	case 0:
 		minX = 129;
@@ -2777,7 +2777,7 @@ bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 
 bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 	debug("moveMonsterGroupOther %d %d", monsterId, direction);
-	
+
 	switch (direction - 1) {
 	case 0:
 		--_mapMonsters[monsterId]._posY;
@@ -2829,7 +2829,7 @@ bool EfhEngine::moveMonsterGroup(int16 monsterId) {
 
 int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
 	debugC(2, kDebugEngine, "computeMonsterGroupDistance %d", monsterId);
-	
+
 	int16 monsterPosX = _mapMonsters[monsterId]._posX;
 	int16 monsterPosY = _mapMonsters[monsterId]._posY;
 
@@ -2841,7 +2841,7 @@ int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
 
 bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
 	debugC(6, kDebugEngine, "checkWeaponRange %d %d", monsterId, weaponId);
-	
+
 	static const int16 kRange[5] = {1, 2, 3, 3, 3};
 
 	assert(_items[weaponId]._range < 5);
@@ -2886,7 +2886,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 
 bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkIfMonsterOnSameLargeMapPlace %d", monsterId);
-	
+
 	if (_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
 		return true;
 
@@ -2898,7 +2898,7 @@ bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 
 bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMonsterWeaponRange %d", monsterId);
-	
+
 	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
 }
 
@@ -2907,7 +2907,7 @@ void EfhEngine::sub174A0() {
 
 	static int16 sub174A0_monsterPosX = -1;
 	static int16 sub174A0_monsterPosY = -1;
-	
+
 	int16 var14 = 0;
 	int16 var6 = 0;
 	_redrawNeededFl = true;
@@ -2917,7 +2917,7 @@ void EfhEngine::sub174A0() {
 	int16 minDisplayedMapY = CLIP<int16>(_mapPosY - 9, 0, mapSize);
 	int16 maxDisplayedMapX = CLIP<int16>(minDisplayedMapX + 20, 0, mapSize);
 	int16 maxDisplayedMapY = CLIP<int16>(minDisplayedMapY + 17, 0, mapSize);
-	
+
 	for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
 		if (!checkPictureRefAvailability(monsterId))
 			continue;
@@ -3071,7 +3071,7 @@ void EfhEngine::sub174A0() {
 					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
 					continue;
 				}
-				
+
 				break;
 			}
 		} while (!var1A && var16 > 0);
@@ -3083,7 +3083,7 @@ void EfhEngine::sub174A0() {
 
 bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkPictureRefAvailability %d", monsterId);
-	
+
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
@@ -3283,7 +3283,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		displayAnimFrames(0xFE, true);
 		return true;
 	default:
-		
+
 		break;
 	}
 
@@ -3336,7 +3336,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 			do {
 				switch (*var12) {
 				case 0x00:
-				case 0x0A:					
+				case 0x0A:
 					break;
 				case 0x0D:
 				case 0x20:
@@ -3388,7 +3388,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 						var2 = sub1C219(_messageToBePrinted, 1, 1, true);
 						if (var2 != 0xFF)
 							var4 = var2;
-						
+
 						if (var4 != -1) {
 							for (int16 counter = 0; counter < 2; ++counter) {
 								if (varA) {
@@ -3405,7 +3405,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					if (var2 != 0xFF)
 						var4 = var2;
 				}
-				
+
 			} while (varA == 0 && var4 != -1);
 
 			varA = 0;
@@ -3419,7 +3419,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 
 bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
 	debug("sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
-	
+
 	int16 var8 = sub151FD(mapPosX, mapPosY);
 
 	if (var8 == -1) {
@@ -3479,7 +3479,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					sub22AA8(_mapUnknown[var8]._field5);
 					return true;
 				}
-			}		
+			}
 		}
 	}
 
@@ -3492,7 +3492,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		if (_mapUnknown[var8]._field7 > 0xFE)
 			return false;
 		sub22AA8(_mapUnknown[var8]._field7);
-		return true;		
+		return true;
 	}
 
 	return false;
@@ -3500,7 +3500,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 
 int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	debug("sub15581 %d-%d %d", mapPosX, mapPosY, arg4);
-	
+
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
 	imageSetId *= 72;
@@ -3608,7 +3608,7 @@ void EfhEngine::sub1BE89(int16 monsterId) {
 
 void EfhEngine::resetTeamMonsterIdArray() {
 	debug("resetTeamMonsterIdArray");
-	
+
 	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
 	}
@@ -3616,7 +3616,7 @@ void EfhEngine::resetTeamMonsterIdArray() {
 
 bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 	debug("isTeamMemberStatusNormal %d", teamMemberId);
-	
+
 	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
 		return true;
 
@@ -3625,7 +3625,7 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 
 void EfhEngine::sub1CDFA() {
 	debug("sub1CDFA"); // Initiatives
-	
+
 	for (int16 counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
 			_stru3244C[counter]._field0 = counter + 1000;
@@ -3652,14 +3652,14 @@ void EfhEngine::sub1CDFA() {
 				continue;
 
 			SWAP(_stru3244C[counter]._field0, _stru3244C[counter2]._field0);
-			SWAP(_stru3244C[counter]._field2, _stru3244C[counter2]._field2);			
+			SWAP(_stru3244C[counter]._field2, _stru3244C[counter2]._field2);
 		}
 	}
 }
 
 void EfhEngine::redrawScreenForced() {
 	debug("redrawScreenForced");
-	
+
 	for (int16 counter = 0; counter < 2; ++counter) {
 		drawScreen();
 		if (counter == 0)
@@ -3669,7 +3669,7 @@ void EfhEngine::redrawScreenForced() {
 
 int16 EfhEngine::selectMonsterGroup() {
 	debug("selectMonsterGroup");
-	
+
 	int16 retVal = -1;
 
 	while (retVal == -1) {
@@ -3697,9 +3697,9 @@ int16 EfhEngine::selectMonsterGroup() {
 
 int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
-	
+
 	int16 varE = -1;
-	
+
 	int16 var6 = sub1C80A(charId, unkFied18Val, true);
 	int16 range = 0;
 	if (var6 != 0x7FFF)
@@ -3748,7 +3748,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 
 	if (varE == 27)
 		varE = -1;
-	
+
 	return varE;
 }
 
@@ -3841,7 +3841,7 @@ bool EfhEngine::sub1CB27() {
 					case 26:
 						_teamNextAttack[counter1] = 0xC8;
 						break;
-						
+
 					case 19:
 					case 20:
 					case 21:
@@ -3850,9 +3850,9 @@ bool EfhEngine::sub1CB27() {
 					default:
 						break;
 					}
-					
+
 				}
-				
+
 				}
 				break;
 			case Common::KEYCODE_t: // Terrain
@@ -3895,7 +3895,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 			}
 			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
 		}
-		
+
 	}
 	// sub1BE9A - 1rst loop counter1_monsterId - End
 
@@ -3916,7 +3916,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 			for (int16 counter1 = 0; counter1 < 64; ++counter1) {
 				if (_mapMonsters[counter1]._guess_fullPlaceId == 0xFF)
 					continue;
-				
+
 				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._field_1)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(counter1)) {
 						bool var6 = false;
@@ -3946,12 +3946,12 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
 							_stru32686[counter1]._field0[counter2] = 0;
 						}
-						
+
 						if (++var4 >= 5)
 							break;
 					}
 				}
-			}			
+			}
 		}
 		// sub1BE9A - loop var2 - End
 	}
@@ -3993,7 +3993,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 
 int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	debugC(9, kDebugEngine, "countMonsterGroupMembers %d", monsterGroup);
-	
+
 	int16 result = 0;
 	for (int16 counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(monsterGroup, counter))
@@ -4121,7 +4121,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 
 void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	debug("handleFight_checkEndEffect %d", charId);
-	
+
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 	if (_teamCharStatus[charId]._status == 0)
@@ -4159,7 +4159,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 
 int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 	debug("sub1DEC8 %d", groupNumber);
-	
+
 	int16 var4 = -1;
 	int16 monsterId = _teamMonsterIdArray[groupNumber];
 
@@ -4390,7 +4390,7 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	debug("hasAdequateDefense %d %d", monsterId, attackType);
 
 	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
-	
+
 	if (_items[itemId].field_16 != 0)
 		return false;
 
@@ -4662,14 +4662,14 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		break;
 	default:
 		break;
-	}	
+	}
 
 	strncat((char *)_messageToBePrinted, buffer, 80);
 }
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
-	
+
 	int16 rndVal = getRandom(100);
 	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
 		return false;
@@ -4708,12 +4708,12 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 	strncat((char *)_messageToBePrinted, buffer, 80);
 	if (!characterSearchesMonsterCorpse(charId, monsterId))
 		strncat((char *)_messageToBePrinted, "!", 2);
-	
+
 }
 
 void EfhEngine::addReactionText(int16 id) {
 	debug("addReactionText %d", id);
-	
+
 	int16 rand3 = getRandom(3);
 	char buffer[80];
 	memset(buffer, 0, 80);
@@ -4910,12 +4910,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						}
 					}
 					// Action A - Loop var84 - End
-					
+
 					if (originalDamage < 0)
 						originalDamage = 0;
 
 					hitPoints = originalDamage + damagePointsAbsorbed;
-					
+
 					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
 						var62 = 0;
 
@@ -5127,7 +5127,7 @@ char EfhEngine::getFightMessageLastCharacter(char *message) {
 
 void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	debug("sub1D8C2 %d %d", charId, damage);
-	
+
 	int16 var42 = 0;
 	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
 
@@ -5432,7 +5432,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										break;
 									default:
 										break;
-									} 
+									}
 									// handleFight - Check effect - end
 								} else {
 									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
@@ -5697,7 +5697,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 
 void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
 	debug("displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
-	
+
 	setTextColorRed();
 	Common::String buffer = _npcBuf[charId]._name;
 	setTextPos(146, 27);
@@ -5734,7 +5734,7 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 
 void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
 	debug("displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
-	
+
 	drawColoredRect(144, 15, 310, 184, 0);
 	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
 	_textColor = 0x0E;
@@ -5807,7 +5807,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 	debug("displayString_3 %s %s %d %d %d %d", str, animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
-	
+
 	for (int16 counter = 0; counter < 2; ++counter) {
 		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
@@ -5824,7 +5824,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 		getLastCharAfterAnimCount(_guessAnimationAmount);
 		sub18E80(charId, windowId, menuId, curMenuLine);
 	}
-	
+
 	return retVal;
 }
 
@@ -5855,7 +5855,7 @@ void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, in
 	} else {
 		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
 	}
-	
+
 }
 
 void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
@@ -5919,7 +5919,7 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 	debug("selectOtherCharFromTeam");
 
 	Common::KeyCode maxVal = (Common::KeyCode) (Common::KEYCODE_0 + _teamSize);
-	Common::KeyCode input = Common::KEYCODE_INVALID; 
+	Common::KeyCode input = Common::KEYCODE_INVALID;
 	for (;;) {
 		input = waitForKey();
 		if (input == Common::KEYCODE_ESCAPE || (input >= Common::KEYCODE_0 && input <= maxVal))
@@ -5970,7 +5970,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					}
 				}
 			}
-			// The original was duplicating this code in each branch of the previous random check. 
+			// The original was duplicating this code in each branch of the previous random check.
 			if (victims > 1) {
 				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			} else {
@@ -6051,7 +6051,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 						}
 						break;
 					}
-				}				
+				}
 			}
 		}
 		varA6 = true;
@@ -6071,7 +6071,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					if (isMonsterActive(windowId, counter)) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
-				}				
+				}
 			}
 		}
 
@@ -6106,7 +6106,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (_word32482[varAA] < 0)
 				_word32482[varAA] = 0;
 		}
-		
+
 		varA6 = true;
 		}
 		break;
@@ -6122,7 +6122,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (teamCharId != 0x1B) {
 			buffer1 = "  The magic makes the user invisible!";
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine); 
+				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
 				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			}
@@ -6172,7 +6172,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			}
 		}
 
-		varA6 = true;		
+		varA6 = true;
 		}
 		break;
 	case 17: { // "Devil Dust"
@@ -6384,7 +6384,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				if (_teamCharStatus[teamCharId]._status == 0) {
 					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!", 80);
 					_teamCharStatus[teamCharId]._status = 0;
-					_teamCharStatus[teamCharId]._duration = 0; 
+					_teamCharStatus[teamCharId]._duration = 0;
 				} else {
 					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!", 80);
 				}
@@ -6401,7 +6401,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		} else {
 			teamCharId = windowId;
 		}
-		
+
 		if (teamCharId != 0x1B) {
 			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
@@ -6453,7 +6453,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		varA6 = true;
-		
+
 		}
 		break;
 	case 3:
@@ -7105,9 +7105,9 @@ void EfhEngine::checkProtection() {
 	_textColor = 0xE;
 
 	//CHECKME : Well, yeah, some code may be missing there. Who knows.
-	
+
 	_protectionPassed = true;
-	drawGameScreenAndTempText(true);	
+	drawGameScreenAndTempText(true);
 }
 
 void EfhEngine::loadEfhGame() {
@@ -7141,7 +7141,7 @@ void EfhEngine::loadEfhGame() {
 
 	_teamSize = f.readSint16LE();
 
-	_unkArray2C8AA[0] = f.readSint16LE();		
+	_unkArray2C8AA[0] = f.readSint16LE();
 
 	_word2C872 = f.readSint16LE();
 
@@ -7212,7 +7212,7 @@ uint16 EfhEngine::getStringWidth(const char *buffer) {
 
 	if (retVal)
 		retVal--;
-	
+
 	return retVal;
 }
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8e5211638e3..8b8d3e1fd68 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -49,7 +49,7 @@ class RandomSource;
  *
  * Games using this engine:
  * - Escape From Hell
- * 
+ *
  * Note: Wasteland and Fountain of dreams *seem* to use the same engine, but it's not the case.
  * Escape From Hell was written from scratch based on the visual look of the other
  */
@@ -481,7 +481,7 @@ private:
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
 	void loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
-	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);	
+	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
 	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	int16 getRandom(int16 maxVal);
 	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
@@ -526,7 +526,7 @@ private:
 	Common::String _nameBuffer;
 	char _attackBuffer[20];
 	uint8 _messageToBePrinted[400];
-	
+
 	uint8 *_mapBitmapRefArr[19];
 	UnkMapStruct _mapUnknown[100];
 	MapMonster _mapMonsters[64];
@@ -558,7 +558,7 @@ private:
 	int16 _teamCharId[3];
 	int16 _textPosX;
 	int16 _textPosY;
-	
+
 	Common::Rect _initRect;
 	bool _engineInitPending;
 	bool _protectionPassed;
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 486fd75ecdc..cb81f6841dc 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -103,7 +103,7 @@ void EfhEngine::displayAnimFrames(int16 animId, bool displayMenuBoxFl) {
 
 void EfhEngine::displayFctFullScreen() {
 	debugC(1, kDebugGraphics, "displayFctFullScreen");
-	
+
 	// CHECKME: 319 is in the original but looks suspicious.
 	// copyDirtyRect(0, 0, 319, 200);
 
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index 01d76fb8264..f39da1dfd73 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -155,7 +155,7 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 			return SaveStateDescriptor();
 		}
 		desc.setThumbnail(thumbnail);
-		
+
 		// Read in save date/time
 		int16 year = file->readSint16LE();
 		int16 month = file->readSint16LE();
@@ -164,7 +164,7 @@ SaveStateDescriptor EfhMetaEngine::querySaveMetaInfos(const char *target, int sl
 		int16 minute = file->readSint16LE();
 		desc.setSaveDate(year, month, day);
 		desc.setSaveTime(hour, minute);
-		
+
 		desc.setDeletableFlag(slot != 0);
 		desc.setWriteProtectedFlag(slot == 0);
 
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index e621d91b37a..d95845d0458 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -285,7 +285,7 @@ Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
 	_system->getEventManager()->pollEvent(event);
 	Common::KeyCode retVal = Common::KEYCODE_INVALID;
 
-	uint32 lastMs = _system->getMillis(); 
+	uint32 lastMs = _system->getMillis();
 	while (retVal == Common::KEYCODE_INVALID) {
 		_system->getEventManager()->pollEvent(event);
 


Commit: 473b74aab3cc936f2aa1d01d1a931ece7f64411e
    https://github.com/scummvm/scummvm/commit/473b74aab3cc936f2aa1d01d1a931ece7f64411e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Fix headers (GPLv3)

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/detection.cpp
    engines/efh/detection.h
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp
    engines/efh/metaengine.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 2deb3ec0782..a4ac45ecc2c 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 0fced1a00fa..d90cab882f5 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/detection.cpp b/engines/efh/detection.cpp
index e58602b5e1c..3f563edce6a 100644
--- a/engines/efh/detection.cpp
+++ b/engines/efh/detection.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/detection.h b/engines/efh/detection.h
index 9c4a40452b8..c48a6d0ea2f 100644
--- a/engines/efh/detection.h
+++ b/engines/efh/detection.h
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3068ab76f0f..40a35c40b5e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8b8d3e1fd68..44eaaee13b9 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index cb81f6841dc..7d87337f7ce 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index f39da1dfd73..fbb31d5181e 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index d95845d0458..2d379bde859 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -4,19 +4,18 @@
  * are too numerous to list here. Please refer to the COPYRIGHT
  * file distributed with this source distribution.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
-
+ *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
 


Commit: 7ec543b2bf2ab3b1c349f30f653e42e67427fe9d
    https://github.com/scummvm/scummvm/commit/7ec543b2bf2ab3b1c349f30f653e42e67427fe9d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Remove game type, simplify game descriptions

Changed paths:
  R engines/efh/detection.h
    engines/efh/constants.cpp
    engines/efh/detection.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/metaengine.cpp


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index a4ac45ecc2c..e5550d481d7 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -21,7 +21,7 @@
 
 #include "efh/constants.h"
 
-#include "engine.h"
+#include "engines/engine.h"
 
 namespace Efh {
 
diff --git a/engines/efh/detection.cpp b/engines/efh/detection.cpp
index 3f563edce6a..81f13ff46dd 100644
--- a/engines/efh/detection.cpp
+++ b/engines/efh/detection.cpp
@@ -21,9 +21,7 @@
 
 #include "base/plugins.h"
 #include "engines/advancedDetector.h"
-#include "common/textconsole.h"
 
-#include "efh/detection.h"
 #include "efh/efh.h"
 
 namespace Efh {
@@ -34,27 +32,25 @@ static const PlainGameDescriptor efhGames[] = {
 	{nullptr, nullptr}
 };
 
-static const EfhGameDescription gameDescriptions[] = {
+static const ADGameDescription gameDescriptions[] = {
 
 	// Escape From Hell English - Unpacked version
 	{
-		{"efh", nullptr, AD_ENTRY1s("escape.exe", "2702f8f713e113a853a925d29aecc709", 147312),
-			Common::EN_ANY,
-			Common::kPlatformDOS,
-			ADGF_UNSTABLE,
-			GUIO0()
-		},
-		kGameTypeEfh
+		"efh", nullptr, AD_ENTRY1s("escape.exe", "2702f8f713e113a853a925d29aecc709", 147312),
+		Common::EN_ANY,
+		Common::kPlatformDOS,
+		ADGF_UNSTABLE,
+		GUIO0()
 	},
 	// Escape From Hell English
 	{
-		{"efh", nullptr, AD_ENTRY1s("escape.exe", "1ca4ae3f2ea66c30d1ef3e257a86cd05", 141487),
-		 Common::EN_ANY,
-		 Common::kPlatformDOS,
-		 ADGF_UNSTABLE,
-		 GUIO0()},
-		kGameTypeEfh},
-	{AD_TABLE_END_MARKER, kGameTypeNone}
+		"efh", nullptr, AD_ENTRY1s("escape.exe", "1ca4ae3f2ea66c30d1ef3e257a86cd05", 141487),
+		Common::EN_ANY,
+		Common::kPlatformDOS,
+		ADGF_UNSTABLE,
+		GUIO0()
+	},
+	AD_TABLE_END_MARKER
 };
 
 static const DebugChannelDef debugFlagList[] = {
@@ -65,7 +61,7 @@ static const DebugChannelDef debugFlagList[] = {
 
 class EfhMetaEngineDetection : public AdvancedMetaEngineDetection {
 public:
-	EfhMetaEngineDetection() : AdvancedMetaEngineDetection(gameDescriptions, sizeof(EfhGameDescription), efhGames) {
+	EfhMetaEngineDetection() : AdvancedMetaEngineDetection(gameDescriptions, sizeof(ADGameDescription), efhGames) {
 	}
 
 	const char *getEngineName() const override {
diff --git a/engines/efh/detection.h b/engines/efh/detection.h
deleted file mode 100644
index c48a6d0ea2f..00000000000
--- a/engines/efh/detection.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef EFH_DETECTION_H
-#define EFH_DETECTION_H
-
-#include "engines/advancedDetector.h"
-
-namespace Efh {
-
-enum GameType {
-	kGameTypeNone  = 0,
-	kGameTypeEfh
-};
-
-struct EfhGameDescription {
-	ADGameDescription desc;
-	GameType gameType;
-};
-
-} // End of namespace Efh
-
-#endif // EFH_DETECTION_H
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 40a35c40b5e..e3768e5c009 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -174,7 +174,7 @@ void TileFactStruct::init() {
 	_field0 = _field1 = 0;
 }
 
-EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst), _gameDescription(gd) {
+EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 
 	SearchMan.addSubDirectoryMatching(gameDataDir, "gendata");
@@ -188,7 +188,6 @@ EfhEngine::EfhEngine(OSystem *syst, const EfhGameDescription *gd) : Engine(syst)
 	_shouldQuit = false;
 	_eventMan = nullptr;
 	_lastTime = 0;
-	_gameType = kGameTypeNone;
 	_platform = Common::kPlatformUnknown;
 	_mainSurface = nullptr;
 
@@ -368,10 +367,6 @@ const char *EfhEngine::getCopyrightString() const {
 	return "Escape From Hell (C) Electronic Arts, 1990";
 }
 
-GameType EfhEngine::getGameType() const {
-	return _gameType;
-}
-
 Common::Platform EfhEngine::getPlatform() const {
 	return _platform;
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 44eaaee13b9..7c59a9ceffe 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -22,9 +22,10 @@
 #ifndef EFH_EFH_H
 #define EFH_EFH_H
 
-#include "efh/detection.h"
 #include "efh/constants.h"
 
+#include "engines/advancedDetector.h"
+
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/events.h"
@@ -63,8 +64,6 @@ enum AccessDebugChannels {
 	kDebugGraphics = 1 << 2
 };
 
-struct EfhGameDescription;
-
 class EfhGraphicsStruct {
 public:
 	EfhGraphicsStruct();
@@ -240,19 +239,18 @@ struct TileFactStruct {
 
 class EfhEngine : public Engine {
 public:
-	EfhEngine(OSystem *syst, const EfhGameDescription *gd);
+	EfhEngine(OSystem *syst, const ADGameDescription *gd);
 	~EfhEngine() override;
 
 	OSystem *_system;
 	Graphics::Surface *_mainSurface;
 	Common::RandomSource *_rnd;
 
-	const EfhGameDescription *_gameDescription;
+	const ADGameDescription *_gameDescription;
 	uint32 getFeatures() const;
 	const char *getGameId() const;
 
-	void initGame(const EfhGameDescription *gd);
-	GameType getGameType() const;
+	void initGame(const ADGameDescription *gd);
 	Common::Platform getPlatform() const;
 
 	bool hasFeature(EngineFeature f) const override;
@@ -278,7 +276,6 @@ protected:
 private:
 	static EfhEngine *s_Engine;
 
-	GameType _gameType;
 	Common::Platform _platform;
 	int _loadSaveSlot;
 
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index fbb31d5181e..26aca59b97d 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -27,16 +27,15 @@
 #include "graphics/surface.h"
 
 #include "efh/efh.h"
-#include "efh/detection.h"
 
 namespace Efh {
 
 uint32 EfhEngine::getFeatures() const {
-	return _gameDescription->desc.flags;
+	return _gameDescription->flags;
 }
 
 const char *EfhEngine::getGameId() const {
-	return _gameDescription->desc.gameId;
+	return _gameDescription->gameId;
 }
 
 } // End of namespace Efh
@@ -59,8 +58,8 @@ public:
 };
 
 Common::Error EfhMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
-	*engine = new EfhEngine(syst, (const EfhGameDescription *)gd);
-	((EfhEngine *)*engine)->initGame((const EfhGameDescription *)gd);
+	*engine = new EfhEngine(syst, gd);
+	((EfhEngine *)*engine)->initGame(gd);
 	return Common::kNoError;
 }
 
@@ -188,9 +187,8 @@ REGISTER_PLUGIN_STATIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
 
 namespace Efh {
 
-void EfhEngine::initGame(const EfhGameDescription *gd) {
-	_gameType = gd->gameType;
-	_platform = gd->desc.platform;
+void EfhEngine::initGame(const ADGameDescription *gd) {
+	_platform = gd->platform;
 }
 
 } // End of namespace Efh


Commit: e10d31a6b9f77360a7ab9a0ce43332415123944c
    https://github.com/scummvm/scummvm/commit/e10d31a6b9f77360a7ab9a0ce43332415123944c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Fix alignment in metaengine, reorder some includes, remove a useless include

Changed paths:
    engines/efh/constants.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp
    engines/efh/metaengine.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index e5550d481d7..6d1d01c6ee9 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -21,8 +21,6 @@
 
 #include "efh/constants.h"
 
-#include "engines/engine.h"
-
 namespace Efh {
 
 const uint8 kFontWidthArray[96] = {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 7c59a9ceffe..3d31f85993e 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -22,8 +22,6 @@
 #ifndef EFH_EFH_H
 #define EFH_EFH_H
 
-#include "efh/constants.h"
-
 #include "engines/advancedDetector.h"
 
 #include "common/file.h"
@@ -34,6 +32,7 @@
 #include "engines/engine.h"
 #include "graphics/surface.h"
 
+#include "efh/constants.h"
 
 namespace Common {
 class RandomSource;
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 7d87337f7ce..d77759d8481 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -19,9 +19,9 @@
  *
  */
 
-#include "efh/efh.h"
 #include "graphics/palette.h"
 #include "common/system.h"
+#include "efh/efh.h"
 
 namespace Efh {
 
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index 26aca59b97d..8276fe4012d 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -182,7 +182,7 @@ void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
 #if PLUGIN_ENABLED_DYNAMIC(EFH)
 	REGISTER_PLUGIN_DYNAMIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
 #else
-REGISTER_PLUGIN_STATIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
+	REGISTER_PLUGIN_STATIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
 #endif
 
 namespace Efh {
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index 2d379bde859..a720686e325 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -19,9 +19,9 @@
  *
  */
 
-#include "efh/efh.h"
 #include "common/system.h"
 #include "common/random.h"
+#include "efh/efh.h"
 
 namespace Efh {
 


Commit: 17a6120f5a5c1163520c2e5970e8e716040d04bd
    https://github.com/scummvm/scummvm/commit/17a6120f5a5c1163520c2e5970e8e716040d04bd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Start splitting efh.cpp

Changed paths:
  A engines/efh/files.cpp
  A engines/efh/savegames.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/metaengine.cpp
    engines/efh/module.mk
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e3768e5c009..01293e74dae 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -25,10 +25,7 @@
 #include "common/config-manager.h"
 #include "common/events.h"
 #include "engines/util.h"
-#include "common/savefile.h"
 #include "graphics/palette.h"
-#include "graphics/scaler.h"
-#include "graphics/thumbnail.h"
 
 #include "efh/efh.h"
 #include "efh/constants.h"
@@ -377,100 +374,6 @@ void EfhEngine::syncSoundSettings() {
 	//	_sound->syncVolume();
 }
 
-Common::String EfhEngine::getSavegameFilename(int slot) {
-	return _targetName + Common::String::format("-%03d.SAV", slot);
-}
-
-bool EfhEngine::canLoadGameStateCurrently() {
-	return true;
-}
-
-bool EfhEngine::canSaveGameStateCurrently() {
-	return true;
-}
-
-Common::Error EfhEngine::loadGameState(int slot) {
-	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(getSaveStateName(slot));
-	if (!saveFile)
-		return Common::kReadingFailed;
-
-	uint32 signature = saveFile->readUint32LE();
-	byte version = saveFile->readByte();
-
-	if (signature != EFH_SAVE_HEADER || version > kSavegameVersion)
-		error("Invalid savegame");
-
-	// Skip savegame name
-	uint16 size = saveFile->readUint16LE();
-	saveFile->skip(size);
-
-	// Skip the thumbnail
-	Graphics::Surface *thumbnail;
-	Graphics::loadThumbnail(*saveFile, thumbnail);
-	delete (thumbnail);
-
-	// Skip the savegame date
-	saveFile->skip(10); // year, month, day, hours, minutes (all int16)
-
-	Common::Serializer s(saveFile, nullptr);
-	synchronize(s);
-
-	delete saveFile;
-
-	_oldMapPosX = _mapPosX;
-	_oldMapPosY = _mapPosY;
-	_unkRelatedToAnimImageSetId = 0;
-
-	loadTechMapImp(_techId);
-	_lastMainPlaceId = 0xFFFF;
-	loadPlacesFile(_fullPlaceId, true);
-
-	return Common::kNoError;
-}
-
-Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
-	Common::OutSaveFile *out = _system->getSavefileManager()->openForSaving(getSaveStateName(slot));
-	if (!out)
-		return Common::kCreatingFileFailed;
-
-	out->writeUint32LE(EFH_SAVE_HEADER);
-	out->writeByte(kSavegameVersion);
-
-	// Write savegame name
-	uint16 size = desc.size();
-	out->writeUint16LE(size);
-	for (int i = 0; i < size; ++i)
-		out->writeByte(desc.c_str()[i]);
-
-	// Get the active palette
-	uint8 thumbPalette[16 * 3];
-	_system->getPaletteManager()->grabPalette(thumbPalette, 0, 16);
-	// Create a thumbnail and save it
-	Graphics::Surface *thumb = new Graphics::Surface();
-	Graphics::Surface *sf = _mainSurface;
-	::createThumbnail(thumb, (const byte *)sf->getPixels(), 320, 200, thumbPalette);
-	Graphics::saveThumbnail(*out, *thumb);
-	thumb->free();
-	delete thumb;
-
-	// Write out the save date/time
-	TimeDate td;
-	g_system->getTimeAndDate(td);
-	out->writeSint16LE(td.tm_year + 1900);
-	out->writeSint16LE(td.tm_mon + 1);
-	out->writeSint16LE(td.tm_mday);
-	out->writeSint16LE(td.tm_hour);
-	out->writeSint16LE(td.tm_min);
-
-	Common::Serializer s(nullptr, out);
-	synchronize(s);
-
-	out->finalize();
-	delete out;
-
-	return Common::kNoError;
-}
-
 Common::Error EfhEngine::run() {
 	debug("run");
 	s_Engine = this;
@@ -684,276 +587,14 @@ void EfhEngine::initialize() {
 	_shouldQuit = false;
 }
 
-void EfhEngine::readAnimInfo() {
-	debugC(6, kDebugEngine, "readAnimInfo");
-
-	Common::String fileName = "animinfo";
-	uint8 animInfoBuf[9000];
-	memset(animInfoBuf, 0, 9000);
-	uint8 *curPtr = animInfoBuf;
-
-	readFileToBuffer(fileName, animInfoBuf);
-	for (int i = 0; i < 100; ++i) {
-		for (int id = 0; id < 15; ++id) {
-			_animInfo[i]._unkAnimArray[id]._field[0] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[1] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[2] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[3] = *curPtr++;
-
-			debugC(6, kDebugEngine, "%d %d %d %d", _animInfo[i]._unkAnimArray[id]._field[0], _animInfo[i]._unkAnimArray[id]._field[1], _animInfo[i]._unkAnimArray[id]._field[2], _animInfo[i]._unkAnimArray[id]._field[3]);
-		}
-
-		Common::String debugStr = "";
-		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field3C_startY[id] = *curPtr++;
-			debugStr += Common::String::format("%d ", _animInfo[i]._field3C_startY[id]);
-		}
-		debugC(6, kDebugEngine, "%s", debugStr.c_str());
-
-		debugStr = "";
-		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field46_startX[id] = READ_LE_INT16(curPtr);
-			curPtr += 2;
-			debugStr += Common::String::format("%d ", _animInfo[i]._field46_startX[id]);
-		}
-		debugC(6, kDebugEngine, "%s", debugStr.c_str());
-		debugC(6, kDebugEngine, "---------");
-	}
-}
-
-void EfhEngine::findMapFile(int16 mapId) {
-	debugC(7, kDebugEngine, "findMapFile %d", mapId);
-
-	if (!_word31E9E)
-		return;
-
-	Common::String fileName = Common::String::format("map.%d", mapId);
-	Common::File f;
-	// The original was checking for the file and eventually asking to change floppies
-	if (!f.open(fileName))
-		error("File not found: %s", fileName.c_str());
-
-	f.close();
-}
-
-void EfhEngine::loadNewPortrait() {
-	debugC(7, kDebugEngine, "loadNewPortrait");
-
-	static int16 const unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
-	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
-
-	if (_currentAnimImageSetId == 200 + _unkRelatedToAnimImageSetId)
-		return;
-
-	findMapFile(_techId);
-	_currentAnimImageSetId = 200 + _unkRelatedToAnimImageSetId;
-	int imageSetId = _unkRelatedToAnimImageSetId + 13;
-	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
-}
-
-void EfhEngine::loadAnimImageSet() {
-	debug("loadAnimImageSet");
-
-	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
-		return;
-
-	findMapFile(_techId);
-
-	_unkAnimRelatedIndex = 0;
-	_currentAnimImageSetId = _animImageSetId;
-
-	int16 animSetId = _animImageSetId + 17;
-	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
-}
-
-void EfhEngine::loadHistory() {
-	debug("loadHistory");
-
-	Common::String fileName = "history";
-	readFileToBuffer(fileName, _history);
-}
-
-void EfhEngine::loadTechMapImp(int16 fileId) {
-	debug("loadTechMapImp %d", fileId);
-
-	if (fileId == 0xFF)
-		return;
-
-	_techId = fileId;
-	findMapFile(_techId);
-
-	// The original was loading the specific tech.%d and map.%d files.
-	// This is gone in our implementation as we pre-load all the files to save them inside the savegames
-
-	// This is not present in the original.
-	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
-	loadMapArrays(_techId);
-
-	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId][0] + 1);
-	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId][1] + 1);
-
-	initMapMonsters();
-	readImpFile(_techId, true);
-	displayAnimFrames(0xFE, false);
-
-}
-
-void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
-	debug("loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
-
-	if (fullPlaceId == 0xFF)
-		return;
-
-	findMapFile(_techId);
-	_fullPlaceId = fullPlaceId;
-	uint16 minPlace = _lastMainPlaceId * 20;
-	uint16 maxPlace = minPlace + 19;
-
-	if (_fullPlaceId < minPlace || _fullPlaceId > maxPlace || forceReloadFl) {
-		_lastMainPlaceId = _fullPlaceId / 20;
-		Common::String fileName = Common::String::format("places.%d", _lastMainPlaceId);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _places);
-	}
-	copyCurrentPlaceToBuffer(_fullPlaceId % 20);
-}
-
-void EfhEngine::readTileFact() {
-	debugC(7, kDebugEngine, "readTileFact");
-
-	Common::String fileName = "tilefact";
-	uint8 tileFactBuff[864];
-	readFileToBuffer(fileName, tileFactBuff);
-	uint8 *curPtr = tileFactBuff;
-	for (int i = 0; i < 432; ++i) {
-		_tileFact[i]._field0 = *curPtr++;
-		_tileFact[i]._field1 = *curPtr++;
-	}
-}
-
-void EfhEngine::readItems() {
-	debugC(7, kDebugEngine, "readItems");
-
-	Common::String fileName = "items";
-	uint8 itemBuff[8100];
-	readFileToBuffer(fileName, itemBuff);
-	uint8 *curPtr = itemBuff;
-
-	for (int i = 0; i < 300; ++i) {
-		for (int16 idx = 0; idx < 15; ++idx)
-			_items[i]._name[idx] = *curPtr++;
-
-
-		_items[i]._damage = *curPtr++;
-		_items[i]._defense = *curPtr++;
-		_items[i]._attacks = *curPtr++;
-		_items[i]._uses = *curPtr++;
-		_items[i].field_13 = *curPtr++;
-		_items[i]._range = *curPtr++;
-		_items[i]._attackType = *curPtr++;
-		_items[i].field_16 = *curPtr++;
-		_items[i].field17_attackTypeDefense = *curPtr++;
-		_items[i].field_18 = *curPtr++;
-		_items[i].field_19 = *curPtr++;
-		_items[i].field_1A = *curPtr++;
-
-		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
-	}
-}
-
-void EfhEngine::loadNPCS() {
-	debugC(7, kDebugEngine, "loadNPCS");
-
-	Common::String fileName = "npcs";
-	uint8 npcLoading[13400];
-	readFileToBuffer(fileName, npcLoading);
-	uint8 *curPtr = npcLoading;
-
-	for (int i = 0; i < 99; ++i) {
-		for (int idx = 0; idx < 11; ++idx)
-			_npcBuf[i]._name[idx] = *curPtr++;
-		_npcBuf[i].field_B = *curPtr++;
-		_npcBuf[i].field_C = *curPtr++;
-		_npcBuf[i].field_D = *curPtr++;
-		_npcBuf[i].field_E = *curPtr++;
-		_npcBuf[i].field_F = *curPtr++;
-		_npcBuf[i].field_10 = *curPtr++;
-		_npcBuf[i].field_11 = *curPtr++;
-		_npcBuf[i].field_12 = READ_LE_INT16(curPtr);
-		_npcBuf[i].field_14 = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i]._xp = READ_LE_INT32(curPtr);
-		curPtr += 4;
-		for (int idx = 0; idx < 15; ++idx) {
-			_npcBuf[i]._activeScore[idx] = *curPtr++;
-		}
-		for (int idx = 0; idx < 11; ++idx) {
-			_npcBuf[i]._passiveScore[idx] = *curPtr++;
-		}
-		for (int idx = 0; idx < 11; ++idx) {
-			_npcBuf[i]._infoScore[idx] = *curPtr++;
-		}
-		_npcBuf[i].field_3F = *curPtr++;
-		_npcBuf[i].field_40 = *curPtr++;
-		for (int idx = 0; idx < 10; ++idx) {
-			_npcBuf[i]._inventory[idx]._ref = READ_LE_INT16(curPtr);
-			curPtr += 2;
-			_npcBuf[i]._inventory[idx]._stat1 = *curPtr++;
-			_npcBuf[i]._inventory[idx]._stat2 = *curPtr++;
-		}
-		_npcBuf[i]._possessivePronounSHL6 = *curPtr++;
-		_npcBuf[i]._speed = *curPtr++;
-		_npcBuf[i].field_6B = *curPtr++;
-		_npcBuf[i].field_6C = *curPtr++;
-		_npcBuf[i].field_6D = *curPtr++;
-		_npcBuf[i]._unkItemId = *curPtr++;
-		_npcBuf[i].field_6F = *curPtr++;
-		_npcBuf[i].field_70 = *curPtr++;
-		_npcBuf[i].field_71 = *curPtr++;
-		_npcBuf[i].field_72 = *curPtr++;
-		_npcBuf[i].field_73 = *curPtr++;
-		_npcBuf[i]._hitPoints = READ_LE_INT16(curPtr);
-		_npcBuf[i]._maxHP = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i].field_78 = *curPtr++;
-		_npcBuf[i].field_79 = READ_LE_INT16(curPtr);
-		_npcBuf[i].field_7B = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i].field_7D = *curPtr++;
-		_npcBuf[i].field_7E = *curPtr++;
-		_npcBuf[i].field_7F = *curPtr++;
-		_npcBuf[i].field_80 = *curPtr++;
-		_npcBuf[i].field_81 = *curPtr++;
-		_npcBuf[i].field_82 = *curPtr++;
-		_npcBuf[i].field_83 = *curPtr++;
-		_npcBuf[i].field_84 = *curPtr++;
-		_npcBuf[i].field_85 = *curPtr++;
-	}
-}
-
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	warning("STUB: playSong");
 
-
-
 	_system->delayMillis(1000);
 
 	return Common::KEYCODE_INVALID;
 }
 
-void EfhEngine::readImpFile(int16 id, bool techMapFl) {
-	debug("readImpFile %d %s", id, techMapFl ? "True" : "False");
-
-	Common::String fileName = Common::String::format("imp.%d", id);
-
-	if (techMapFl)
-		readFileToBuffer(fileName, _imp1);
-	else
-		readFileToBuffer(fileName, _imp2);
-
-	decryptImpFile(techMapFl);
-}
-
 void EfhEngine::playIntro() {
 	debugC(6, kDebugEngine, "playIntro");
 
@@ -1031,24 +672,6 @@ void EfhEngine::playIntro() {
 	getLastCharAfterAnimCount(80);
 }
 
-/**
- * Pre-Loads MAP and TECH files.
- * This is required in order to implement a clean savegame feature
- */
-void EfhEngine::preLoadMaps() {
-	for (int i = 0; i < 19; ++i) {
-		Common::String fileName = Common::String::format("tech.%d", i);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _techDataArr[i]);
-
-		fileName = Common::String::format("map.%d", i);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _mapArr[i]);
-
-		_mapBitmapRefArr[i] = &_mapArr[i][0];
-	}
-}
-
 void EfhEngine::initEngine() {
 	_videoMode = 2; // In the original, 2 = VGA/MCGA, EGA = 4, Tandy = 6, cga = 8.
 	_graphicsStruct = new EfhGraphicsStruct;
@@ -6974,104 +6597,6 @@ bool EfhEngine::checkMonsterCollision() {
 	return true;
 }
 
-void EfhEngine::synchronize(Common::Serializer &s) {
-	s.syncAsSint16LE(_techId);
-	s.syncAsUint16LE(_fullPlaceId);
-	s.syncAsSint16LE(_guessAnimationAmount);
-	s.syncAsUint16LE(_largeMapFlag);
-	s.syncAsSint16LE(_teamCharId[0]);
-	s.syncAsSint16LE(_teamCharId[1]);
-	s.syncAsSint16LE(_teamCharId[2]);
-
-	for (int i = 0; i < 3; ++i) {
-		s.syncAsSint16LE(_teamCharStatus[i]._status);
-		s.syncAsSint16LE(_teamCharStatus[i]._duration);
-	}
-
-	s.syncAsSint16LE(_teamSize);
-	s.syncAsSint16LE(_unkArray2C8AA[0]);
-	s.syncAsSint16LE(_word2C872);
-	s.syncAsSint16LE(_imageSetSubFilesIdx);
-	s.syncAsSint16LE(_mapPosX);
-	s.syncAsSint16LE(_mapPosY);
-	s.syncAsSint16LE(_techDataId_MapPosX);
-	s.syncAsSint16LE(_techDataId_MapPosY);
-
-	for (int i = 0; i < 19; ++i) {
-		int size = ARRAYSIZE(_techDataArr[i]);
-		for (int j = 0; j < size; ++j)
-			s.syncAsByte(_techDataArr[i][j]);
-
-		size = ARRAYSIZE(_mapArr[i]);
-		for (int j = 0; j < size; ++j)
-			s.syncAsByte(_mapArr[i][j]);
-
-		_mapBitmapRefArr[i] = &_mapArr[i][0];
-	}
-
-	// Dialog flags
-	for (int i = 0; i < 256; ++i)
-		s.syncAsByte(_history[i]);
-
-	// NPCs
-	for (int i = 0; i < 99; ++i) {
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._name[idx]);
-
-		s.syncAsByte(_npcBuf[i].field_B);
-		s.syncAsByte(_npcBuf[i].field_C);
-		s.syncAsByte(_npcBuf[i].field_D);
-		s.syncAsByte(_npcBuf[i].field_E);
-		s.syncAsByte(_npcBuf[i].field_F);
-		s.syncAsByte(_npcBuf[i].field_10);
-		s.syncAsByte(_npcBuf[i].field_11);
-		s.syncAsSint16LE(_npcBuf[i].field_12);
-		s.syncAsSint16LE(_npcBuf[i].field_14);
-		s.syncAsSint32LE(_npcBuf[i]._xp);
-		for (int idx = 0; idx < 15; ++idx)
-			s.syncAsByte(_npcBuf[i]._activeScore[idx]);
-
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._passiveScore[idx]);
-
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._infoScore[idx]);
-
-		s.syncAsByte(_npcBuf[i].field_3F);
-		s.syncAsByte(_npcBuf[i].field_40);
-		for (int idx = 0; idx < 10; ++idx) {
-			s.syncAsSint16LE(_npcBuf[i]._inventory[idx]._ref);
-			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat1);
-			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat2);
-		}
-		s.syncAsByte(_npcBuf[i]._possessivePronounSHL6);
-		s.syncAsByte(_npcBuf[i]._speed);
-		s.syncAsByte(_npcBuf[i].field_6B);
-		s.syncAsByte(_npcBuf[i].field_6C);
-		s.syncAsByte(_npcBuf[i].field_6D);
-		s.syncAsByte(_npcBuf[i]._unkItemId);
-		s.syncAsByte(_npcBuf[i].field_6F);
-		s.syncAsByte(_npcBuf[i].field_70);
-		s.syncAsByte(_npcBuf[i].field_71);
-		s.syncAsByte(_npcBuf[i].field_72);
-		s.syncAsByte(_npcBuf[i].field_73);
-		s.syncAsSint16LE(_npcBuf[i]._hitPoints);
-		s.syncAsSint16LE(_npcBuf[i]._maxHP);
-		s.syncAsByte(_npcBuf[i].field_78);
-		s.syncAsSint16LE(_npcBuf[i].field_79);
-		s.syncAsSint16LE(_npcBuf[i].field_7B);
-		s.syncAsByte(_npcBuf[i].field_7D);
-		s.syncAsByte(_npcBuf[i].field_7E);
-		s.syncAsByte(_npcBuf[i].field_7F);
-		s.syncAsByte(_npcBuf[i].field_80);
-		s.syncAsByte(_npcBuf[i].field_81);
-		s.syncAsByte(_npcBuf[i].field_82);
-		s.syncAsByte(_npcBuf[i].field_83);
-		s.syncAsByte(_npcBuf[i].field_84);
-		s.syncAsByte(_npcBuf[i].field_85);
-	}
-}
-
 void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 	debugC(3, kDebugEngine, "loadImageSetToTileBank %d %d", tileBankId, imageSetId);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 3d31f85993e..8d25d0dbb19 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -255,15 +255,15 @@ public:
 	bool hasFeature(EngineFeature f) const override;
 	const char *getCopyrightString() const;
 
-	Common::String getSavegameFilename(int slot);
+	void syncSoundSettings() override;
 
+	// Savegames.cpp
+	Common::String getSavegameFilename(int slot);
 	bool canLoadGameStateCurrently() override;
 	bool canSaveGameStateCurrently() override;
 	Common::Error loadGameState(int slot) override;
 	Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
 
-	void syncSoundSettings() override;
-
 	bool _shouldQuit;
 
 protected:
@@ -279,20 +279,8 @@ private:
 	int _loadSaveSlot;
 
 	void initialize();
-	void readAnimInfo();
-	void findMapFile(int16 mapId);
-	void loadNewPortrait();
-	void loadAnimImageSet();
-	void loadHistory();
-	void loadTechMapImp(int16 fileId);
-	void loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl);
-	void readTileFact();
-	void readItems();
-	void loadNPCS();
 	Common::KeyCode playSong(uint8 *buffer);
-	void readImpFile(int16 id, bool techMapFl);
 	void playIntro();
-	void preLoadMaps();
 	void initEngine();
 	void initMapMonsters();
 	void loadMapArrays(int idx);
@@ -433,7 +421,22 @@ private:
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	bool checkMonsterCollision();
-	void synchronize(Common::Serializer &s);
+
+	// Files
+	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
+	void readAnimInfo();
+	void findMapFile(int16 mapId);
+	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
+	void readItems();
+	void readImpFile(int16 id, bool techMapFl);
+	void loadNewPortrait();
+	void loadAnimImageSet();
+	void loadHistory();
+	void loadTechMapImp(int16 fileId);
+	void loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl);
+	void readTileFact();
+	void loadNPCS();
+	void preLoadMaps();
 
 	// Graphics
 	void initPalette();
@@ -468,15 +471,13 @@ private:
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 
+	// Savegames
+	void synchronize(Common::Serializer &s);
+
 	// Utils
-	#if false
-	void copyString(char *srcStr, char *destStr);
-	#endif
-	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
 	void loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer);
-	void rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer);
 	uint32 uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf);
 	int16 getRandom(int16 maxVal);
 	Common::KeyCode getLastCharAfterAnimCount(int16 delay);
@@ -488,7 +489,6 @@ private:
 	void setNumLock();
 	bool getValidationFromUser();
 
-
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
 	int8 *_vgaLineBuffer[200];
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
new file mode 100644
index 00000000000..5c6a50d27e9
--- /dev/null
+++ b/engines/efh/files.cpp
@@ -0,0 +1,344 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "efh/efh.h"
+
+namespace Efh {
+
+int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
+	debugC(1, kDebugUtils, "readFileToBuffer %s", filename.c_str());
+	Common::File f;
+	if (!f.open(filename))
+		error("Unable to find file %s", filename.c_str());
+
+	int size = f.size();
+
+	return f.read(destBuffer, size);
+}
+
+void EfhEngine::readAnimInfo() {
+	debugC(6, kDebugEngine, "readAnimInfo");
+
+	Common::String fileName = "animinfo";
+	uint8 animInfoBuf[9000];
+	memset(animInfoBuf, 0, 9000);
+	uint8 *curPtr = animInfoBuf;
+
+	readFileToBuffer(fileName, animInfoBuf);
+	for (int i = 0; i < 100; ++i) {
+		for (int id = 0; id < 15; ++id) {
+			_animInfo[i]._unkAnimArray[id]._field[0] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[1] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[2] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[3] = *curPtr++;
+
+			debugC(6, kDebugEngine, "%d %d %d %d", _animInfo[i]._unkAnimArray[id]._field[0], _animInfo[i]._unkAnimArray[id]._field[1], _animInfo[i]._unkAnimArray[id]._field[2], _animInfo[i]._unkAnimArray[id]._field[3]);
+		}
+
+		Common::String debugStr = "";
+		for (int id = 0; id < 10; ++id) {
+			_animInfo[i]._field3C_startY[id] = *curPtr++;
+			debugStr += Common::String::format("%d ", _animInfo[i]._field3C_startY[id]);
+		}
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
+
+		debugStr = "";
+		for (int id = 0; id < 10; ++id) {
+			_animInfo[i]._field46_startX[id] = READ_LE_INT16(curPtr);
+			curPtr += 2;
+			debugStr += Common::String::format("%d ", _animInfo[i]._field46_startX[id]);
+		}
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
+		debugC(6, kDebugEngine, "---------");
+	}
+}
+
+void EfhEngine::findMapFile(int16 mapId) {
+	debugC(7, kDebugEngine, "findMapFile %d", mapId);
+
+	if (!_word31E9E)
+		return;
+
+	Common::String fileName = Common::String::format("map.%d", mapId);
+	Common::File f;
+	// The original was checking for the file and eventually asking to change floppies
+	if (!f.open(fileName))
+		error("File not found: %s", fileName.c_str());
+
+	f.close();
+}
+
+void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
+	debugC(1, kDebugUtils, "rImageFile %s", filename.c_str());
+	readFileToBuffer(filename, packedBuffer);
+	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
+
+#ifdef debug
+	// dump a decompressed image file
+	Common::DumpFile dump;
+	dump.open(filename + ".dump");
+	dump.write(targetBuffer, size);
+	dump.flush();
+	dump.close();
+	// End of dump
+#endif
+
+	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
+	// => Write a class to handle that more properly
+	uint8 *ptr = targetBuffer;
+	uint16 counter = 0;
+	while (READ_LE_INT16(ptr) != 0) {
+		subFilesArray[counter] = ptr;
+		++counter;
+		int16 imageWidth = READ_LE_INT16(ptr);
+		ptr += 2;
+		int16 imageHeight = READ_LE_INT16(ptr);
+		ptr += 2;
+		ptr += (imageWidth * imageHeight);
+	}
+}
+
+void EfhEngine::readImpFile(int16 id, bool techMapFl) {
+	debug("readImpFile %d %s", id, techMapFl ? "True" : "False");
+
+	Common::String fileName = Common::String::format("imp.%d", id);
+
+	if (techMapFl)
+		readFileToBuffer(fileName, _imp1);
+	else
+		readFileToBuffer(fileName, _imp2);
+
+	decryptImpFile(techMapFl);
+}
+
+void EfhEngine::readItems() {
+	debugC(7, kDebugEngine, "readItems");
+
+	Common::String fileName = "items";
+	uint8 itemBuff[8100];
+	readFileToBuffer(fileName, itemBuff);
+	uint8 *curPtr = itemBuff;
+
+	for (int i = 0; i < 300; ++i) {
+		for (int16 idx = 0; idx < 15; ++idx)
+			_items[i]._name[idx] = *curPtr++;
+
+		_items[i]._damage = *curPtr++;
+		_items[i]._defense = *curPtr++;
+		_items[i]._attacks = *curPtr++;
+		_items[i]._uses = *curPtr++;
+		_items[i].field_13 = *curPtr++;
+		_items[i]._range = *curPtr++;
+		_items[i]._attackType = *curPtr++;
+		_items[i].field_16 = *curPtr++;
+		_items[i].field17_attackTypeDefense = *curPtr++;
+		_items[i].field_18 = *curPtr++;
+		_items[i].field_19 = *curPtr++;
+		_items[i].field_1A = *curPtr++;
+
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
+	}
+}
+
+void EfhEngine::loadNewPortrait() {
+	debugC(7, kDebugEngine, "loadNewPortrait");
+
+	static int16 const unkConstRelatedToAnimImageSetId[19] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2};
+	_unkRelatedToAnimImageSetId = unkConstRelatedToAnimImageSetId[_techId];
+
+	if (_currentAnimImageSetId == 200 + _unkRelatedToAnimImageSetId)
+		return;
+
+	findMapFile(_techId);
+	_currentAnimImageSetId = 200 + _unkRelatedToAnimImageSetId;
+	int imageSetId = _unkRelatedToAnimImageSetId + 13;
+	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
+}
+
+void EfhEngine::loadAnimImageSet() {
+	debug("loadAnimImageSet");
+
+	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
+		return;
+
+	findMapFile(_techId);
+
+	_unkAnimRelatedIndex = 0;
+	_currentAnimImageSetId = _animImageSetId;
+
+	int16 animSetId = _animImageSetId + 17;
+	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
+}
+
+void EfhEngine::loadHistory() {
+	debug("loadHistory");
+
+	Common::String fileName = "history";
+	readFileToBuffer(fileName, _history);
+}
+
+void EfhEngine::loadTechMapImp(int16 fileId) {
+	debug("loadTechMapImp %d", fileId);
+
+	if (fileId == 0xFF)
+		return;
+
+	_techId = fileId;
+	findMapFile(_techId);
+
+	// The original was loading the specific tech.%d and map.%d files.
+	// This is gone in our implementation as we pre-load all the files to save them inside the savegames
+
+	// This is not present in the original.
+	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
+	loadMapArrays(_techId);
+
+	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId][0] + 1);
+	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId][1] + 1);
+
+	initMapMonsters();
+	readImpFile(_techId, true);
+	displayAnimFrames(0xFE, false);
+}
+
+void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
+	debug("loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
+
+	if (fullPlaceId == 0xFF)
+		return;
+
+	findMapFile(_techId);
+	_fullPlaceId = fullPlaceId;
+	uint16 minPlace = _lastMainPlaceId * 20;
+	uint16 maxPlace = minPlace + 19;
+
+	if (_fullPlaceId < minPlace || _fullPlaceId > maxPlace || forceReloadFl) {
+		_lastMainPlaceId = _fullPlaceId / 20;
+		Common::String fileName = Common::String::format("places.%d", _lastMainPlaceId);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _places);
+	}
+	copyCurrentPlaceToBuffer(_fullPlaceId % 20);
+}
+
+void EfhEngine::readTileFact() {
+	debugC(7, kDebugEngine, "readTileFact");
+
+	Common::String fileName = "tilefact";
+	uint8 tileFactBuff[864];
+	readFileToBuffer(fileName, tileFactBuff);
+	uint8 *curPtr = tileFactBuff;
+	for (int i = 0; i < 432; ++i) {
+		_tileFact[i]._field0 = *curPtr++;
+		_tileFact[i]._field1 = *curPtr++;
+	}
+}
+
+void EfhEngine::loadNPCS() {
+	debugC(7, kDebugEngine, "loadNPCS");
+
+	Common::String fileName = "npcs";
+	uint8 npcLoading[13400];
+	readFileToBuffer(fileName, npcLoading);
+	uint8 *curPtr = npcLoading;
+
+	for (int i = 0; i < 99; ++i) {
+		for (int idx = 0; idx < 11; ++idx)
+			_npcBuf[i]._name[idx] = *curPtr++;
+		_npcBuf[i].field_B = *curPtr++;
+		_npcBuf[i].field_C = *curPtr++;
+		_npcBuf[i].field_D = *curPtr++;
+		_npcBuf[i].field_E = *curPtr++;
+		_npcBuf[i].field_F = *curPtr++;
+		_npcBuf[i].field_10 = *curPtr++;
+		_npcBuf[i].field_11 = *curPtr++;
+		_npcBuf[i].field_12 = READ_LE_INT16(curPtr);
+		_npcBuf[i].field_14 = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i]._xp = READ_LE_INT32(curPtr);
+		curPtr += 4;
+		for (int idx = 0; idx < 15; ++idx) {
+			_npcBuf[i]._activeScore[idx] = *curPtr++;
+		}
+		for (int idx = 0; idx < 11; ++idx) {
+			_npcBuf[i]._passiveScore[idx] = *curPtr++;
+		}
+		for (int idx = 0; idx < 11; ++idx) {
+			_npcBuf[i]._infoScore[idx] = *curPtr++;
+		}
+		_npcBuf[i].field_3F = *curPtr++;
+		_npcBuf[i].field_40 = *curPtr++;
+		for (int idx = 0; idx < 10; ++idx) {
+			_npcBuf[i]._inventory[idx]._ref = READ_LE_INT16(curPtr);
+			curPtr += 2;
+			_npcBuf[i]._inventory[idx]._stat1 = *curPtr++;
+			_npcBuf[i]._inventory[idx]._stat2 = *curPtr++;
+		}
+		_npcBuf[i]._possessivePronounSHL6 = *curPtr++;
+		_npcBuf[i]._speed = *curPtr++;
+		_npcBuf[i].field_6B = *curPtr++;
+		_npcBuf[i].field_6C = *curPtr++;
+		_npcBuf[i].field_6D = *curPtr++;
+		_npcBuf[i]._unkItemId = *curPtr++;
+		_npcBuf[i].field_6F = *curPtr++;
+		_npcBuf[i].field_70 = *curPtr++;
+		_npcBuf[i].field_71 = *curPtr++;
+		_npcBuf[i].field_72 = *curPtr++;
+		_npcBuf[i].field_73 = *curPtr++;
+		_npcBuf[i]._hitPoints = READ_LE_INT16(curPtr);
+		_npcBuf[i]._maxHP = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i].field_78 = *curPtr++;
+		_npcBuf[i].field_79 = READ_LE_INT16(curPtr);
+		_npcBuf[i].field_7B = READ_LE_INT16(curPtr + 2);
+		curPtr += 4;
+		_npcBuf[i].field_7D = *curPtr++;
+		_npcBuf[i].field_7E = *curPtr++;
+		_npcBuf[i].field_7F = *curPtr++;
+		_npcBuf[i].field_80 = *curPtr++;
+		_npcBuf[i].field_81 = *curPtr++;
+		_npcBuf[i].field_82 = *curPtr++;
+		_npcBuf[i].field_83 = *curPtr++;
+		_npcBuf[i].field_84 = *curPtr++;
+		_npcBuf[i].field_85 = *curPtr++;
+	}
+}
+
+/**
+ * Pre-Loads MAP and TECH files.
+ * This is required in order to implement a clean savegame feature
+ */
+void EfhEngine::preLoadMaps() {
+	for (int i = 0; i < 19; ++i) {
+		Common::String fileName = Common::String::format("tech.%d", i);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _techDataArr[i]);
+
+		fileName = Common::String::format("map.%d", i);
+		readFileToBuffer(fileName, _hiResImageBuf);
+		uncompressBuffer(_hiResImageBuf, _mapArr[i]);
+
+		_mapBitmapRefArr[i] = &_mapArr[i][0];
+	}
+}
+
+} // End of namespace Efh
+
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index 8276fe4012d..cb6cf14a08b 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -177,6 +177,10 @@ void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
 	g_system->getSavefileManager()->removeSavefile(fileName);
 }
 
+void EfhEngine::initGame(const ADGameDescription *gd) {
+	_platform = gd->platform;
+}
+
 } // End of namespace Efh
 
 #if PLUGIN_ENABLED_DYNAMIC(EFH)
@@ -184,11 +188,3 @@ void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
 #else
 	REGISTER_PLUGIN_STATIC(EFH, PLUGIN_TYPE_ENGINE, Efh::EfhMetaEngine);
 #endif
-
-namespace Efh {
-
-void EfhEngine::initGame(const ADGameDescription *gd) {
-	_platform = gd->platform;
-}
-
-} // End of namespace Efh
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index 158d389f1c3..aee8803c525 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -3,7 +3,9 @@ MODULE := engines/efh
 MODULE_OBJS = \
 	constants.o \
 	efh.o \
+	files.o \
 	graphics.o \
+	savegames.o \
 	utils.o \
 	metaengine.o
 
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
new file mode 100644
index 00000000000..6401564e103
--- /dev/null
+++ b/engines/efh/savegames.cpp
@@ -0,0 +1,225 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/savefile.h"
+#include "graphics/scaler.h"
+#include "graphics/thumbnail.h"
+#include "common/system.h"
+#include "graphics/palette.h"
+
+#include "efh/efh.h"
+
+namespace Efh {
+
+Common::String EfhEngine::getSavegameFilename(int slot) {
+	return _targetName + Common::String::format("-%03d.SAV", slot);
+}
+
+bool EfhEngine::canLoadGameStateCurrently() {
+	return true;
+}
+
+bool EfhEngine::canSaveGameStateCurrently() {
+	return true;
+}
+
+Common::Error EfhEngine::loadGameState(int slot) {
+	Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(getSaveStateName(slot));
+	if (!saveFile)
+		return Common::kReadingFailed;
+
+	uint32 signature = saveFile->readUint32LE();
+	byte version = saveFile->readByte();
+
+	if (signature != EFH_SAVE_HEADER || version > kSavegameVersion)
+		error("Invalid savegame");
+
+	// Skip savegame name
+	uint16 size = saveFile->readUint16LE();
+	saveFile->skip(size);
+
+	// Skip the thumbnail
+	Graphics::Surface *thumbnail;
+	Graphics::loadThumbnail(*saveFile, thumbnail);
+	delete (thumbnail);
+
+	// Skip the savegame date
+	saveFile->skip(10); // year, month, day, hours, minutes (all int16)
+
+	Common::Serializer s(saveFile, nullptr);
+	synchronize(s);
+
+	delete saveFile;
+
+	_oldMapPosX = _mapPosX;
+	_oldMapPosY = _mapPosY;
+	_unkRelatedToAnimImageSetId = 0;
+
+	loadTechMapImp(_techId);
+	_lastMainPlaceId = 0xFFFF;
+	loadPlacesFile(_fullPlaceId, true);
+
+	return Common::kNoError;
+}
+
+Common::Error EfhEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
+	Common::OutSaveFile *out = _system->getSavefileManager()->openForSaving(getSaveStateName(slot));
+	if (!out)
+		return Common::kCreatingFileFailed;
+
+	out->writeUint32LE(EFH_SAVE_HEADER);
+	out->writeByte(kSavegameVersion);
+
+	// Write savegame name
+	uint16 size = desc.size();
+	out->writeUint16LE(size);
+	for (int i = 0; i < size; ++i)
+		out->writeByte(desc.c_str()[i]);
+
+	// Get the active palette
+	uint8 thumbPalette[16 * 3];
+	_system->getPaletteManager()->grabPalette(thumbPalette, 0, 16);
+	// Create a thumbnail and save it
+	Graphics::Surface *thumb = new Graphics::Surface();
+	Graphics::Surface *sf = _mainSurface;
+	::createThumbnail(thumb, (const byte *)sf->getPixels(), 320, 200, thumbPalette);
+	Graphics::saveThumbnail(*out, *thumb);
+	thumb->free();
+	delete thumb;
+
+	// Write out the save date/time
+	TimeDate td;
+	g_system->getTimeAndDate(td);
+	out->writeSint16LE(td.tm_year + 1900);
+	out->writeSint16LE(td.tm_mon + 1);
+	out->writeSint16LE(td.tm_mday);
+	out->writeSint16LE(td.tm_hour);
+	out->writeSint16LE(td.tm_min);
+
+	Common::Serializer s(nullptr, out);
+	synchronize(s);
+
+	out->finalize();
+	delete out;
+
+	return Common::kNoError;
+}
+
+void EfhEngine::synchronize(Common::Serializer &s) {
+	s.syncAsSint16LE(_techId);
+	s.syncAsUint16LE(_fullPlaceId);
+	s.syncAsSint16LE(_guessAnimationAmount);
+	s.syncAsUint16LE(_largeMapFlag);
+	s.syncAsSint16LE(_teamCharId[0]);
+	s.syncAsSint16LE(_teamCharId[1]);
+	s.syncAsSint16LE(_teamCharId[2]);
+
+	for (int i = 0; i < 3; ++i) {
+		s.syncAsSint16LE(_teamCharStatus[i]._status);
+		s.syncAsSint16LE(_teamCharStatus[i]._duration);
+	}
+
+	s.syncAsSint16LE(_teamSize);
+	s.syncAsSint16LE(_unkArray2C8AA[0]);
+	s.syncAsSint16LE(_word2C872);
+	s.syncAsSint16LE(_imageSetSubFilesIdx);
+	s.syncAsSint16LE(_mapPosX);
+	s.syncAsSint16LE(_mapPosY);
+	s.syncAsSint16LE(_techDataId_MapPosX);
+	s.syncAsSint16LE(_techDataId_MapPosY);
+
+	for (int i = 0; i < 19; ++i) {
+		int size = ARRAYSIZE(_techDataArr[i]);
+		for (int j = 0; j < size; ++j)
+			s.syncAsByte(_techDataArr[i][j]);
+
+		size = ARRAYSIZE(_mapArr[i]);
+		for (int j = 0; j < size; ++j)
+			s.syncAsByte(_mapArr[i][j]);
+
+		_mapBitmapRefArr[i] = &_mapArr[i][0];
+	}
+
+	// Dialog flags
+	for (int i = 0; i < 256; ++i)
+		s.syncAsByte(_history[i]);
+
+	// NPCs
+	for (int i = 0; i < 99; ++i) {
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._name[idx]);
+
+		s.syncAsByte(_npcBuf[i].field_B);
+		s.syncAsByte(_npcBuf[i].field_C);
+		s.syncAsByte(_npcBuf[i].field_D);
+		s.syncAsByte(_npcBuf[i].field_E);
+		s.syncAsByte(_npcBuf[i].field_F);
+		s.syncAsByte(_npcBuf[i].field_10);
+		s.syncAsByte(_npcBuf[i].field_11);
+		s.syncAsSint16LE(_npcBuf[i].field_12);
+		s.syncAsSint16LE(_npcBuf[i].field_14);
+		s.syncAsSint32LE(_npcBuf[i]._xp);
+		for (int idx = 0; idx < 15; ++idx)
+			s.syncAsByte(_npcBuf[i]._activeScore[idx]);
+
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._passiveScore[idx]);
+
+		for (int idx = 0; idx < 11; ++idx)
+			s.syncAsByte(_npcBuf[i]._infoScore[idx]);
+
+		s.syncAsByte(_npcBuf[i].field_3F);
+		s.syncAsByte(_npcBuf[i].field_40);
+		for (int idx = 0; idx < 10; ++idx) {
+			s.syncAsSint16LE(_npcBuf[i]._inventory[idx]._ref);
+			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat1);
+			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat2);
+		}
+		s.syncAsByte(_npcBuf[i]._possessivePronounSHL6);
+		s.syncAsByte(_npcBuf[i]._speed);
+		s.syncAsByte(_npcBuf[i].field_6B);
+		s.syncAsByte(_npcBuf[i].field_6C);
+		s.syncAsByte(_npcBuf[i].field_6D);
+		s.syncAsByte(_npcBuf[i]._unkItemId);
+		s.syncAsByte(_npcBuf[i].field_6F);
+		s.syncAsByte(_npcBuf[i].field_70);
+		s.syncAsByte(_npcBuf[i].field_71);
+		s.syncAsByte(_npcBuf[i].field_72);
+		s.syncAsByte(_npcBuf[i].field_73);
+		s.syncAsSint16LE(_npcBuf[i]._hitPoints);
+		s.syncAsSint16LE(_npcBuf[i]._maxHP);
+		s.syncAsByte(_npcBuf[i].field_78);
+		s.syncAsSint16LE(_npcBuf[i].field_79);
+		s.syncAsSint16LE(_npcBuf[i].field_7B);
+		s.syncAsByte(_npcBuf[i].field_7D);
+		s.syncAsByte(_npcBuf[i].field_7E);
+		s.syncAsByte(_npcBuf[i].field_7F);
+		s.syncAsByte(_npcBuf[i].field_80);
+		s.syncAsByte(_npcBuf[i].field_81);
+		s.syncAsByte(_npcBuf[i].field_82);
+		s.syncAsByte(_npcBuf[i].field_83);
+		s.syncAsByte(_npcBuf[i].field_84);
+		s.syncAsByte(_npcBuf[i].field_85);
+	}
+}
+
+} // End of namespace Efh
+
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index a720686e325..fb2b82a4b40 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -25,31 +25,6 @@
 
 namespace Efh {
 
-#if 0
-// Note : The original engine is using copyString(src, dest). It has been replaced either by a string assignment or a snprintf
-void EfhEngine::copyString(char *srcStr, char *destStr) {
-	debugC(1, kDebugUtils, "copyString %s", srcStr);
-	char lastChar = 1;
-	int16 idx = 0;
-
-	while (lastChar != 0) {
-		lastChar = destStr[idx] = srcStr[idx];
-		++idx;
-	}
-}
-#endif
-
-int32 EfhEngine::readFileToBuffer(Common::String &filename, uint8 *destBuffer) {
-	debugC(1, kDebugUtils, "readFileToBuffer %s", filename.c_str());
-	Common::File f;
-	if (!f.open(filename))
-		error("Unable to find file %s", filename.c_str());
-
-	int size = f.size();
-
-	return f.read(destBuffer, size);
-}
-
 void EfhEngine::setDefaultNoteDuration() {
 	// Original implementation is based on the int1C, which is triggered at 18.2065Hz.
 	// Every 4 times, it sets a flag (thus, approx every 220ms)
@@ -85,7 +60,8 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 			++curPtr;
 	} while (*curPtr != 0x60 && counter <= target);
 
-// TODO: remove the dump part
+#ifdef debug
+// Dump the decompressed IMP file
 	Common::DumpFile dump;
 	if (!techMapFl) {
 		dump.open("imp2_unc.dump");
@@ -96,6 +72,7 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 	}
 	dump.flush();
 	dump.close();
+#endif
 }
 
 void EfhEngine::loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {
@@ -104,33 +81,6 @@ void EfhEngine::loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesAr
 	rImageFile(fileName, buffer, subFilesArray, destBuffer);
 }
 
-void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
-	debugC(1, kDebugUtils, "rImageFile %s", filename.c_str());
-	readFileToBuffer(filename, packedBuffer);
-	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
-	// TODO: Keep this dump for debug purposes only
-	Common::DumpFile dump;
-	dump.open(filename + ".dump");
-	dump.write(targetBuffer, size);
-	dump.flush();
-	dump.close();
-	// End of dump
-
-	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
-	// => Write a class to handle that more properly
-	uint8 *ptr = targetBuffer;
-	uint16 counter = 0;
-	while (READ_LE_INT16(ptr) != 0) {
-		subFilesArray[counter] = ptr;
-		++counter;
-		int16 imageWidth = READ_LE_INT16(ptr);
-		ptr += 2;
-		int16 imageHeight = READ_LE_INT16(ptr);
-		ptr += 2;
-		ptr += (imageWidth * imageHeight);
-	}
-}
-
 uint32 EfhEngine::uncompressBuffer(uint8 *compressedBuf, uint8 *destBuf) {
 	debugC(1, kDebugUtils, "uncompressBuffer");
 	if (compressedBuf == nullptr || destBuf == nullptr)


Commit: 22227d37e24405204dee7f40a04dfc282a0b8205
    https://github.com/scummvm/scummvm/commit/22227d37e24405204dee7f40a04dfc282a0b8205
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: take into account some more comments raised by sev during the first code review

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/metaengine.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 01293e74dae..f56906be20f 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -205,7 +205,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_fontDescr._charHeight = 0;
 	_fontDescr._extraHorizontalSpace = _fontDescr._extraVerticalSpace = 0;
 
-	_word31E9E = false;
+	_introDoneFl = false;
 	_oldAnimImageSetId = -1;
 	_animImageSetId = 0xFE;
 	_paletteTransformationConstant = 10;
@@ -356,22 +356,10 @@ EfhEngine::~EfhEngine() {
 	delete _vgaGraphicsStruct2;
 }
 
-bool EfhEngine::hasFeature(EngineFeature f) const {
-	return (f == kSupportsReturnToLauncher) || (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
-}
-
-const char *EfhEngine::getCopyrightString() const {
-	return "Escape From Hell (C) Electronic Arts, 1990";
-}
-
-Common::Platform EfhEngine::getPlatform() const {
-	return _platform;
-}
-
 void EfhEngine::syncSoundSettings() {
 	Engine::syncSoundSettings();
 
-	//	_sound->syncVolume();
+	warning("TODO: _sound->syncVolume();");
 }
 
 Common::Error EfhEngine::run() {
@@ -583,7 +571,7 @@ Common::Error EfhEngine::run() {
 
 void EfhEngine::initialize() {
 	_rnd = new Common::RandomSource("Hell");
-	_rnd->setSeed(666);                              // Kick random number generator
+	_rnd->setSeed(g_system->getMillis());   // Kick random number generator
 	_shouldQuit = false;
 }
 
@@ -691,7 +679,7 @@ void EfhEngine::initEngine() {
 	_fontDescr._charHeight = 8;
 	_fontDescr._extraVerticalSpace = 3;
 	_fontDescr._extraHorizontalSpace = 1;
-	_word31E9E = false;
+	_introDoneFl = false;
 
 	// Pre-load stuff required for savegames
 	preLoadMaps();
@@ -743,7 +731,7 @@ void EfhEngine::initEngine() {
 
 	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
 	readImpFile(99, false);
-	_word31E9E = true;
+	_introDoneFl = true;
 	restoreAnimImageSetId();
 
 	// Note: The original at this point saves int 24h and sets a new int24 to handle fatal failure
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8d25d0dbb19..b4cdb33a08f 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -246,18 +246,18 @@ public:
 	Common::RandomSource *_rnd;
 
 	const ADGameDescription *_gameDescription;
-	uint32 getFeatures() const;
-	const char *getGameId() const;
 
+	void syncSoundSettings() override;
+
+	// metaengine.cpp
 	void initGame(const ADGameDescription *gd);
+	uint32 getFeatures() const;
+	const char *getGameId() const;
 	Common::Platform getPlatform() const;
-
 	bool hasFeature(EngineFeature f) const override;
 	const char *getCopyrightString() const;
 
-	void syncSoundSettings() override;
-
-	// Savegames.cpp
+	// savegames.cpp
 	Common::String getSavegameFilename(int slot);
 	bool canLoadGameStateCurrently() override;
 	bool canSaveGameStateCurrently() override;
@@ -530,7 +530,7 @@ private:
 	uint8 _defaultBoxColor;
 	FontDescr _fontDescr;
 
-	bool _word31E9E;
+	bool _introDoneFl;
 	uint16 _textColor;
 
 	int16 _oldAnimImageSetId;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 5c6a50d27e9..90c166e75da 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -74,7 +74,7 @@ void EfhEngine::readAnimInfo() {
 void EfhEngine::findMapFile(int16 mapId) {
 	debugC(7, kDebugEngine, "findMapFile %d", mapId);
 
-	if (!_word31E9E)
+	if (!_introDoneFl)
 		return;
 
 	Common::String fileName = Common::String::format("map.%d", mapId);
diff --git a/engines/efh/metaengine.cpp b/engines/efh/metaengine.cpp
index cb6cf14a08b..122e2c4d649 100644
--- a/engines/efh/metaengine.cpp
+++ b/engines/efh/metaengine.cpp
@@ -38,6 +38,21 @@ const char *EfhEngine::getGameId() const {
 	return _gameDescription->gameId;
 }
 
+void EfhEngine::initGame(const ADGameDescription *gd) {
+	_platform = gd->platform;
+}
+
+bool EfhEngine::hasFeature(EngineFeature f) const {
+	return (f == kSupportsReturnToLauncher) || (f == kSupportsLoadingDuringRuntime) || (f == kSupportsSavingDuringRuntime);
+}
+
+const char *EfhEngine::getCopyrightString() const {
+	return "Escape From Hell (C) Electronic Arts, 1990";
+}
+
+Common::Platform EfhEngine::getPlatform() const {
+	return _platform;
+}
 } // End of namespace Efh
 
 namespace Efh {
@@ -177,10 +192,6 @@ void EfhMetaEngine::removeSaveState(const char *target, int slot) const {
 	g_system->getSavefileManager()->removeSavefile(fileName);
 }
 
-void EfhEngine::initGame(const ADGameDescription *gd) {
-	_platform = gd->platform;
-}
-
 } // End of namespace Efh
 
 #if PLUGIN_ENABLED_DYNAMIC(EFH)


Commit: c833b8a55beb508cd5f1aab69a0d3f85e5a71f18
    https://github.com/scummvm/scummvm/commit/c833b8a55beb508cd5f1aab69a0d3f85e5a71f18
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Partial rewrite of file loading

Changed paths:
    engines/efh/efh.cpp
    engines/efh/files.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index f56906be20f..3ec7b22a06a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -6627,7 +6627,7 @@ void EfhEngine::loadEfhGame() {
 	// The savegame is used to initialize the engine, so this part is reimplemented.
 	// The check for existence is replaced by an error.
 
-	Common::String fileName = "savegame";
+	Common::String fileName("savegame");
 	Common::File f;
 
 	if (!f.open(fileName))
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 90c166e75da..fc0090c0b07 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -38,32 +38,30 @@ void EfhEngine::readAnimInfo() {
 	debugC(6, kDebugEngine, "readAnimInfo");
 
 	Common::String fileName = "animinfo";
-	uint8 animInfoBuf[9000];
-	memset(animInfoBuf, 0, 9000);
-	uint8 *curPtr = animInfoBuf;
+	Common::File f;
+	if (!f.open(fileName))
+		error("Unable to find file %s", fileName.c_str());
 
-	readFileToBuffer(fileName, animInfoBuf);
 	for (int i = 0; i < 100; ++i) {
 		for (int id = 0; id < 15; ++id) {
-			_animInfo[i]._unkAnimArray[id]._field[0] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[1] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[2] = *curPtr++;
-			_animInfo[i]._unkAnimArray[id]._field[3] = *curPtr++;
+			_animInfo[i]._unkAnimArray[id]._field[0] = f.readByte();
+			_animInfo[i]._unkAnimArray[id]._field[1] = f.readByte();
+			_animInfo[i]._unkAnimArray[id]._field[2] = f.readByte();
+			_animInfo[i]._unkAnimArray[id]._field[3] = f.readByte();
 
 			debugC(6, kDebugEngine, "%d %d %d %d", _animInfo[i]._unkAnimArray[id]._field[0], _animInfo[i]._unkAnimArray[id]._field[1], _animInfo[i]._unkAnimArray[id]._field[2], _animInfo[i]._unkAnimArray[id]._field[3]);
 		}
 
 		Common::String debugStr = "";
 		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field3C_startY[id] = *curPtr++;
+			_animInfo[i]._field3C_startY[id] = f.readByte();
 			debugStr += Common::String::format("%d ", _animInfo[i]._field3C_startY[id]);
 		}
 		debugC(6, kDebugEngine, "%s", debugStr.c_str());
 
 		debugStr = "";
 		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field46_startX[id] = READ_LE_INT16(curPtr);
-			curPtr += 2;
+			_animInfo[i]._field46_startX[id] = f.readUint16LE();
 			debugStr += Common::String::format("%d ", _animInfo[i]._field46_startX[id]);
 		}
 		debugC(6, kDebugEngine, "%s", debugStr.c_str());
@@ -133,26 +131,26 @@ void EfhEngine::readItems() {
 	debugC(7, kDebugEngine, "readItems");
 
 	Common::String fileName = "items";
-	uint8 itemBuff[8100];
-	readFileToBuffer(fileName, itemBuff);
-	uint8 *curPtr = itemBuff;
+	Common::File f;
+	if (!f.open(fileName))
+		error("Unable to find file %s", fileName.c_str());
 
 	for (int i = 0; i < 300; ++i) {
 		for (int16 idx = 0; idx < 15; ++idx)
-			_items[i]._name[idx] = *curPtr++;
-
-		_items[i]._damage = *curPtr++;
-		_items[i]._defense = *curPtr++;
-		_items[i]._attacks = *curPtr++;
-		_items[i]._uses = *curPtr++;
-		_items[i].field_13 = *curPtr++;
-		_items[i]._range = *curPtr++;
-		_items[i]._attackType = *curPtr++;
-		_items[i].field_16 = *curPtr++;
-		_items[i].field17_attackTypeDefense = *curPtr++;
-		_items[i].field_18 = *curPtr++;
-		_items[i].field_19 = *curPtr++;
-		_items[i].field_1A = *curPtr++;
+			_items[i]._name[idx] = f.readByte();
+
+		_items[i]._damage = f.readByte();
+		_items[i]._defense = f.readByte();
+		_items[i]._attacks = f.readByte();
+		_items[i]._uses = f.readByte();
+		_items[i].field_13 = f.readByte();
+		_items[i]._range = f.readByte();
+		_items[i]._attackType = f.readByte();
+		_items[i].field_16 = f.readByte();
+		_items[i].field17_attackTypeDefense = f.readByte();
+		_items[i].field_18 = f.readByte();
+		_items[i].field_19 = f.readByte();
+		_items[i].field_1A = f.readByte();
 
 		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
 	}
@@ -243,82 +241,78 @@ void EfhEngine::readTileFact() {
 	debugC(7, kDebugEngine, "readTileFact");
 
 	Common::String fileName = "tilefact";
-	uint8 tileFactBuff[864];
-	readFileToBuffer(fileName, tileFactBuff);
-	uint8 *curPtr = tileFactBuff;
+	Common::File f;
+	if (!f.open(fileName))
+		error("Unable to find file %s", fileName.c_str());
+
 	for (int i = 0; i < 432; ++i) {
-		_tileFact[i]._field0 = *curPtr++;
-		_tileFact[i]._field1 = *curPtr++;
+		_tileFact[i]._field0 = f.readByte();
+		_tileFact[i]._field1 = f.readByte();
 	}
 }
 
 void EfhEngine::loadNPCS() {
 	debugC(7, kDebugEngine, "loadNPCS");
 
-	Common::String fileName = "npcs";
-	uint8 npcLoading[13400];
-	readFileToBuffer(fileName, npcLoading);
-	uint8 *curPtr = npcLoading;
+	Common::String fileName("npcs");
+	Common::File f;
+	if (!f.open(fileName))
+		error("Unable to find file %s", fileName.c_str());
 
 	for (int i = 0; i < 99; ++i) {
 		for (int idx = 0; idx < 11; ++idx)
-			_npcBuf[i]._name[idx] = *curPtr++;
-		_npcBuf[i].field_B = *curPtr++;
-		_npcBuf[i].field_C = *curPtr++;
-		_npcBuf[i].field_D = *curPtr++;
-		_npcBuf[i].field_E = *curPtr++;
-		_npcBuf[i].field_F = *curPtr++;
-		_npcBuf[i].field_10 = *curPtr++;
-		_npcBuf[i].field_11 = *curPtr++;
-		_npcBuf[i].field_12 = READ_LE_INT16(curPtr);
-		_npcBuf[i].field_14 = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i]._xp = READ_LE_INT32(curPtr);
-		curPtr += 4;
+			_npcBuf[i]._name[idx] = f.readByte();
+		_npcBuf[i].field_B = f.readByte();
+		_npcBuf[i].field_C = f.readByte();
+		_npcBuf[i].field_D = f.readByte();
+		_npcBuf[i].field_E = f.readByte();
+		_npcBuf[i].field_F = f.readByte();
+		_npcBuf[i].field_10 = f.readByte();
+		_npcBuf[i].field_11 = f.readByte();
+		_npcBuf[i].field_12 = f.readUint16LE();
+		_npcBuf[i].field_14 = f.readUint16LE();
+		_npcBuf[i]._xp = f.readUint32LE();
 		for (int idx = 0; idx < 15; ++idx) {
-			_npcBuf[i]._activeScore[idx] = *curPtr++;
+			_npcBuf[i]._activeScore[idx] = f.readByte();
 		}
 		for (int idx = 0; idx < 11; ++idx) {
-			_npcBuf[i]._passiveScore[idx] = *curPtr++;
+			_npcBuf[i]._passiveScore[idx] = f.readByte();
 		}
 		for (int idx = 0; idx < 11; ++idx) {
-			_npcBuf[i]._infoScore[idx] = *curPtr++;
+			_npcBuf[i]._infoScore[idx] = f.readByte();
 		}
-		_npcBuf[i].field_3F = *curPtr++;
-		_npcBuf[i].field_40 = *curPtr++;
+		_npcBuf[i].field_3F = f.readByte();
+		_npcBuf[i].field_40 = f.readByte();
 		for (int idx = 0; idx < 10; ++idx) {
-			_npcBuf[i]._inventory[idx]._ref = READ_LE_INT16(curPtr);
-			curPtr += 2;
-			_npcBuf[i]._inventory[idx]._stat1 = *curPtr++;
-			_npcBuf[i]._inventory[idx]._stat2 = *curPtr++;
+			_npcBuf[i]._inventory[idx]._ref = f.readSint16LE();
+			_npcBuf[i]._inventory[idx]._stat1 = f.readByte();
+			_npcBuf[i]._inventory[idx]._stat2 = f.readByte();
 		}
-		_npcBuf[i]._possessivePronounSHL6 = *curPtr++;
-		_npcBuf[i]._speed = *curPtr++;
-		_npcBuf[i].field_6B = *curPtr++;
-		_npcBuf[i].field_6C = *curPtr++;
-		_npcBuf[i].field_6D = *curPtr++;
-		_npcBuf[i]._unkItemId = *curPtr++;
-		_npcBuf[i].field_6F = *curPtr++;
-		_npcBuf[i].field_70 = *curPtr++;
-		_npcBuf[i].field_71 = *curPtr++;
-		_npcBuf[i].field_72 = *curPtr++;
-		_npcBuf[i].field_73 = *curPtr++;
-		_npcBuf[i]._hitPoints = READ_LE_INT16(curPtr);
-		_npcBuf[i]._maxHP = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i].field_78 = *curPtr++;
-		_npcBuf[i].field_79 = READ_LE_INT16(curPtr);
-		_npcBuf[i].field_7B = READ_LE_INT16(curPtr + 2);
-		curPtr += 4;
-		_npcBuf[i].field_7D = *curPtr++;
-		_npcBuf[i].field_7E = *curPtr++;
-		_npcBuf[i].field_7F = *curPtr++;
-		_npcBuf[i].field_80 = *curPtr++;
-		_npcBuf[i].field_81 = *curPtr++;
-		_npcBuf[i].field_82 = *curPtr++;
-		_npcBuf[i].field_83 = *curPtr++;
-		_npcBuf[i].field_84 = *curPtr++;
-		_npcBuf[i].field_85 = *curPtr++;
+		_npcBuf[i]._possessivePronounSHL6 = f.readByte();
+		_npcBuf[i]._speed = f.readByte();
+		_npcBuf[i].field_6B = f.readByte();
+		_npcBuf[i].field_6C = f.readByte();
+		_npcBuf[i].field_6D = f.readByte();
+		_npcBuf[i]._unkItemId = f.readByte();
+		_npcBuf[i].field_6F = f.readByte();
+		_npcBuf[i].field_70 = f.readByte();
+		_npcBuf[i].field_71 = f.readByte();
+		_npcBuf[i].field_72 = f.readByte();
+		_npcBuf[i].field_73 = f.readByte();
+		_npcBuf[i]._hitPoints = f.readSint16LE();
+		_npcBuf[i]._maxHP = f.readSint16LE();
+		_npcBuf[i].field_78 = f.readByte();
+		_npcBuf[i].field_79 = f.readUint16LE();
+		_npcBuf[i].field_7B = f.readUint16LE();
+		_npcBuf[i].field_7D = f.readByte();
+		_npcBuf[i].field_7E = f.readByte();
+		_npcBuf[i].field_7F = f.readByte();
+		_npcBuf[i].field_80 = f.readByte();
+		_npcBuf[i].field_81 = f.readByte();
+		_npcBuf[i].field_82 = f.readByte();
+		_npcBuf[i].field_83 = f.readByte();
+		_npcBuf[i].field_84 = f.readByte();
+		_npcBuf[i].field_85 = f.readByte();
 	}
 }
 


Commit: 4605be8169b29cb0b063152f26e6e9031a28c5d2
    https://github.com/scummvm/scummvm/commit/4605be8169b29cb0b063152f26e6e9031a28c5d2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Change uint8 to uint in some loops

Changed paths:
    engines/efh/efh.cpp
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3ec7b22a06a..45e26da8de8 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -749,18 +749,18 @@ void EfhEngine::initEngine() {
 void EfhEngine::initMapMonsters() {
 	debug("initMapMonsters");
 
-	for (uint8 monsterId = 0; monsterId < 64; ++monsterId) {
+	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
 		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 			continue;
 
-		for (uint8 counter = 0; counter < 9; ++counter)
+		for (uint counter = 0; counter < 9; ++counter)
 			_mapMonsters[monsterId]._pictureRef[counter] = 0;
 
 		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
 		if (groupSize == 0)
 			groupSize = getRandom(10);
 
-		for (uint8 counter = 0; counter < groupSize; ++counter) {
+		for (uint counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
 			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._monsterRef]._pictureRef;
 
@@ -1826,7 +1826,7 @@ void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 void EfhEngine::displayMiddleLeftTempText(uint8 *impArray, bool flag) {
 	debugC(3, kDebugEngine, "displayMiddleLeftTempText %s %s", (char *)impArray, flag ? "True" : "False");
 
-	for (uint8 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			// clear middle-left text area
 			drawColoredRect(16, 115, 111, 133, 0);
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index d77759d8481..ac1ee0305da 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -211,7 +211,7 @@ void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 t
 		// int16 var6 = _fontDescr._extraLines[0] + startY - 1; // Used in case 0x8000
 	}
 
-	for (uint8 curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
+	for (uint curChar = *curPtr++; curChar != 0; curChar = *curPtr++) {
 		if (curChar == 0x0A) {
 			startX = minX;
 			startY += lineHeight;


Commit: 1f7fe868ad666964a2a727342b9c99d569eeacdc
    https://github.com/scummvm/scummvm/commit/1f7fe868ad666964a2a727342b9c99d569eeacdc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Fix missing space in while statements

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 45e26da8de8..fc25b9f6f9c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -387,7 +387,7 @@ Common::Error EfhEngine::run() {
 		return Common::kNoError;
 
 	uint32 lastMs = _system->getMillis();
-	while(!_shouldQuit) {
+	while (!_shouldQuit) {
 		_system->delayMillis(20);
 		uint32 newMs = _system->getMillis();
 
@@ -1235,7 +1235,7 @@ void EfhEngine::handleWinSequence() {
 
 	Common::KeyCode input = Common::KEYCODE_INVALID;
 
-	while(input != Common::KEYCODE_ESCAPE) {
+	while (input != Common::KEYCODE_ESCAPE) {
 		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
 		displayFctFullScreen();
 		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);


Commit: 8f115830aa384ba874044d3d6ef8ac6c1be7286d
    https://github.com/scummvm/scummvm/commit/8f115830aa384ba874044d3d6ef8ac6c1be7286d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: remove the use of int16 in most loops, fix a compilation warning

Changed paths:
    engines/efh/efh.cpp
    engines/efh/files.cpp
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index fc25b9f6f9c..720a5ccc992 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -84,7 +84,7 @@ void AnimInfo::init() {
 }
 
 void ItemStruct::init() {
-	for (int16 idx = 0; idx < 15; ++idx)
+	for (uint idx = 0; idx < 15; ++idx)
 		_name[idx] = 0;
 
 	_damage = 0;
@@ -465,7 +465,7 @@ Common::Error EfhEngine::run() {
 			}
 			break;
 		case Common::KEYCODE_F5: { // Original is using CTRL-S
-			for (int16 counter = 0; counter < 2; ++counter) {
+			for (uint counter = 0; counter < 2; ++counter) {
 				clearBottomTextZone(0);
 				displayCenteredString("Are You Sure You Want To Save?", 24, 296, 160);
 				if (counter == 0)
@@ -488,7 +488,7 @@ Common::Error EfhEngine::run() {
 			}
 			break;
 		case Common::KEYCODE_F7: { // Original is using CTRL-L
-			for (int16 counter = 0; counter < 2; ++counter) {
+			for (uint counter = 0; counter < 2; ++counter) {
 				clearBottomTextZone(0);
 				displayCenteredString("Are You Sure You Want To Load?", 24, 296, 160);
 				if (counter == 0)
@@ -878,13 +878,13 @@ uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
 void EfhEngine::drawGameScreenAndTempText(bool flag) {
 	debugC(2, kDebugEngine, "drawGameScreenAndTempText %s", flag ? "True" : "False");
 
-	#if 0
+#if 0
 	// This code is present in the original, but looks strictly useless.
 	uint8 mapTileInfo = getMapTileInfo(_mapPosX, _mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[mapTileInfo / 72];
 
 	int16 mapImageSetId = (imageSetId * 72) + (mapTileInfo % 72);
-	#endif
+#endif
 
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -961,7 +961,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 	}
 
 	if (drawMonstersFl) {
-		for (int16 var16 = 0; var16 < 64; ++var16) {
+		for (uint var16 = 0; var16 < 64; ++var16) {
 			if ((_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == _fullPlaceId)){
 				bool var4 = false;
 				int16 posX = _mapMonsters[var16]._posX;
@@ -970,7 +970,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
 					continue;
 
-				for (int16 counterY = 0; counterY < 9 && !var4; ++counterY) {
+				for (uint counterY = 0; counterY < 9 && !var4; ++counterY) {
 					if (_mapMonsters[var16]._pictureRef[counterY] > 0)
 						var4 = true;
 				}
@@ -1010,7 +1010,7 @@ void EfhEngine::displayLargeMap(int16 posX, int16 posY) {
 void EfhEngine::drawScreen() {
 	debugC(2, kDebugEngine, "drawScreen");
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		_redrawNeededFl = false;
 		if (!_largeMapFlag) {
 			if (_fullPlaceId != 0xFF)
@@ -1035,12 +1035,12 @@ void EfhEngine::drawScreen() {
 void EfhEngine::displayLowStatusScreen(bool flag) {
 	debugC(6, kDebugEngine, "displayLowStatusScreen %s", flag ? "True" : "False");
 
-	static char strName[5] = "Name";
-	static char strDef[4] = "DEF";
-	static char strHp[3] = "HP";
-	static char strMaxHp[7] = "Max HP";
-	static char strWeapon[7] = "Weapon";
-	static char strDead[9] = "* DEAD *";
+	const char strName[5] = "Name";
+	const char strDef[4] = "DEF";
+	const char strHp[3] = "HP";
+	const char strMaxHp[7] = "Max HP";
+	const char strWeapon[7] = "Weapon";
+	const char strDead[9] = "* DEAD *";
 
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -1106,7 +1106,7 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 	debug("script_readNumberArray");
 
 	uint8 *buffer = srcBuffer;
-	for (int16 i = 0; i < destArraySize; ++i) {
+	for (int i = 0; i < destArraySize; ++i) {
 		buffer++;
 		buffer = script_getNumber(buffer, &destArray[i]);
 	}
@@ -1140,7 +1140,7 @@ void EfhEngine::removeObject(int16 charId, int16 objectId) {
 void EfhEngine::totalPartyKill() {
 	debug("totalPartyKill");
 
-	for (int16 counter = 0; counter < 3; ++counter) {
+	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
 			_npcBuf[counter]._hitPoints = 0;
 	}
@@ -1159,7 +1159,7 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	_teamCharStatus[teamMemberId]._status = 0;
 	_teamCharStatus[teamMemberId]._duration = 0;
 
-	for (int16 var4 = teamMemberId; var4 < 2; ++var4) {
+	for (int var4 = teamMemberId; var4 < 2; ++var4) {
 		_teamCharId[var4] = _teamCharId[var4 + 1];
 		_teamCharId[var4 + 1] = -1;
 	}
@@ -1171,7 +1171,7 @@ void EfhEngine::refreshTeamSize() {
 	debug("refreshTeamSize");
 
 	_teamSize = 0;
-	for (int16 counter = 0; counter < 3; ++counter) {
+	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
 			++_teamSize;
 	}
@@ -1180,7 +1180,7 @@ void EfhEngine::refreshTeamSize() {
 bool EfhEngine::isCharacterATeamMember(int16 id) {
 	debug("isCharacterATeamMember %d", id);
 
-	for (int16 counter = 0; counter < _teamSize; ++counter) {
+	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharId[counter] == id)
 			return true;
 	}
@@ -1192,7 +1192,7 @@ bool EfhEngine::isTPK() {
 	debug("isTPK");
 
 	int16 zeroedChar = 0;
-	for (int16 counter = 0; counter < _teamSize; ++counter) {
+	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
 			++zeroedChar;
 	}
@@ -1215,7 +1215,7 @@ void EfhEngine::handleWinSequence() {
 	loadImageSet(64, winSeqBuf3, winSeqSubFilesArray1, decompBuffer);
 	loadImageSet(65, winSeqBuf4, winSeqSubFilesArray2, decompBuffer);
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
 		displayRawDataAtPos(winSeqSubFilesArray2[0], 136, 48);
 		if (counter == 0)
@@ -1223,8 +1223,8 @@ void EfhEngine::handleWinSequence() {
 	}
 
 	getInput(12);
-	for (int16 animId = 1; animId < 8; ++animId) {
-		for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint animId = 1; animId < 8; ++animId) {
+		for (uint counter = 0; counter < 2; ++counter) {
 			displayRawDataAtPos(winSeqSubFilesArray1[0], 0, 0);
 			displayRawDataAtPos(winSeqSubFilesArray2[animId], 136, 48);
 			if (counter == 0)
@@ -1284,7 +1284,7 @@ void EfhEngine::handleWinSequence() {
 bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
 	debug("giveItemTo %d %d %d", charId, objectId, altCharId);
 
-	for (int16 newObjectId = 0; newObjectId < 10; ++newObjectId) {
+	for (uint newObjectId = 0; newObjectId < 10; ++newObjectId) {
 		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
 			continue;
 
@@ -1325,13 +1325,13 @@ int16 EfhEngine::handleCharacterJoining() {
 	debug("handleCharacterJoining");
 
 	static char strReplaceWho[13] = "Replace Who?";
-	for (int16 counter = 0; counter < 3; ++counter) {
+	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
 			return counter;
 		}
 	}
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		drawColoredRect(200, 112, 278, 132, 0);
 		displayCenteredString(strReplaceWho, 200, 278, 117);
 		if (counter == 0)
@@ -1339,7 +1339,7 @@ int16 EfhEngine::handleCharacterJoining() {
 	}
 
 	int16 charId = chooseCharacterToReplace();
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		drawColoredRect(200, 112, 278, 132, 0);
 		if (counter == 0)
 			displayFctFullScreen();
@@ -1554,8 +1554,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				bool found = false;
-				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
-					for (int16 objectId = 0; objectId < 10; ++objectId) {
+				for (int counter = 0; counter < _teamSize && !found; ++counter) {
+					for (uint objectId = 0; objectId < 10; ++objectId) {
 						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
 							removeObject(_teamCharId[counter], objectId);
 							found = true;
@@ -1570,7 +1570,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
-				for (int16 counter = 0; counter < _teamSize; ++counter) {
+				for (int counter = 0; counter < _teamSize; ++counter) {
 					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
 						break;
 				}
@@ -1581,8 +1581,8 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				bool found = false;
-				for (int16 counter = 0; counter < _teamSize && !found; ++counter) {
-					for (int16 objectId = 0; objectId < 10; ++objectId) {
+				for (int counter = 0; counter < _teamSize && !found; ++counter) {
+					for (uint objectId = 0; objectId < 10; ++objectId) {
 						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
 							found = true;
 							break;
@@ -1659,7 +1659,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 				int16 var110 = scriptNumberArray[0];
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
 				if (isCharacterATeamMember(var110)) {
-					for (int16 counter = 0; counter < 3; ++counter) {
+					for (uint counter = 0; counter < 3; ++counter) {
 						if (_teamCharId[counter] == var110) {
 							removeCharacterFromTeam(counter);
 							break;
@@ -1853,8 +1853,8 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 	if (varC < 0)
 		varC = 0;
 
-	for (int16 counter = 0; counter <= 23; counter += 2) {
-		for (int16 var8 = 0; var8 <= 23; ++var8) {
+	for (uint counter = 0; counter <= 23; counter += 2) {
+		for (uint var8 = 0; var8 <= 23; ++var8) {
 			int16 var4 = counter + varE;
 			int16 var2 = var8 + varC;
 			_mapGameMap[var4][var2] = _curPlace[counter][var8];
@@ -1862,8 +1862,8 @@ void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
 		drawScreen();
 	}
 
-	for (int16 counter = 1; counter <= 23; counter += 2) {
-		for (int16 var8 = 0; var8 <= 23; ++var8) {
+	for (uint counter = 1; counter <= 23; counter += 2) {
+		for (uint var8 = 0; var8 <= 23; ++var8) {
 			int16 var4 = counter + varE;
 			int16 var2 = var8 + varC;
 			_mapGameMap[var4][var2] = _curPlace[counter][var8];
@@ -1970,12 +1970,12 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	debug("sub151FD %d %d", posX, posY);
 
 	if (_largeMapFlag) {
-		for (int16 counter = 0; counter < 100; ++counter) {
+		for (uint counter = 0; counter < 100; ++counter) {
 			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == 0xFE)
 				return counter;
 		}
 	} else {
-		for (int16 counter = 0; counter < 100; ++counter) {
+		for (uint counter = 0; counter < 100; ++counter) {
 			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == _fullPlaceId)
 				return counter;
 		}
@@ -2137,7 +2137,7 @@ void EfhEngine::handleNewRoundEffects() {
 	if (!_word2C8D7)
 		return;
 
-	for (int16 counter = 0; counter < _teamSize; ++counter) {
+	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharStatus[counter]._status == 0) // normal
 			continue;
 		if (--_teamCharStatus[counter]._duration <= 0) {
@@ -2149,7 +2149,7 @@ void EfhEngine::handleNewRoundEffects() {
 	if (++regenCounter <= 8)
 		return;
 
-	for (int16 counter = 0; counter < _teamSize; ++counter) {
+	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (++_npcBuf[_teamCharId[counter]]._hitPoints > _npcBuf[_teamCharId[counter]]._maxHP)
 			_npcBuf[_teamCharId[counter]]._hitPoints = _npcBuf[_teamCharId[counter]]._maxHP;
 	}
@@ -2163,7 +2163,7 @@ bool EfhEngine::handleDeathMenu() {
 	_imageSetSubFilesIdx = 213;
 	drawScreen();
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		clearBottomTextZone(0);
 		displayCenteredString("Darkness Prevails...Death Has Taken You!", 24, 296, 153);
 		setTextPos(100, 162);
@@ -2296,7 +2296,7 @@ int8 EfhEngine::sub16B08(int16 monsterId) {
 	if (_mapMonsters[monsterId]._posX == _mapPosX && _mapMonsters[monsterId]._posY == _mapPosY)
 		return 0;
 
-	for (int16 counter = 0; counter < 64; ++counter) {
+	for (int counter = 0; counter < 64; ++counter) {
 		if (counter == monsterId)
 			continue;
 
@@ -2481,7 +2481,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 	if (!_ongoingFightFl)
 		return true;
 
-	for (int16 counter = 0; counter < 5; ++counter) {
+	for (uint counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId && unkFct_checkMonsterField8(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon))
 			return false;
 	}
@@ -2523,7 +2523,7 @@ void EfhEngine::sub174A0() {
 	int16 maxDisplayedMapX = CLIP<int16>(minDisplayedMapX + 20, 0, mapSize);
 	int16 maxDisplayedMapY = CLIP<int16>(minDisplayedMapY + 17, 0, mapSize);
 
-	for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
+	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
 		if (!checkPictureRefAvailability(monsterId))
 			continue;
 
@@ -2692,7 +2692,7 @@ bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
-	for (int16 counter = 0; counter < 9; ++counter) {
+	for (uint counter = 0; counter < 9; ++counter) {
 		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
 			return true;
 	}
@@ -2718,7 +2718,7 @@ int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
 	else
 		monsterId = id;
 
-	for (int16 counter = 0; counter < 9; ++counter) {
+	for (uint counter = 0; counter < 9; ++counter) {
 		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
 			++count;
 	}
@@ -2802,8 +2802,8 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 4:
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
-			for (int16 charId = 0; charId < 10; ++charId) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
+			for (uint charId = 0; charId < 10; ++charId) {
 				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
 					removeObject(_teamCharId[counter], charId);
 					displayMonsterAnim(monsterId);
@@ -2823,8 +2823,8 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 6:
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
-			for (int16 charId = 0; charId < 10; ++charId) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
+			for (uint charId = 0; charId < 10; ++charId) {
 				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
 					displayMonsterAnim(monsterId);
 					sub22AA8(_npcBuf[var58].field_14);
@@ -2835,7 +2835,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 7:
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				removeCharacterFromTeam(counter);
 				displayMonsterAnim(monsterId);
@@ -2846,13 +2846,13 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 8:
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[var58]._name;
 				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
 				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
-				for (int16 i = 0; i < 2; ++i) {
+				for (uint i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
 					_textColor = 0xE;
 					displayCenteredString(buffer, 24, 296, 161);
@@ -2873,7 +2873,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 9:
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
 				sub22AA8(_npcBuf[var58].field_14);
@@ -2984,7 +2984,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 							_word2C87A = false;
 						}
 					} else {
-						for (int16 counter = 0; counter < 2; ++counter) {
+						for (uint counter = 0; counter < 2; ++counter) {
 							drawMapWindow();
 							if (counter == 0)
 								displayFctFullScreen();
@@ -2995,7 +2995,7 @@ void EfhEngine::sub22AA8(int16 arg0) {
 							var4 = var2;
 
 						if (var4 != -1) {
-							for (int16 counter = 0; counter < 2; ++counter) {
+							for (uint counter = 0; counter < 2; ++counter) {
 								if (varA) {
 									displayCenteredString("[DONE]", 128, 303, 117);
 								} else {
@@ -3035,7 +3035,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			sub22AA8(_mapUnknown[var8]._field5); // word!
 			return true;
 		} else if (_mapUnknown[var8]._field3 == 0xFE) {
-			for (int16 counter = 0; counter < _teamSize; ++counter) {
+			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 				if (_teamCharId[counter] == _mapUnknown[var8]._field4) {
@@ -3044,11 +3044,11 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				}
 			}
 		} else if (_mapUnknown[var8]._field3 == 0xFD) {
-			for (int16 counter = 0; counter < _teamSize; ++counter) {
+			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
-				for (int16 var2 = 0; var2 < 10; ++var2) {
+				for (uint var2 = 0; var2 < 10; ++var2) {
 					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4) {
 						sub22AA8(_mapUnknown[var8]._field5);
 						return true;
@@ -3062,7 +3062,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				if (_teamCharId[counter] == -1)
 					continue;
 
-				for (int16 var2 = 0; var2 < 39; ++var2) {
+				for (uint var2 = 0; var2 < 39; ++var2) {
 					if (_npcBuf[_teamCharId[counter]]._activeScore[var2] >= _mapUnknown[var8]._field4) {
 						sub22AA8(_mapUnknown[var8]._field5);
 						return true;
@@ -3088,7 +3088,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		}
 	}
 
-	for (int16 counter = 0; counter < 64; ++counter) {
+	for (uint counter = 0; counter < 64; ++counter) {
 		if (!sub21820(counter, arg8, itemId))
 			return true;
 	}
@@ -3140,7 +3140,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
 	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
 
-	for (int16 counter = 0; counter < teamMonsterId; ++counter) {
+	for (int counter = 0; counter < teamMonsterId; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId)
 			return true;
 	}
@@ -3156,11 +3156,11 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 		_teamMonsterIdArray[0] = monsterTeamId;
 	}
 
-	for (int16 counter2 = 1; counter2 <= 3; ++counter2) {
+	for (int counter2 = 1; counter2 <= 3; ++counter2) {
 		if (counter >= 5)
 			break;
 
-		for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
+		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
 			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 				continue;
 
@@ -3171,7 +3171,7 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 				continue;
 
 			bool var6 = false;
-			for (int16 counter3 = 0; counter3 < 9; ++counter3) {
+			for (uint counter3 = 0; counter3 < 9; ++counter3) {
 				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
 					var6 = true;
 					break;
@@ -3191,14 +3191,14 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 	if (counter > 4)
 		return;
 
-	for (int16 id = counter; id < 5; ++id)
+	for (uint id = counter; id < 5; ++id)
 		_teamMonsterIdArray[id] = -1;
 }
 
 void EfhEngine::reset_stru32686() {
 	debug("reset_stru32686");
-	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
-		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
 			_stru32686[counter1]._field0[counter2] = 0;
 			_stru32686[counter1]._field2[counter2] = 0;
 		}
@@ -3231,7 +3231,7 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 void EfhEngine::sub1CDFA() {
 	debug("sub1CDFA"); // Initiatives
 
-	for (int16 counter = 0; counter < 3; ++counter) {
+	for (int counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
 			_stru3244C[counter]._field0 = counter + 1000;
 			_stru3244C[counter]._field2 = _npcBuf[_teamCharId[counter]]._infoScore[3];
@@ -3241,7 +3241,7 @@ void EfhEngine::sub1CDFA() {
 		}
 	}
 
-	for (int16 counter = 0; counter < 5; ++counter) {
+	for (int counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == -1) {
 			_stru3244C[counter + 3]._field0 = -1;
 			_stru3244C[counter + 3]._field2 = -1;
@@ -3251,8 +3251,8 @@ void EfhEngine::sub1CDFA() {
 		}
 	}
 
-	for (int16 counter = 0; counter < 8; ++counter) {
-		for (int16 counter2 = 0; counter2 < 8; ++counter2) {
+	for (uint counter = 0; counter < 8; ++counter) {
+		for (uint counter2 = 0; counter2 < 8; ++counter2) {
 			if (_stru3244C[counter]._field2 >= _stru3244C[counter2]._field2)
 				continue;
 
@@ -3265,7 +3265,7 @@ void EfhEngine::sub1CDFA() {
 void EfhEngine::redrawScreenForced() {
 	debug("redrawScreenForced");
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		drawScreen();
 		if (counter == 0)
 			displayFctFullScreen();
@@ -3326,7 +3326,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 	}
 
 	do {
-		for (int16 counter = 0; counter < 2; ++counter) {
+		for (uint counter = 0; counter < 2; ++counter) {
 			drawCombatScreen(charId, true, false);
 			if (_teamMonsterIdArray[1] != -1)
 				sub1C219((uint8 *)"Select Monster Group:", 3, 0, false);
@@ -3360,7 +3360,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 void EfhEngine::sub1CAB6(int16 charId) {
 	debug("sub1CAB6 %d", charId);
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		drawGameScreenAndTempText(false);
 		displayLowStatusScreen(false);
 		drawCombatScreen(charId, false, false);
@@ -3373,7 +3373,7 @@ bool EfhEngine::sub1CB27() {
 	debug("sub1CB27");
 
 	bool var4 = false;
-	for (int16 counter1 = 0; counter1 < _teamSize; ++counter1) {
+	for (int counter1 = 0; counter1 < _teamSize; ++counter1) {
 		_teamLastAction[counter1] = 0;
 		if (!isTeamMemberStatusNormal(counter1))
 			continue;
@@ -3396,7 +3396,7 @@ bool EfhEngine::sub1CB27() {
 				_teamLastAction[counter1] = 'H';
 				break;
 			case Common::KEYCODE_r: // Run
-				for (int16 counter2 = 0; counter2 < _teamSize; ++counter2) {
+				for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
 					_teamLastAction[counter2] = 'R';
 				}
 				return true;
@@ -3482,19 +3482,19 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	int16 var4 = 1;
 
 	// sub1BE9A - 1rst loop counter1_monsterId - Start
-	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
 		if (countMonsterGroupMembers(counter1))
 			continue;
 
-		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
 			_mapMonsters[_teamMonsterIdArray[counter1]]._pictureRef[counter2] = 0;
 			_stru32686[counter1]._field0[counter2] = 0;
 			_stru32686[counter1]._field2[counter2] = 0;
 		}
 
 		_teamMonsterIdArray[counter1] = -1;
-		for (int16 counter2 = counter1 + 1; counter2 < 5; ++counter2) {
-			for (int16 var8 = 0; var8 < 9; ++var8) {
+		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
+			for (uint var8 = 0; var8 < 9; ++var8) {
 				_stru32686[counter1]._field0[var8] = _stru32686[counter2]._field0[var8];
 				_stru32686[counter1]._field2[var8] = _stru32686[counter2]._field2[var8];
 			}
@@ -3505,7 +3505,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	// sub1BE9A - 1rst loop counter1_monsterId - End
 
 	var4 = -1;
-	for (int16 counter1 = 0; counter1 < 5; ++counter1) {
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
 		if (_teamMonsterIdArray[counter1] == -1) {
 			var4 = counter1;
 			break;
@@ -3514,18 +3514,18 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 
 	if (var4 != -1) {
 		// sub1BE9A - loop var2 - Start
-		for (int16 var2 = 1; var2 < 3; ++var2) {
+		for (int var2 = 1; var2 < 3; ++var2) {
 			if (var4 >= 5)
 				break;
 
-			for (int16 counter1 = 0; counter1 < 64; ++counter1) {
+			for (uint counter1 = 0; counter1 < 64; ++counter1) {
 				if (_mapMonsters[counter1]._guess_fullPlaceId == 0xFF)
 					continue;
 
 				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._field_1)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(counter1)) {
 						bool var6 = false;
-						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+						for (uint counter2 = 0; counter2 < 9; ++counter2) {
 							if (_mapMonsters[counter1]._pictureRef[counter2] > 0) {
 								var6 = true;
 								break;
@@ -3548,7 +3548,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 						// Furthermore, it was accessing _stru32686[counter1]._field0[counter1] which doesn't make
 						// sense...
 						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
-						for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+						for (uint counter2 = 0; counter2 < 9; ++counter2) {
 							_stru32686[counter1]._field0[counter2] = 0;
 						}
 
@@ -3567,7 +3567,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	// sub1BE9A - last loop counter1_monsterId - Start
 	for (int16 counter1 = var4; counter1 < 5; ++counter1) {
 		_teamMonsterIdArray[counter1] = -1;
-		for (int16 counter2 = 0; counter2 < 9; ++counter2) {
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
 			_stru32686[counter1]._field0[counter2] = (int16)0x8000;
 		}
 	}
@@ -3578,7 +3578,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 		debug("getTeamMonsterAnimId");
 
 	int16 retVal = 0xFF;
-	for (int16 counter = 0; counter < 5; ++counter) {
+	for (uint counter = 0; counter < 5; ++counter) {
 		int16 monsterId = _teamMonsterIdArray[counter];
 		if (monsterId == -1)
 			continue;
@@ -3600,7 +3600,7 @@ int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	debugC(9, kDebugEngine, "countMonsterGroupMembers %d", monsterGroup);
 
 	int16 result = 0;
-	for (int16 counter = 0; counter < 9; ++counter) {
+	for (uint counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(monsterGroup, counter))
 			++result;
 	}
@@ -3612,7 +3612,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 	debug("sub1C4CA %s", whiteFl ? "True" : "False");
 
 	int16 textPosY = 20;
-	for (int16 counter = 0; counter < 5; ++counter) {
+	for (uint counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == -1)
 			continue;
 
@@ -3707,7 +3707,7 @@ void EfhEngine::displayCombatMenu(int16 charId) {
 void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 	debug("drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", forceDrawFl ? "True" : "False");
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || forceDrawFl) {
 			drawMapWindow();
 			displayCenteredString("Combat", 128, 303, 9);
@@ -3771,7 +3771,7 @@ int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 	if (monsterId == -1)
 		return -1;
 
-	for (int16 counter = 0; counter < 9; ++counter) {
+	for (uint counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(groupNumber, counter)) {
 			var4 = counter;
 			break;
@@ -3980,7 +3980,7 @@ void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
 	case 11:
 	case 12:
 	case 13:
-		for (int16 counter = 0; counter < repeatCount; ++counter) {
+		for (int counter = 0; counter < repeatCount; ++counter) {
 			generateSound(17);
 		}
 		break;
@@ -4010,7 +4010,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
 		return true;
 
-	for (int16 counter = 0; counter < 10; ++counter) {
+	for (uint counter = 0; counter < 10; ++counter) {
 		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || _npcBuf[charId]._inventory[counter]._stat1 == 0x80)
 			continue;
 
@@ -4499,7 +4499,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var64 = _items[unk_monsterField5_itemId]._attacks *_npcBuf[_teamCharId[teamCharId]]._speed;
 
 					// Action A - Loop var84 - Start
-					for (int16 var84 = 0; var84 < var64; ++var84) {
+					for (int var84 = 0; var84 < var64; ++var84) {
 						if (getRandom(100) < charScore) {
 							++var62;
 							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[unk_monsterField5_itemId]._attackType)) {
@@ -4743,7 +4743,7 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	if (damage > 50)
 		damage = 50;
 
-	for (int16 objectId = 0; objectId < 10; ++objectId) {
+	for (uint objectId = 0; objectId < 10; ++objectId) {
 		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || (_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0 && _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
 			continue;
 
@@ -4812,7 +4812,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 		int16 varInt = getTeamMonsterAnimId();
 		displayAnimFrames(varInt, true);
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
 			_word32680[counter] = 100;
 			_word32482[counter] = 65;
 		}
@@ -4825,7 +4825,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			return false;
 		}
 
-		for (int16 counter = 0; counter < _teamSize; ++counter) {
+		for (int counter = 0; counter < _teamSize; ++counter) {
 			if (_teamLastAction[counter] == 0x52) // 'R'
 				mainLoopCond = true;
 		}
@@ -4833,7 +4833,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		sub1CDFA();
 		sub1C219(nullptr, 2, 1, false);
 
-		for (int16 counter = 0; counter < 8; ++counter) {
+		for (uint counter = 0; counter < 8; ++counter) {
 			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
 			if (monsterGroupIdOrMonsterId == -1)
 				continue;
@@ -4861,7 +4861,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 				}
 			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
 				// handleFight - Loop on var86 - Start
-				for (int16 var86 = 0; var86 < 9; ++var86) {
+				for (uint var86 = 0; var86 < 9; ++var86) {
 					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
 						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
 						if (unk_monsterField5_itemId == 0xFF)
@@ -4869,7 +4869,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 						int16 teamMemberId = -1;
 						int16 var54;
 						if (_items[unk_monsterField5_itemId]._range < 3) {
-							for (int16 var84 = 0; var84 < 10; ++var84) {
+							for (uint var84 = 0; var84 < 10; ++var84) {
 								teamMemberId = getRandom(_teamSize) - 1;
 								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _word32680[teamMemberId]) {
 									break;
@@ -4898,7 +4898,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 originalDamage = 0;
 								int16 damagePointsAbsorbed = 0;
 								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
-								for (int16 var84 = 0; var84 < var64; ++var84) {
+								for (int var84 = 0; var84 < var64; ++var84) {
 									// handleFight - Loop var84 on var64 (objectId) - Start
 									if (getRandom(100) > _word32482[var7E])
 										continue;
@@ -5115,7 +5115,7 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 mi
 void EfhEngine::displayStatusMenu(int16 windowId) {
 	debug("displayStatusMenu %d", windowId);
 
-	for (int16 counter = 0; counter < 9; ++counter) {
+	for (uint counter = 0; counter < 9; ++counter) {
 		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
 	}
 
@@ -5170,7 +5170,7 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 	}
 
 	if (var4 == -1) {
-		for (int16 counter = 0; counter < 10; ++counter) {
+		for (uint counter = 0; counter < 10; ++counter) {
 			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
 				_word3273A[_menuItemCounter++] = counter;
 			}
@@ -5242,7 +5242,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 		return;
 	}
 
-	for (int16 counter = 0; counter < _menuItemCounter; ++counter) {
+	for (int counter = 0; counter < _menuItemCounter; ++counter) {
 		if (_menuDepth == 0)
 			setTextColorGrey();
 		else {
@@ -5316,7 +5316,7 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 		return;
 	}
 
-	for (int16 counter = 0; counter < _menuItemCounter; ++counter) {
+	for (int counter = 0; counter < _menuItemCounter; ++counter) {
 		if (counter == curMenuLine)
 			setTextColorWhite();
 		int16 textPosY = 38 + counter * 9;
@@ -5413,7 +5413,7 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 
 	int16 retVal = 0;
 
-	for (int16 counter = 0; counter < 2; ++counter) {
+	for (uint counter = 0; counter < 2; ++counter) {
 		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
 
@@ -5473,7 +5473,7 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 	} else {
 		int16 var2 = _items[itemId].field_18;
 		if (var2 != 4) {
-			for (int16 counter = 0; counter < 10; ++counter) {
+			for (uint counter = 0; counter < 10; ++counter) {
 				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
 					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
 			}
@@ -5554,7 +5554,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 victims = 0;
 			strncat((char *)_messageToBePrinted, "  The item emits a low droning hum...", 400);
 			if (getRandom(100) < 50) {
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						++victims;
 						_stru32686[windowId]._field0[counter] = 1;
@@ -5563,7 +5563,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				}
 			} else {
 				int16 NumberOfTargets = getRandom(9);
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					if (NumberOfTargets == 0)
 						break;
 
@@ -5593,7 +5593,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			strncat((char *)_messageToBePrinted, "  The item emits a blue beam...", 400);
 			int16 victim = 0;
 			if (getRandom(100) < 50) {
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+				for (uint varA8 = 0; varA8 < 9; ++varA8) {
 					if (isMonsterActive(windowId, varA8)) {
 						++victim;
 						_stru32686[windowId]._field0[varA8] = 2;
@@ -5602,7 +5602,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				}
 			} else {
 				int16 varAC = getRandom(9);
-				for (int16 varA8 = 0; varA8 < 9; ++varA8) {
+				for (uint varA8 = 0; varA8 < 9; ++varA8) {
 					if (varAC == 0)
 						break;
 
@@ -5643,13 +5643,13 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		} else {
 			strncat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!", 400);
 			if (getRandom(100) < 50) {
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
 				}
 			} else {
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						if (getRandom(100) < 50) {
 							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
@@ -5667,12 +5667,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		} else {
 			if (getRandom(100) < 50) {
 				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!", 400);
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 				}
 			} else {
 				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!", 400);
-				for (int16 counter = 0; counter < 9; ++counter) {
+				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 					}
@@ -6470,7 +6470,7 @@ bool EfhEngine::checkMonsterCollision() {
 
 	int16 var68 = 0;
 
-	for (int16 monsterId = 0; monsterId < 64; ++monsterId) {
+	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
 		if (!checkPictureRefAvailability(monsterId))
 			continue;
 
@@ -6494,14 +6494,14 @@ bool EfhEngine::checkMonsterCollision() {
 		_redrawNeededFl = true;
 
 		int16 var6A = 0;
-		for (int16 var6C = 0; var6C < 9; ++var6C) {
+		for (uint var6C = 0; var6C < 9; ++var6C) {
 			if (_mapMonsters[monsterId]._pictureRef[var6C])
 				++var6A;
 		}
 
 		Common::String buffer = "";
 		do {
-			for (int16 var6C = 0; var6C < 2; ++var6C) {
+			for (uint var6C = 0; var6C < 2; ++var6C) {
 				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 				Common::String dest;
 				if (var1 <= 0x3D) {
@@ -6736,8 +6736,8 @@ void EfhEngine::copyCurrentPlaceToBuffer(int16 id) {
 	// Note that 576 = 24 * 24
 	uint8 *placesPtr = &_places[576 * id];
 
-	for (int16 i = 0; i < 24; ++i) {
-		for (int16 j = 0; j < 24; ++j) {
+	for (uint i = 0; i < 24; ++i) {
+		for (uint j = 0; j < 24; ++j) {
 			_curPlace[i][j] = placesPtr[i * 24 + j];
 		}
 	}
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index fc0090c0b07..38b6984f266 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -87,9 +87,11 @@ void EfhEngine::findMapFile(int16 mapId) {
 void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 **subFilesArray, uint8 *packedBuffer) {
 	debugC(1, kDebugUtils, "rImageFile %s", filename.c_str());
 	readFileToBuffer(filename, packedBuffer);
-	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
 
-#ifdef debug
+#ifndef debug
+	uncompressBuffer(packedBuffer, targetBuffer);
+#else
+	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
 	// dump a decompressed image file
 	Common::DumpFile dump;
 	dump.open(filename + ".dump");
@@ -136,7 +138,7 @@ void EfhEngine::readItems() {
 		error("Unable to find file %s", fileName.c_str());
 
 	for (int i = 0; i < 300; ++i) {
-		for (int16 idx = 0; idx < 15; ++idx)
+		for (uint idx = 0; idx < 15; ++idx)
 			_items[i]._name[idx] = f.readByte();
 
 		_items[i]._damage = f.readByte();
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index ac1ee0305da..8e9a97213c9 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -299,7 +299,7 @@ void EfhEngine::drawChar(uint8 curChar, int16 posX, int16 posY) {
 	int16 charId = curChar - 0x20;
 	uint8 width = _fontDescr._widthArray[charId];
 
-	for (int16 line = 0; line < 8; ++line) {
+	for (uint line = 0; line < 8; ++line) {
 		int16 x = 0;
 		for (int i = 7; i >= 7 - width; --i) {
 			if (_fontDescr._fontData[charId]._lines[line] & (1 << i))


Commit: d03b0043ddde839b73d18503948ee1e6abc5ee20
    https://github.com/scummvm/scummvm/commit/d03b0043ddde839b73d18503948ee1e6abc5ee20
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Fix formatting, remove an obsolete comment

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 720a5ccc992..2aa65620bde 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1324,7 +1324,7 @@ int16 EfhEngine::chooseCharacterToReplace() {
 int16 EfhEngine::handleCharacterJoining() {
 	debug("handleCharacterJoining");
 
-	static char strReplaceWho[13] = "Replace Who?";
+	const char strReplaceWho[13] = "Replace Who?";
 	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
 			return counter;
@@ -3572,10 +3572,10 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 		}
 	}
 	// sub1BE9A - last loop counter1_monsterId - End
-	}
+}
 
 int16 EfhEngine::getTeamMonsterAnimId() {
-		debug("getTeamMonsterAnimId");
+	debug("getTeamMonsterAnimId");
 
 	int16 retVal = 0xFF;
 	for (uint counter = 0; counter < 5; ++counter) {
@@ -3918,34 +3918,34 @@ void EfhEngine::generateSound5(int arg0) {
 
 void EfhEngine::generateSound(int16 soundType) {
 	switch (soundType) {
-		case 5:
-			generateSound3();
-			break;
-		case 9:
-			generateSound1(20, 888, 3000);
-			generateSound1(20, 888, 3000);
-			break;
-		case 10:
-			generateSound5(1);
-			break;
-		case 13:
-			generateSound2(256, 4096, 18);
-			break;
-		case 14:
-			generateSound2(20, 400, 100);
-			break;
-		case 15:
-			generateSound2(100, 888, 88);
-			break;
-		case 16:
-			generateSound1(2000, 6096, 1500);
-			break;
-		case 17:
-			generateSound4(1);
-			break;
-		default:
-			// Not implemented because not used by the engine
-			break;
+	case 5:
+		generateSound3();
+		break;
+	case 9:
+		generateSound1(20, 888, 3000);
+		generateSound1(20, 888, 3000);
+		break;
+	case 10:
+		generateSound5(1);
+		break;
+	case 13:
+		generateSound2(256, 4096, 18);
+		break;
+	case 14:
+		generateSound2(20, 400, 100);
+		break;
+	case 15:
+		generateSound2(100, 888, 88);
+		break;
+	case 16:
+		generateSound1(2000, 6096, 1500);
+		break;
+	case 17:
+		generateSound4(1);
+		break;
+	default:
+		// Not implemented because not used by the engine
+		break;
 	}
 }
 
@@ -5099,7 +5099,7 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 mi
 		else
 			setTextColorGrey();
 
-		snprintf(buffer, 20,"> %s <", str);
+		snprintf(buffer, 20, "> %s <", str);
 		displayCenteredString(buffer, minX, maxX, minY);
 		setTextColorRed();
 	} else {
@@ -5914,7 +5914,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		break;
 	case 25: {
-			int16 teamCharId;
+		int16 teamCharId;
 		if (argA == 2) {
 			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
@@ -6571,7 +6571,6 @@ bool EfhEngine::checkMonsterCollision() {
 				var68 = true;
 				break;
 			default:
-//				warning("STUB: checkMonsterCollision - Missing mapping ?");
 				break;
 			}
 		} while (!var68);


Commit: bc7de3a10a483d38ae1746ceb0fd4c845340e037
    https://github.com/scummvm/scummvm/commit/bc7de3a10a483d38ae1746ceb0fd4c845340e037
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Split some more functions from efh.cpp

Changed paths:
  A engines/efh/fight.cpp
  A engines/efh/script.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/module.mk


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2aa65620bde..46a5c9da2d9 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1102,33 +1102,6 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 	}
 }
 
-uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
-	debug("script_readNumberArray");
-
-	uint8 *buffer = srcBuffer;
-	for (int i = 0; i < destArraySize; ++i) {
-		buffer++;
-		buffer = script_getNumber(buffer, &destArray[i]);
-	}
-
-	return buffer;
-}
-
-uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
-	debug("script_getNumber");
-
-	uint8 *buffer = srcBuffer;
-	int16 var2 = 0;
-	for (;;) {
-		uint8 curChar = *buffer;
-		if (curChar < 0x30 || curChar > 0x39) {
-			*retval = var2;
-			return buffer;
-		}
-		var2 = var2 * 10 + curChar - 0x30;
-		buffer++;
-	}
-}
 
 void EfhEngine::removeObject(int16 charId, int16 objectId) {
 	debug("removeObject %d %d", charId, objectId);
@@ -1352,450 +1325,6 @@ int16 EfhEngine::handleCharacterJoining() {
 	return 2;
 }
 
-int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("script_parse %s %d-%d %d-%d %s", (char *) stringBuffer, posX, posY, maxX, maxY, flag ? "True" : "False");
-
-	bool doneFlag = false;
-	int16 var_F2 = -1;
-	int16 var_F0 = 0xFF;
-	int16 var_EE = 0xFF;
-	uint16 curLineNb = 0;
-	int16 numbLines = (1 + maxY - posY) / 9;
-	int16 width = maxX - posX;
-	int16 spaceWidth = getStringWidth(" ");
-	uint8 *buffer = stringBuffer;
-	char nextWord[80];
-	char curLine[150];
-	memset(nextWord, 0, sizeof(nextWord));
-	memset(curLine, 0, sizeof(curLine));
-	int16 curWordPos = 0;
-	setTextPos(posX, curLineNb * 9 + posY);
-
-	while (!doneFlag) {
-		uint8 curChar = *buffer;
-		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
-			var_F2 = 0;
-			nextWord[curWordPos++] = curChar;
-			++buffer;
-			continue;
-		}
-
-		if (curChar != 0x5E) {
-			if (curChar == 0)
-				doneFlag = true;
-			else if (curChar == 0x7C)
-				var_F2 = 0;
-
-			nextWord[curWordPos] = 0;
-			int16 widthNextWord = getStringWidth(nextWord);
-			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine);
-
-			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) {
-				if (curLineNb >= numbLines) {
-					doneFlag = true;
-				} else {
-					if (var_F2 == 0)
-						displayStringAtTextPos(curLine);
-
-					*curLine = 0;
-					strncpy(curLine, nextWord, 80);
-					strncat(curLine, " ",2);
-					++curLineNb;
-					setTextPos(posX, posY + curLineNb * 9);
-					curWordPos = 0;
-				}
-			} else {
-				strncat(curLine, nextWord, 80);
-				strncat(curLine, " ", 2);
-				curWordPos = 0;
-			}
-			++buffer;
-			continue;
-		}
-
-		// At this point, curChar == 0x5E
-		++buffer;
-		int16 opCode = 0;
-		buffer = script_getNumber(buffer, &opCode);
-		int16 scriptNumberArray[10];
-		memset(scriptNumberArray, 0, sizeof(scriptNumberArray));
-
-		switch (opCode) {
-		case 0x00:
-			// Enter room { full Place Id, posX, posY }
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				if (_largeMapFlag) {
-					_largeMapFlag = false;
-					_techDataId_MapPosX = _mapPosX;
-					_techDataId_MapPosY = _mapPosY;
-				}
-				_oldMapPosX = _mapPosX = scriptNumberArray[1];
-				_oldMapPosY = _mapPosY = scriptNumberArray[2];
-				loadPlacesFile(scriptNumberArray[0], false);
-				_word2C880 = true;
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x01:
-			// Exit room { }
-			if (flag) {
-				_largeMapFlag = true;
-				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
-				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
-				_word2C880 = true;
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x02:
-			// Change map. { map number, posX, posY }
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				if (_word2C8D7)
-					writeTechAndMapFiles();
-				_oldMapPosX = _mapPosX = scriptNumberArray[1];
-				_oldMapPosY = _mapPosY = scriptNumberArray[2];
-				loadTechMapImp(scriptNumberArray[0]);
-				_largeMapFlag = true;
-				_word2C880 = true;
-				_redrawNeededFl = true;
-				doneFlag = true;
-			}
-			break;
-		case 0x03:
-			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[2] - scriptNumberArray[0];
-				int16 var10E = scriptNumberArray[3] - scriptNumberArray[1];
-
-				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
-				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
-				_word2C880 = true;
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x04:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				_mapPosX = scriptNumberArray[0];
-				_mapPosY = scriptNumberArray[1];
-				_word2C880 = true;
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x05:
-			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = scriptNumberArray[1];
-					_npcBuf[var110]._activeScore[var10E] += scriptNumberArray[2] & 0xFF;
-					_npcBuf[var110]._activeScore[var10E] -= scriptNumberArray[3] & 0xFF;
-				}
-			}
-			break;
-		case 0x06:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = scriptNumberArray[1];
-					_npcBuf[var110]._activeScore[var10E] = scriptNumberArray[1];
-				}
-			}
-			break;
-		case 0x07:
-			if (flag) {
-				totalPartyKill();
-				// emptyFunction(2);
-			}
-			break;
-		case 0x08:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag && scriptNumberArray[0] != -1) {
-				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
-			}
-			break;
-		case 0x09:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = getRandom(scriptNumberArray[1]);
-					_npcBuf[var110]._hitPoints += var10E;
-					if (_npcBuf[var110]._hitPoints > _npcBuf[var110]._maxHP)
-						_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
-				}
-			}
-			break;
-		case 0x0A:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
-				}
-			}
-			break;
-		case 0x0B:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = getRandom(scriptNumberArray[1]);
-					_npcBuf[var110]._hitPoints -= var10E;
-					if (_npcBuf[var110]._hitPoints < 0)
-						_npcBuf[var110]._hitPoints = 0;
-				}
-			}
-			break;
-		case 0x0C:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				bool found = false;
-				for (int counter = 0; counter < _teamSize && !found; ++counter) {
-					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
-							removeObject(_teamCharId[counter], objectId);
-							found = true;
-							break;
-						}
-					}
-				}
-			}
-			break;
-		case 0x0D:
-			// Put item in inventory { objectId }
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				for (int counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
-						break;
-				}
-			}
-			break;
-		case 0x0E:
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				bool found = false;
-				for (int counter = 0; counter < _teamSize && !found; ++counter) {
-					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
-							found = true;
-							break;
-						}
-					}
-				}
-
-				if (found)
-					var_F0 = scriptNumberArray[1];
-				else
-					var_F0 = scriptNumberArray[2];
-			}
-			break;
-		case 0x0F:
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				if (isCharacterATeamMember(var110))
-					var_F0 = scriptNumberArray[1];
-				else
-					var_F0 = scriptNumberArray[2];
-			}
-			break;
-		case 0x10:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag)
-				var_F0 = scriptNumberArray[0];
-
-			break;
-		case 0x11:
-			if (flag)
-				_unkArray2C8AA[0] = 0;
-			break;
-		case 0x12:
-			// Guess : disable special tile { }
-			if (flag) {
-				int16 var110 = sub151FD(_mapPosX, _mapPosY);
-				if (var110 != -1)
-					_mapUnknown[var110]._posX = 0xFF;
-			}
-			break;
-		case 0x13:
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag && _largeMapFlag) {
-				_word2C87A = true;
-				loadPlacesFile(scriptNumberArray[0], false);
-				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
-				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
-				var_F0 = -1;
-			}
-			break;
-		case 0x14:
-			// Add character to team { charId }
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				if (!isCharacterATeamMember(var110))
-					var_EE = var110;
-				var_F0 = -1;
-			}
-			break;
-		case 0x15:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				_oldMapPosX = _mapPosX = scriptNumberArray[0];
-				_oldMapPosY = _mapPosY = scriptNumberArray[1];
-				_largeMapFlag = true;
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x16:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
-				if (isCharacterATeamMember(var110)) {
-					for (uint counter = 0; counter < 3; ++counter) {
-						if (_teamCharId[counter] == var110) {
-							removeCharacterFromTeam(counter);
-							break;
-						}
-					}
-				}
-			}
-			break;
-		case 0x17:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				displayAnimFrames(var110, true);
-			}
-			break;
-		case 0x18:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[1] - scriptNumberArray[0] + 1;
-				bool found = false;
-				var110 = getRandom(var110) + scriptNumberArray[0] - 1;
-				int16 counter;
-				for (counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], var110, 0xFF)) {
-						found = true;
-						break;
-					}
-				}
-
-				if (!found) {
-					drawMapWindow();
-					displayFctFullScreen();
-					drawMapWindow();
-					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
-					displayFctFullScreen();
-				} else {
-					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
-					_nameBuffer = _items[var110]._name;
-					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
-					drawMapWindow();
-					displayFctFullScreen();
-					drawMapWindow();
-					var110 = sub1C219((uint8 *)curLine, 1, 2, true);
-					displayFctFullScreen();
-				}
-
-				var110 = sub151FD(_mapPosX, _mapPosY);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
-				}
-				_redrawNeededFl = true;
-			}
-			break;
-		case 0x19:
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				if (_largeMapFlag) {
-					_mapGameMap[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
-				} else {
-					_curPlace[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
-				}
-			}
-			break;
-		case 0x1A:
-			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
-				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
-				}
-			}
-			break;
-		case 0x1B:
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
-				}
-				_mapUnknown[scriptNumberArray[2]]._posX = scriptNumberArray[0];
-				_mapUnknown[scriptNumberArray[2]]._posY = scriptNumberArray[1];
-			}
-			break;
-		case 0x1C:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				_history[scriptNumberArray[0]] = 0xFF;
-			}
-			break;
-		case 0x1D:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				_history[scriptNumberArray[0]] = 0;
-			}
-			break;
-		case 0x1E:
-			// Dialog with condition { historyId, dialogId1, dialogId2 }
-			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
-				if (_history[scriptNumberArray[0]] == 0)
-					var_F0 = scriptNumberArray[2];
-				else
-					var_F0 = scriptNumberArray[1];
-			}
-			break;
-		case 0x1F:
-			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag)
-				_unkArray2C8AA[0] = scriptNumberArray[0];
-
-			break;
-		case 0x20:
-			if (flag) {
-				handleWinSequence();
-				_system->quit();
-			}
-		default:
-			break;
-		}
-	}
-
-	if (*curLine != 0 && curLineNb < numbLines && var_F2 == 0)
-		displayStringAtTextPos(curLine);
-
-	if (var_EE != 0xFF) {
-		displayLowStatusScreen(true);
-		int16 teamSlot = handleCharacterJoining();
-		if (teamSlot > -1) {
-			_teamCharId[teamSlot] = var_EE;
-		}
-		refreshTeamSize();
-	}
-
-	return var_F0;
-}
-
 void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
 	debugC(7, kDebugEngine, "drawText %d-%d %d-%d %s", posX, posY, maxX, maxY, flag ? "True" : "False");
 
@@ -3724,44 +3253,6 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 	}
 }
 
-void EfhEngine::handleFight_checkEndEffect(int16 charId) {
-	debug("handleFight_checkEndEffect %d", charId);
-
-	// In the original, this function is part of handleFight.
-	// It has been split for readability purposes.
-	if (_teamCharStatus[charId]._status == 0)
-		return;
-	if (--_teamCharStatus[charId]._duration != 0)
-		return;
-
-	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
-	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
-	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
-		_enemyNamePt1 = "The ";
-	} else {
-		_enemyNamePt1 = "";
-	}
-
-	// End of effect message depends on the type of effect
-	switch (_teamCharStatus[charId]._status) {
-	case 1:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-		break;
-	case 2:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-		break;
-	default:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-		break;
-	}
-
-	// The character status is back to normal
-	_teamCharStatus[charId]._status = 0;
-
-	// Finally, display the message
-	sub1C219(_messageToBePrinted, 1, 2, true);
-}
-
 int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 	debug("sub1DEC8 %d", groupNumber);
 
@@ -4436,284 +3927,6 @@ void EfhEngine::addReactionText(int16 id) {
 	strncat((char *)_messageToBePrinted, buffer, 80);
 }
 
-void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
-	debug("handleFight_lastAction_A %d", teamCharId);
-
-	// In the original, this function is part of handleFight.
-	// It has been split for readability purposes.
-
-	int16 unk_monsterField5_itemId = sub1C80A(_teamCharId[teamCharId], 9, true);
-	if (unk_monsterField5_itemId == 0x7FFF)
-		unk_monsterField5_itemId = 0x3F;
-	int16 monsterGroupNumber = _teamNextAttack[teamCharId];
-	if (monsterGroupNumber == 0x64)
-		monsterGroupNumber = 0;
-
-	if (monsterGroupNumber == -1)
-		return;
-	int16 var58;
-	if (_items[unk_monsterField5_itemId]._range == 4)
-		var58 = 5;
-	else
-		var58 = monsterGroupNumber + 1;
-
-	int16 var54;
-	int16 teamMemberId;
-	if (_items[unk_monsterField5_itemId]._range < 3) {
-		teamMemberId = sub1DEC8(monsterGroupNumber);
-		var54 = teamMemberId + 1;
-	} else {
-		teamMemberId = 0;
-		var54 = 9;
-	}
-
-	if (teamMemberId != -1) {
-		bool var6E = true;
-		for (int16 groupId = monsterGroupNumber; groupId < var58; ++groupId) {
-			if (_teamMonsterIdArray[groupId] == -1)
-				continue;
-
-			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
-				if (isMonsterActive(groupId, var7E) && var6E) {
-					int16 var5C;
-					if (unkFct_checkMonsterField8(groupId, true)) {
-						sub1E028(groupId, 9, true);
-						_unkArray2C8AA[0] += 500;
-						var5C = -1;
-					} else
-						var5C = 0;
-
-					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
-					int16 varInt = _teamCharId[teamCharId];
-					int16 var51 = _npcBuf[varInt]._possessivePronounSHL6;
-					var51 >>= 6;
-					int16 var70 = var51;
-					varInt = _teamMonsterIdArray[groupId];
-					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
-					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
-					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
-					int16 var62 = 0;
-					int16 hitPoints = 0;
-					int16 originalDamage = 0;
-					int16 damagePointsAbsorbed = 0;
-					int16 var64 = _items[unk_monsterField5_itemId]._attacks *_npcBuf[_teamCharId[teamCharId]]._speed;
-
-					// Action A - Loop var84 - Start
-					for (int var84 = 0; var84 < var64; ++var84) {
-						if (getRandom(100) < charScore) {
-							++var62;
-							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[unk_monsterField5_itemId]._attackType)) {
-								int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
-								varInt = var7C - var76;
-								if (varInt > 0) {
-									originalDamage += varInt;
-									damagePointsAbsorbed += var76;
-								} else {
-									damagePointsAbsorbed += var7C;
-								}
-							}
-						}
-					}
-					// Action A - Loop var84 - End
-
-					if (originalDamage < 0)
-						originalDamage = 0;
-
-					hitPoints = originalDamage + damagePointsAbsorbed;
-
-					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
-						var62 = 0;
-
-					if (var62 > 0) {
-						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
-						if (var62 > 1) {
-							snprintf(_attackBuffer, 20, "%d times ", var62);
-						} else {
-							*_attackBuffer = 0;
-						}
-					}
-					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
-					int16 var6A = getRandom(3) - 1;
-					if (var5E == 2) {
-						snprintf(_characterNamePt1, 5, "The ");
-					} else {
-						*_characterNamePt1 = 0;
-					}
-
-					if (var70 == 2) {
-						_enemyNamePt1 = "The ";
-					} else {
-						_enemyNamePt1 = "";
-					}
-
-					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
-					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-					_nameBuffer = _items[unk_monsterField5_itemId]._name;
-					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
-						// Action A - Check damages - Start
-						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
-						} else if (hitPoints <= 0){
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
-						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
-								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
-							} else {
-								strncat((char *)_messageToBePrinted, "!", 2);
-							}
-						} else {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
-								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
-							} else {
-								strncat((char *)_messageToBePrinted, "!", 2);
-							}
-						}
-						// Action A - Check damages - End
-
-						// Action A - Add reaction text - Start
-						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] - 5 <= originalDamage) {
-								addReactionText(0);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 8) {
-								addReactionText(1);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 4) {
-								addReactionText(2);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 2) {
-								addReactionText(3);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 3) {
-								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
-								addReactionText(4);
-							} else if (var80 / 8 >= originalDamage) {
-								addReactionText(5);
-							} else if (originalDamage == 0 && getRandom(100) < 35) {
-								addReactionText(6);
-							}
-						}
-						// Action A - Add reaction text - End
-
-						// Action A - Add armor absorb text - Start
-						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							char buffer[80];
-							memset(buffer, 0, 80);
-							if (damagePointsAbsorbed <= 1)
-								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
-							else
-								snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
-
-							strncat((char *)_messageToBePrinted, buffer, 80);
-						}
-						// Action A - Add armor absorb text - End
-
-						if (var5C)
-							strncat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...", 400);
-
-						// Action A - Check item durability - Start
-						varInt = _teamCharId[teamCharId];
-						var64 = sub1C80A(varInt, 9, false);
-						if (var64 != 0x7FFF && (_npcBuf[varInt]._inventory[var64]._stat1 & 0x7F) != 0x7F) {
-							var51 = _npcBuf[varInt]._inventory[var64]._stat1 & 0x7F;
-							--var51;
-							if (var51 <= 0) {
-								char buffer[80];
-								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
-								strncat((char *)_messageToBePrinted, buffer, 80);
-								setCharacterObjectToBroken(varInt, var64);
-								var6E = false;
-							} else {
-								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + var51;
-							}
-						}
-						// Action A - Check item durability - End
-
-						// Action A - Check effect - Start
-						if (_items[unk_monsterField5_itemId].field_16 == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							if (getRandom(100) < 35) {
-								_stru32686[var7E]._field0[groupId] = 1;
-								_stru32686[var7E]._field2[groupId] = getRandom(10);
-								char buffer[80];
-								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
-								strncat((char *)_messageToBePrinted, buffer, 80);
-							}
-						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							_stru32686[var7E]._field0[groupId] = 2;
-							_stru32686[var7E]._field2[groupId] = getRandom(10);
-							char buffer[80];
-							memset(buffer, 0, 80);
-							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
-							strncat((char *)_messageToBePrinted, buffer, 80);
-						}
-						// Action A - Check effect - End
-					} else {
-						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
-					}
-
-					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
-					sub1C219(_messageToBePrinted, 1, 2, true);
-				}
-			}
-		}
-	}
-}
-
-void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
-	debug("handleFight_lastAction_D %d", teamCharId);
-
-	_word32482[teamCharId] -= 40;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
-
-	if (var70 == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
-
-	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
-	sub1C219(_messageToBePrinted, 1, 2, true);
-}
-
-void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
-	debug("handleFight_lastAction_H %d", teamCharId);
-
-	// In the original, this function is part of handleFight.
-	// It has been split for readability purposes.
-
-	_word32680[teamCharId] -= 50;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
-
-	if (var70 == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
-
-	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
-	sub1C219(_messageToBePrinted, 1, 2, true);
-}
-
-void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
-	debug("handleFight_lastAction_U %d", teamCharId);
-
-	// In the original, this function is part of handleFight.
-	// It has been split for readability purposes.
-	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	_nameBuffer = _items[unk_monsterField5_itemId]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
-	if (var70 == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
-
-	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
-	sub1C219(_messageToBePrinted, 1, 2, true);
-}
-
 char EfhEngine::getFightMessageLastCharacter(char *message) {
 	debug("getFightMessageLastCharacter %s", message);
 
@@ -4778,315 +3991,6 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	}
 }
 
-bool EfhEngine::handleFight(int16 monsterId) {
-	debug("handleFight %d", monsterId);
-
-	int16 var8C = 0;
-	_ongoingFightFl = true;
-
-	sub1BE89(monsterId);
-
-	if (_teamMonsterIdArray[0] == -1) {
-		resetTeamMonsterIdArray();
-		_ongoingFightFl = false;
-		displayAnimFrames(0xFE, true);
-		return true;
-	}
-
-	drawCombatScreen(0, false, true);
-
-	for (bool mainLoopCond = false; !mainLoopCond;) {
-		if (isTPK()) {
-			resetTeamMonsterIdArray();
-			_ongoingFightFl = false;
-			displayAnimFrames(0xFE, true);
-			return false;
-		}
-
-		if (_teamMonsterIdArray[0] == -1) {
-			resetTeamMonsterIdArray();
-			_ongoingFightFl = false;
-			displayAnimFrames(0xFE, true);
-			return true;
-		}
-
-		int16 varInt = getTeamMonsterAnimId();
-		displayAnimFrames(varInt, true);
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			_word32680[counter] = 100;
-			_word32482[counter] = 65;
-		}
-
-		if (!sub1CB27()) {
-			resetTeamMonsterIdArray();
-			_ongoingFightFl = false;
-			totalPartyKill();
-			displayAnimFrames(0xFE, true);
-			return false;
-		}
-
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_teamLastAction[counter] == 0x52) // 'R'
-				mainLoopCond = true;
-		}
-
-		sub1CDFA();
-		sub1C219(nullptr, 2, 1, false);
-
-		for (uint counter = 0; counter < 8; ++counter) {
-			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
-			if (monsterGroupIdOrMonsterId == -1)
-				continue;
-			if (monsterGroupIdOrMonsterId > 999) { // Team Member
-				monsterGroupIdOrMonsterId -= 1000;
-				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
-					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
-				} else {
-					switch (_teamLastAction[monsterGroupIdOrMonsterId]) {
-					case 0x41:// 'A'ttack
-						handleFight_lastAction_A(monsterGroupIdOrMonsterId);
-						break;
-					case 0x44: // 'D'efend
-						handleFight_lastAction_D(monsterGroupIdOrMonsterId);
-						break;
-					case 0x48: // 'H'ide
-						handleFight_lastAction_H(monsterGroupIdOrMonsterId);
-						break;
-					case 0x55: // 'U'se
-						handleFight_lastAction_U(monsterGroupIdOrMonsterId);
-						break;
-					default:
-						break;
-					}
-				}
-			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
-				// handleFight - Loop on var86 - Start
-				for (uint var86 = 0; var86 < 9; ++var86) {
-					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
-						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
-						if (unk_monsterField5_itemId == 0xFF)
-							unk_monsterField5_itemId = 0x3F;
-						int16 teamMemberId = -1;
-						int16 var54;
-						if (_items[unk_monsterField5_itemId]._range < 3) {
-							for (uint var84 = 0; var84 < 10; ++var84) {
-								teamMemberId = getRandom(_teamSize) - 1;
-								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _word32680[teamMemberId]) {
-									break;
-								}
-								teamMemberId = -1;
-							}
-							var54 = teamMemberId + 1;
-						} else {
-							teamMemberId = 0;
-							var54 = _teamSize;
-						}
-						if (teamMemberId != -1) {
-							// handleFight - Loop on var7E - Start
-							for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
-								if (_teamCharId[var7E] == -1 || !isTeamMemberStatusNormal(var7E))
-									continue;
-
-								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
-								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
-								int16 var70 = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
-								int16 var5E = _npcBuf[_teamCharId[var7E]]._possessivePronounSHL6 >> 6;
-								varInt = _items[unk_monsterField5_itemId].field_13;
-								_word32482[var7E] += (varInt * 5);
-								int16 var62 = 0;
-								int16 hitPoints = 0;
-								int16 originalDamage = 0;
-								int16 damagePointsAbsorbed = 0;
-								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
-								for (int var84 = 0; var84 < var64; ++var84) {
-									// handleFight - Loop var84 on var64 (objectId) - Start
-									if (getRandom(100) > _word32482[var7E])
-										continue;
-
-									++var62;
-
-									if (hasAdequateDefense_2(_teamCharId[var7E], _items[unk_monsterField5_itemId]._attackType))
-										continue;
-
-									int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
-									varInt = var7C - var76;
-
-									if (varInt > 0) {
-										damagePointsAbsorbed += var76;
-										originalDamage += varInt;
-									} else {
-										damagePointsAbsorbed += var7C;
-									}
-									// handleFight - Loop var84 on var64 (objectId) - End
-								}
-
-								if (originalDamage < 0)
-									originalDamage = 0;
-
-								hitPoints = originalDamage + damagePointsAbsorbed;
-								if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
-									var62 = 0;
-
-								if (var62 > 0) {
-									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
-									if (var62 > 1)
-										snprintf(_attackBuffer, 20, "%d times ", var62);
-									else
-										*_attackBuffer = 0;
-								}
-
-								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
-								int16 var6A = getRandom(3);
-								if (var5E == 2)
-									snprintf(_characterNamePt1, 5, "The ");
-								else
-									*_characterNamePt1 = 0;
-
-								if (var7E == 2)
-									_enemyNamePt1 = "The ";
-								else
-									_enemyNamePt1 = "";
-
-								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
-								_nameBuffer = _items[unk_monsterField5_itemId]._name;
-								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
-									// handleFight - check damages - Start
-									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
-									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
-									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
-											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
-										else
-											strncat((char *)_messageToBePrinted, "!", 2);
-									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
-											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
-										else
-											strncat((char *)_messageToBePrinted, "!", 2);
-									}
-									// handleFight - check damages - End
-
-									// handleFight - Add reaction text - start
-									if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints - 5 <= originalDamage) {
-											addReactionText(0);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 8) {
-											addReactionText(1);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 4) {
-											addReactionText(2);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
-											addReactionText(3);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
-											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
-											addReactionText(4);
-										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
-											addReactionText(5);
-										} else if (originalDamage == 0 && getRandom(100) < 35) {
-											addReactionText(6);
-										}
-									}
-									// handleFight - Add reaction text - end
-
-									// handleFight - Check armor - start
-									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
-										char buffer[80];
-										memset(buffer, 0, 80);
-										if (damagePointsAbsorbed <= 1)
-											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
-										else
-											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
-
-										strncat((char *)_messageToBePrinted, buffer, 80);
-										varInt = (originalDamage + damagePointsAbsorbed) / 10;
-										sub1D8C2(_teamCharId[var7E], varInt);
-									}
-									// handleFight - Check armor - end
-
-									// handleFight - Check effect - start
-									char buffer[80];
-									memset(buffer, 0, 80);
-									switch (_items[unk_monsterField5_itemId].field_16) {
-									case 1:
-										if (getRandom(100) < 20) {
-											_teamCharStatus[var7E]._status = 1;
-											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
-										}
-										break;
-									case 2:
-										if (getRandom(100) < 20) {
-											_teamCharStatus[var7E]._status = 2;
-											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
-										}
-										break;
-									case 5:
-									case 6:
-										if (getRandom(100) < 20) {
-											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
-											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
-										}
-										break;
-									default:
-										break;
-									}
-									// handleFight - Check effect - end
-								} else {
-									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
-								}
-								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
-								sub1C219(_messageToBePrinted, 1, 2, true);
-							}
-							// handleFight - Loop on var7E - End
-						}
-					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
-						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
-						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
-							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
-							if (var70 == 2)
-								_enemyNamePt1 = "The ";
-							else
-								_enemyNamePt1 = "";
-
-							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
-							case 1:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							case 2:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							default:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							}
-							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
-							sub1C219(_messageToBePrinted, 1, 2, true);
-						}
-					}
-				}
-				// handleFight - Loop on var86 - End
-			}
-		}
-
-		sub174A0();
-		sub1BE9A(monsterId);
-	}
-
-	resetTeamMonsterIdArray();
-	_ongoingFightFl = false;
-	displayAnimFrames(0xFE, true);
-	return true;
-}
-
 void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
 	debug("displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b4cdb33a08f..8dca9fa5254 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -304,8 +304,6 @@ private:
 	void displaySmallMap(int16 posX, int16 posY);
 	void displayLargeMap(int16 posX, int16 posY);
 	void drawScreen();
-	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
-	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
 	void removeObject(int16 charId, int16 objectId);
 	void totalPartyKill();
 	void removeCharacterFromTeam(int16 teamMemberId);
@@ -316,7 +314,6 @@ private:
 	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
-	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 	void drawText(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
@@ -375,7 +372,6 @@ private:
 	void sub1C4CA(bool WhiteFl);
 	void displayCombatMenu(int16 charId);
 	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
-	void handleFight_checkEndEffect(int16 charId);
 	int16 sub1DEC8(int16 groupNumber);
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
@@ -392,13 +388,8 @@ private:
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	void addReactionText(int16 id);
-	void handleFight_lastAction_A(int16 teamCharId);
-	void handleFight_lastAction_D(int16 teamCharId);
-	void handleFight_lastAction_H(int16 teamCharId);
-	void handleFight_lastAction_U(int16 teamCharId);
 	char getFightMessageLastCharacter(char *message);
 	void sub1D8C2(int16 charId, int16 damage);
-	bool handleFight(int16 monsterId);
 	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
 	void displayStatusMenu(int16 windowId);
 	void countRightWindowItems(int16 menuId, int16 charId);
@@ -422,6 +413,14 @@ private:
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	bool checkMonsterCollision();
 
+	// Fight
+	bool handleFight(int16 monsterId);
+	void handleFight_checkEndEffect(int16 charId);
+	void handleFight_lastAction_A(int16 teamCharId);
+	void handleFight_lastAction_D(int16 teamCharId);
+	void handleFight_lastAction_H(int16 teamCharId);
+	void handleFight_lastAction_U(int16 teamCharId);
+
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
 	void readAnimInfo();
@@ -474,6 +473,11 @@ private:
 	// Savegames
 	void synchronize(Common::Serializer &s);
 
+	// Script
+	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
+	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
+	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
+
 	// Utils
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
new file mode 100644
index 00000000000..0c1a6a10210
--- /dev/null
+++ b/engines/efh/fight.cpp
@@ -0,0 +1,651 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "efh/efh.h"
+
+namespace Efh {
+
+bool EfhEngine::handleFight(int16 monsterId) {
+	debug("handleFight %d", monsterId);
+
+	int16 var8C = 0;
+	_ongoingFightFl = true;
+
+	sub1BE89(monsterId);
+
+	if (_teamMonsterIdArray[0] == -1) {
+		resetTeamMonsterIdArray();
+		_ongoingFightFl = false;
+		displayAnimFrames(0xFE, true);
+		return true;
+	}
+
+	drawCombatScreen(0, false, true);
+
+	for (bool mainLoopCond = false; !mainLoopCond;) {
+		if (isTPK()) {
+			resetTeamMonsterIdArray();
+			_ongoingFightFl = false;
+			displayAnimFrames(0xFE, true);
+			return false;
+		}
+
+		if (_teamMonsterIdArray[0] == -1) {
+			resetTeamMonsterIdArray();
+			_ongoingFightFl = false;
+			displayAnimFrames(0xFE, true);
+			return true;
+		}
+
+		int16 varInt = getTeamMonsterAnimId();
+		displayAnimFrames(varInt, true);
+		for (int counter = 0; counter < _teamSize; ++counter) {
+			_word32680[counter] = 100;
+			_word32482[counter] = 65;
+		}
+
+		if (!sub1CB27()) {
+			resetTeamMonsterIdArray();
+			_ongoingFightFl = false;
+			totalPartyKill();
+			displayAnimFrames(0xFE, true);
+			return false;
+		}
+
+		for (int counter = 0; counter < _teamSize; ++counter) {
+			if (_teamLastAction[counter] == 0x52) // 'R'
+				mainLoopCond = true;
+		}
+
+		sub1CDFA();
+		sub1C219(nullptr, 2, 1, false);
+
+		for (uint counter = 0; counter < 8; ++counter) {
+			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
+			if (monsterGroupIdOrMonsterId == -1)
+				continue;
+			if (monsterGroupIdOrMonsterId > 999) { // Team Member
+				monsterGroupIdOrMonsterId -= 1000;
+				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
+					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
+				} else {
+					switch (_teamLastAction[monsterGroupIdOrMonsterId]) {
+					case 0x41: // 'A'ttack
+						handleFight_lastAction_A(monsterGroupIdOrMonsterId);
+						break;
+					case 0x44: // 'D'efend
+						handleFight_lastAction_D(monsterGroupIdOrMonsterId);
+						break;
+					case 0x48: // 'H'ide
+						handleFight_lastAction_H(monsterGroupIdOrMonsterId);
+						break;
+					case 0x55: // 'U'se
+						handleFight_lastAction_U(monsterGroupIdOrMonsterId);
+						break;
+					default:
+						break;
+					}
+				}
+			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
+				// handleFight - Loop on var86 - Start
+				for (uint var86 = 0; var86 < 9; ++var86) {
+					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
+						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
+						if (unk_monsterField5_itemId == 0xFF)
+							unk_monsterField5_itemId = 0x3F;
+						int16 teamMemberId = -1;
+						int16 var54;
+						if (_items[unk_monsterField5_itemId]._range < 3) {
+							for (uint var84 = 0; var84 < 10; ++var84) {
+								teamMemberId = getRandom(_teamSize) - 1;
+								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _word32680[teamMemberId]) {
+									break;
+								}
+								teamMemberId = -1;
+							}
+							var54 = teamMemberId + 1;
+						} else {
+							teamMemberId = 0;
+							var54 = _teamSize;
+						}
+						if (teamMemberId != -1) {
+							// handleFight - Loop on var7E - Start
+							for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
+								if (_teamCharId[var7E] == -1 || !isTeamMemberStatusNormal(var7E))
+									continue;
+
+								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
+								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
+								int16 var70 = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
+								int16 var5E = _npcBuf[_teamCharId[var7E]]._possessivePronounSHL6 >> 6;
+								varInt = _items[unk_monsterField5_itemId].field_13;
+								_word32482[var7E] += (varInt * 5);
+								int16 var62 = 0;
+								int16 hitPoints = 0;
+								int16 originalDamage = 0;
+								int16 damagePointsAbsorbed = 0;
+								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
+								for (int var84 = 0; var84 < var64; ++var84) {
+									// handleFight - Loop var84 on var64 (objectId) - Start
+									if (getRandom(100) > _word32482[var7E])
+										continue;
+
+									++var62;
+
+									if (hasAdequateDefense_2(_teamCharId[var7E], _items[unk_monsterField5_itemId]._attackType))
+										continue;
+
+									int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+									varInt = var7C - var76;
+
+									if (varInt > 0) {
+										damagePointsAbsorbed += var76;
+										originalDamage += varInt;
+									} else {
+										damagePointsAbsorbed += var7C;
+									}
+									// handleFight - Loop var84 on var64 (objectId) - End
+								}
+
+								if (originalDamage < 0)
+									originalDamage = 0;
+
+								hitPoints = originalDamage + damagePointsAbsorbed;
+								if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+									var62 = 0;
+
+								if (var62 > 0) {
+									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
+									if (var62 > 1)
+										snprintf(_attackBuffer, 20, "%d times ", var62);
+									else
+										*_attackBuffer = 0;
+								}
+
+								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+								int16 var6A = getRandom(3);
+								if (var5E == 2)
+									snprintf(_characterNamePt1, 5, "The ");
+								else
+									*_characterNamePt1 = 0;
+
+								if (var7E == 2)
+									_enemyNamePt1 = "The ";
+								else
+									_enemyNamePt1 = "";
+
+								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
+								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
+								_nameBuffer = _items[unk_monsterField5_itemId]._name;
+								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+									// handleFight - check damages - Start
+									if (var62 == 0) {
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+									} else if (hitPoints <= 0) {
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+									} else if (hitPoints == 1) {
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
+											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
+										else
+											strncat((char *)_messageToBePrinted, "!", 2);
+									} else {
+										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
+											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
+										else
+											strncat((char *)_messageToBePrinted, "!", 2);
+									}
+									// handleFight - check damages - End
+
+									// handleFight - Add reaction text - start
+									if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
+										if (_npcBuf[_teamCharId[var7E]]._hitPoints - 5 <= originalDamage) {
+											addReactionText(0);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 8) {
+											addReactionText(1);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 4) {
+											addReactionText(2);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
+											addReactionText(3);
+										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
+											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+											addReactionText(4);
+										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
+											addReactionText(5);
+										} else if (originalDamage == 0 && getRandom(100) < 35) {
+											addReactionText(6);
+										}
+									}
+									// handleFight - Add reaction text - end
+
+									// handleFight - Check armor - start
+									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
+										char buffer[80];
+										memset(buffer, 0, 80);
+										if (damagePointsAbsorbed <= 1)
+											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+										else
+											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+
+										strncat((char *)_messageToBePrinted, buffer, 80);
+										varInt = (originalDamage + damagePointsAbsorbed) / 10;
+										sub1D8C2(_teamCharId[var7E], varInt);
+									}
+									// handleFight - Check armor - end
+
+									// handleFight - Check effect - start
+									char buffer[80];
+									memset(buffer, 0, 80);
+									switch (_items[unk_monsterField5_itemId].field_16) {
+									case 1:
+										if (getRandom(100) < 20) {
+											_teamCharStatus[var7E]._status = 1;
+											_teamCharStatus[var7E]._duration = getRandom(10);
+											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
+											strncat((char *)_messageToBePrinted, buffer, 80);
+										}
+										break;
+									case 2:
+										if (getRandom(100) < 20) {
+											_teamCharStatus[var7E]._status = 2;
+											_teamCharStatus[var7E]._duration = getRandom(10);
+											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
+											strncat((char *)_messageToBePrinted, buffer, 80);
+										}
+										break;
+									case 5:
+									case 6:
+										if (getRandom(100) < 20) {
+											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
+											strncat((char *)_messageToBePrinted, buffer, 80);
+											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
+										}
+										break;
+									default:
+										break;
+									}
+									// handleFight - Check effect - end
+								} else {
+									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+								}
+								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+								sub1C219(_messageToBePrinted, 1, 2, true);
+							}
+							// handleFight - Loop on var7E - End
+						}
+					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
+						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
+						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
+							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
+							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
+							if (var70 == 2)
+								_enemyNamePt1 = "The ";
+							else
+								_enemyNamePt1 = "";
+
+							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
+							case 1:
+								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								break;
+							case 2:
+								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								break;
+							default:
+								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								break;
+							}
+							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
+							sub1C219(_messageToBePrinted, 1, 2, true);
+						}
+					}
+				}
+				// handleFight - Loop on var86 - End
+			}
+		}
+
+		sub174A0();
+		sub1BE9A(monsterId);
+	}
+
+	resetTeamMonsterIdArray();
+	_ongoingFightFl = false;
+	displayAnimFrames(0xFE, true);
+	return true;
+}
+
+void EfhEngine::handleFight_checkEndEffect(int16 charId) {
+	debug("handleFight_checkEndEffect %d", charId);
+
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+	if (_teamCharStatus[charId]._status == 0)
+		return;
+	if (--_teamCharStatus[charId]._duration != 0)
+		return;
+
+	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
+	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
+	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
+		_enemyNamePt1 = "The ";
+	} else {
+		_enemyNamePt1 = "";
+	}
+
+	// End of effect message depends on the type of effect
+	switch (_teamCharStatus[charId]._status) {
+	case 1:
+		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		break;
+	case 2:
+		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		break;
+	default:
+		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		break;
+	}
+
+	// The character status is back to normal
+	_teamCharStatus[charId]._status = 0;
+
+	// Finally, display the message
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
+	debug("handleFight_lastAction_A %d", teamCharId);
+
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+
+	int16 unk_monsterField5_itemId = sub1C80A(_teamCharId[teamCharId], 9, true);
+	if (unk_monsterField5_itemId == 0x7FFF)
+		unk_monsterField5_itemId = 0x3F;
+	int16 monsterGroupNumber = _teamNextAttack[teamCharId];
+	if (monsterGroupNumber == 0x64)
+		monsterGroupNumber = 0;
+
+	if (monsterGroupNumber == -1)
+		return;
+	int16 var58;
+	if (_items[unk_monsterField5_itemId]._range == 4)
+		var58 = 5;
+	else
+		var58 = monsterGroupNumber + 1;
+
+	int16 var54;
+	int16 teamMemberId;
+	if (_items[unk_monsterField5_itemId]._range < 3) {
+		teamMemberId = sub1DEC8(monsterGroupNumber);
+		var54 = teamMemberId + 1;
+	} else {
+		teamMemberId = 0;
+		var54 = 9;
+	}
+
+	if (teamMemberId != -1) {
+		bool var6E = true;
+		for (int16 groupId = monsterGroupNumber; groupId < var58; ++groupId) {
+			if (_teamMonsterIdArray[groupId] == -1)
+				continue;
+
+			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
+				if (isMonsterActive(groupId, var7E) && var6E) {
+					int16 var5C;
+					if (unkFct_checkMonsterField8(groupId, true)) {
+						sub1E028(groupId, 9, true);
+						_unkArray2C8AA[0] += 500;
+						var5C = -1;
+					} else
+						var5C = 0;
+
+					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
+					int16 varInt = _teamCharId[teamCharId];
+					int16 var51 = _npcBuf[varInt]._possessivePronounSHL6;
+					var51 >>= 6;
+					int16 var70 = var51;
+					varInt = _teamMonsterIdArray[groupId];
+					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
+					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
+					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
+					int16 var62 = 0;
+					int16 hitPoints = 0;
+					int16 originalDamage = 0;
+					int16 damagePointsAbsorbed = 0;
+					int16 var64 = _items[unk_monsterField5_itemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
+
+					// Action A - Loop var84 - Start
+					for (int var84 = 0; var84 < var64; ++var84) {
+						if (getRandom(100) < charScore) {
+							++var62;
+							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[unk_monsterField5_itemId]._attackType)) {
+								int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+								varInt = var7C - var76;
+								if (varInt > 0) {
+									originalDamage += varInt;
+									damagePointsAbsorbed += var76;
+								} else {
+									damagePointsAbsorbed += var7C;
+								}
+							}
+						}
+					}
+					// Action A - Loop var84 - End
+
+					if (originalDamage < 0)
+						originalDamage = 0;
+
+					hitPoints = originalDamage + damagePointsAbsorbed;
+
+					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+						var62 = 0;
+
+					if (var62 > 0) {
+						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
+						if (var62 > 1) {
+							snprintf(_attackBuffer, 20, "%d times ", var62);
+						} else {
+							*_attackBuffer = 0;
+						}
+					}
+					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+					int16 var6A = getRandom(3) - 1;
+					if (var5E == 2) {
+						snprintf(_characterNamePt1, 5, "The ");
+					} else {
+						*_characterNamePt1 = 0;
+					}
+
+					if (var70 == 2) {
+						_enemyNamePt1 = "The ";
+					} else {
+						_enemyNamePt1 = "";
+					}
+
+					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
+					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+					_nameBuffer = _items[unk_monsterField5_itemId]._name;
+					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+						// Action A - Check damages - Start
+						if (var62 == 0) {
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+						} else if (hitPoints <= 0) {
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+						} else if (hitPoints == 1) {
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+								getDeathTypeDescription(groupId, teamCharId + 1000);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+							} else {
+								strncat((char *)_messageToBePrinted, "!", 2);
+							}
+						} else {
+							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+								getDeathTypeDescription(groupId, teamCharId + 1000);
+								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+							} else {
+								strncat((char *)_messageToBePrinted, "!", 2);
+							}
+						}
+						// Action A - Check damages - End
+
+						// Action A - Add reaction text - Start
+						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] - 5 <= originalDamage) {
+								addReactionText(0);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 8) {
+								addReactionText(1);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 4) {
+								addReactionText(2);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 2) {
+								addReactionText(3);
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 3) {
+								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+								addReactionText(4);
+							} else if (var80 / 8 >= originalDamage) {
+								addReactionText(5);
+							} else if (originalDamage == 0 && getRandom(100) < 35) {
+								addReactionText(6);
+							}
+						}
+						// Action A - Add reaction text - End
+
+						// Action A - Add armor absorb text - Start
+						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							char buffer[80];
+							memset(buffer, 0, 80);
+							if (damagePointsAbsorbed <= 1)
+								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+							else
+								snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+
+							strncat((char *)_messageToBePrinted, buffer, 80);
+						}
+						// Action A - Add armor absorb text - End
+
+						if (var5C)
+							strncat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...", 400);
+
+						// Action A - Check item durability - Start
+						varInt = _teamCharId[teamCharId];
+						var64 = sub1C80A(varInt, 9, false);
+						if (var64 != 0x7FFF && (_npcBuf[varInt]._inventory[var64]._stat1 & 0x7F) != 0x7F) {
+							var51 = _npcBuf[varInt]._inventory[var64]._stat1 & 0x7F;
+							--var51;
+							if (var51 <= 0) {
+								char buffer[80];
+								memset(buffer, 0, 80);
+								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
+								strncat((char *)_messageToBePrinted, buffer, 80);
+								setCharacterObjectToBroken(varInt, var64);
+								var6E = false;
+							} else {
+								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + var51;
+							}
+						}
+						// Action A - Check item durability - End
+
+						// Action A - Check effect - Start
+						if (_items[unk_monsterField5_itemId].field_16 == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							if (getRandom(100) < 35) {
+								_stru32686[var7E]._field0[groupId] = 1;
+								_stru32686[var7E]._field2[groupId] = getRandom(10);
+								char buffer[80];
+								memset(buffer, 0, 80);
+								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
+								strncat((char *)_messageToBePrinted, buffer, 80);
+							}
+						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							_stru32686[var7E]._field0[groupId] = 2;
+							_stru32686[var7E]._field2[groupId] = getRandom(10);
+							char buffer[80];
+							memset(buffer, 0, 80);
+							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
+							strncat((char *)_messageToBePrinted, buffer, 80);
+						}
+						// Action A - Check effect - End
+					} else {
+						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+					}
+
+					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+					sub1C219(_messageToBePrinted, 1, 2, true);
+				}
+			}
+		}
+	}
+}
+
+void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
+	debug("handleFight_lastAction_D %d", teamCharId);
+
+	_word32482[teamCharId] -= 40;
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+
+	if (var70 == 2)
+		_enemyNamePt1 = "The ";
+	else
+		_enemyNamePt1 = "";
+
+	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
+	debug("handleFight_lastAction_H %d", teamCharId);
+
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+
+	_word32680[teamCharId] -= 50;
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+
+	if (var70 == 2)
+		_enemyNamePt1 = "The ";
+	else
+		_enemyNamePt1 = "";
+
+	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
+	debug("handleFight_lastAction_U %d", teamCharId);
+
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	_nameBuffer = _items[unk_monsterField5_itemId]._name;
+	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+	if (var70 == 2)
+		_enemyNamePt1 = "The ";
+	else
+		_enemyNamePt1 = "";
+
+	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+	sub1C219(_messageToBePrinted, 1, 2, true);
+}
+
+} // End of namespace Efh
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index aee8803c525..c5e7ac247dd 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -3,9 +3,11 @@ MODULE := engines/efh
 MODULE_OBJS = \
 	constants.o \
 	efh.o \
+	fight.o \
 	files.o \
 	graphics.o \
 	savegames.o \
+	script.o \
 	utils.o \
 	metaengine.o
 
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
new file mode 100644
index 00000000000..8712f7725d9
--- /dev/null
+++ b/engines/efh/script.cpp
@@ -0,0 +1,500 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/system.h"
+#include "efh/efh.h"
+
+namespace Efh {
+
+uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
+	debug("script_readNumberArray");
+
+	uint8 *buffer = srcBuffer;
+	for (int i = 0; i < destArraySize; ++i) {
+		buffer++;
+		buffer = script_getNumber(buffer, &destArray[i]);
+	}
+
+	return buffer;
+}
+
+uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
+	debug("script_getNumber");
+
+	uint8 *buffer = srcBuffer;
+	int16 var2 = 0;
+	for (;;) {
+		uint8 curChar = *buffer;
+		if (curChar < 0x30 || curChar > 0x39) {
+			*retval = var2;
+			return buffer;
+		}
+		var2 = var2 * 10 + curChar - 0x30;
+		buffer++;
+	}
+}
+
+int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
+	debug("script_parse %s %d-%d %d-%d %s", (char *)stringBuffer, posX, posY, maxX, maxY, flag ? "True" : "False");
+
+	bool doneFlag = false;
+	int16 var_F2 = -1;
+	int16 var_F0 = 0xFF;
+	int16 var_EE = 0xFF;
+	uint16 curLineNb = 0;
+	int16 numbLines = (1 + maxY - posY) / 9;
+	int16 width = maxX - posX;
+	int16 spaceWidth = getStringWidth(" ");
+	uint8 *buffer = stringBuffer;
+	char nextWord[80];
+	char curLine[150];
+	memset(nextWord, 0, sizeof(nextWord));
+	memset(curLine, 0, sizeof(curLine));
+	int16 curWordPos = 0;
+	setTextPos(posX, curLineNb * 9 + posY);
+
+	while (!doneFlag) {
+		uint8 curChar = *buffer;
+		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
+			var_F2 = 0;
+			nextWord[curWordPos++] = curChar;
+			++buffer;
+			continue;
+		}
+
+		if (curChar != 0x5E) {
+			if (curChar == 0)
+				doneFlag = true;
+			else if (curChar == 0x7C)
+				var_F2 = 0;
+
+			nextWord[curWordPos] = 0;
+			int16 widthNextWord = getStringWidth(nextWord);
+			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine);
+
+			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) {
+				if (curLineNb >= numbLines) {
+					doneFlag = true;
+				} else {
+					if (var_F2 == 0)
+						displayStringAtTextPos(curLine);
+
+					*curLine = 0;
+					strncpy(curLine, nextWord, 80);
+					strncat(curLine, " ", 2);
+					++curLineNb;
+					setTextPos(posX, posY + curLineNb * 9);
+					curWordPos = 0;
+				}
+			} else {
+				strncat(curLine, nextWord, 80);
+				strncat(curLine, " ", 2);
+				curWordPos = 0;
+			}
+			++buffer;
+			continue;
+		}
+
+		// At this point, curChar == 0x5E
+		++buffer;
+		int16 opCode = 0;
+		buffer = script_getNumber(buffer, &opCode);
+		int16 scriptNumberArray[10];
+		memset(scriptNumberArray, 0, sizeof(scriptNumberArray));
+
+		switch (opCode) {
+		case 0x00:
+			// Enter room { full Place Id, posX, posY }
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				if (_largeMapFlag) {
+					_largeMapFlag = false;
+					_techDataId_MapPosX = _mapPosX;
+					_techDataId_MapPosY = _mapPosY;
+				}
+				_oldMapPosX = _mapPosX = scriptNumberArray[1];
+				_oldMapPosY = _mapPosY = scriptNumberArray[2];
+				loadPlacesFile(scriptNumberArray[0], false);
+				_word2C880 = true;
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x01:
+			// Exit room { }
+			if (flag) {
+				_largeMapFlag = true;
+				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
+				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
+				_word2C880 = true;
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x02:
+			// Change map. { map number, posX, posY }
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				if (_word2C8D7)
+					writeTechAndMapFiles();
+				_oldMapPosX = _mapPosX = scriptNumberArray[1];
+				_oldMapPosY = _mapPosY = scriptNumberArray[2];
+				loadTechMapImp(scriptNumberArray[0]);
+				_largeMapFlag = true;
+				_word2C880 = true;
+				_redrawNeededFl = true;
+				doneFlag = true;
+			}
+			break;
+		case 0x03:
+			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[2] - scriptNumberArray[0];
+				int16 var10E = scriptNumberArray[3] - scriptNumberArray[1];
+
+				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
+				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
+				_word2C880 = true;
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x04:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				_mapPosX = scriptNumberArray[0];
+				_mapPosY = scriptNumberArray[1];
+				_word2C880 = true;
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x05:
+			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
+			if (flag) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = scriptNumberArray[1];
+					_npcBuf[var110]._activeScore[var10E] += scriptNumberArray[2] & 0xFF;
+					_npcBuf[var110]._activeScore[var10E] -= scriptNumberArray[3] & 0xFF;
+				}
+			}
+			break;
+		case 0x06:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = scriptNumberArray[1];
+					_npcBuf[var110]._activeScore[var10E] = scriptNumberArray[1];
+				}
+			}
+			break;
+		case 0x07:
+			if (flag) {
+				totalPartyKill();
+				// emptyFunction(2);
+			}
+			break;
+		case 0x08:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag && scriptNumberArray[0] != -1) {
+				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
+			}
+			break;
+		case 0x09:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = getRandom(scriptNumberArray[1]);
+					_npcBuf[var110]._hitPoints += var10E;
+					if (_npcBuf[var110]._hitPoints > _npcBuf[var110]._maxHP)
+						_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				}
+			}
+			break;
+		case 0x0A:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				}
+			}
+			break;
+		case 0x0B:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = _teamCharId[scriptNumberArray[0]];
+				if (var110 != -1) {
+					int16 var10E = getRandom(scriptNumberArray[1]);
+					_npcBuf[var110]._hitPoints -= var10E;
+					if (_npcBuf[var110]._hitPoints < 0)
+						_npcBuf[var110]._hitPoints = 0;
+				}
+			}
+			break;
+		case 0x0C:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				bool found = false;
+				for (int counter = 0; counter < _teamSize && !found; ++counter) {
+					for (uint objectId = 0; objectId < 10; ++objectId) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+							removeObject(_teamCharId[counter], objectId);
+							found = true;
+							break;
+						}
+					}
+				}
+			}
+			break;
+		case 0x0D:
+			// Put item in inventory { objectId }
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				for (int counter = 0; counter < _teamSize; ++counter) {
+					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
+						break;
+				}
+			}
+			break;
+		case 0x0E:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				bool found = false;
+				for (int counter = 0; counter < _teamSize && !found; ++counter) {
+					for (uint objectId = 0; objectId < 10; ++objectId) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+							found = true;
+							break;
+						}
+					}
+				}
+
+				if (found)
+					var_F0 = scriptNumberArray[1];
+				else
+					var_F0 = scriptNumberArray[2];
+			}
+			break;
+		case 0x0F:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				if (isCharacterATeamMember(var110))
+					var_F0 = scriptNumberArray[1];
+				else
+					var_F0 = scriptNumberArray[2];
+			}
+			break;
+		case 0x10:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag)
+				var_F0 = scriptNumberArray[0];
+
+			break;
+		case 0x11:
+			if (flag)
+				_unkArray2C8AA[0] = 0;
+			break;
+		case 0x12:
+			// Guess : disable special tile { }
+			if (flag) {
+				int16 var110 = sub151FD(_mapPosX, _mapPosY);
+				if (var110 != -1)
+					_mapUnknown[var110]._posX = 0xFF;
+			}
+			break;
+		case 0x13:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag && _largeMapFlag) {
+				_word2C87A = true;
+				loadPlacesFile(scriptNumberArray[0], false);
+				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
+				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
+				var_F0 = -1;
+			}
+			break;
+		case 0x14:
+			// Add character to team { charId }
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				if (!isCharacterATeamMember(var110))
+					var_EE = var110;
+				var_F0 = -1;
+			}
+			break;
+		case 0x15:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				_oldMapPosX = _mapPosX = scriptNumberArray[0];
+				_oldMapPosY = _mapPosY = scriptNumberArray[1];
+				_largeMapFlag = true;
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x16:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
+				if (isCharacterATeamMember(var110)) {
+					for (uint counter = 0; counter < 3; ++counter) {
+						if (_teamCharId[counter] == var110) {
+							removeCharacterFromTeam(counter);
+							break;
+						}
+					}
+				}
+			}
+			break;
+		case 0x17:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[0];
+				displayAnimFrames(var110, true);
+			}
+			break;
+		case 0x18:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = scriptNumberArray[1] - scriptNumberArray[0] + 1;
+				bool found = false;
+				var110 = getRandom(var110) + scriptNumberArray[0] - 1;
+				int16 counter;
+				for (counter = 0; counter < _teamSize; ++counter) {
+					if (giveItemTo(_teamCharId[counter], var110, 0xFF)) {
+						found = true;
+						break;
+					}
+				}
+
+				if (!found) {
+					drawMapWindow();
+					displayFctFullScreen();
+					drawMapWindow();
+					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
+					displayFctFullScreen();
+				} else {
+					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
+					_nameBuffer = _items[var110]._name;
+					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
+					drawMapWindow();
+					displayFctFullScreen();
+					drawMapWindow();
+					var110 = sub1C219((uint8 *)curLine, 1, 2, true);
+					displayFctFullScreen();
+				}
+
+				var110 = sub151FD(_mapPosX, _mapPosY);
+				if (var110 != -1) {
+					_mapUnknown[var110]._posX = 0xFF;
+				}
+				_redrawNeededFl = true;
+			}
+			break;
+		case 0x19:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				if (_largeMapFlag) {
+					_mapGameMap[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+				} else {
+					_curPlace[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+				}
+			}
+			break;
+		case 0x1A:
+			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
+			if (flag) {
+				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (var110 != -1) {
+					_mapUnknown[var110]._posX = 0xFF;
+				}
+			}
+			break;
+		case 0x1B:
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (var110 != -1) {
+					_mapUnknown[var110]._posX = 0xFF;
+				}
+				_mapUnknown[scriptNumberArray[2]]._posX = scriptNumberArray[0];
+				_mapUnknown[scriptNumberArray[2]]._posY = scriptNumberArray[1];
+			}
+			break;
+		case 0x1C:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				_history[scriptNumberArray[0]] = 0xFF;
+			}
+			break;
+		case 0x1D:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag) {
+				_history[scriptNumberArray[0]] = 0;
+			}
+			break;
+		case 0x1E:
+			// Dialog with condition { historyId, dialogId1, dialogId2 }
+			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
+			if (flag) {
+				if (_history[scriptNumberArray[0]] == 0)
+					var_F0 = scriptNumberArray[2];
+				else
+					var_F0 = scriptNumberArray[1];
+			}
+			break;
+		case 0x1F:
+			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
+			if (flag)
+				_unkArray2C8AA[0] = scriptNumberArray[0];
+
+			break;
+		case 0x20:
+			if (flag) {
+				handleWinSequence();
+				_system->quit();
+			}
+		default:
+			break;
+		}
+	}
+
+	if (*curLine != 0 && curLineNb < numbLines && var_F2 == 0)
+		displayStringAtTextPos(curLine);
+
+	if (var_EE != 0xFF) {
+		displayLowStatusScreen(true);
+		int16 teamSlot = handleCharacterJoining();
+		if (teamSlot > -1) {
+			_teamCharId[teamSlot] = var_EE;
+		}
+		refreshTeamSize();
+	}
+
+	return var_F0;
+}
+
+} // End of namespace Efh
+


Commit: 452eedce4e7764edfa85d1f9553b0dd984539dd6
    https://github.com/scummvm/scummvm/commit/452eedce4e7764edfa85d1f9553b0dd984539dd6
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: move some more functions out of efh.cpp, some renaming

Changed paths:
  A engines/efh/sound.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/module.mk


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 46a5c9da2d9..bf57fa12436 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -263,7 +263,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_teamCharStatus[i]._status = 0;
 		_teamCharStatus[i]._duration = 0;
 		_unkArray2C8AA[i] = 0;
-		_word32680[i] = 0;
+		_teamPctVisible[i] = 0;
 		_word32482[i] = 0;
 		_teamNextAttack[i] = -1;
 		_word31780[i] = 0;
@@ -2666,88 +2666,6 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return _tileFact[imageSetId]._field0;
 }
 
-bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
-	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
-
-	for (int counter = 0; counter < teamMonsterId; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId)
-			return true;
-	}
-	return false;
-}
-
-void EfhEngine::sub1BCA7(int16 monsterTeamId) {
-	debug("sub1BCA7 %d", monsterTeamId);
-
-	int16 counter = 0;
-	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
-		counter = 1;
-		_teamMonsterIdArray[0] = monsterTeamId;
-	}
-
-	for (int counter2 = 1; counter2 <= 3; ++counter2) {
-		if (counter >= 5)
-			break;
-
-		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
-				continue;
-
-			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
-				continue;
-
-			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
-				continue;
-
-			bool var6 = false;
-			for (uint counter3 = 0; counter3 < 9; ++counter3) {
-				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
-					var6 = true;
-					break;
-				}
-			}
-
-			if (var6) {
-				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
-					_teamMonsterIdArray[counter] = monsterId;
-					if (++counter >= 5)
-						break;
-				}
-			}
-		}
-	}
-
-	if (counter > 4)
-		return;
-
-	for (uint id = counter; id < 5; ++id)
-		_teamMonsterIdArray[id] = -1;
-}
-
-void EfhEngine::reset_stru32686() {
-	debug("reset_stru32686");
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_stru32686[counter1]._field0[counter2] = 0;
-			_stru32686[counter1]._field2[counter2] = 0;
-		}
-	}
-}
-
-void EfhEngine::sub1BE89(int16 monsterId) {
-	debug("sub1BE89 %d", monsterId);
-	sub1BCA7(monsterId);
-	reset_stru32686();
-}
-
-void EfhEngine::resetTeamMonsterIdArray() {
-	debug("resetTeamMonsterIdArray");
-
-	for (int i = 0; i < 5; ++i) {
-		_teamMonsterIdArray[i] = -1;
-	}
-}
-
 bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 	debug("isTeamMemberStatusNormal %d", teamMemberId);
 
@@ -3385,103 +3303,6 @@ bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 	}
 }
 
-void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
-	warning("STUB: generateSound1 %d %d %d", arg0, arg2, duration);
-}
-
-void EfhEngine::generateSound2(int startFreq, int endFreq, int arg4) {
-	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, arg4);
-
-	// Arg4 doesn't seem to be used.
-}
-
-void EfhEngine::generateSound3() {
-	warning("STUB: generateSound3");
-}
-
-void EfhEngine::generateSound4(int arg0) {
-	warning("STUB: generateSound4 %d", arg0);
-}
-
-void EfhEngine::generateSound5(int arg0) {
-	warning("STUB: generateSound5 %d", arg0);
-}
-
-void EfhEngine::generateSound(int16 soundType) {
-	switch (soundType) {
-	case 5:
-		generateSound3();
-		break;
-	case 9:
-		generateSound1(20, 888, 3000);
-		generateSound1(20, 888, 3000);
-		break;
-	case 10:
-		generateSound5(1);
-		break;
-	case 13:
-		generateSound2(256, 4096, 18);
-		break;
-	case 14:
-		generateSound2(20, 400, 100);
-		break;
-	case 15:
-		generateSound2(100, 888, 88);
-		break;
-	case 16:
-		generateSound1(2000, 6096, 1500);
-		break;
-	case 17:
-		generateSound4(1);
-		break;
-	default:
-		// Not implemented because not used by the engine
-		break;
-	}
-}
-
-void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
-	if (repeatCount <= 0)
-		return;
-
-	switch (soundType) {
-	case 0:
-	case 1:
-	case 2:
-		generateSound(5);
-		break;
-	case 3:
-	case 4:
-	case 6:
-		generateSound(9);
-		break;
-	case 5:
-	case 7:
-		generateSound(13);
-		break;
-	case 8:
-	case 9:
-	case 10:
-		generateSound(10);
-		generateSound(9);
-		break;
-	case 14:
-		generateSound(14);
-		break;
-	case 11:
-	case 12:
-	case 13:
-		for (int counter = 0; counter < repeatCount; ++counter) {
-			generateSound(17);
-		}
-		break;
-	case 15:
-		generateSound(16);
-	default:
-		break;
-	}
-}
-
 bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	debug("hasAdequateDefense %d %d", monsterId, attackType);
 
@@ -4636,9 +4457,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
 			}
 
-			_word32680[teamCharId] -= 50;
-			if (_word32680[teamCharId] < 0)
-				_word32680[teamCharId] = 0;
+			_teamPctVisible[teamCharId] -= 50;
+			if (_teamPctVisible[teamCharId] < 0)
+				_teamPctVisible[teamCharId] = 0;
 		}
 
 		varA6 = true;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8dca9fa5254..cff5abd1597 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -354,11 +354,6 @@ private:
 	void sub22AA8(int16 arg0);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
-	bool sub1BC74(int16 monsterId, int16 teamMonsterId);
-	void sub1BCA7(int16 monsterTeamId);
-	void reset_stru32686();
-	void sub1BE89(int16 monsterId);
-	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
 	void sub1CDFA();
 	void redrawScreenForced();
@@ -375,13 +370,6 @@ private:
 	int16 sub1DEC8(int16 groupNumber);
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
-	void generateSound1(int arg0, int arg2, int duration);
-	void generateSound2(int startFreq, int endFreq, int arg4);
-	void generateSound3();
-	void generateSound4(int arg0);
-	void generateSound5(int arg0);
-	void generateSound(int16 soundType);
-	void genericGenerateSound(int16 soundType, int16 repeatCount);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
@@ -420,6 +408,11 @@ private:
 	void handleFight_lastAction_D(int16 teamCharId);
 	void handleFight_lastAction_H(int16 teamCharId);
 	void handleFight_lastAction_U(int16 teamCharId);
+	bool sub1BC74(int16 monsterId, int16 teamMonsterId);
+	void sub1BCA7(int16 monsterTeamId);
+	void reset_stru32686();
+	void sub1BE89(int16 monsterId);
+	void resetTeamMonsterIdArray();
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
@@ -478,6 +471,15 @@ private:
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
 	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 
+	// Sound
+	void generateSound1(int arg0, int arg2, int duration);
+	void generateSound2(int startFreq, int endFreq, int arg4);
+	void generateSound3();
+	void generateSound4(int arg0);
+	void generateSound5(int arg0);
+	void generateSound(int16 soundType);
+	void genericGenerateSound(int16 soundType, int16 repeatCount);
+
 	// Utils
 	void setDefaultNoteDuration();
 	void decryptImpFile(bool techMapFl);
@@ -593,7 +595,7 @@ private:
 	bool _statusMenuActive;
 	int16 _menuDepth;
 	int16 _menuItemCounter;
-	int16 _word32680[3];
+	int16 _teamPctVisible[3];
 	int16 _word32482[3];
 	int16 _teamNextAttack[3];
 	int16 _word31780[3];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 0c1a6a10210..9a69241cc0a 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -58,7 +58,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		int16 varInt = getTeamMonsterAnimId();
 		displayAnimFrames(varInt, true);
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			_word32680[counter] = 100;
+			_teamPctVisible[counter] = 100;
 			_word32482[counter] = 65;
 		}
 
@@ -116,7 +116,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 						if (_items[unk_monsterField5_itemId]._range < 3) {
 							for (uint var84 = 0; var84 < 10; ++var84) {
 								teamMemberId = getRandom(_teamSize) - 1;
-								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _word32680[teamMemberId]) {
+								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _teamPctVisible[teamMemberId]) {
 									break;
 								}
 								teamMemberId = -1;
@@ -617,7 +617,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 
-	_word32680[teamCharId] -= 50;
+	_teamPctVisible[teamCharId] -= 50;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
@@ -648,4 +648,86 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
+bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
+	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
+
+	for (int counter = 0; counter < teamMonsterId; ++counter) {
+		if (_teamMonsterIdArray[counter] == monsterId)
+			return true;
+	}
+	return false;
+}
+
+void EfhEngine::sub1BCA7(int16 monsterTeamId) {
+	debug("sub1BCA7 %d", monsterTeamId);
+
+	int16 counter = 0;
+	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
+		counter = 1;
+		_teamMonsterIdArray[0] = monsterTeamId;
+	}
+
+	for (int counter2 = 1; counter2 <= 3; ++counter2) {
+		if (counter >= 5)
+			break;
+
+		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
+			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+				continue;
+
+			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+				continue;
+
+			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
+				continue;
+
+			bool var6 = false;
+			for (uint counter3 = 0; counter3 < 9; ++counter3) {
+				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
+					var6 = true;
+					break;
+				}
+			}
+
+			if (var6) {
+				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
+					_teamMonsterIdArray[counter] = monsterId;
+					if (++counter >= 5)
+						break;
+				}
+			}
+		}
+	}
+
+	if (counter > 4)
+		return;
+
+	for (uint id = counter; id < 5; ++id)
+		_teamMonsterIdArray[id] = -1;
+}
+
+void EfhEngine::reset_stru32686() {
+	debug("reset_stru32686");
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
+			_stru32686[counter1]._field0[counter2] = 0;
+			_stru32686[counter1]._field2[counter2] = 0;
+		}
+	}
+}
+
+void EfhEngine::sub1BE89(int16 monsterId) {
+	debug("sub1BE89 %d", monsterId);
+	sub1BCA7(monsterId);
+	reset_stru32686();
+}
+
+void EfhEngine::resetTeamMonsterIdArray() {
+	debug("resetTeamMonsterIdArray");
+
+	for (int i = 0; i < 5; ++i) {
+		_teamMonsterIdArray[i] = -1;
+	}
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index c5e7ac247dd..9cfeeb35953 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS = \
 	graphics.o \
 	savegames.o \
 	script.o \
+	sound.o \
 	utils.o \
 	metaengine.o
 
diff --git a/engines/efh/sound.cpp b/engines/efh/sound.cpp
new file mode 100644
index 00000000000..8da1fa70078
--- /dev/null
+++ b/engines/efh/sound.cpp
@@ -0,0 +1,124 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "efh/efh.h"
+
+namespace Efh {
+
+void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
+	warning("STUB: generateSound1 %d %d %d", arg0, arg2, duration);
+}
+
+void EfhEngine::generateSound2(int startFreq, int endFreq, int arg4) {
+	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, arg4);
+
+	// Arg4 doesn't seem to be used.
+}
+
+void EfhEngine::generateSound3() {
+	warning("STUB: generateSound3");
+}
+
+void EfhEngine::generateSound4(int arg0) {
+	warning("STUB: generateSound4 %d", arg0);
+}
+
+void EfhEngine::generateSound5(int arg0) {
+	warning("STUB: generateSound5 %d", arg0);
+}
+
+void EfhEngine::generateSound(int16 soundType) {
+	switch (soundType) {
+	case 5:
+		generateSound3();
+		break;
+	case 9:
+		generateSound1(20, 888, 3000);
+		generateSound1(20, 888, 3000);
+		break;
+	case 10:
+		generateSound5(1);
+		break;
+	case 13:
+		generateSound2(256, 4096, 18);
+		break;
+	case 14:
+		generateSound2(20, 400, 100);
+		break;
+	case 15:
+		generateSound2(100, 888, 88);
+		break;
+	case 16:
+		generateSound1(2000, 6096, 1500);
+		break;
+	case 17:
+		generateSound4(1);
+		break;
+	default:
+		// Not implemented because not used by the engine
+		break;
+	}
+}
+
+void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
+	if (repeatCount <= 0)
+		return;
+
+	switch (soundType) {
+	case 0:
+	case 1:
+	case 2:
+		generateSound(5);
+		break;
+	case 3:
+	case 4:
+	case 6:
+		generateSound(9);
+		break;
+	case 5:
+	case 7:
+		generateSound(13);
+		break;
+	case 8:
+	case 9:
+	case 10:
+		generateSound(10);
+		generateSound(9);
+		break;
+	case 14:
+		generateSound(14);
+		break;
+	case 11:
+	case 12:
+	case 13:
+		for (int counter = 0; counter < repeatCount; ++counter) {
+			generateSound(17);
+		}
+		break;
+	case 15:
+		generateSound(16);
+	default:
+		break;
+	}
+}
+
+} // End of namespace Efh
+


Commit: 88299f79675357da92a54f3d86d3a76ec1dc5e20
    https://github.com/scummvm/scummvm/commit/88299f79675357da92a54f3d86d3a76ec1dc5e20
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: turn _messageToBePrinted into a Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index bf57fa12436..df5a37aa46a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -308,7 +308,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_word3273A[i] = 0;
 	}
 
-	memset(_messageToBePrinted, 0, 400);
+	_messageToBePrinted = "";
 	for (int i = 0; i < 8; ++i)
 		_stru3244C[i].init();
 
@@ -1330,7 +1330,7 @@ void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 
 	uint16 stringIdx = 0;
 	uint8 *impPtr = srcPtr;
-	memset(_messageToBePrinted, 0, 200);
+	_messageToBePrinted = "";
 
 	for (;;) {
 		uint8 curChar = *impPtr;
@@ -1339,12 +1339,14 @@ void EfhEngine::drawText(uint8 *srcPtr, int16 posX, int16 posY, int16 maxX, int1
 			break;
 
 		if (curChar == 0x0D) {
-			_messageToBePrinted[stringIdx++] = ' ';
+			_messageToBePrinted += " ";
+			stringIdx++;
 			++impPtr;
 		} else if (curChar == 0x0A) {
 			++impPtr;
 		} else {
-			_messageToBePrinted[stringIdx++] = curChar;
+			_messageToBePrinted += curChar;
+			stringIdx++;
 			++impPtr;
 		}
 	}
@@ -1427,8 +1429,8 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl) {
-	debug("sub1C219 %s %d %d %s", (char *)str, menuType, arg4, displayTeamWindowFl ? "True" : "False");
+int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 arg4, bool displayTeamWindowFl) {
+	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, arg4, displayTeamWindowFl ? "True" : "False");
 
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;
@@ -1466,7 +1468,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 	}
 
 	drawColoredRect(minX, minY, maxX, maxY, 0);
-	if (str)
+	if (str.size())
 		varA = script_parse(str, minX, minY, maxX, maxY, true);
 
 	if (displayTeamWindowFl)
@@ -1478,7 +1480,7 @@ int16 EfhEngine::sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTe
 			_word2C87A = false;
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
-			if (str)
+			if (str.size())
 				int16 varC = script_parse(str, minX, minY, maxX, maxY, false);
 		}
 
@@ -2442,8 +2444,8 @@ void EfhEngine::sub221D2(int16 monsterId) {
 void EfhEngine::sub22AA8(int16 arg0) {
 	debug("sub22AA8 %d", arg0);
 
-	int16 var8, varA, varC, varE;
-	var8 = varA = varC = varE = 0;
+	int16 var8, varA, varC, stringIdx;
+	var8 = varA = varC = stringIdx = 0;
 
 	if (arg0 <= 0xFE) {
 		if (_tempTextPtr) {
@@ -2465,8 +2467,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 			if (var12 == nullptr)
 				break;
 
-			if (varE == 0)
-				memset(_messageToBePrinted, 0, 400);
+			if (stringIdx == 0)
+				_messageToBePrinted = "";
 			do {
 				switch (*var12) {
 				case 0x00:
@@ -2474,9 +2476,9 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					break;
 				case 0x0D:
 				case 0x20:
-					_messageToBePrinted[varE++] = 0x20;
+					_messageToBePrinted += " ";
+					stringIdx++;
 					if (++varC >= 350) {
-						_messageToBePrinted[varE] = 0;
 						var8 = -1;
 					}
 					break;
@@ -2485,10 +2487,10 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					varA = -1;
 					break;
 				case 0x7C:
-					_messageToBePrinted[varE++] = 0x7C;
+					_messageToBePrinted += Common::String(0x7C);
+					stringIdx++;
 					varC += 20;
 					if (varC >= 350) {
-						_messageToBePrinted[varE] = 0;
 						var8 = -1;
 					}
 					break;
@@ -2496,7 +2498,8 @@ void EfhEngine::sub22AA8(int16 arg0) {
 					var8 = -1;
 					break;
 				default:
-					_messageToBePrinted[varE++] = *var12;
+					_messageToBePrinted += Common::String(*var12);
+					stringIdx++;
 					varC++;
 				break;
 				}
@@ -2504,11 +2507,11 @@ void EfhEngine::sub22AA8(int16 arg0) {
 				int16 var2 = 0xFF ;
 				if (var8 != 0 || varA != 0) {
 					var8 = 0;
-					_messageToBePrinted[varE] = 0;
-					varE = 0;
+					stringIdx = 0;
 					varC = 0;
-					if (*_messageToBePrinted == 0x5E || *_messageToBePrinted == 0) {
-						if (*_messageToBePrinted == 0x5E) {
+					uint8 firstChar = _messageToBePrinted.firstChar(); 
+					if (firstChar == 0x5E || firstChar == 0) {
+						if (firstChar == 0x5E) {
 							var2 = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
 							_word2C87A = false;
 						}
@@ -2776,7 +2779,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 		for (uint counter = 0; counter < 2; ++counter) {
 			drawCombatScreen(charId, true, false);
 			if (_teamMonsterIdArray[1] != -1)
-				sub1C219((uint8 *)"Select Monster Group:", 3, 0, false);
+				sub1C219("Select Monster Group:", 3, 0, false);
 
 			if (counter == 0)
 				displayFctFullScreen();
@@ -2884,7 +2887,7 @@ bool EfhEngine::sub1CB27() {
 					case 28:
 					case 29:
 					case 30:
-						sub1C219((uint8 *)"Select Character:", 3, 1, false);
+						sub1C219("Select Character:", 3, 1, false);
 						_teamNextAttack[counter1] = selectOtherCharFromTeam();
 						break;
 
@@ -3160,7 +3163,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 			displayCenteredString("Combat", 128, 303, 9);
 			drawColoredRect(200, 112, 278, 132, 0);
 			displayCenteredString("'T' for Terrain", 128, 303, 117);
-			sub1C219(nullptr, 1, 0, false);
+			sub1C219("", 1, 0, false);
 			sub1C4CA(whiteFl);
 			displayCombatMenu(charId);
 			displayLowStatusScreen(false);
@@ -3373,20 +3376,18 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	}
 
 	int16 rndDescrForDeathType = getRandom((3)) - 1;
-	char buffer[80];
-	memset(buffer, 0, 80);
-	snprintf(buffer, 80, "DUDE IS TOAST!");
+	Common::String tmpStr = "DUDE IS TOAST!";
 	switch (deathType) {
 	case 0:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", killing %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", killing %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", slaughtering %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", slaughtering %s!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", annihilating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", annihilating %s!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3395,13 +3396,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 1:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", cutting %s in two!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", cutting %s in two!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", dicing %s into small cubes!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", dicing %s into small cubes!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3410,13 +3411,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 2:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", popping %s like a zit!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", popping %s like a zit!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3425,13 +3426,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 3:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3440,13 +3441,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 4:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", totally incinerating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", totally incinerating %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", leaving a blistered mass of flesh behind!");
+			tmpStr = Common::String::format(", leaving a blistered mass of flesh behind!");
 			break;
 		default:
 			break;
@@ -3456,13 +3457,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		switch (rndDescrForDeathType) {
 		case 0:
 			// The original has a typo: popscicle
-			snprintf(buffer, 80, ", turning %s into a popsicle!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a popsicle!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", shattering %s into shards!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", shattering %s into shards!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3471,13 +3472,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 6:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", leaving pudding for brains");
+			tmpStr = Common::String::format(", leaving pudding for brains");
 			break;
 		case 1:
-			snprintf(buffer, 80, ", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3486,13 +3487,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 7:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3501,13 +3502,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 8:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", sucking %s into eternity!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", sucking %s into eternity!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3518,13 +3519,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 11:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", completely disintegrating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", completely disintegrating %s!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3535,13 +3536,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 14:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", blowing %s brains out!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", blowing %s brains out!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", exploding %s entire chest!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3550,13 +3551,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 15:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", choking %s to death!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", choking %s to death!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", melting %s lungs!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", melting %s lungs!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3565,13 +3566,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 16:
 		switch (rndDescrForDeathType) {
 		case 0:
-			snprintf(buffer, 80, ", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
 			break;
 		case 1:
-			snprintf(buffer, 80, ", piercing %s heart!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
 			break;
 		case 2:
-			snprintf(buffer, 80, ", impaling %s brain!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", impaling %s brain!", kPersonal[possessivePronoun]);
 			break;
 		default:
 			break;
@@ -3581,7 +3582,7 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		break;
 	}
 
-	strncat((char *)_messageToBePrinted, buffer, 80);
+	_messageToBePrinted += tmpStr;
 }
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
@@ -3599,8 +3600,7 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	if (!giveItemTo(charId, itemId, 0xFF))
 		return false;
 
-	Common::String buffer = Common::String::format(" and finds a %s!", _items[itemId]._name);
-	strncat((char *)_messageToBePrinted, buffer.c_str(), buffer.size() + 1);
+	_messageToBePrinted += Common::String::format(" and finds a %s!", _items[itemId]._name);
 	return true;
 }
 
@@ -3609,8 +3609,7 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 
 	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
-	char buffer[80];
-	snprintf(buffer, 80, "  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
+
 	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
 		generateSound(15);
 		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
@@ -3622,9 +3621,10 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
 		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
 	}
-	strncat((char *)_messageToBePrinted, buffer, 80);
+
+	_messageToBePrinted += Common::String::format("  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
 	if (!characterSearchesMonsterCorpse(charId, monsterId))
-		strncat((char *)_messageToBePrinted, "!", 2);
+		_messageToBePrinted += "!";
 
 }
 
@@ -3632,20 +3632,18 @@ void EfhEngine::addReactionText(int16 id) {
 	debug("addReactionText %d", id);
 
 	int16 rand3 = getRandom(3);
-	char buffer[80];
-	memset(buffer, 0, 80);
 
 	switch (id) {
 	case 0:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s looks dazed!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s looks dazed!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3654,13 +3652,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 1:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s wails terribly!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s wails terribly!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3669,13 +3667,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 2:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s is staggering!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3684,13 +3682,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 3:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3699,13 +3697,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 4:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s screams!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s bellows!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s bellows!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s shrills!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s shrills!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3714,13 +3712,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 5:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s chortles!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s seems amused!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s seems amused!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s looks concerned!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s looks concerned!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3729,13 +3727,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 6:
 		switch (rand3) {
 		case 1:
-			snprintf(buffer, 80, "  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 2:
-			snprintf(buffer, 80, "  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		case 3:
-			snprintf(buffer, 80, "  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3745,29 +3743,12 @@ void EfhEngine::addReactionText(int16 id) {
 		break;
 	}
 
-	strncat((char *)_messageToBePrinted, buffer, 80);
-}
-
-char EfhEngine::getFightMessageLastCharacter(char *message) {
-	debug("getFightMessageLastCharacter %s", message);
-
-	char *ptr = message;
-
-	if (ptr == nullptr || *ptr == 0)
-		return 0;
-
-	char lastChar = *ptr;
-	while (*ptr != 0) {
-		lastChar = *ptr++;
-	}
-
-	return lastChar;
 }
 
 void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	debug("sub1D8C2 %d %d", charId, damage);
 
-	int16 var42 = 0;
+	int16 destroyCounter = 0;
 	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
 
 	if (var40 > 2) {
@@ -3788,14 +3769,12 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
 			removeObject(charId, objectId);
 
-			if (var42 == 0) {
-				var42 = 1;
-				Common::String buffer = Common::String::format(", but %s ", kPossessive[var40]) + buffer2;
-				strncat((char *)_messageToBePrinted, buffer.c_str(), 40);
+			if (destroyCounter == 0) {
+				destroyCounter = 1;
+				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[var40]) + buffer2;
 			} else {
-				++var42;
-				Common::String buffer = Common::String(", ") + buffer2;
-				strncat((char *)_messageToBePrinted, buffer.c_str(), 40);
+				++destroyCounter;
+				_messageToBePrinted += Common::String(", ") + buffer2;
 			}
 		}
 
@@ -3803,12 +3782,12 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 			damage = var44;
 	}
 
-	if (var42 == 0) {
-		strncat((char *)_messageToBePrinted, "!", 2);
-	} else if (var42 > 1 || getFightMessageLastCharacter((char *)_messageToBePrinted) == 's' || getFightMessageLastCharacter((char *)_messageToBePrinted) == 'S') {
-		strncat((char *)_messageToBePrinted, " are destroyed!", 17);
+	if (destroyCounter == 0) {
+		_messageToBePrinted += "!";
+	} else if (destroyCounter > 1 || _messageToBePrinted.lastChar() == 's' || _messageToBePrinted.lastChar() == 'S') {
+		_messageToBePrinted += " are destroyed!";
 	} else {
-		strncat((char *)_messageToBePrinted, " is destroyed!", 16);
+		_messageToBePrinted += " is destroyed!";
 	}
 }
 
@@ -4133,8 +4112,8 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 	}
 }
 
-int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayString_3 %s %s %d %d %d %d", str, animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
 
@@ -4143,10 +4122,10 @@ int16 EfhEngine::displayString_3(const char *str, bool animFl, int16 charId, int
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
 
 		if (counter == 0) {
-			script_parse((uint8 *)str, 28, 122, 105, 166, false);
+			script_parse(str, 28, 122, 105, 166, false);
 			displayFctFullScreen();
 		} else {
-			retVal = script_parse((uint8 *)str, 28, 122, 105, 166, true);
+			retVal = script_parse(str, 28, 122, 105, 166, true);
 		}
 	}
 
@@ -4277,7 +4256,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			int16 victims = 0;
-			strncat((char *)_messageToBePrinted, "  The item emits a low droning hum...", 400);
+			_messageToBePrinted += "  The item emits a low droning hum...";
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
@@ -4306,7 +4285,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 400);
+			_messageToBePrinted += buffer1;
 		}
 
 		varA6 = true;
@@ -4315,7 +4294,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, "  The item emits a blue beam...", 400);
+			_messageToBePrinted += "  The item emits a blue beam...";
 			int16 victim = 0;
 			if (getRandom(100) < 50) {
 				for (uint varA8 = 0; varA8 < 9; ++varA8) {
@@ -4346,7 +4325,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
 			}
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 			// </CHECKME>
 		}
 
@@ -4356,7 +4335,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, "  The combat pauses...as there is a moment of forgiveness...", 400);
+			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
 			_unkArray2C8AA[0] = 0;
 		}
 
@@ -4366,7 +4345,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!", 400);
+			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
@@ -4391,12 +4370,12 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			if (getRandom(100) < 50) {
-				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!", 400);
+				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
 				for (uint counter = 0; counter < 9; ++counter) {
 					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
 				}
 			} else {
-				strncat((char *)_messageToBePrinted, "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!", 400);
+				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
@@ -4411,7 +4390,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, "  The magic sparkles brilliant hues in the air!", 400);
+			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
 			sub1E028(windowId, _items[itemId].field17_attackTypeDefense, true);
 		}
 		varA6 = true;
@@ -4430,7 +4409,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 			}
 			_word32482[varAA] -= 50;
 			if (_word32482[varAA] < 0)
@@ -4454,7 +4433,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 			}
 
 			_teamPctVisible[teamCharId] -= 50;
@@ -4478,7 +4457,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
 			// emptyFunction(2);
@@ -4488,7 +4467,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				if (argA == 2) {
 					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+					_messageToBePrinted += buffer1;
 					retVal = true;
 				}
 			} else {
@@ -4496,7 +4475,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				if (argA == 2) {
 					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+					_messageToBePrinted += buffer1;
 					retVal = true;
 				}
 			}
@@ -4515,7 +4494,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
 			// emptyFunction(2);
@@ -4525,7 +4504,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				if (argA == 2) {
 					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+					_messageToBePrinted += buffer1;
 					retVal = true;
 				}
 			} else {
@@ -4533,7 +4512,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				if (argA == 2) {
 					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+					_messageToBePrinted += buffer1;
 					retVal = true;
 				}
 			}
@@ -4549,11 +4528,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 teamCharId = windowId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
-					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!", 80);
+					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
 					_teamCharStatus[teamCharId]._status = 0;
 					_teamCharStatus[teamCharId]._duration = 0;
 				} else {
-					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!", 80);
+					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
 				}
 			}
 		}
@@ -4565,7 +4544,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 		}
 		setCharacterObjectToBroken(charId, objectId);
 		varA6 = true;
@@ -4601,7 +4580,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 			retVal = true;
 		}
 
@@ -4630,7 +4609,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
 		}
@@ -4661,7 +4640,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
 		}
@@ -4674,7 +4653,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 			retVal = true;
 		}
 		totalPartyKill();
@@ -4696,7 +4675,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (argA == 2) {
 				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 			} else {
-				strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
 			// emptyFunction(2);
@@ -4712,11 +4691,11 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			int16 teamCharId = windowId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 0) {
-					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, awakening the character!", 80);
+					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
 					_teamCharStatus[teamCharId]._status = 0;
 					_teamCharStatus[teamCharId]._duration = 0;
 				} else {
-					strncat((char *)_messageToBePrinted, "  The item makes a loud noise, but has no effect!", 80);
+					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
 				}
 			}
 		}
@@ -4747,7 +4726,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 			retVal = true;
 		}
 
@@ -4778,7 +4757,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (argA == 2) {
 			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 		} else {
-			strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+			_messageToBePrinted += buffer1;
 			retVal = true;
 		}
 
@@ -4810,7 +4789,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
 					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
 				} else {
-					strncat((char *)_messageToBePrinted, buffer1.c_str(), 80);
+					_messageToBePrinted += buffer1;
 				}
 				setCharacterObjectToBroken(charId, objectId);
 			} else {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index cff5abd1597..fa282c29a6c 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -318,7 +318,7 @@ private:
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(uint8 *str, int16 menuType, int16 arg4, bool displayTeamWindowFl);
+	int16 sub1C219(Common::String str, int16 menuType, int16 arg4, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
@@ -376,7 +376,6 @@ private:
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	void addReactionText(int16 id);
-	char getFightMessageLastCharacter(char *message);
 	void sub1D8C2(int16 charId, int16 damage);
 	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
 	void displayStatusMenu(int16 windowId);
@@ -387,7 +386,7 @@ private:
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
 	void unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 displayString_3(const char *str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
 	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
@@ -469,7 +468,7 @@ private:
 	// Script
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
-	int16 script_parse(uint8 *str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
+	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 
 	// Sound
 	void generateSound1(int arg0, int arg2, int duration);
@@ -526,7 +525,7 @@ private:
 	Common::String _characterNamePt2;
 	Common::String _nameBuffer;
 	char _attackBuffer[20];
-	uint8 _messageToBePrinted[400];
+	Common::String _messageToBePrinted;
 
 	uint8 *_mapBitmapRefArr[19];
 	UnkMapStruct _mapUnknown[100];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 9a69241cc0a..8f606c7fab2 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -76,7 +76,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		}
 
 		sub1CDFA();
-		sub1C219(nullptr, 2, 1, false);
+		sub1C219("", 2, 1, false);
 
 		for (uint counter = 0; counter < 8; ++counter) {
 			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
@@ -198,21 +198,21 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
-											strncat((char *)_messageToBePrinted, "!", 2);
+											_messageToBePrinted += "!";
 									} else {
-										snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
-											strncat((char *)_messageToBePrinted, "!", 2);
+											_messageToBePrinted += "!";
 									}
 									// handleFight - check damages - End
 
@@ -239,44 +239,36 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 									// handleFight - Check armor - start
 									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
-										char buffer[80];
-										memset(buffer, 0, 80);
 										if (damagePointsAbsorbed <= 1)
-											snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
 										else
-											snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
 
-										strncat((char *)_messageToBePrinted, buffer, 80);
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;
 										sub1D8C2(_teamCharId[var7E], varInt);
 									}
 									// handleFight - Check armor - end
 
 									// handleFight - Check effect - start
-									char buffer[80];
-									memset(buffer, 0, 80);
 									switch (_items[unk_monsterField5_itemId].field_16) {
 									case 1:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
+											_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
 										}
 										break;
 									case 2:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 2;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
+											_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
 										}
 										break;
 									case 5:
 									case 6:
 										if (getRandom(100) < 20) {
-											snprintf(buffer, 80, "  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
-											strncat((char *)_messageToBePrinted, buffer, 80);
+											_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
 											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
 										}
 										break;
@@ -285,7 +277,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									}
 									// handleFight - Check effect - end
 								} else {
-									snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
@@ -304,13 +296,13 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
 							case 1:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							case 2:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							default:
-								snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+								_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							}
 							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
@@ -353,13 +345,13 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	// End of effect message depends on the type of effect
 	switch (_teamCharStatus[charId]._status) {
 	case 1:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	case 2:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	default:
-		snprintf((char *)_messageToBePrinted, 400, "%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+		_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	}
 
@@ -486,24 +478,24 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
-								strncat((char *)_messageToBePrinted, "!", 2);
+								_messageToBePrinted += "!";
 							}
 						} else {
-							snprintf((char *)_messageToBePrinted, 400, "%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
-								strncat((char *)_messageToBePrinted, "!", 2);
+								_messageToBePrinted += "!";
 							}
 						}
 						// Action A - Check damages - End
@@ -531,19 +523,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 						// Action A - Add armor absorb text - Start
 						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							char buffer[80];
-							memset(buffer, 0, 80);
 							if (damagePointsAbsorbed <= 1)
-								snprintf(buffer, 80, "  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
 							else
-								snprintf(buffer, 80, "  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
-
-							strncat((char *)_messageToBePrinted, buffer, 80);
+								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
 						}
 						// Action A - Add armor absorb text - End
 
 						if (var5C)
-							strncat((char *)_messageToBePrinted, "  Your actions do not go un-noticed...", 400);
+							_messageToBePrinted += Common::String("  Your actions do not go un-noticed...");
 
 						// Action A - Check item durability - Start
 						varInt = _teamCharId[teamCharId];
@@ -552,10 +540,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							var51 = _npcBuf[varInt]._inventory[var64]._stat1 & 0x7F;
 							--var51;
 							if (var51 <= 0) {
-								char buffer[80];
-								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
-								strncat((char *)_messageToBePrinted, buffer, 80);
+								_messageToBePrinted += Common::String::format("  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
 							} else {
@@ -569,22 +554,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (getRandom(100) < 35) {
 								_stru32686[var7E]._field0[groupId] = 1;
 								_stru32686[var7E]._field2[groupId] = getRandom(10);
-								char buffer[80];
-								memset(buffer, 0, 80);
-								snprintf(buffer, 80, "  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
-								strncat((char *)_messageToBePrinted, buffer, 80);
+								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
 							}
 						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
 							_stru32686[var7E]._field0[groupId] = 2;
 							_stru32686[var7E]._field2[groupId] = getRandom(10);
-							char buffer[80];
-							memset(buffer, 0, 80);
-							snprintf(buffer, 80, "  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
-							strncat((char *)_messageToBePrinted, buffer, 80);
+							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
 						}
 						// Action A - Check effect - End
 					} else {
-						snprintf((char *)_messageToBePrinted, 400, "%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+						_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
@@ -607,7 +586,7 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	else
 		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -626,7 +605,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	else
 		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -644,7 +623,7 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	else
 		_enemyNamePt1 = "";
 
-	snprintf((char *)_messageToBePrinted, 400, "%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 8712f7725d9..fe3cba39c28 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -52,8 +52,8 @@ uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
 	}
 }
 
-int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("script_parse %s %d-%d %d-%d %s", (char *)stringBuffer, posX, posY, maxX, maxY, flag ? "True" : "False");
+int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
+	debug("script_parse %s %d-%d %d-%d %s", stringBuffer.c_str(), posX, posY, maxX, maxY, flag ? "True" : "False");
 
 	bool doneFlag = false;
 	int16 var_F2 = -1;
@@ -63,11 +63,10 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 	int16 numbLines = (1 + maxY - posY) / 9;
 	int16 width = maxX - posX;
 	int16 spaceWidth = getStringWidth(" ");
-	uint8 *buffer = stringBuffer;
+	uint8 *buffer = (uint8 *)stringBuffer.c_str();
 	char nextWord[80];
-	char curLine[150];
+	Common::String curLine = "";
 	memset(nextWord, 0, sizeof(nextWord));
-	memset(curLine, 0, sizeof(curLine));
 	int16 curWordPos = 0;
 	setTextPos(posX, curLineNb * 9 + posY);
 
@@ -88,7 +87,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 
 			nextWord[curWordPos] = 0;
 			int16 widthNextWord = getStringWidth(nextWord);
-			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine);
+			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine.c_str());
 
 			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) {
 				if (curLineNb >= numbLines) {
@@ -97,16 +96,13 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 					if (var_F2 == 0)
 						displayStringAtTextPos(curLine);
 
-					*curLine = 0;
-					strncpy(curLine, nextWord, 80);
-					strncat(curLine, " ", 2);
+					curLine = Common::String(nextWord) + " ";
 					++curLineNb;
 					setTextPos(posX, posY + curLineNb * 9);
 					curWordPos = 0;
 				}
 			} else {
-				strncat(curLine, nextWord, 80);
-				strncat(curLine, " ", 2);
+				curLine += Common::String(nextWord) + " ";
 				curWordPos = 0;
 			}
 			++buffer;
@@ -393,16 +389,16 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219((uint8 *)"Nothing...", 1, 2, true);
+					var110 = sub1C219("Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
 					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
 					_nameBuffer = _items[var110]._name;
-					snprintf(curLine, 150, "%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
+					curLine = Common::String::format("%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219((uint8 *)curLine, 1, 2, true);
+					var110 = sub1C219(curLine, 1, 2, true);
 					displayFctFullScreen();
 				}
 
@@ -481,7 +477,7 @@ int16 EfhEngine::script_parse(uint8 *stringBuffer, int16 posX, int16 posY, int16
 		}
 	}
 
-	if (*curLine != 0 && curLineNb < numbLines && var_F2 == 0)
+	if (curLine.size() >= 0 && curLineNb < numbLines && var_F2 == 0)
 		displayStringAtTextPos(curLine);
 
 	if (var_EE != 0xFF) {


Commit: 0df6c4b880ba46bd446ed1e9a0e961be9dfb222b
    https://github.com/scummvm/scummvm/commit/0df6c4b880ba46bd446ed1e9a0e961be9dfb222b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:41+01:00

Commit Message:
EFH: Remove an original unused debug flag, fix some warnings

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index df5a37aa46a..c310f821b0c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -293,7 +293,6 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_tempTextPtr = nullptr;
 	_word2C880 = false;
 	_redrawNeededFl = false;
-	_word2C8D7 = true;
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
 	_word2C87A = false;
@@ -739,6 +738,7 @@ void EfhEngine::initEngine() {
 	checkProtection();
 	if (_loadSaveSlot == -1) {
 		loadEfhGame();
+		resetGame();
 	} else {
 		loadGameState(_loadSaveSlot);
 		_loadSaveSlot = -1;
@@ -990,11 +990,6 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 			}
 		}
 	}
-
-	if (_word2C8D7)
-		return;
-
-	warning("drawMap() - unexpected code reached, not implemented");
 }
 
 void EfhEngine::displaySmallMap(int16 posX, int16 posY) {
@@ -1481,14 +1476,14 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 arg4, bool d
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 			if (str.size())
-				int16 varC = script_parse(str, minX, minY, maxX, maxY, false);
+				script_parse(str, minX, minY, maxX, maxY, false);
 		}
 
 		if (displayTeamWindowFl)
 			displayLowStatusScreen(false);
 
 		if (arg4 >= 2)
-			int16 varC = getLastCharAfterAnimCount(_guessAnimationAmount);
+			getLastCharAfterAnimCount(_guessAnimationAmount);
 
 		if (arg4 == 3)
 			drawColoredRect(minX, minY, maxX, maxY, 0);
@@ -1665,9 +1660,6 @@ void EfhEngine::handleNewRoundEffects() {
 
 	static int16 regenCounter = 0;
 
-	if (!_word2C8D7)
-		return;
-
 	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharStatus[counter]._status == 0) // normal
 			continue;
@@ -1687,6 +1679,15 @@ void EfhEngine::handleNewRoundEffects() {
 	regenCounter = 0;
 }
 
+void EfhEngine::resetGame() {
+	loadTechMapImp(0);
+	_largeMapFlag = true;
+	_oldMapPosX = _mapPosX = 31;
+	_oldMapPosY = _mapPosY = 31;
+	_unkRelatedToAnimImageSetId = 0;
+	_unkArray2C8AA[0] = 0;
+}
+
 bool EfhEngine::handleDeathMenu() {
 	debug("handleDeathMenu");
 
@@ -1720,25 +1721,22 @@ bool EfhEngine::handleDeathMenu() {
 		Common::KeyCode input = waitForKey();
 		switch (input) {
 		case Common::KEYCODE_l:
-			loadEfhGame();
+			//loadEfhGame();
+			//TODO : saveEfhGame opens the GUI save/load screen. It shouldn't bepossible to save at this point
+			saveEfhGame();
 			found = true;
 			break;
 		case Common::KEYCODE_q:
+			_shouldQuit = true;
 			return true;
 			break;
 		case Common::KEYCODE_r:
 			loadEfhGame();
-			loadTechMapImp(0);
-			_largeMapFlag = true;
-			_oldMapPosX = _mapPosX = 31;
-			_oldMapPosY = _mapPosY = 31;
-			_unkRelatedToAnimImageSetId = 0;
-			_unkArray2C8AA[0] = 0;
+			resetGame();
 			found = true;
 			break;
 		case Common::KEYCODE_x:
-			if (!_word2C8D7)
-				found = true;
+			found = true;
 			break;
 		default:
 			break;
@@ -2044,8 +2042,6 @@ void EfhEngine::sub174A0() {
 	static int16 sub174A0_monsterPosX = -1;
 	static int16 sub174A0_monsterPosY = -1;
 
-	int16 var14 = 0;
-	int16 var6 = 0;
 	_redrawNeededFl = true;
 	int16 unkMonsterId = -1;
 	int16 mapSize = _largeMapFlag ? 63 : 23;
@@ -2071,7 +2067,7 @@ void EfhEngine::sub174A0() {
 			continue;
 
 		bool var1A = false;
-		var14 = 0;
+		int16 var14 = 0;
 
 		sub174A0_monsterPosX = _mapMonsters[monsterId]._posX;
 		sub174A0_monsterPosY = _mapMonsters[monsterId]._posY;
@@ -2566,7 +2562,9 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		if (_mapUnknown[var8]._field3 == 0xFF) {
 			sub22AA8(_mapUnknown[var8]._field5); // word!
 			return true;
-		} else if (_mapUnknown[var8]._field3 == 0xFE) {
+		}
+
+		if (_mapUnknown[var8]._field3 == 0xFE) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
@@ -2595,7 +2593,9 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					continue;
 
 				for (uint var2 = 0; var2 < 39; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var2] >= _mapUnknown[var8]._field4) {
+					// CHECKME : the whole look doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
+					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4) {
 						sub22AA8(_mapUnknown[var8]._field5);
 						return true;
 					}
@@ -2643,8 +2643,8 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	imageSetId *= 72;
 	imageSetId += curTileInfo % 72;
 
-	if (arg4 == 1 && _word2C8D7) {
-		int16 var2 = sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, imageSetId);
+	if (arg4 == 1) {
+		sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, imageSetId);
 	}
 
 	if (_word2C880) {
@@ -2652,7 +2652,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 		return -1;
 	}
 	if (_tileFact[imageSetId]._field1 != 0xFF && !_dbgForceMonsterBlock) {
-		if ((arg4 == 1 && _word2C8D7) || (arg4 == 0 && _word2C8D7 && imageSetId != 128 && imageSetId != 121)) {
+		if ((arg4 == 1) || (arg4 == 0 && imageSetId != 128 && imageSetId != 121)) {
 			if (_largeMapFlag) {
 				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
 			} else {
@@ -5188,9 +5188,6 @@ bool EfhEngine::checkMonsterCollision() {
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
 			continue;
 
-		if (!_word2C8D7)
-			return false;
-
 		_mapPosX = _oldMapPosX;
 		_mapPosY = _oldMapPosY;
 		if (_imageSetSubFilesIdx != _oldImageSetSubFilesIdx)
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index fa282c29a6c..d9fdb4338c3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -330,6 +330,7 @@ private:
 	void goNorthWest();
 	void goSouthWest();
 	void handleNewRoundEffects();
+	void resetGame();
 	bool handleDeathMenu();
 	void computeMapAnimation();
 	void unkFct_anim();
@@ -588,7 +589,6 @@ private:
 	// TODO: Remove those useless debug flags
 	bool _dbgForceDisplayUpperRightBorder; // Original debug flag? Always false.
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
-	bool _word2C8D7; // Original debug flag? Always true.
 
 	bool _ongoingFightFl;
 	bool _statusMenuActive;
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index fe3cba39c28..5ebc63cbee9 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -147,8 +147,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			// Change map. { map number, posX, posY }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				if (_word2C8D7)
-					writeTechAndMapFiles();
+				writeTechAndMapFiles();
 				_oldMapPosX = _mapPosX = scriptNumberArray[1];
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadTechMapImp(scriptNumberArray[0]);


Commit: 68b66cad8360e000d6cc584526635e86de9d9264
    https://github.com/scummvm/scummvm/commit/68b66cad8360e000d6cc584526635e86de9d9264
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: turn some more char[] into Common::String, fix 4 warnings

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/graphics.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c310f821b0c..1857ed4545d 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1030,12 +1030,12 @@ void EfhEngine::drawScreen() {
 void EfhEngine::displayLowStatusScreen(bool flag) {
 	debugC(6, kDebugEngine, "displayLowStatusScreen %s", flag ? "True" : "False");
 
-	const char strName[5] = "Name";
-	const char strDef[4] = "DEF";
-	const char strHp[3] = "HP";
-	const char strMaxHp[7] = "Max HP";
-	const char strWeapon[7] = "Weapon";
-	const char strDead[9] = "* DEAD *";
+	Common::String strName = "Name";
+	Common::String strDef = "DEF";
+	Common::String strHp = "HP";
+	Common::String strMaxHp = "Max HP";
+	Common::String strWeapon = "Weapon";
+	Common::String strDead = "* DEAD *";
 
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
@@ -1057,11 +1057,11 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				setTextPos(16, textPosY);
 				displayStringAtTextPos(buffer);
 				buffer = Common::String::format("%d", getEquipmentDefense(charId, false));
-				displayCenteredString(buffer.c_str(), 104, 128, textPosY);
+				displayCenteredString(buffer, 104, 128, textPosY);
 				buffer = Common::String::format("%d", _npcBuf[charId]._hitPoints);
-				displayCenteredString(buffer.c_str(), 144, 176, textPosY);
+				displayCenteredString(buffer, 144, 176, textPosY);
 				buffer = Common::String::format("%d", _npcBuf[charId]._maxHP);
-				displayCenteredString(buffer.c_str(), 192, 224, textPosY);
+				displayCenteredString(buffer, 192, 224, textPosY);
 
 				if (_npcBuf[charId]._hitPoints <= 0) {
 					displayCenteredString(strDead, 225, 302, textPosY);
@@ -1088,7 +1088,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					break;
 				}
 
-				displayCenteredString(_nameBuffer.c_str(), 225, 302, textPosY);
+				displayCenteredString(_nameBuffer, 225, 302, textPosY);
 			}
 		}
 
@@ -2265,9 +2265,6 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	debug("sub21820 %d %d %d", monsterId, arg2, itemId);
 
-	char buffer[80];
-	memset(buffer, 0, 80);
-
 	uint8 var51 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
@@ -2378,7 +2375,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[var58]._name;
 				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
-				snprintf(buffer, 80, "%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
+				Common::String buffer = Common::String::format("%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
 				for (uint i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
 					_textColor = 0xE;
@@ -3794,16 +3791,13 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
 	debug("displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
 
-	char buffer[20];
-	memset(buffer, 0, 20);
-
 	if (menuBoxId == thisBoxId) {
 		if (_menuDepth == 0)
 			setTextColorWhite();
 		else
 			setTextColorGrey();
 
-		snprintf(buffer, 20, "> %s <", str);
+		Common::String buffer = Common::String::format("> %s <", str);
 		displayCenteredString(buffer, minX, maxX, minY);
 		setTextColorRed();
 	} else {
@@ -4407,7 +4401,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (varAA != 0x1B) {
 			buffer1 = "  The magic makes the user as quick and agile as a bird!";
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -4431,7 +4425,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		if (teamCharId != 0x1B) {
 			buffer1 = "  The magic makes the user invisible!";
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -4445,8 +4439,6 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		break;
 	case 16: { // Fairy Dust
-		int16 varAC = _mapPosX;
-		int16 varAA = _mapPosY;
 		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
 		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
 		int16 varAE = sub15538(_mapPosX, _mapPosY);
@@ -4455,7 +4447,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -4465,7 +4457,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (varAE == 0 || varAE == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -4473,7 +4465,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -4492,7 +4484,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -4502,7 +4494,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (varAE == 0 || varAE == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -4510,7 +4502,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -4542,7 +4534,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 19: // "Junk"
 		buffer1 = "  * The item breaks!";
 		if (argA == 2) {
-			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 		}
@@ -4578,7 +4570,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		buffer1 += "'";
 		if (argA == 2) {
-			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -4607,7 +4599,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -4638,7 +4630,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -4651,7 +4643,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 26: // "Black Sphere"
 		buffer1 = "The entire party collapses, dead!!!";
 		if (argA == 2) {
-			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -4673,7 +4665,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
 			if (argA == 2) {
-				displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -4724,7 +4716,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -4755,7 +4747,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -4786,8 +4778,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (varA1 <= 0) {
 				buffer1 = "  * The item breaks!";
 				if (argA == 2) {
-					Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
-					displayString_3(buffer1.c_str(), false, charId, windowId, menuId, curMenuLine);
+					getLastCharAfterAnimCount(_guessAnimationAmount);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 				}
@@ -4799,7 +4791,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (argA == 2) {
-			Common::KeyCode varAE = getLastCharAfterAnimCount(_guessAnimationAmount);
+			getLastCharAfterAnimCount(_guessAnimationAmount);
 			sub18E80(charId, windowId, menuId, curMenuLine);
 		}
 	}
@@ -5223,7 +5215,7 @@ bool EfhEngine::checkMonsterCollision() {
 				clearBottomTextZone(0);
 				_textColor = 0xE;
 				displayCenteredString("Interaction", 24, 296, 152);
-				displayCenteredString(buffer.c_str(), 24, 296, 161);
+				displayCenteredString(buffer, 24, 296, 161);
 				setTextPos(24, 169);
 				setTextColorWhite();
 				displayStringAtTextPos("T");
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index d9fdb4338c3..4fef5309737 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -444,7 +444,7 @@ private:
 	void clearScreen(int16 color);
 	void displayRawDataAtPos(uint8 *imagePtr, int16 posX, int16 posY);
 	void drawString(const char *str, int16 startX, int16 startY, uint16 textColor);
-	void displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY);
+	void displayCenteredString(Common::String str, int16 minX, int16 maxX, int16 posY);
 	void displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int16 posY);
 	void drawMapWindow();
 	void displayGameScreen();
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 8e9a97213c9..5062448b68e 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -235,11 +235,11 @@ void EfhEngine::drawString(const char *str, int16 startX, int16 startY, uint16 t
 	}
 }
 
-void EfhEngine::displayCenteredString(const char *str, int16 minX, int16 maxX, int16 posY) {
-	debugC(1, kDebugGraphics, "displayCenteredString %s %d-%d %d", str, minX, maxX, posY);
-	uint16 length = getStringWidth(str);
+void EfhEngine::displayCenteredString(Common::String str, int16 minX, int16 maxX, int16 posY) {
+	debugC(1, kDebugGraphics, "displayCenteredString %s %d-%d %d", str.c_str(), minX, maxX, posY);
+	uint16 length = getStringWidth(str.c_str());
 	int16 startCenteredDisplayX = minX + (maxX - minX - length) / 2;
-	drawString(str, startCenteredDisplayX, posY, _textColor);
+	drawString(str.c_str(), startCenteredDisplayX, posY, _textColor);
 }
 
 void EfhEngine::displayMenuAnswerString(const char *str, int16 minX, int16 maxX, int16 posY) {


Commit: db6ba84b0fb9fa0944d60a3ccec00a290107dd79
    https://github.com/scummvm/scummvm/commit/db6ba84b0fb9fa0944d60a3ccec00a290107dd79
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Fix another warning

Changed paths:
    engines/efh/fight.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 8f606c7fab2..7999205f453 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -26,7 +26,6 @@ namespace Efh {
 bool EfhEngine::handleFight(int16 monsterId) {
 	debug("handleFight %d", monsterId);
 
-	int16 var8C = 0;
 	_ongoingFightFl = true;
 
 	sub1BE89(monsterId);


Commit: 6c11b653a360eee3a6901c5b8c9a324495fe1fdc
    https://github.com/scummvm/scummvm/commit/6c11b653a360eee3a6901c5b8c9a324495fe1fdc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: turn some more char[] into Common::String

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 1857ed4545d..107fabd5ca1 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -232,12 +232,12 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_portraitSubFilesArray[i] = nullptr;
 	}
 
-	memset(_characterNamePt1, 0, 5);
+	_characterNamePt1 = "";
 	_characterNamePt2 = "";
 	_enemyNamePt1 = "";
 	_enemyNamePt2 = "";
 	_nameBuffer = "";
-	memset(_attackBuffer, 0, 20);
+	_attackBuffer = "";
 
 	for (int i = 0; i < 100; ++i) {
 		_imp1PtrArray[i] = nullptr;
@@ -3634,13 +3634,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 0:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s sways from the attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s sways from the attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s looks dazed!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s looks dazed!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3649,13 +3649,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 1:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s screams from the abuse!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s screams from the abuse!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s wails terribly!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s wails terribly!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3664,13 +3664,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 2:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s falters for a moment!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s falters for a moment!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s is stumbling about!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s is stumbling about!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3679,13 +3679,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 3:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s cringes from the damage!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s cringes from the damage!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s shrinks from the wound!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s shrinks from the wound!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3694,13 +3694,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 4:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s bellows!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s bellows!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s shrills!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s shrills!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3709,13 +3709,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 5:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s seems amused!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s seems amused!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s looks concerned!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s looks concerned!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
@@ -3724,13 +3724,13 @@ void EfhEngine::addReactionText(int16 id) {
 	case 6:
 		switch (rand3) {
 		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s smiles at the pathetic attack!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s smiles at the pathetic attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s laughs at the ineffective assault!", _characterNamePt1, _characterNamePt2.c_str());
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the ineffective assault!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 			break;
 		default:
 			break;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4fef5309737..490f68dea4e 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -522,10 +522,10 @@ private:
 	uint8 _techDataArr[19][4100];
 	Common::String _enemyNamePt1;
 	Common::String _enemyNamePt2;
-	char _characterNamePt1[5];
+	Common::String _characterNamePt1;
 	Common::String _characterNamePt2;
 	Common::String _nameBuffer;
-	char _attackBuffer[20];
+	Common::String _attackBuffer;
 	Common::String _messageToBePrinted;
 
 	uint8 *_mapBitmapRefArr[19];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 7999205f453..3006e207361 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -174,17 +174,17 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (var62 > 0) {
 									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
 									if (var62 > 1)
-										snprintf(_attackBuffer, 20, "%d times ", var62);
+										_attackBuffer = Common::String::format("%d times ", var62);
 									else
-										*_attackBuffer = 0;
+										_attackBuffer = "";
 								}
 
 								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 								int16 var6A = getRandom(3);
 								if (var5E == 2)
-									snprintf(_characterNamePt1, 5, "The ");
+									_characterNamePt1 = "The ";
 								else
-									*_characterNamePt1 = 0;
+									_characterNamePt1 = "";
 
 								if (var7E == 2)
 									_enemyNamePt1 = "The ";
@@ -197,17 +197,17 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											_messageToBePrinted += "!";
 									} else {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -239,9 +239,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									// handleFight - Check armor - start
 									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
 										if (damagePointsAbsorbed <= 1)
-											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 										else
-											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;
 										sub1D8C2(_teamCharId[var7E], varInt);
@@ -254,20 +254,20 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
+											_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 										}
 										break;
 									case 2:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 2;
 											_teamCharStatus[var7E]._duration = getRandom(10);
-											_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
+											_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 										}
 										break;
 									case 5:
 									case 6:
 										if (getRandom(100) < 20) {
-											_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1, _characterNamePt2.c_str());
+											_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
 										}
 										break;
@@ -452,17 +452,17 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (var62 > 0) {
 						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
 						if (var62 > 1) {
-							snprintf(_attackBuffer, 20, "%d times ", var62);
+							_attackBuffer = Common::String::format("%d times ", var62);
 						} else {
-							*_attackBuffer = 0;
+							_attackBuffer = "";
 						}
 					}
 					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 					int16 var6A = getRandom(3) - 1;
 					if (var5E == 2) {
-						snprintf(_characterNamePt1, 5, "The ");
+						_characterNamePt1 = "The ";
 					} else {
-						*_characterNamePt1 = 0;
+						_characterNamePt1 = "";
 					}
 
 					if (var70 == 2) {
@@ -477,11 +477,11 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints <= 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -489,7 +489,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 								_messageToBePrinted += "!";
 							}
 						} else {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1, _characterNamePt2.c_str(), _attackBuffer, kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str(), hitPoints);
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -523,9 +523,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add armor absorb text - Start
 						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
 							if (damagePointsAbsorbed <= 1)
-								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1, _characterNamePt2.c_str());
+								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							else
-								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1, _characterNamePt2.c_str(), damagePointsAbsorbed);
+								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
 						}
 						// Action A - Add armor absorb text - End
 
@@ -553,12 +553,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							if (getRandom(100) < 35) {
 								_stru32686[var7E]._field0[groupId] = 1;
 								_stru32686[var7E]._field2[groupId] = getRandom(10);
-								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1, _characterNamePt2.c_str());
+								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
 						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
 							_stru32686[var7E]._field0[groupId] = 2;
 							_stru32686[var7E]._field2[groupId] = getRandom(10);
-							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1, _characterNamePt2.c_str());
+							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						// Action A - Check effect - End
 					} else {


Commit: d598eefac42eeee47ca6703154c3f3130bdf29bd
    https://github.com/scummvm/scummvm/commit/d598eefac42eeee47ca6703154c3f3130bdf29bd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Fix bug in displayImp1Text, renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 107fabd5ca1..b45042d6653 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -66,7 +66,7 @@ void InvObject::init() {
 
 void UnkMapStruct::init() {
 	_placeId = _posX = _posY = _field3 = _field4 = 0;
-	_field5 = _field7 = 0;
+	_field5_textId = _field7_textId = 0;
 }
 
 void UnkAnimStruct::init() {
@@ -111,8 +111,8 @@ void NPCStruct::init() {
 	field_F = 0;
 	field_10 = 0;
 	field_11 = 0;
-	field_12 = 0;
-	field_14 = 0;
+	field12_textId = 0;
+	field14_textId = 0;
 	_xp = 0;
 
 	for (int i = 0; i < 15; ++i)
@@ -788,8 +788,8 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapUnknown[i]._posY = _mapUnknownPtr[9 * i + 2];
 		_mapUnknown[i]._field3 = _mapUnknownPtr[9 * i + 3];
 		_mapUnknown[i]._field4 = _mapUnknownPtr[9 * i + 4];
-		_mapUnknown[i]._field5 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
-		_mapUnknown[i]._field7 = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
+		_mapUnknown[i]._field5_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
+		_mapUnknown[i]._field7_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
 	}
 
 	uint8 *mapMonstersPtr = &_mapArr[idx][902];
@@ -804,7 +804,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapMonsters[i]._field_6 = mapMonstersPtr[29 * i + 6];
 		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
 		_mapMonsters[i]._field_8 = mapMonstersPtr[29 * i + 8];
-		_mapMonsters[i]._field_9 = mapMonstersPtr[29 * i + 9];
+		_mapMonsters[i]._field9_textId = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
 			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
@@ -1118,8 +1118,8 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	debug("removeCharacterFromTeam %d", teamMemberId);
 
 	int16 charId = _teamCharId[teamMemberId];
-	_npcBuf[charId].field_12 = _npcBuf[charId].field_B;
-	_npcBuf[charId].field_14 = _npcBuf[charId].field_E;
+	_npcBuf[charId].field12_textId = _npcBuf[charId].field_B;
+	_npcBuf[charId].field14_textId = _npcBuf[charId].field_E;
 	_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
 	_npcBuf[charId].field_11 = _npcBuf[charId].field_D;
 
@@ -1424,8 +1424,8 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 arg4, bool displayTeamWindowFl) {
-	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, arg4, displayTeamWindowFl ? "True" : "False");
+int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl) {
+	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, displayOption, displayTeamWindowFl ? "True" : "False");
 
 	int16 varA = 0xFF;
 	int16 minX, maxX, minY, maxY;
@@ -1469,7 +1469,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 arg4, bool d
 	if (displayTeamWindowFl)
 		displayLowStatusScreen(false);
 
-	if (arg4 != 0) {
+	if (displayOption != 0) {
 		displayFctFullScreen();
 		if (_word2C87A)
 			_word2C87A = false;
@@ -1482,10 +1482,10 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 arg4, bool d
 		if (displayTeamWindowFl)
 			displayLowStatusScreen(false);
 
-		if (arg4 >= 2)
+		if (displayOption >= 2)
 			getLastCharAfterAnimCount(_guessAnimationAmount);
 
-		if (arg4 == 3)
+		if (displayOption == 3)
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 	}
 
@@ -2279,11 +2279,11 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		return false;
 
 	if (var51 != 0x3F) {
-		if (_mapMonsters[monsterId]._field_9 == 0xFF || arg2 != 5) {
+		if (_mapMonsters[monsterId]._field9_textId == 0xFF || arg2 != 5) {
 			return false;
 		}
 		displayMonsterAnim(monsterId);
-		sub22AA8(_mapMonsters[monsterId]._field_9);
+		displayImp1Text(_mapMonsters[monsterId]._field9_textId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	}
@@ -2296,7 +2296,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 0:
 		if (arg2 == 4 && _npcBuf[var58].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			sub22AA8(_npcBuf[var58].field_14);
+			displayImp1Text(_npcBuf[var58].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2304,7 +2304,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 1:
 		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			sub22AA8(_npcBuf[var58].field_14);
+			displayImp1Text(_npcBuf[var58].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2312,7 +2312,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 2:
 		if (arg2 == 1 && _npcBuf[var58].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			sub22AA8(_npcBuf[var58].field_14);
+			displayImp1Text(_npcBuf[var58].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2320,7 +2320,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 3:
 		if (_history[_npcBuf[var58].field_11] != 0) {
 			displayMonsterAnim(monsterId);
-			sub22AA8(_npcBuf[var58].field_14);
+			displayImp1Text(_npcBuf[var58].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2331,7 +2331,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
 					removeObject(_teamCharId[counter], charId);
 					displayMonsterAnim(monsterId);
-					sub22AA8(_npcBuf[var58].field_14);
+					displayImp1Text(_npcBuf[var58].field14_textId);
 					displayAnimFrames(0xFE, true);
 					return true;
 				}
@@ -2341,7 +2341,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 5:
 		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			sub22AA8(_npcBuf[var58].field_14);
+			displayImp1Text(_npcBuf[var58].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2351,7 +2351,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 			for (uint charId = 0; charId < 10; ++charId) {
 				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
 					displayMonsterAnim(monsterId);
-					sub22AA8(_npcBuf[var58].field_14);
+					displayImp1Text(_npcBuf[var58].field14_textId);
 					displayAnimFrames(0xFE, true);
 					return true;
 				}
@@ -2363,7 +2363,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				removeCharacterFromTeam(counter);
 				displayMonsterAnim(monsterId);
-				sub22AA8(_npcBuf[var58].field_14);
+				displayImp1Text(_npcBuf[var58].field14_textId);
 				displayAnimFrames(0xFE, true);
 				return true;
 			}
@@ -2389,7 +2389,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				Common::KeyCode input = mapInputCode(waitForKey());
 				if (input == Common::KEYCODE_y) {
 					removeCharacterFromTeam(counter);
-					sub22AA8(_npcBuf[var58].field_14);
+					displayImp1Text(_npcBuf[var58].field14_textId);
 				}
 				displayAnimFrames(0xFE, true);
 				return true;
@@ -2400,7 +2400,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
-				sub22AA8(_npcBuf[var58].field_14);
+				displayImp1Text(_npcBuf[var58].field14_textId);
 				displayAnimFrames(0xFE, true);
 				return true;
 			}
@@ -2408,7 +2408,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 16:
 		displayMonsterAnim(monsterId);
-		sub22AA8(_npcBuf[var58].field_14);
+		displayImp1Text(_npcBuf[var58].field14_textId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	default:
@@ -2416,11 +2416,11 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	}
 
-	if (_npcBuf[var58].field_12 == 0x7FFF || arg2 != 5)
+	if (_npcBuf[var58].field12_textId == 0x7FFF || arg2 != 5)
 		return false;
 
 	displayMonsterAnim(monsterId);
-	sub22AA8(_npcBuf[var58].field_12);
+	displayImp1Text(_npcBuf[var58].field12_textId);
 	displayAnimFrames(0xFE, true);
 	return true;
 }
@@ -2434,13 +2434,15 @@ void EfhEngine::sub221D2(int16 monsterId) {
 	}
 }
 
-void EfhEngine::sub22AA8(int16 arg0) {
-	debug("sub22AA8 %d", arg0);
+void EfhEngine::displayImp1Text(int16 textId) {
+	debug("displayImp1Text %d", textId);
 
-	int16 var8, varA, varC, stringIdx;
-	var8 = varA = varC = stringIdx = 0;
+	int16 charCounter = 0;
+	int16 stringIdx = 0;
+	bool textComplete = false;
+	bool maxReached = false;
 
-	if (arg0 <= 0xFE) {
+	if (textId <= 0xFE) {
 		if (_tempTextPtr) {
 			_tempTextPtr = nullptr;
 			displayMiddleLeftTempText(_tempTextPtr, true);
@@ -2448,22 +2450,23 @@ void EfhEngine::sub22AA8(int16 arg0) {
 		if (_statusMenuActive)
 			drawGameScreenAndTempText(true);
 
-		int16 var4 = arg0;
+		int16 curTextId = textId;
 
 		for (;;) {
-			uint8 *var12 = nullptr;
-			if (var4 >= 0 && var4 <= 0xFE) {
-				var12 = _imp1PtrArray[var4];
+			uint8 *curString = nullptr;
+			if (curTextId >= 0 && curTextId <= 0xFE) {
+				curString = _imp1PtrArray[curTextId];
 			}
 
-			var4 = 0xFF;
-			if (var12 == nullptr)
+			curTextId = 0xFF;
+			if (curString == nullptr)
 				break;
 
-			if (stringIdx == 0)
-				_messageToBePrinted = "";
 			do {
-				switch (*var12) {
+				if (stringIdx == 0)
+					_messageToBePrinted = "";
+
+				switch (*curString) {
 				case 0x00:
 				case 0x0A:
 					break;
@@ -2471,41 +2474,41 @@ void EfhEngine::sub22AA8(int16 arg0) {
 				case 0x20:
 					_messageToBePrinted += " ";
 					stringIdx++;
-					if (++varC >= 350) {
-						var8 = -1;
+					if (++charCounter >= 350) {
+						maxReached = true;
 					}
 					break;
 				case 0x40:
 				case 0x60:
-					varA = -1;
+					textComplete = true;
 					break;
 				case 0x7C:
 					_messageToBePrinted += Common::String(0x7C);
 					stringIdx++;
-					varC += 20;
-					if (varC >= 350) {
-						var8 = -1;
+					charCounter += 20;
+					if (charCounter >= 350) {
+						maxReached = true;
 					}
 					break;
 				case 0x7E:
-					var8 = -1;
+					maxReached = true;
 					break;
 				default:
-					_messageToBePrinted += Common::String(*var12);
+					_messageToBePrinted += Common::String(*curString);
 					stringIdx++;
-					varC++;
+					charCounter++;
 				break;
 				}
-				var12 += 1;
-				int16 var2 = 0xFF ;
-				if (var8 != 0 || varA != 0) {
-					var8 = 0;
+				curString += 1;
+				if (maxReached || textComplete) {
+					int16 nextTextId = 0xFF;
+					maxReached = false;
 					stringIdx = 0;
-					varC = 0;
+					charCounter = 0;
 					uint8 firstChar = _messageToBePrinted.firstChar(); 
 					if (firstChar == 0x5E || firstChar == 0) {
 						if (firstChar == 0x5E) {
-							var2 = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
+							nextTextId = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
 							_word2C87A = false;
 						}
 					} else {
@@ -2515,13 +2518,13 @@ void EfhEngine::sub22AA8(int16 arg0) {
 								displayFctFullScreen();
 						}
 
-						var2 = sub1C219(_messageToBePrinted, 1, 1, true);
-						if (var2 != 0xFF)
-							var4 = var2;
+						nextTextId = sub1C219(_messageToBePrinted, 1, 1, true);
+						if (nextTextId != 0xFF)
+							curTextId = nextTextId;
 
-						if (var4 != -1) {
+						if (curTextId != -1) {
 							for (uint counter = 0; counter < 2; ++counter) {
-								if (varA) {
+								if (textComplete) {
 									displayCenteredString("[DONE]", 128, 303, 117);
 								} else {
 									displayCenteredString("[MORE]", 128, 303, 117);
@@ -2532,14 +2535,14 @@ void EfhEngine::sub22AA8(int16 arg0) {
 							getInputBlocking();
 						}
 					}
-					if (var2 != 0xFF)
-						var4 = var2;
+					if (nextTextId != 0xFF)
+						curTextId = nextTextId;
 				}
 
-			} while (varA == 0 && var4 != -1);
+			} while (!textComplete && curTextId != -1);
 
-			varA = 0;
-			if (var4 == 0xFF || var4 == -1)
+			textComplete = false;
+			if (curTextId == 0xFF || curTextId == -1)
 				break;
 		}
 	}
@@ -2557,7 +2560,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (arg8 == 0) {
 		if (_mapUnknown[var8]._field3 == 0xFF) {
-			sub22AA8(_mapUnknown[var8]._field5); // word!
+			displayImp1Text(_mapUnknown[var8]._field5_textId); // word!
 			return true;
 		}
 
@@ -2566,7 +2569,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				if (_teamCharId[counter] == -1)
 					continue;
 				if (_teamCharId[counter] == _mapUnknown[var8]._field4) {
-					sub22AA8(_mapUnknown[var8]._field5);
+					displayImp1Text(_mapUnknown[var8]._field5_textId);
 					return true;
 				}
 			}
@@ -2577,7 +2580,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
 					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4) {
-						sub22AA8(_mapUnknown[var8]._field5);
+						displayImp1Text(_mapUnknown[var8]._field5_textId);
 						return true;
 					}
 				}
@@ -2593,7 +2596,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					// CHECKME : the whole look doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
 					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4) {
-						sub22AA8(_mapUnknown[var8]._field5);
+						displayImp1Text(_mapUnknown[var8]._field5_textId);
 						return true;
 					}
 				}
@@ -2602,7 +2605,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	} else {
 		if ((_mapUnknown[var8]._field3 == 0xFA && arg8 == 1) || (_mapUnknown[var8]._field3 == 0xFC && arg8 == 2) || (_mapUnknown[var8]._field3 == 0xFB && arg8 == 3)) {
 			if (_mapUnknown[var8]._field4 == itemId) {
-				sub22AA8(_mapUnknown[var8]._field5);
+				displayImp1Text(_mapUnknown[var8]._field5_textId);
 				return true;
 			}
 		} else if (arg8 == 4) {
@@ -2610,7 +2613,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			if (var6 >= 0x7B && var6 <= 0xEF) {
 				var6 -= 0x78;
 				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknown[var8]._field4 <= _npcBuf[charId]._activeScore[itemId]) {
-					sub22AA8(_mapUnknown[var8]._field5);
+					displayImp1Text(_mapUnknown[var8]._field5_textId);
 					return true;
 				}
 			}
@@ -2623,9 +2626,9 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	}
 
 	if ((arg8 == 4 && _mapUnknown[var8]._field3 < 0xFA) || arg8 != 4) {
-		if (_mapUnknown[var8]._field7 > 0xFE)
+		if (_mapUnknown[var8]._field7_textId > 0xFE)
 			return false;
-		sub22AA8(_mapUnknown[var8]._field7);
+		displayImp1Text(_mapUnknown[var8]._field7_textId);
 		return true;
 	}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 490f68dea4e..d23e908d9d6 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -91,8 +91,8 @@ struct UnkMapStruct {
 	uint8 _posY;
 	uint8 _field3;
 	uint8 _field4;
-	uint16 _field5;
-	uint16 _field7;
+	uint16 _field5_textId;
+	uint16 _field7_textId;
 
 	void init();
 };
@@ -137,8 +137,8 @@ struct NPCStruct {
 	uint8 field_F;
 	uint8 field_10;
 	uint8 field_11;
-	uint16 field_12;
-	uint16 field_14;
+	uint16 field12_textId;
+	uint16 field14_textId;
 	uint32 _xp;
 	uint8 _activeScore[15];
 	uint8 _passiveScore[11];
@@ -210,7 +210,7 @@ struct MapMonster {
 	uint8 _field_6;
 	uint8 _monsterRef;
 	uint8 _field_8;
-	uint8 _field_9;
+	uint8 _field9_textId;
 	uint8 _groupSize;
 	int16 _pictureRef[9];
 };
@@ -318,7 +318,7 @@ private:
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(Common::String str, int16 menuType, int16 arg4, bool displayTeamWindowFl);
+	int16 sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
@@ -352,7 +352,7 @@ private:
 	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
 	void sub221D2(int16 monsterId);
-	void sub22AA8(int16 arg0);
+	void displayImp1Text(int16 textId);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
 	bool isTeamMemberStatusNormal(int16 id);
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 38b6984f266..79f71c03abe 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -271,8 +271,8 @@ void EfhEngine::loadNPCS() {
 		_npcBuf[i].field_F = f.readByte();
 		_npcBuf[i].field_10 = f.readByte();
 		_npcBuf[i].field_11 = f.readByte();
-		_npcBuf[i].field_12 = f.readUint16LE();
-		_npcBuf[i].field_14 = f.readUint16LE();
+		_npcBuf[i].field12_textId = f.readUint16LE();
+		_npcBuf[i].field14_textId = f.readUint16LE();
 		_npcBuf[i]._xp = f.readUint32LE();
 		for (int idx = 0; idx < 15; ++idx) {
 			_npcBuf[i]._activeScore[idx] = f.readByte();
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 6401564e103..e43bda6a876 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -174,8 +174,8 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		s.syncAsByte(_npcBuf[i].field_F);
 		s.syncAsByte(_npcBuf[i].field_10);
 		s.syncAsByte(_npcBuf[i].field_11);
-		s.syncAsSint16LE(_npcBuf[i].field_12);
-		s.syncAsSint16LE(_npcBuf[i].field_14);
+		s.syncAsSint16LE(_npcBuf[i].field12_textId);
+		s.syncAsSint16LE(_npcBuf[i].field14_textId);
 		s.syncAsSint32LE(_npcBuf[i]._xp);
 		for (int idx = 0; idx < 15; ++idx)
 			s.syncAsByte(_npcBuf[i]._activeScore[idx]);


Commit: 41dd4d0b4bd89d6656b166a9d57761d663ab400b
    https://github.com/scummvm/scummvm/commit/41dd4d0b4bd89d6656b166a9d57761d663ab400b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Some renaming, verify some more functions (and use debugC for those)

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/graphics.cpp
    engines/efh/script.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index b45042d6653..a3995f8a7e0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -392,7 +392,7 @@ Common::Error EfhEngine::run() {
 
 		if (newMs - lastMs >= 220) {
 			lastMs = newMs;
-			unkFct_anim();
+			handleAnimations();
 		}
 
 		Common::Event event;
@@ -1156,18 +1156,6 @@ bool EfhEngine::isCharacterATeamMember(int16 id) {
 	return false;
 }
 
-bool EfhEngine::isTPK() {
-	debug("isTPK");
-
-	int16 zeroedChar = 0;
-	for (int counter = 0; counter < _teamSize; ++counter) {
-		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
-			++zeroedChar;
-	}
-
-	return zeroedChar == _teamSize;
-}
-
 void EfhEngine::handleWinSequence() {
 	debugC(1, kDebugEngine, "handleWinSequence");
 
@@ -1748,7 +1736,7 @@ bool EfhEngine::handleDeathMenu() {
 }
 
 void EfhEngine::computeMapAnimation() {
-	debug("computeMapAnimation");
+	debugC(6, kDebugEngine, "computeMapAnimation");
 
 	const int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
@@ -1797,13 +1785,13 @@ void EfhEngine::computeMapAnimation() {
 	}
 }
 
-void EfhEngine::unkFct_anim() {
+void EfhEngine::handleAnimations() {
 	setNumLock();
 
 	if (_engineInitPending)
 		return;
 
-	debug("unkFct_anim");
+	debugC(6, kDebugEngine, "handleAnimations");
 
 	if (_animImageSetId != 0xFF) {
 		displayNextAnimFrame();
@@ -2435,7 +2423,7 @@ void EfhEngine::sub221D2(int16 monsterId) {
 }
 
 void EfhEngine::displayImp1Text(int16 textId) {
-	debug("displayImp1Text %d", textId);
+	debugC(6, kDebugEngine,"displayImp1Text %d", textId);
 
 	int16 charCounter = 0;
 	int16 stringIdx = 0;
@@ -5381,17 +5369,10 @@ uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	return _curPlace[mapPosX][mapPosY];
 }
 
-void EfhEngine::displayNextAnimFrame() {
-	debug("displayNextAnimFrame");
-
-	if (++_unkAnimRelatedIndex >= 15)
-		_unkAnimRelatedIndex = 0;
-
-	displayAnimFrame();
-}
-
 void EfhEngine::writeTechAndMapFiles() {
-	warning("STUB - writeTechAndMapFiles");
+	// The original game overwrite game data files when switching map, keeping track of modified data.
+	// In our implementation, we have everything in memory and save it in savegames only.
+	// This function is therefore not useful and is not implemented.
 }
 
 uint16 EfhEngine::getStringWidth(const char *buffer) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index d23e908d9d6..1cc11ce6982 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -60,7 +60,8 @@ static const uint8 kSavegameVersion = 1;
 enum AccessDebugChannels {
 	kDebugEngine = 1 << 0,
 	kDebugUtils = 1 << 1,
-	kDebugGraphics = 1 << 2
+	kDebugGraphics = 1 << 2,
+	kDebugScript = 1 << 3
 };
 
 class EfhGraphicsStruct {
@@ -295,7 +296,6 @@ private:
 	void saveEfhGame();
 	void copyCurrentPlaceToBuffer(int16 id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
-	void displayNextAnimFrame();
 	void writeTechAndMapFiles();
 	uint16 getStringWidth(const char *buffer);
 	void setTextPos(int16 textPosX, int16 textPosY);
@@ -309,7 +309,6 @@ private:
 	void removeCharacterFromTeam(int16 teamMemberId);
 	void refreshTeamSize();
 	bool isCharacterATeamMember(int16 id);
-	bool isTPK();
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
 	int16 chooseCharacterToReplace();
@@ -333,7 +332,7 @@ private:
 	void resetGame();
 	bool handleDeathMenu();
 	void computeMapAnimation();
-	void unkFct_anim();
+	void handleAnimations();
 	int8 sub16B08(int16 monsterId);
 	bool moveMonsterAwayFromTeam(int16 monsterId);
 	bool moveMonsterTowardsTeam(int16 monsterId);
@@ -408,6 +407,7 @@ private:
 	void handleFight_lastAction_D(int16 teamCharId);
 	void handleFight_lastAction_H(int16 teamCharId);
 	void handleFight_lastAction_U(int16 teamCharId);
+	bool isTPK();
 	bool sub1BC74(int16 monsterId, int16 teamMonsterId);
 	void sub1BCA7(int16 monsterTeamId);
 	void reset_stru32686();
@@ -433,6 +433,7 @@ private:
 	// Graphics
 	void initPalette();
 	void drawLeftCenterBox();
+	void displayNextAnimFrame();
 	void displayAnimFrame();
 	void displayAnimFrames(int16 animId, bool displayMenuBoxFl);
 	void displayFctFullScreen();
@@ -468,7 +469,7 @@ private:
 
 	// Script
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
-	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retval);
+	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retBuf);
 	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 
 	// Sound
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 3006e207361..08aa415b02c 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -611,11 +611,12 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	debug("handleFight_lastAction_U %d", teamCharId);
 
+	// Fight - Action 'U' - Use Item
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
-	int16 unk_monsterField5_itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
+	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	_nameBuffer = _items[unk_monsterField5_itemId]._name;
+	_nameBuffer = _items[itemId]._name;
 	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 	if (var70 == 2)
 		_enemyNamePt1 = "The ";
@@ -626,6 +627,18 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
+bool EfhEngine::isTPK() {
+	debugC(6, kDebugEngine,"isTPK");
+
+	int16 zeroedChar = 0;
+	for (int counter = 0; counter < _teamSize; ++counter) {
+		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
+			++zeroedChar;
+	}
+
+	return zeroedChar == _teamSize;
+}
+
 bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
 	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
 
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 79f71c03abe..8e1153dbd4c 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -117,7 +117,7 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 }
 
 void EfhEngine::readImpFile(int16 id, bool techMapFl) {
-	debug("readImpFile %d %s", id, techMapFl ? "True" : "False");
+	debugC(6, kDebugEngine, "readImpFile %d %s", id, techMapFl ? "True" : "False");
 
 	Common::String fileName = Common::String::format("imp.%d", id);
 
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 5062448b68e..7d73ea35cf9 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -56,6 +56,15 @@ void EfhEngine::drawLeftCenterBox() {
 	drawColoredRect(16, 8, 111, 135, 0);
 }
 
+void EfhEngine::displayNextAnimFrame() {
+	debugC(6, kDebugGraphics, "displayNextAnimFrame");
+
+	if (++_unkAnimRelatedIndex >= 15)
+		_unkAnimRelatedIndex = 0;
+
+	displayAnimFrame();
+}
+
 void EfhEngine::displayAnimFrame() {
 	debugC(1, kDebugGraphics, "displayAnimFrame");
 	// The original had a parameter. As it was always equal to zero, it was removed in ScummVM
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 5ebc63cbee9..be42723e2f5 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -25,7 +25,7 @@
 namespace Efh {
 
 uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize, int16 *destArray) {
-	debug("script_readNumberArray");
+	debugC(6, kDebugScript, "script_readNumberArray");
 
 	uint8 *buffer = srcBuffer;
 	for (int i = 0; i < destArraySize; ++i) {
@@ -36,20 +36,22 @@ uint8 *EfhEngine::script_readNumberArray(uint8 *srcBuffer, int16 destArraySize,
 	return buffer;
 }
 
-uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retval) {
-	debug("script_getNumber");
+uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retBuf) {
+	debugC(6, kDebugScript, "script_getNumber");
 
 	uint8 *buffer = srcBuffer;
-	int16 var2 = 0;
+	int16 retVal = 0;
 	for (;;) {
 		uint8 curChar = *buffer;
 		if (curChar < 0x30 || curChar > 0x39) {
-			*retval = var2;
-			return buffer;
+			break;
 		}
-		var2 = var2 * 10 + curChar - 0x30;
+		retVal = retVal * 10 + curChar - 0x30;
 		buffer++;
 	}
+
+	*retBuf = retVal;
+	return buffer;
 }
 
 int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index fb2b82a4b40..78a01fe96d1 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -157,7 +157,7 @@ Common::KeyCode EfhEngine::getLastCharAfterAnimCount(int16 delay) {
 		if (newMs - lastMs >= 200) {
 			lastMs = newMs;
 			--delay;
-			unkFct_anim();
+			handleAnimations();
 		}
 
 		lastChar = handleAndMapInput(false);
@@ -182,7 +182,7 @@ Common::KeyCode EfhEngine::getInput(int16 delay) {
 		if (newMs - lastMs >= 200) {
 			lastMs = newMs;
 			--delay;
-			unkFct_anim();
+			handleAnimations();
 		}
 
 		lastChar = handleAndMapInput(false);
@@ -205,7 +205,7 @@ Common::KeyCode EfhEngine::waitForKey() {
 
 		if (newMs - lastMs >= 200) {
 			lastMs = newMs;
-			unkFct_anim();
+			handleAnimations();
 		}
 
 		_system->getEventManager()->pollEvent(event);
@@ -248,7 +248,7 @@ Common::KeyCode EfhEngine::handleAndMapInput(bool animFl) {
 
 			if (newMs - lastMs >= 200) {
 				lastMs = newMs;
-				unkFct_anim();
+				handleAnimations();
 			}
 		} else
 			break;
@@ -276,7 +276,7 @@ Common::KeyCode EfhEngine::getInputBlocking() {
 
 		if (newMs - lastMs >= 220) {
 			lastMs = newMs;
-			unkFct_anim();
+			handleAnimations();
 		}
 	}
 	return retVal;


Commit: 86b0c137c90ece062dd0f38451b029c4a513e665
    https://github.com/scummvm/scummvm/commit/86b0c137c90ece062dd0f38451b029c4a513e665
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: move some functions from efh to fight, tag some more functions as reviewed (via the use of debugC)

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a3995f8a7e0..8de22d8a284 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1099,14 +1099,14 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 
 
 void EfhEngine::removeObject(int16 charId, int16 objectId) {
-	debug("removeObject %d %d", charId, objectId);
+	debugC(6, kDebugEngine, "removeObject %d %d", charId, objectId);
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 	_npcBuf[charId]._inventory[objectId]._stat1 = 0;
 	_npcBuf[charId]._inventory[objectId]._stat2 = 0;
 }
 
 void EfhEngine::totalPartyKill() {
-	debug("totalPartyKill");
+	debugC(6, kDebugEngine, "totalPartyKill");
 
 	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1)
@@ -1115,7 +1115,7 @@ void EfhEngine::totalPartyKill() {
 }
 
 void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
-	debug("removeCharacterFromTeam %d", teamMemberId);
+	debugC(6, kDebugEngine, "removeCharacterFromTeam %d", teamMemberId);
 
 	int16 charId = _teamCharId[teamMemberId];
 	_npcBuf[charId].field12_textId = _npcBuf[charId].field_B;
@@ -1136,7 +1136,7 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 }
 
 void EfhEngine::refreshTeamSize() {
-	debug("refreshTeamSize");
+	debugC(6, kDebugEngine, "refreshTeamSize");
 
 	_teamSize = 0;
 	for (uint counter = 0; counter < 3; ++counter) {
@@ -1146,7 +1146,7 @@ void EfhEngine::refreshTeamSize() {
 }
 
 bool EfhEngine::isCharacterATeamMember(int16 id) {
-	debug("isCharacterATeamMember %d", id);
+	debugC(6, kDebugEngine,"isCharacterATeamMember %d", id);
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharId[counter] == id)
@@ -1803,9 +1803,8 @@ void EfhEngine::handleAnimations() {
 }
 
 int8 EfhEngine::sub16B08(int16 monsterId) {
-	debug("sub16B08 %d", monsterId);
+	debugC(3, kDebugEngine,"sub16B08 %d", monsterId);
 
-	// Simplified version compared to the original
 	int16 maxSize = _largeMapFlag ? 63 : 23;
 	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
 		return 0;
@@ -2657,15 +2656,6 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return _tileFact[imageSetId]._field0;
 }
 
-bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
-	debug("isTeamMemberStatusNormal %d", teamMemberId);
-
-	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
-		return true;
-
-	return false;
-}
-
 void EfhEngine::sub1CDFA() {
 	debug("sub1CDFA"); // Initiatives
 
@@ -2738,63 +2728,6 @@ int16 EfhEngine::selectMonsterGroup() {
 	return retVal;
 }
 
-int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
-	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
-
-	int16 varE = -1;
-
-	int16 var6 = sub1C80A(charId, unkFied18Val, true);
-	int16 range = 0;
-	if (var6 != 0x7FFF)
-		range = _items[var6]._range;
-
-	switch (range) {
-	case 3:
-	case 2:
-		++range;
-	case 1:
-		++range;
-	case 0:
-		++range;
-		break;
-	case 4:
-		return 100;
-	default:
-		return varE;
-	}
-
-	do {
-		for (uint counter = 0; counter < 2; ++counter) {
-			drawCombatScreen(charId, true, false);
-			if (_teamMonsterIdArray[1] != -1)
-				sub1C219("Select Monster Group:", 3, 0, false);
-
-			if (counter == 0)
-				displayFctFullScreen();
-		}
-
-		if (_teamMonsterIdArray[1] == -1)
-			varE = 0;
-		else
-			varE = selectMonsterGroup();
-
-		if (!arg4) {
-			if (varE == 27) // Esc
-				varE = 0;
-		} else if (varE != 27) {
-			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[varE]);
-			if (monsterGroupDistance > range) {
-				varE = 27;
-			}
-		}
-	} while (varE == -1);
-
-	if (varE == 27)
-		varE = -1;
-
-	return varE;
-}
-
 void EfhEngine::sub1CAB6(int16 charId) {
 	debug("sub1CAB6 %d", charId);
 
@@ -2807,112 +2740,6 @@ void EfhEngine::sub1CAB6(int16 charId) {
 	}
 }
 
-bool EfhEngine::sub1CB27() {
-	debug("sub1CB27");
-
-	bool var4 = false;
-	for (int counter1 = 0; counter1 < _teamSize; ++counter1) {
-		_teamLastAction[counter1] = 0;
-		if (!isTeamMemberStatusNormal(counter1))
-			continue;
-
-		var4 = true;
-		do {
-			drawCombatScreen(_teamCharId[counter1], false, true);
-			Common::KeyCode var1 = handleAndMapInput(true);
-			switch (var1) {
-			case Common::KEYCODE_a: // Attack
-				_teamLastAction[counter1] = 'A';
-				_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, true);
-				if (_teamNextAttack[counter1] == -1)
-					_teamLastAction[counter1] = 0;
-				break;
-			case Common::KEYCODE_d: // Defend
-				_teamLastAction[counter1] = 'D';
-				break;
-			case Common::KEYCODE_h: // Hide
-				_teamLastAction[counter1] = 'H';
-				break;
-			case Common::KEYCODE_r: // Run
-				for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
-					_teamLastAction[counter2] = 'R';
-				}
-				return true;
-			case Common::KEYCODE_s: { // Status
-				int16 var8 = handleStatusMenu(2, _teamCharId[counter1]);
-				sub1CAB6(_teamCharId[counter1]);
-				if (var8 > 999) {
-					if (var8 == 0x7D00)
-						_teamLastAction[counter1] = 'S';
-				} else {
-					_teamLastAction[counter1] = 'U';
-					_word31780[counter1] = var8;
-					int16 var6 = _npcBuf[_teamCharId[counter1]]._inventory[var8]._ref;
-					switch (var6 - 1) {
-					case 0:
-					case 1:
-					case 2:
-					case 3:
-					case 4:
-					case 5:
-					case 6:
-					case 7:
-					case 8:
-					case 10:
-					case 12:
-					case 13:
-						_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, false);
-						break;
-
-					case 9:
-					case 11:
-					case 14:
-					case 15:
-					case 18:
-					case 24:
-					case 25:
-					case 27:
-					case 28:
-					case 29:
-					case 30:
-						sub1C219("Select Character:", 3, 1, false);
-						_teamNextAttack[counter1] = selectOtherCharFromTeam();
-						break;
-
-					case 16:
-					case 17:
-					case 26:
-						_teamNextAttack[counter1] = 0xC8;
-						break;
-
-					case 19:
-					case 20:
-					case 21:
-					case 22:
-					case 23:
-					default:
-						break;
-					}
-
-				}
-
-				}
-				break;
-			case Common::KEYCODE_t: // Terrain
-				redrawScreenForced();
-				getInputBlocking();
-				drawCombatScreen(_teamCharId[counter1], false, true);
-				break;
-			default:
-				break;
-			}
-		} while (_teamLastAction[counter1] == 0);
-
-	}
-
-	return var4;
-}
-
 // The parameter isn't used in the original
 void EfhEngine::sub1BE9A(int16 monsterId) {
 	debug("sub1BE9A %d", monsterId);
@@ -3324,255 +3151,6 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 	return false;
 }
 
-void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
-	debug("getDeathTypeDescription %d %d", attackerId, victimId);
-
-	int16 possessivePronoun;
-
-	if (attackerId > 999) {
-		int16 charId = _teamCharId[attackerId - 1000];
-		possessivePronoun = _npcBuf[charId]._possessivePronounSHL6 >> 6;
-	} else {
-		int16 charId = _teamMonsterIdArray[attackerId];
-		possessivePronoun = _mapMonsters[charId]._possessivePronounSHL6 >> 6;
-	}
-
-	if (possessivePronoun > 2)
-		possessivePronoun = 2;
-
-	int16 deathType;
-	if (getRandom(100) < 20) {
-		deathType = 0;
-	} else {
-		if (victimId >= 1000) {
-			int16 charId = _teamCharId[victimId - 1000];
-			if (charId == -1)
-				deathType = 0;
-			else {
-				int16 var6 = sub1C80A(charId, 9, true);
-				if (var6 == 0x7FFF)
-					deathType = 0;
-				else
-					deathType = _items[var6]._attackType + 1;
-			}
-		} else if (_teamMonsterIdArray[victimId] == -1)
-			deathType = 0;
-		else {
-			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
-			deathType = _items[itemId]._attackType;
-		}
-	}
-
-	int16 rndDescrForDeathType = getRandom((3)) - 1;
-	Common::String tmpStr = "DUDE IS TOAST!";
-	switch (deathType) {
-	case 0:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", killing %s!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", slaughtering %s!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", annihilating %s!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 1:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", cutting %s in two!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", dicing %s into small cubes!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 2:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", popping %s like a zit!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 3:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 4:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", totally incinerating %s!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", leaving a blistered mass of flesh behind!");
-			break;
-		default:
-			break;
-		}
-		break;
-	case 5:
-		switch (rndDescrForDeathType) {
-		case 0:
-			// The original has a typo: popscicle
-			tmpStr = Common::String::format(", turning %s into a popsicle!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", shattering %s into shards!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 6:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", leaving pudding for brains");
-			break;
-		case 1:
-			tmpStr = Common::String::format(", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 7:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 8:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", sucking %s into eternity!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 9:
-	case 10:
-	case 11:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", completely disintegrating %s!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 12:
-	case 13:
-	case 14:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", blowing %s brains out!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", exploding %s entire chest!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 15:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", choking %s to death!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", melting %s lungs!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	case 16:
-		switch (rndDescrForDeathType) {
-		case 0:
-			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
-			break;
-		case 1:
-			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
-			break;
-		case 2:
-			tmpStr = Common::String::format(", impaling %s brain!", kPersonal[possessivePronoun]);
-			break;
-		default:
-			break;
-		}
-		break;
-	default:
-		break;
-	}
-
-	_messageToBePrinted += tmpStr;
-}
-
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 1cc11ce6982..46b6a2f28b3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -61,7 +61,8 @@ enum AccessDebugChannels {
 	kDebugEngine = 1 << 0,
 	kDebugUtils = 1 << 1,
 	kDebugGraphics = 1 << 2,
-	kDebugScript = 1 << 3
+	kDebugScript = 1 << 3,
+	kDebugFight = 1 << 4
 };
 
 class EfhGraphicsStruct {
@@ -354,13 +355,10 @@ private:
 	void displayImp1Text(int16 textId);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
-	bool isTeamMemberStatusNormal(int16 id);
 	void sub1CDFA();
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
-	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
 	void sub1CAB6(int16 charId);
-	bool sub1CB27();
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
@@ -372,7 +370,6 @@ private:
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
-	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	void addReactionText(int16 id);
@@ -413,6 +410,10 @@ private:
 	void reset_stru32686();
 	void sub1BE89(int16 monsterId);
 	void resetTeamMonsterIdArray();
+	bool isTeamMemberStatusNormal(int16 id);
+	void getDeathTypeDescription(int16 attackerId, int16 victimId);
+	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
+	bool sub1CB27();
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 08aa415b02c..3ca3c8e41f8 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -23,6 +23,60 @@
 
 namespace Efh {
 
+void EfhEngine::sub1BCA7(int16 monsterTeamId) {
+	debug("sub1BCA7 %d", monsterTeamId);
+
+	int16 counter = 0;
+	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
+		counter = 1;
+		_teamMonsterIdArray[0] = monsterTeamId;
+	}
+
+	for (int counter2 = 1; counter2 <= 3; ++counter2) {
+		if (counter >= 5)
+			break;
+
+		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
+			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+				continue;
+
+			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+				continue;
+
+			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
+				continue;
+
+			bool found = false;
+			for (uint counter3 = 0; counter3 < 9; ++counter3) {
+				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
+					found = true;
+					break;
+				}
+			}
+
+			if (found) {
+				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
+					_teamMonsterIdArray[counter] = monsterId;
+					if (++counter >= 5)
+						break;
+				}
+			}
+		}
+	}
+
+	if (counter > 4)
+		return;
+
+	for (uint id = counter; id < 5; ++id)
+		_teamMonsterIdArray[id] = -1;
+}
+
+void EfhEngine::sub1BE89(int16 monsterId) {
+	debug("sub1BE89 %d", monsterId);
+	sub1BCA7(monsterId);
+	reset_stru32686();
+}
+
 bool EfhEngine::handleFight(int16 monsterId) {
 	debug("handleFight %d", monsterId);
 
@@ -628,7 +682,7 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 }
 
 bool EfhEngine::isTPK() {
-	debugC(6, kDebugEngine,"isTPK");
+	debugC(6, kDebugFight, "isTPK");
 
 	int16 zeroedChar = 0;
 	for (int counter = 0; counter < _teamSize; ++counter) {
@@ -649,76 +703,440 @@ bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
 	return false;
 }
 
-void EfhEngine::sub1BCA7(int16 monsterTeamId) {
-	debug("sub1BCA7 %d", monsterTeamId);
+void EfhEngine::reset_stru32686() {
+	debug("reset_stru32686");
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
+			_stru32686[counter1]._field0[counter2] = 0;
+			_stru32686[counter1]._field2[counter2] = 0;
+		}
+	}
+}
 
-	int16 counter = 0;
-	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
-		counter = 1;
-		_teamMonsterIdArray[0] = monsterTeamId;
+void EfhEngine::resetTeamMonsterIdArray() {
+	debug("resetTeamMonsterIdArray");
+
+	for (int i = 0; i < 5; ++i) {
+		_teamMonsterIdArray[i] = -1;
 	}
+}
 
-	for (int counter2 = 1; counter2 <= 3; ++counter2) {
-		if (counter >= 5)
-			break;
+bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
+	debugC(6, kDebugFight, "isTeamMemberStatusNormal %d", teamMemberId);
 
-		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
-				continue;
+	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
+		return true;
 
-			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
-				continue;
+	return false;
+}
 
-			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
-				continue;
+void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
+	debug("getDeathTypeDescription %d %d", attackerId, victimId);
 
-			bool var6 = false;
-			for (uint counter3 = 0; counter3 < 9; ++counter3) {
-				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
-					var6 = true;
-					break;
-				}
-			}
+	int16 possessivePronoun;
 
-			if (var6) {
-				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
-					_teamMonsterIdArray[counter] = monsterId;
-					if (++counter >= 5)
-						break;
-				}
+	if (attackerId > 999) {
+		int16 charId = _teamCharId[attackerId - 1000];
+		possessivePronoun = _npcBuf[charId]._possessivePronounSHL6 >> 6;
+	} else {
+		int16 charId = _teamMonsterIdArray[attackerId];
+		possessivePronoun = _mapMonsters[charId]._possessivePronounSHL6 >> 6;
+	}
+
+	if (possessivePronoun > 2)
+		possessivePronoun = 2;
+
+	int16 deathType;
+	if (getRandom(100) < 20) {
+		deathType = 0;
+	} else {
+		if (victimId >= 1000) {
+			int16 charId = _teamCharId[victimId - 1000];
+			if (charId == -1)
+				deathType = 0;
+			else {
+				int16 var6 = sub1C80A(charId, 9, true);
+				if (var6 == 0x7FFF)
+					deathType = 0;
+				else
+					deathType = _items[var6]._attackType + 1;
 			}
+		} else if (_teamMonsterIdArray[victimId] == -1)
+			deathType = 0;
+		else {
+			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
+			deathType = _items[itemId]._attackType;
 		}
 	}
 
-	if (counter > 4)
-		return;
+	int16 rndDescrForDeathType = getRandom((3)) - 1;
+	Common::String tmpStr = "DUDE IS TOAST!";
+	switch (deathType) {
+	case 0:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", killing %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", slaughtering %s!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", annihilating %s!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 1:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", cutting %s in two!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", dicing %s into small cubes!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 2:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", popping %s like a zit!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 3:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 4:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", totally incinerating %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", leaving a blistered mass of flesh behind!");
+			break;
+		default:
+			break;
+		}
+		break;
+	case 5:
+		switch (rndDescrForDeathType) {
+		case 0:
+			// The original has a typo: popscicle
+			tmpStr = Common::String::format(", turning %s into a popsicle!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", shattering %s into shards!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 6:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", leaving pudding for brains");
+			break;
+		case 1:
+			tmpStr = Common::String::format(", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 7:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 8:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", sucking %s into eternity!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 9:
+	case 10:
+	case 11:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", completely disintegrating %s!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 12:
+	case 13:
+	case 14:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", blowing %s brains out!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 15:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", choking %s to death!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", melting %s lungs!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	case 16:
+		switch (rndDescrForDeathType) {
+		case 0:
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			break;
+		case 1:
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
+			break;
+		case 2:
+			tmpStr = Common::String::format(", impaling %s brain!", kPersonal[possessivePronoun]);
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
 
-	for (uint id = counter; id < 5; ++id)
-		_teamMonsterIdArray[id] = -1;
+	_messageToBePrinted += tmpStr;
 }
 
-void EfhEngine::reset_stru32686() {
-	debug("reset_stru32686");
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_stru32686[counter1]._field0[counter2] = 0;
-			_stru32686[counter1]._field2[counter2] = 0;
-		}
+int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
+	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
+
+	int16 varE = -1;
+
+	int16 var6 = sub1C80A(charId, unkFied18Val, true);
+	int16 range = 0;
+	if (var6 != 0x7FFF)
+		range = _items[var6]._range;
+
+	switch (range) {
+	case 3:
+	case 2:
+		++range;
+	case 1:
+		++range;
+	case 0:
+		++range;
+		break;
+	case 4:
+		return 100;
+	default:
+		return varE;
 	}
-}
 
-void EfhEngine::sub1BE89(int16 monsterId) {
-	debug("sub1BE89 %d", monsterId);
-	sub1BCA7(monsterId);
-	reset_stru32686();
+	do {
+		for (uint counter = 0; counter < 2; ++counter) {
+			drawCombatScreen(charId, true, false);
+			if (_teamMonsterIdArray[1] != -1)
+				sub1C219("Select Monster Group:", 3, 0, false);
+
+			if (counter == 0)
+				displayFctFullScreen();
+		}
+
+		if (_teamMonsterIdArray[1] == -1)
+			varE = 0;
+		else
+			varE = selectMonsterGroup();
+
+		if (!arg4) {
+			if (varE == 27) // Esc
+				varE = 0;
+		} else if (varE != 27) {
+			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[varE]);
+			if (monsterGroupDistance > range) {
+				varE = 27;
+			}
+		}
+	} while (varE == -1);
+
+	if (varE == 27)
+		varE = -1;
+
+	return varE;
 }
 
-void EfhEngine::resetTeamMonsterIdArray() {
-	debug("resetTeamMonsterIdArray");
+bool EfhEngine::sub1CB27() {
+	debug("sub1CB27");
+
+	bool var4 = false;
+	for (int counter1 = 0; counter1 < _teamSize; ++counter1) {
+		_teamLastAction[counter1] = 0;
+		if (!isTeamMemberStatusNormal(counter1))
+			continue;
+
+		var4 = true;
+		do {
+			drawCombatScreen(_teamCharId[counter1], false, true);
+			Common::KeyCode var1 = handleAndMapInput(true);
+			switch (var1) {
+			case Common::KEYCODE_a: // Attack
+				_teamLastAction[counter1] = 'A';
+				_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, true);
+				if (_teamNextAttack[counter1] == -1)
+					_teamLastAction[counter1] = 0;
+				break;
+			case Common::KEYCODE_d: // Defend
+				_teamLastAction[counter1] = 'D';
+				break;
+			case Common::KEYCODE_h: // Hide
+				_teamLastAction[counter1] = 'H';
+				break;
+			case Common::KEYCODE_r: // Run
+				for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
+					_teamLastAction[counter2] = 'R';
+				}
+				return true;
+			case Common::KEYCODE_s: { // Status
+				int16 var8 = handleStatusMenu(2, _teamCharId[counter1]);
+				sub1CAB6(_teamCharId[counter1]);
+				if (var8 > 999) {
+					if (var8 == 0x7D00)
+						_teamLastAction[counter1] = 'S';
+				} else {
+					_teamLastAction[counter1] = 'U';
+					_word31780[counter1] = var8;
+					int16 var6 = _npcBuf[_teamCharId[counter1]]._inventory[var8]._ref;
+					switch (var6 - 1) {
+					case 0:
+					case 1:
+					case 2:
+					case 3:
+					case 4:
+					case 5:
+					case 6:
+					case 7:
+					case 8:
+					case 10:
+					case 12:
+					case 13:
+						_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, false);
+						break;
 
-	for (int i = 0; i < 5; ++i) {
-		_teamMonsterIdArray[i] = -1;
+					case 9:
+					case 11:
+					case 14:
+					case 15:
+					case 18:
+					case 24:
+					case 25:
+					case 27:
+					case 28:
+					case 29:
+					case 30:
+						sub1C219("Select Character:", 3, 1, false);
+						_teamNextAttack[counter1] = selectOtherCharFromTeam();
+						break;
+
+					case 16:
+					case 17:
+					case 26:
+						_teamNextAttack[counter1] = 0xC8;
+						break;
+
+					case 19:
+					case 20:
+					case 21:
+					case 22:
+					case 23:
+					default:
+						break;
+					}
+				}
+
+			} break;
+			case Common::KEYCODE_t: // Terrain
+				redrawScreenForced();
+				getInputBlocking();
+				drawCombatScreen(_teamCharId[counter1], false, true);
+				break;
+			default:
+				break;
+			}
+		} while (_teamLastAction[counter1] == 0);
 	}
+
+	return var4;
 }
 
 } // End of namespace Efh


Commit: 19fae17e60893e3d905f90339b9b5006e0995a6b
    https://github.com/scummvm/scummvm/commit/19fae17e60893e3d905f90339b9b5006e0995a6b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Fix a bug in checkMonsterCollision(), some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8de22d8a284..944fd4359ea 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -104,10 +104,10 @@ void ItemStruct::init() {
 void NPCStruct::init() {
 	for (int i = 0; i < 11; ++i)
 		_name[i] =  0;
-	field_B = 0;
+	fieldB_textId = 0;
 	field_C = 0;
 	field_D = 0;
-	field_E = 0;
+	fieldE_textId = 0;
 	field_F = 0;
 	field_10 = 0;
 	field_11 = 0;
@@ -1118,8 +1118,8 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	debugC(6, kDebugEngine, "removeCharacterFromTeam %d", teamMemberId);
 
 	int16 charId = _teamCharId[teamMemberId];
-	_npcBuf[charId].field12_textId = _npcBuf[charId].field_B;
-	_npcBuf[charId].field14_textId = _npcBuf[charId].field_E;
+	_npcBuf[charId].field12_textId = _npcBuf[charId].fieldB_textId;
+	_npcBuf[charId].field14_textId = _npcBuf[charId].fieldE_textId;
 	_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
 	_npcBuf[charId].field_11 = _npcBuf[charId].field_D;
 
@@ -1280,7 +1280,6 @@ int16 EfhEngine::chooseCharacterToReplace() {
 int16 EfhEngine::handleCharacterJoining() {
 	debug("handleCharacterJoining");
 
-	const char strReplaceWho[13] = "Replace Who?";
 	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
 			return counter;
@@ -1289,7 +1288,7 @@ int16 EfhEngine::handleCharacterJoining() {
 
 	for (uint counter = 0; counter < 2; ++counter) {
 		drawColoredRect(200, 112, 278, 132, 0);
-		displayCenteredString(strReplaceWho, 200, 278, 117);
+		displayCenteredString("Replace Who?", 200, 278, 117);
 		if (counter == 0)
 			displayFctFullScreen();
 	}
@@ -4742,8 +4741,8 @@ bool EfhEngine::checkMonsterCollision() {
 		if (!(_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE) && !(!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId))
 			continue;
 
-		if ((_mapMonsters[monsterId]._field_1 & 0x3F) > 0x3D
-		&& (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)))
+		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
+		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isCharacterATeamMember(_mapMonsters[monsterId]._field_1)))
 			continue;
 
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 46b6a2f28b3..18638bbcb48 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -132,10 +132,10 @@ struct ItemStruct {
 
 struct NPCStruct {
 	char _name[11];
-	uint8 field_B;
+	uint8 fieldB_textId;
 	uint8 field_C;
 	uint8 field_D;
-	uint8 field_E;
+	uint8 fieldE_textId;
 	uint8 field_F;
 	uint8 field_10;
 	uint8 field_11;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 8e1153dbd4c..e43026a2b1c 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -264,10 +264,10 @@ void EfhEngine::loadNPCS() {
 	for (int i = 0; i < 99; ++i) {
 		for (int idx = 0; idx < 11; ++idx)
 			_npcBuf[i]._name[idx] = f.readByte();
-		_npcBuf[i].field_B = f.readByte();
+		_npcBuf[i].fieldB_textId = f.readByte();
 		_npcBuf[i].field_C = f.readByte();
 		_npcBuf[i].field_D = f.readByte();
-		_npcBuf[i].field_E = f.readByte();
+		_npcBuf[i].fieldE_textId = f.readByte();
 		_npcBuf[i].field_F = f.readByte();
 		_npcBuf[i].field_10 = f.readByte();
 		_npcBuf[i].field_11 = f.readByte();
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index e43bda6a876..bdf6962ae1b 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -167,10 +167,10 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		for (int idx = 0; idx < 11; ++idx)
 			s.syncAsByte(_npcBuf[i]._name[idx]);
 
-		s.syncAsByte(_npcBuf[i].field_B);
+		s.syncAsByte(_npcBuf[i].fieldB_textId);
 		s.syncAsByte(_npcBuf[i].field_C);
 		s.syncAsByte(_npcBuf[i].field_D);
-		s.syncAsByte(_npcBuf[i].field_E);
+		s.syncAsByte(_npcBuf[i].fieldE_textId);
 		s.syncAsByte(_npcBuf[i].field_F);
 		s.syncAsByte(_npcBuf[i].field_10);
 		s.syncAsByte(_npcBuf[i].field_11);


Commit: 7e326f5cd3ce05601af10a6126d35a55af74f8dc
    https://github.com/scummvm/scummvm/commit/7e326f5cd3ce05601af10a6126d35a55af74f8dc
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: validate some more functions, some renaming and code simplification

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 944fd4359ea..1b2494cf72b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -304,7 +304,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_menuItemCounter = 0;
 
 	for (int i = 0; i < 15; ++i) {
-		_word3273A[i] = 0;
+		_menuStatItemArr[i] = 0;
 	}
 
 	_messageToBePrinted = "";
@@ -3357,7 +3357,7 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 }
 
 void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
-	debug("displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
+	debugC(6, kDebugEngine, "displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
 
 	if (menuBoxId == thisBoxId) {
 		if (_menuDepth == 0)
@@ -3379,7 +3379,7 @@ void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 mi
 }
 
 void EfhEngine::displayStatusMenu(int16 windowId) {
-	debug("displayStatusMenu %d", windowId);
+	debugC(3, kDebugEngine, "displayStatusMenu %d", windowId);
 
 	for (uint counter = 0; counter < 9; ++counter) {
 		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
@@ -3402,49 +3402,40 @@ void EfhEngine::displayStatusMenu(int16 windowId) {
 }
 
 void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
-	debug("countRightWindowItems %d %d", menuId, charId);
+	debugC(6, kDebugEngine, "countRightWindowItems %d %d", menuId, charId);
 
-	int16 var2 = 0;
-	int16 var4 = 0;
+	int16 maxId = 0;
+	int16 minId;
 	_menuItemCounter = 0;
 
 	switch (menuId) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-	case 9:
-		var4 = -1;
-		break;
 	case 5:
-		var4 = 26;
-		var2 = 36;
+		minId = 26;
+		maxId = 36;
 		break;
 	case 6:
-		var4 = 15;
-		var2 = 25;
+		minId = 15;
+		maxId = 25;
 		break;
 	case 7:
-		var4 = 0;
-		var2 = 14;
+		minId = 0;
+		maxId = 14;
 		break;
-	default: // Case 8 + Default
-		var4 = -1;
-		_menuItemCounter = 0;
+	default:
+		minId = -1;
 		break;
 	}
 
-	if (var4 == -1) {
+	if (minId == -1) {
 		for (uint counter = 0; counter < 10; ++counter) {
 			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
-				_word3273A[_menuItemCounter++] = counter;
+				_menuStatItemArr[_menuItemCounter++] = counter;
 			}
 		}
 	} else {
-		for (int16 counter = var4; counter < var2; ++counter) {
+		for (int16 counter = minId; counter < maxId; ++counter) {
 			if (_npcBuf[charId]._activeScore[counter] != 0) {
-				_word3273A[_menuItemCounter++] = counter;
+				_menuStatItemArr[_menuItemCounter++] = counter;
 			}
 		}
 	}
@@ -3472,7 +3463,7 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 }
 
 void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
-	debug("displayCharacterSummary %d %d", curMenuLine, npcId);
+	debugC(3, kDebugEngine, "displayCharacterSummary %d %d", curMenuLine, npcId);
 
 	setTextColorRed();
 	Common::String buffer1 = _npcBuf[npcId]._name;
@@ -3516,9 +3507,9 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 				setTextColorWhite();
 		}
 		int16 textPosY = 81 + counter * 9;
-		int16 itemId = _npcBuf[npcId]._inventory[_word3273A[counter]]._ref;
+		int16 itemId = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref;
 		if (itemId != 0x7FFF) {
-			if (_npcBuf[npcId]._inventory[_word3273A[counter]]._stat1 & 0x80) {
+			if (_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1 & 0x80) {
 				setTextPos(146, textPosY);
 				displayCharAtTextPos('E');
 			}
@@ -3539,23 +3530,24 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 			setTextPos(262, textPosY);
 
 			if (_items[itemId]._defense > 0) {
-				int16 var54 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat2;
-				if (var54 == 0xFF) {
-					// useless?
-					var54 = _items[_npcBuf[npcId]._inventory[_word3273A[counter]]._ref]._defense;
-				} else {
-					buffer1 = Common::String::format("%d", 1 + var54 / 8);
+				int16 stat2 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat2;
+				if (stat2 != 0xFF) {
+					buffer1 = Common::String::format("%d", 1 + stat2 / 8);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					displayStringAtTextPos("Def");
 				}
+				// useless code removed.
+				// else {
+				//	var54 = _items[_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref]._defense;
+				// {
 			} else if (_items[itemId]._uses != 0x7F) {
-				int16 var52 = _npcBuf[npcId]._inventory[_word3273A[counter]]._stat1;
-				if (var52 != 0x7F) {
-					buffer1 = Common::String::format("%d", var52);
+				int16 stat1 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1;
+				if (stat1 != 0x7F) {
+					buffer1 = Common::String::format("%d", stat1);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
-					if (var52 == 1)
+					if (stat1 == 1)
 						displayStringAtTextPos("Use");
 					else
 						displayStringAtTextPos("Uses");
@@ -3595,8 +3587,8 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 
 		displayStringAtTextPos(buffer);
 		setTextPos(163, textPosY);
-		displayStringAtTextPos(kSkillArray[_word3273A[counter]]);
-		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_word3273A[counter]]);
+		displayStringAtTextPos(kSkillArray[_menuStatItemArr[counter]]);
+		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_menuStatItemArr[counter]]);
 		setTextPos(278, textPosY);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
@@ -4535,7 +4527,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		int16 itemId;
 		switch (menuId) {
 		case 0:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
 			if (gameMode == 2) {
@@ -4545,7 +4537,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 1:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (gameMode == 2) {
 				restoreAnimImageSetId();
@@ -4561,7 +4553,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
 			break;
 		case 2:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -4587,7 +4579,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 			break;
 		case 3:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -4645,7 +4637,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 4:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
@@ -4672,7 +4664,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 5:
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
@@ -4684,7 +4676,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 6: // Identical to case 5?
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
@@ -4696,7 +4688,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case 7: // Identical to case 5?
-			objectId = _word3273A[selectedLine];
+			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 18638bbcb48..4b02a2841ec 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -601,7 +601,7 @@ private:
 	int16 _teamNextAttack[3];
 	int16 _word31780[3];
 
-	int16 _word3273A[15];
+	int16 _menuStatItemArr[15];
 	Stru32686 _stru32686[5];
 	Stru3244C _stru3244C[8];
 };


Commit: 4395cfc17e2f2c3312d92279c5387c25489ec11b
    https://github.com/scummvm/scummvm/commit/4395cfc17e2f2c3312d92279c5387c25489ec11b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Double check more functions, some renaming

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 1b2494cf72b..110b07184b3 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1511,7 +1511,7 @@ bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
 }
 
 void EfhEngine::goSouth() {
-	debug("goSouth");
+	debugC(6,kDebugEngine, "goSouth");
 
 	if (_largeMapFlag) {
 		if (++_mapPosY > 63)
@@ -1528,7 +1528,7 @@ void EfhEngine::goSouth() {
 }
 
 void EfhEngine::goNorth() {
-	debug("goNorth");
+	debugC(6,kDebugEngine, "goNorth");
 
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
@@ -1540,7 +1540,7 @@ void EfhEngine::goNorth() {
 }
 
 void EfhEngine::goEast() {
-	debug("goEast");
+	debugC(6, kDebugEngine, "goEast");
 
 	if (_largeMapFlag) {
 		if (++_mapPosX > 63)
@@ -1557,7 +1557,7 @@ void EfhEngine::goEast() {
 }
 
 void EfhEngine::goWest() {
-	debug("goWest");
+	debugC(6, kDebugEngine, "goWest");
 
 	if (--_mapPosX < 0)
 		_mapPosX = 0;
@@ -1569,7 +1569,7 @@ void EfhEngine::goWest() {
 }
 
 void EfhEngine::goNorthEast() {
-	debug("goNorthEast");
+	debugC(6, kDebugEngine, "goNorthEast");
 
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
@@ -1589,7 +1589,7 @@ void EfhEngine::goNorthEast() {
 }
 
 void EfhEngine::goSouthEast() {
-	debug("goSouthEast");
+	debugC(6, kDebugEngine, "goSouthEast");
 
 	if (_largeMapFlag) {
 		if (++_mapPosX > 63)
@@ -1610,7 +1610,7 @@ void EfhEngine::goSouthEast() {
 }
 
 void EfhEngine::goNorthWest() {
-	debug("goNorthWest");
+	debugC(6, kDebugEngine,"goNorthWest");
 
 	if (--_mapPosY < 0)
 		_mapPosY = 0;
@@ -1625,7 +1625,7 @@ void EfhEngine::goNorthWest() {
 }
 
 void EfhEngine::goSouthWest() {
-	debug("goSouthWest");
+	debugC(6, kDebugEngine, "goSouthWest");
 
 	if (--_mapPosX < 0)
 		_mapPosX = 0;
@@ -1828,7 +1828,7 @@ int8 EfhEngine::sub16B08(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
-	debug("moveMonsterAwayFromTeam %d", monsterId);
+	debugC(6, kDebugEngine, "moveMonsterAwayFromTeam %d", monsterId);
 
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		--_mapMonsters[monsterId]._posX;
@@ -1847,7 +1847,7 @@ bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 		else if (_mapMonsters[monsterId]._posY > _mapPosY)
 			++_mapMonsters[monsterId]._posY;
 
-			return true;
+		return true;
 	}
 
 	// Original checks for posX equality, which is the only possible option at this point => skipped
@@ -1862,7 +1862,7 @@ bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
-	debug("moveMonsterTowardsTeam %d", monsterId);
+	debugC(6, kDebugEngine, "moveMonsterTowardsTeam %d", monsterId);
 
 	if (_mapMonsters[monsterId]._posX < _mapPosX) {
 		++_mapMonsters[monsterId]._posX;
@@ -1896,40 +1896,53 @@ bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 }
 
 bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
-	debug("moveMonsterGroupOther %d %d", monsterId, direction);
+	debugC(6, kDebugEngine, "moveMonsterGroupOther %d %d", monsterId, direction);
+
+	bool retVal;
 
 	switch (direction - 1) {
 	case 0:
 		--_mapMonsters[monsterId]._posY;
-		return true;
+		retVal = true;
+		break;
 	case 1:
 		--_mapMonsters[monsterId]._posY;
 		++_mapMonsters[monsterId]._posX;
-		return true;
+		retVal = true;
+		break;
 	case 2:
 		++_mapMonsters[monsterId]._posX;
-		return true;
+		retVal = true;
+		break;
 	case 3:
 		++_mapMonsters[monsterId]._posX;
 		++_mapMonsters[monsterId]._posY;
-		return true;
+		retVal = true;
+		break;
 	case 4:
 		++_mapMonsters[monsterId]._posY;
-		return true;
+		retVal = true;
+		break;
 	case 5:
 		++_mapMonsters[monsterId]._posY;
 		--_mapMonsters[monsterId]._posX;
-		return true;
+		retVal = true;
+		break;
 	case 6:
 		--_mapMonsters[monsterId]._posX;
-		return true;
+		retVal = true;
+		break;
 	case 7:
 		--_mapMonsters[monsterId]._posX;
 		--_mapMonsters[monsterId]._posY;
-		return true;
+		retVal = true;
+		break;
 	default:
-		return false;
+		retVal = false;
+		break;
 	}
+
+	return retVal;
 }
 
 bool EfhEngine::moveMonsterGroup(int16 monsterId) {
@@ -2052,8 +2065,8 @@ void EfhEngine::sub174A0() {
 		if (var4 < minDisplayedMapX || var4 > maxDisplayedMapX || var2 < minDisplayedMapY || var2 > maxDisplayedMapY)
 			continue;
 
-		bool var1A = false;
-		int16 var14 = 0;
+		bool monsterMovedFl = false;
+		int16 lastRangeCheck = 0;
 
 		sub174A0_monsterPosX = _mapMonsters[monsterId]._posX;
 		sub174A0_monsterPosY = _mapMonsters[monsterId]._posY;
@@ -2070,106 +2083,106 @@ void EfhEngine::sub174A0() {
 			switch (var1C - 1) {
 			case 0:
 				if (getRandom(100) >= 0xE - var1E)
-					var1A = moveMonsterTowardsTeam(monsterId);
+					monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 				else
-					var1A = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 1:
 				if (getRandom(100) >= 0xE - var1E)
-					var1A = moveMonsterAwayFromTeam(monsterId);
+					monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 				else
-					var1A = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 2:
-				var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+				monsterMovedFl = moveMonsterGroupOther(monsterId, getRandom(8));
 				break;
 			case 3:
-				var1A = moveMonsterGroup(monsterId);
+				monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 4:
 				if (getRandom(100) > 0x32 - var1E)
-					var1A = moveMonsterTowardsTeam(monsterId);
+					monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 				else
-					var1A = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 5:
 				if (getRandom(100) > 0x32 - var1E)
-					var1A = moveMonsterAwayFromTeam(monsterId);
+					monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 				else
-					var1A = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 6:
 				if (getRandom(100) >= 0x32 - var1E)
-					var1A = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			case 7:
 				// var14 is not a typo.
-				var14 = checkMonsterWeaponRange(monsterId);
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				break;
 			case 8:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
 					if (getRandom(100) >= 0xE - var1E)
-						var1A = moveMonsterTowardsTeam(monsterId);
+						monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 					else
-						var1A = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroup(monsterId);
 				}
 				break;
 			case 9:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
 					if (getRandom(100) >= 0xE - var1E)
-						var1A = moveMonsterAwayFromTeam(monsterId);
+						monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 					else
-						var1A = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroup(monsterId);
 				}
 				break;
 			case 10:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
-					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
+					monsterMovedFl = moveMonsterGroupOther(monsterId, getRandom(8));
 				}
 				break;
 			case 11:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
-					var1A = moveMonsterGroup(monsterId);
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				}
 				break;
 			case 12:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
 					if (getRandom(100) >= 0x32 - var1E)
-						var1A = moveMonsterTowardsTeam(monsterId);
+						monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 					else
-						var1A = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroup(monsterId);
 				}
 				break;
 			case 13:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0) {
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0) {
 					if (getRandom(100) >= 0x32 - var1E)
-						var1A = moveMonsterAwayFromTeam(monsterId);
+						monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 					else
-						var1A = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroup(monsterId);
 				}
 				break;
 			case 14:
-				var14 = checkMonsterWeaponRange(monsterId);
-				if (var14 == 0 && getRandom(100) >= 0x32 - var1E)
-					var1A = moveMonsterGroup(monsterId);
+				lastRangeCheck = checkMonsterWeaponRange(monsterId);
+				if (lastRangeCheck == 0 && getRandom(100) >= 0x32 - var1E)
+					monsterMovedFl = moveMonsterGroup(monsterId);
 				break;
 			default:
 				break;
 			}
 
 			for (;;) {
-				if (!var1A) {
-					if (var14 == 0) {
-						var1A = true;
+				if (!monsterMovedFl) {
+					if (lastRangeCheck == 0) {
+						monsterMovedFl = true;
 					} else {
 						unkMonsterId = monsterId;
-						var1A = true;
+						monsterMovedFl = true;
 					}
 				} else {
 					int8 var18 = sub16B08(monsterId);
@@ -2177,7 +2190,7 @@ void EfhEngine::sub174A0() {
 					if (var18 == 0) {
 						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
 						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
-						var1A = false;
+						monsterMovedFl = false;
 						--var16;
 					} else if (var18 == 2) {
 						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
@@ -2185,14 +2198,14 @@ void EfhEngine::sub174A0() {
 					}
 				}
 
-				if (!var1A && var16 == 1 && var1E > 1) {
-					var1A = moveMonsterGroupOther(monsterId, getRandom(8));
+				if (!monsterMovedFl && var16 == 1 && var1E > 1) {
+					monsterMovedFl = moveMonsterGroupOther(monsterId, getRandom(8));
 					continue;
 				}
 
 				break;
 			}
-		} while (!var1A && var16 > 0);
+		} while (!monsterMovedFl && var16 > 0);
 	}
 
 	if (unkMonsterId != -1)
@@ -3559,7 +3572,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 }
 
 void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
-	debug("displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
+	debugC(3, kDebugEngine, "displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
 
 	setTextColorRed();
 	Common::String buffer = _npcBuf[charId]._name;
@@ -3639,6 +3652,8 @@ void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16
 		displayCenteredString("Character Summary", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
+	default:
+		break;
 	}
 }
 


Commit: a354207813b346b75ee16c64748dc0b4be0cd86a
    https://github.com/scummvm/scummvm/commit/a354207813b346b75ee16c64748dc0b4be0cd86a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Disable saving during intro, winning sequence and after death, some renaming and functions review

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 110b07184b3..fd601d708e1 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -296,7 +296,6 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
 	_word2C87A = false;
-	_dbgForceDisplayUpperRightBorder = false;
 	_dbgForceMonsterBlock = false;
 	_ongoingFightFl = false;
 	_statusMenuActive = false;
@@ -341,6 +340,8 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 
 	// If requested, load a savegame instead of showing the intro
 	_loadSaveSlot = -1;
+	_saveAuthorized = false;
+
 	if (ConfMan.hasKey("save_slot")) {
 		int saveSlot = ConfMan.getInt("save_slot");
 		if (saveSlot >= 0 && saveSlot <= 999)
@@ -743,6 +744,8 @@ void EfhEngine::initEngine() {
 		loadGameState(_loadSaveSlot);
 		_loadSaveSlot = -1;
 	}
+
+	_saveAuthorized = true;
 	_engineInitPending = false;
 }
 
@@ -1010,17 +1013,9 @@ void EfhEngine::drawScreen() {
 		if (!_largeMapFlag) {
 			if (_fullPlaceId != 0xFF)
 				displaySmallMap(_mapPosX, _mapPosY);
-
-			// TODO: When refactoring : Always false, to be removed
-			if (_dbgForceDisplayUpperRightBorder)
-				drawUpperRightBorders();
 		} else {
 			if (_techId != 0xFF)
 				displayLargeMap(_mapPosX, _mapPosY);
-
-			// TODO: When refactoring : Always false, to be removed
-			if (_dbgForceDisplayUpperRightBorder)
-				drawUpperRightBorders();
 		}
 		if (counter == 0)
 			displayFctFullScreen();
@@ -1158,6 +1153,7 @@ bool EfhEngine::isCharacterATeamMember(int16 id) {
 
 void EfhEngine::handleWinSequence() {
 	debugC(1, kDebugEngine, "handleWinSequence");
+	_saveAuthorized = false;
 
 	saveAnimImageSetId();
 	findMapFile(18);
@@ -1497,7 +1493,7 @@ int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 }
 
 bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
-	debug("isPosOutOfMap %d %d", mapPosX, mapPosY);
+	debugC(6, kDebugEngine, "isPosOutOfMap %d %d", mapPosX, mapPosY);
 
 	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
@@ -1678,6 +1674,8 @@ void EfhEngine::resetGame() {
 bool EfhEngine::handleDeathMenu() {
 	debug("handleDeathMenu");
 
+	_saveAuthorized = false;
+
 	displayAnimFrames(20, true);
 	_imageSetSubFilesIdx = 213;
 	drawScreen();
@@ -1709,9 +1707,13 @@ bool EfhEngine::handleDeathMenu() {
 		switch (input) {
 		case Common::KEYCODE_l:
 			//loadEfhGame();
-			//TODO : saveEfhGame opens the GUI save/load screen. It shouldn't bepossible to save at this point
+			//TODO:
+			//SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point, which is fine, but it's possible to close the screen without loading.
+			//Maybe adding the _saveAuthorized flag in the savegame would do the trick and could then be used tp keep found at false and loop on the input selection?
+			//like: found = _saveAuthorized
 			saveEfhGame();
 			found = true;
+			_saveAuthorized = true;
 			break;
 		case Common::KEYCODE_q:
 			_shouldQuit = true;
@@ -1721,8 +1723,9 @@ bool EfhEngine::handleDeathMenu() {
 			loadEfhGame();
 			resetGame();
 			found = true;
+			_saveAuthorized = true;
 			break;
-		case Common::KEYCODE_x:
+		case Common::KEYCODE_x: // mysterious and unexpected keycode ?
 			found = true;
 			break;
 		default:
@@ -3414,8 +3417,8 @@ void EfhEngine::displayStatusMenu(int16 windowId) {
 	setTextColorRed();
 }
 
-void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
-	debugC(6, kDebugEngine, "countRightWindowItems %d %d", menuId, charId);
+void EfhEngine::prepareStatusRightWindowIndexes(int16 menuId, int16 charId) {
+	debugC(6, kDebugEngine, "prepareStatusRightWindowIndexes %d %d", menuId, charId);
 
 	int16 maxId = 0;
 	int16 minId;
@@ -3455,21 +3458,21 @@ void EfhEngine::countRightWindowItems(int16 menuId, int16 charId) {
 }
 
 int16 EfhEngine::getXPLevel(int32 xp) {
-	debug("getXPLevel %ld", xp);
+	debugC(6, kDebugEngine, "getXPLevel %ld", xp);
 
 	int16 level = 0;
-	int16 var6 = 1500;
+	int16 nextLevelXP = 1500;
 
 	int32 wrkXp = xp;
 
 	while (wrkXp > 0) {
-		wrkXp -= var6;
+		wrkXp -= nextLevelXP;
 		if (wrkXp >= 0)
 			++level;
 
-		var6 += 1500;
-		if (var6 > 15000)
-			var6 = 15000;
+		nextLevelXP += 1500;
+		if (nextLevelXP > 15000)
+			nextLevelXP = 15000;
 	}
 
 	return level;
@@ -3609,7 +3612,7 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 }
 
 void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
-	debug("displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
+	debugC(6, kDebugEngine, "displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
 
 	drawColoredRect(144, 15, 310, 184, 0);
 	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
@@ -3657,12 +3660,12 @@ void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16
 	}
 }
 
-void EfhEngine::unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
-	debug("unk_StatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
+void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
+	debugC(6, kDebugEngine, "prepareStatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
 
 	displayStatusMenu(windowId);
 
-	countRightWindowItems(menuId, charId);
+	prepareStatusRightWindowIndexes(menuId, charId);
 	displayStatusMenuActions(menuId, curMenuLine, charId);
 
 	if (refreshFl)
@@ -3674,7 +3677,7 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 
 	for (int counter = 0; counter < 2; ++counter) {
 		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
-		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
 
 		if (counter == 0)
 			displayFctFullScreen();
@@ -3687,7 +3690,7 @@ int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId,
 	int16 retVal = 0;
 
 	for (uint counter = 0; counter < 2; ++counter) {
-		unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
 
 		if (counter == 0) {
@@ -4393,7 +4396,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 	for (;;) {
 		if (windowId != -1)
-			unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 		else
 			windowId = 0;
 
@@ -4474,7 +4477,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						_menuDepth = 0;
 						curMenuLine = -1;
 						menuId = 9;
-						unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 					} else {
 						selectedLine = curMenuLine;
 						var10 = true;
@@ -4485,7 +4488,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				_menuDepth = 0;
 				curMenuLine = -1;
 				menuId = 9;
-				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 				break;
 			case Common::KEYCODE_2:
 			case Common::KEYCODE_6:
@@ -4530,9 +4533,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 
 			if (curMenuLine == -1)
-				unk_StatusMenu(windowId, menuId, curMenuLine, charId, false, true);
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, false, true);
 			else
-				unk_StatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
 
 		} while (!var10);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4b02a2841ec..65a04aa60bc 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -279,6 +279,7 @@ private:
 
 	Common::Platform _platform;
 	int _loadSaveSlot;
+	bool _saveAuthorized;
 
 	void initialize();
 	Common::KeyCode playSong(uint8 *buffer);
@@ -376,12 +377,12 @@ private:
 	void sub1D8C2(int16 charId, int16 damage);
 	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
 	void displayStatusMenu(int16 windowId);
-	void countRightWindowItems(int16 menuId, int16 charId);
+	void prepareStatusRightWindowIndexes(int16 menuId, int16 charId);
 	int16 getXPLevel(int32 xp);
 	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
 	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
-	void unk_StatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
+	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
@@ -589,7 +590,6 @@ private:
 	uint16 _tempTextDelay;
 	uint8 *_tempTextPtr;
 	// TODO: Remove those useless debug flags
-	bool _dbgForceDisplayUpperRightBorder; // Original debug flag? Always false.
 	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 
 	bool _ongoingFightFl;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index bdf6962ae1b..55eaf2198aa 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -38,7 +38,7 @@ bool EfhEngine::canLoadGameStateCurrently() {
 }
 
 bool EfhEngine::canSaveGameStateCurrently() {
-	return true;
+	return _saveAuthorized;
 }
 
 Common::Error EfhEngine::loadGameState(int slot) {


Commit: 6e5899047a061f3a11c8892d2a14ca2d1f80cfdd
    https://github.com/scummvm/scummvm/commit/6e5899047a061f3a11c8892d2a14ca2d1f80cfdd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Move several functions from EFH to Menu and Fight

Changed paths:
  A engines/efh/menu.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/module.mk


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index fd601d708e1..278859bcd3a 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1407,74 +1407,6 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl) {
-	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, displayOption, displayTeamWindowFl ? "True" : "False");
-
-	int16 varA = 0xFF;
-	int16 minX, maxX, minY, maxY;
-
-	switch (menuType) {
-	case 0:
-		minX = 129;
-		minY = 9;
-		maxX = 302;
-		maxY = 18;
-		break;
-	case 1:
-		minX = 129;
-		minY = 9;
-		maxX = 302;
-		maxY = 110;
-		break;
-	case 2:
-		minX = 129;
-		minY = 112;
-		maxX = 302;
-		maxY = 132;
-		break;
-	case 3:
-		minX = 129;
-		minY = 79;
-		maxX = 303;
-		maxY = 107;
-		break;
-	default:
-		minX = minY = 0;
-		maxX = 320;
-		maxY = 200;
-		break;
-	}
-
-	drawColoredRect(minX, minY, maxX, maxY, 0);
-	if (str.size())
-		varA = script_parse(str, minX, minY, maxX, maxY, true);
-
-	if (displayTeamWindowFl)
-		displayLowStatusScreen(false);
-
-	if (displayOption != 0) {
-		displayFctFullScreen();
-		if (_word2C87A)
-			_word2C87A = false;
-		else {
-			drawColoredRect(minX, minY, maxX, maxY, 0);
-			if (str.size())
-				script_parse(str, minX, minY, maxX, maxY, false);
-		}
-
-		if (displayTeamWindowFl)
-			displayLowStatusScreen(false);
-
-		if (displayOption >= 2)
-			getLastCharAfterAnimCount(_guessAnimationAmount);
-
-		if (displayOption == 3)
-			drawColoredRect(minX, minY, maxX, maxY, 0);
-	}
-
-	return varA;
-}
-
 int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
 	debug("sub151FD %d %d", posX, posY);
 
@@ -1671,72 +1603,6 @@ void EfhEngine::resetGame() {
 	_unkArray2C8AA[0] = 0;
 }
 
-bool EfhEngine::handleDeathMenu() {
-	debug("handleDeathMenu");
-
-	_saveAuthorized = false;
-
-	displayAnimFrames(20, true);
-	_imageSetSubFilesIdx = 213;
-	drawScreen();
-
-	for (uint counter = 0; counter < 2; ++counter) {
-		clearBottomTextZone(0);
-		displayCenteredString("Darkness Prevails...Death Has Taken You!", 24, 296, 153);
-		setTextPos(100, 162);
-		setTextColorWhite();
-		displayCharAtTextPos('L');
-		setTextColorRed();
-		displayStringAtTextPos("oad last saved game");
-		setTextPos(100, 171);
-		setTextColorWhite();
-		displayCharAtTextPos('R');
-		setTextColorRed();
-		displayStringAtTextPos("estart from beginning");
-		setTextPos(100, 180);
-		setTextColorWhite();
-		displayCharAtTextPos('Q');
-		setTextColorRed();
-		displayStringAtTextPos("uit for now");
-		if (counter == 0)
-			displayFctFullScreen();
-	}
-
-	for (bool found = false; !found;) {
-		Common::KeyCode input = waitForKey();
-		switch (input) {
-		case Common::KEYCODE_l:
-			//loadEfhGame();
-			//TODO:
-			//SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point, which is fine, but it's possible to close the screen without loading.
-			//Maybe adding the _saveAuthorized flag in the savegame would do the trick and could then be used tp keep found at false and loop on the input selection?
-			//like: found = _saveAuthorized
-			saveEfhGame();
-			found = true;
-			_saveAuthorized = true;
-			break;
-		case Common::KEYCODE_q:
-			_shouldQuit = true;
-			return true;
-			break;
-		case Common::KEYCODE_r:
-			loadEfhGame();
-			resetGame();
-			found = true;
-			_saveAuthorized = true;
-			break;
-		case Common::KEYCODE_x: // mysterious and unexpected keycode ?
-			found = true;
-			break;
-		default:
-			break;
-		}
-	}
-
-	displayAnimFrames(0xFE, true);
-	return false;
-}
-
 void EfhEngine::computeMapAnimation() {
 	debugC(6, kDebugEngine, "computeMapAnimation");
 
@@ -2888,444 +2754,6 @@ int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	return result;
 }
 
-void EfhEngine::sub1C4CA(bool whiteFl) {
-	debug("sub1C4CA %s", whiteFl ? "True" : "False");
-
-	int16 textPosY = 20;
-	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == -1)
-			continue;
-
-		int16 var6C = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
-		int16 var6E = countMonsterGroupMembers(counter);
-		if (whiteFl)
-			setTextColorWhite();
-		else
-			setTextColorGrey();
-
-		setTextPos(129, textPosY);
-		char buffer[80];
-		snprintf(buffer, 80, "%c)", 'A' + counter);
-		displayStringAtTextPos(buffer);
-		setTextColorRed();
-		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
-		if (var1 <= 0x3D) {
-			snprintf(buffer, 80, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
-			displayStringAtTextPos(buffer);
-			if (var6E > 1)
-				displayStringAtTextPos("s");
-		} else if (var1 == 0x3E) {
-			displayStringAtTextPos("(NOT DEFINED)");
-		} else if (var1 == 0x3F) {
-			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name;
-			displayStringAtTextPos(stringToDisplay);
-		}
-
-		setTextPos(228, textPosY);
-		if (unkFct_checkMonsterField8(counter, true)) {
-			_textColor = 0xE;
-			displayStringAtTextPos("Hostile");
-		} else {
-			_textColor = 0x2;
-			displayStringAtTextPos("Friendly");
-		}
-
-		setTextColorRed();
-		switch (var6C) {
-		case 1:
-			displayCenteredString("S", 290, 302, textPosY);
-			break;
-		case 2:
-			displayCenteredString("M", 290, 302, textPosY);
-			break;
-		case 3:
-			displayCenteredString("L", 290, 302, textPosY);
-			break;
-		default:
-			displayCenteredString("?", 290, 302, textPosY);
-			break;
-		}
-
-		textPosY += 9;
-	}
-}
-
-void EfhEngine::displayCombatMenu(int16 charId) {
-	debug("displayCombatMenu %d", charId);
-
-	Common::String buffer = _npcBuf[charId]._name;
-	buffer += ":";
-	setTextColorWhite();
-	setTextPos(144, 7);
-	displayStringAtTextPos(buffer);
-	setTextPos(152, 79);
-	displayStringAtTextPos("A");
-	setTextColorRed();
-	displayStringAtTextPos("ttack");
-	setTextPos(195, 79);
-	setTextColorWhite();
-	displayStringAtTextPos("H");
-	setTextColorRed();
-	displayStringAtTextPos("ide");
-	setTextPos(152, 88);
-	setTextColorWhite();
-	displayStringAtTextPos("D");
-	setTextColorRed();
-	displayStringAtTextPos("efend");
-	setTextPos(195, 88);
-	setTextColorWhite();
-	displayStringAtTextPos("R");
-	setTextColorRed();
-	displayStringAtTextPos("un");
-	setTextPos(152, 97);
-	setTextColorWhite();
-	displayStringAtTextPos("S");
-	setTextColorRed();
-	displayStringAtTextPos("tatus");
-}
-
-void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
-	debug("drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", forceDrawFl ? "True" : "False");
-
-	for (uint counter = 0; counter < 2; ++counter) {
-		if (counter == 0 || forceDrawFl) {
-			drawMapWindow();
-			displayCenteredString("Combat", 128, 303, 9);
-			drawColoredRect(200, 112, 278, 132, 0);
-			displayCenteredString("'T' for Terrain", 128, 303, 117);
-			sub1C219("", 1, 0, false);
-			sub1C4CA(whiteFl);
-			displayCombatMenu(charId);
-			displayLowStatusScreen(false);
-		}
-
-		if (counter == 0 && forceDrawFl)
-			displayFctFullScreen();
-	}
-}
-
-int16 EfhEngine::sub1DEC8(int16 groupNumber) {
-	debug("sub1DEC8 %d", groupNumber);
-
-	int16 var4 = -1;
-	int16 monsterId = _teamMonsterIdArray[groupNumber];
-
-	if (monsterId == -1)
-		return -1;
-
-	for (uint counter = 0; counter < 9; ++counter) {
-		if (isMonsterActive(groupNumber, counter)) {
-			var4 = counter;
-			break;
-		}
-	}
-
-	for (int16 counter = var4 + 1; counter < 9; ++counter) {
-		if (!isMonsterActive(groupNumber, counter))
-			continue;
-
-		if (_mapMonsters[monsterId]._pictureRef[var4] > _mapMonsters[monsterId]._pictureRef[counter])
-			var4 = counter;
-	}
-
-	if (_mapMonsters[monsterId]._pictureRef[var4] <= 0)
-		return -1;
-
-	return var4;
-}
-
-int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
-	debug("getCharacterScore %d %d", charId, itemId);
-
-	int16 totalScore = 0;
-	switch (_items[itemId]._range) {
-	case 0:
-		totalScore = _npcBuf[charId]._passiveScore[5] + _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
-		totalScore += _npcBuf[charId]._infoScore[0] / 5;
-		totalScore += _npcBuf[charId]._infoScore[2] * 2,
-		totalScore += _npcBuf[charId]._infoScore[6] / 5;
-		totalScore += 2 * _npcBuf[charId]._infoScore[5] / 5;
-		break;
-	case 1:
-		totalScore = _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
-		totalScore += _npcBuf[charId]._infoScore[2] * 2;
-		totalScore += _npcBuf[charId]._infoScore[1] / 5;
-		totalScore += _npcBuf[charId]._infoScore[3] / 5;
-		break;
-	case 2:
-	case 3:
-	case 4:
-		totalScore = _npcBuf[charId]._passiveScore[1];
-		totalScore += _npcBuf[charId]._infoScore[2] * 2;
-		totalScore += _npcBuf[charId]._infoScore[1] / 5;
-		totalScore += _npcBuf[charId]._infoScore[3] / 5;
-		totalScore += _npcBuf[charId]._infoScore[8] / 5;
-	default:
-		break;
-	}
-
-	int16 extraScore = 0;
-	switch (_items[itemId]._attackType) {
-	case 0:
-	case 1:
-	case 2:
-		if (itemId == 0x3F)
-			extraScore = _npcBuf[charId]._passiveScore[2];
-		else if (itemId == 0x41 || itemId == 0x42 || itemId == 0x6A || itemId == 0x6C || itemId == 0x6D)
-			extraScore = _npcBuf[charId]._passiveScore[0];
-		break;
-	case 3:
-	case 4:
-	case 6:
-		extraScore = _npcBuf[charId]._infoScore[7];
-		break;
-	case 5:
-	case 7:
-		extraScore = _npcBuf[charId]._infoScore[9];
-		break;
-	case 8:
-	case 9:
-		extraScore = _npcBuf[charId]._activeScore[12];
-		break;
-	case 10:
-		extraScore = _npcBuf[charId]._passiveScore[10];
-		break;
-	case 11:
-		extraScore = _npcBuf[charId]._passiveScore[6];
-		break;
-	case 12:
-		extraScore = _npcBuf[charId]._passiveScore[7];
-		break;
-	case 13:
-		extraScore = _npcBuf[charId]._passiveScore[8];
-		break;
-	case 14:
-		extraScore = _npcBuf[charId]._activeScore[13];
-		break;
-	case 15:
-		extraScore = _npcBuf[charId]._passiveScore[9];
-		break;
-	default:
-		break;
-	}
-
-	extraScore += _items[itemId].field_13;
-
-	int16 grandTotalScore = totalScore + extraScore;
-	if (grandTotalScore > 60)
-		grandTotalScore = 60;
-
-	int16 retVal = CLIP(grandTotalScore + 30, 5, 90);
-	return retVal;
-}
-
-bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
-	debug("checkSpecialItemsOnCurrentPlace %d", itemId);
-
-	switch(_techDataArr[_techId][_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
-	case 1:
-		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
-			return true;
-		return false;
-	case 2:
-		if ((itemId < 0x61 || itemId > 0x63) && (itemId < 0x74 || itemId > 0x76) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x5B || itemId > 0x5E) && (itemId < 0x66 || itemId > 0x68) && (itemId != 0x8C))
-			return true;
-		return false;
-	default:
-		return true;
-	}
-}
-
-bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
-	debug("hasAdequateDefense %d %d", monsterId, attackType);
-
-	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
-
-	if (_items[itemId].field_16 != 0)
-		return false;
-
-	return _items[itemId].field17_attackTypeDefense == attackType;
-}
-
-bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
-	debug("hasAdequateDefense_2 %d %d", charId, attackType);
-
-	int16 itemId = _npcBuf[charId]._unkItemId;
-
-	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
-		return true;
-
-	for (uint counter = 0; counter < 10; ++counter) {
-		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || _npcBuf[charId]._inventory[counter]._stat1 == 0x80)
-			continue;
-
-		itemId = _npcBuf[charId]._inventory[counter]._ref;
-		if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
-			return true;
-	}
-	return false;
-}
-
-bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
-	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
-
-	int16 rndVal = getRandom(100);
-	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
-		return false;
-
-	rndVal = getRandom(5) - 1;
-	int16 itemId = kEncounters[_mapMonsters[monsterId]._monsterRef]._dropItemId[rndVal];
-	if (itemId == -1)
-		return false;
-
-	if (!giveItemTo(charId, itemId, 0xFF))
-		return false;
-
-	_messageToBePrinted += Common::String::format(" and finds a %s!", _items[itemId]._name);
-	return true;
-}
-
-void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
-	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
-
-	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
-	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
-
-	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
-		generateSound(15);
-		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
-		_npcBuf[charId]._hitPoints += var2;
-		_npcBuf[charId]._maxHP += var2;
-		_npcBuf[charId]._infoScore[0] += getRandom(3) - 1;
-		_npcBuf[charId]._infoScore[1] += getRandom(3) - 1;
-		_npcBuf[charId]._infoScore[2] += getRandom(3) - 1;
-		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
-		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
-	}
-
-	_messageToBePrinted += Common::String::format("  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
-	if (!characterSearchesMonsterCorpse(charId, monsterId))
-		_messageToBePrinted += "!";
-
-}
-
-void EfhEngine::addReactionText(int16 id) {
-	debug("addReactionText %d", id);
-
-	int16 rand3 = getRandom(3);
-
-	switch (id) {
-	case 0:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s sways from the attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s looks dazed!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 1:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s screams from the abuse!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s wails terribly!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 2:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s falters for a moment!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s is stumbling about!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 3:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s cringes from the damage!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s shrinks from the wound!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 4:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s bellows!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s shrills!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 5:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s seems amused!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s looks concerned!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	case 6:
-		switch (rand3) {
-		case 1:
-			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 2:
-			_messageToBePrinted += Common::String::format("  %s%s smiles at the pathetic attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		case 3:
-			_messageToBePrinted += Common::String::format("  %s%s laughs at the ineffective assault!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-			break;
-		default:
-			break;
-		}
-		break;
-	default:
-		break;
-	}
-
-}
-
 void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	debug("sub1D8C2 %d %d", charId, damage);
 
@@ -3372,90 +2800,6 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	}
 }
 
-void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
-	debugC(6, kDebugEngine, "displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
-
-	if (menuBoxId == thisBoxId) {
-		if (_menuDepth == 0)
-			setTextColorWhite();
-		else
-			setTextColorGrey();
-
-		Common::String buffer = Common::String::format("> %s <", str);
-		displayCenteredString(buffer, minX, maxX, minY);
-		setTextColorRed();
-	} else {
-		if (_menuDepth == 0)
-			setTextColorRed();
-		else
-			setTextColorGrey();
-
-		displayCenteredString(str, minX, maxX, minY);
-	}
-}
-
-void EfhEngine::displayStatusMenu(int16 windowId) {
-	debugC(3, kDebugEngine, "displayStatusMenu %d", windowId);
-
-	for (uint counter = 0; counter < 9; ++counter) {
-		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
-	}
-
-	if (_menuDepth != 0)
-		setTextColorGrey();
-
-	displayMenuItemString(windowId, 0, 80, 134, 39, "EQUIP");
-	displayMenuItemString(windowId, 1, 80, 134, 53, "USE");
-	displayMenuItemString(windowId, 2, 80, 134, 67, "GIVE");
-	displayMenuItemString(windowId, 3, 80, 134, 81, "TRADE");
-	displayMenuItemString(windowId, 4, 80, 134, 95, "DROP");
-	displayMenuItemString(windowId, 5, 80, 134, 109, "INFO.");
-	displayMenuItemString(windowId, 6, 80, 134, 123, "PASSIVE");
-	displayMenuItemString(windowId, 7, 80, 134, 137, "ACTIVE");
-	displayMenuItemString(windowId, 8, 80, 134, 151, "LEAVE");
-
-	setTextColorRed();
-}
-
-void EfhEngine::prepareStatusRightWindowIndexes(int16 menuId, int16 charId) {
-	debugC(6, kDebugEngine, "prepareStatusRightWindowIndexes %d %d", menuId, charId);
-
-	int16 maxId = 0;
-	int16 minId;
-	_menuItemCounter = 0;
-
-	switch (menuId) {
-	case 5:
-		minId = 26;
-		maxId = 36;
-		break;
-	case 6:
-		minId = 15;
-		maxId = 25;
-		break;
-	case 7:
-		minId = 0;
-		maxId = 14;
-		break;
-	default:
-		minId = -1;
-		break;
-	}
-
-	if (minId == -1) {
-		for (uint counter = 0; counter < 10; ++counter) {
-			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
-				_menuStatItemArr[_menuItemCounter++] = counter;
-			}
-		}
-	} else {
-		for (int16 counter = minId; counter < maxId; ++counter) {
-			if (_npcBuf[charId]._activeScore[counter] != 0) {
-				_menuStatItemArr[_menuItemCounter++] = counter;
-			}
-		}
-	}
-}
 
 int16 EfhEngine::getXPLevel(int32 xp) {
 	debugC(6, kDebugEngine, "getXPLevel %ld", xp);
@@ -3478,212 +2822,6 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 	return level;
 }
 
-void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
-	debugC(3, kDebugEngine, "displayCharacterSummary %d %d", curMenuLine, npcId);
-
-	setTextColorRed();
-	Common::String buffer1 = _npcBuf[npcId]._name;
-	setTextPos(146, 27);
-	displayStringAtTextPos("Name: ");
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Level: %d", getXPLevel(_npcBuf[npcId]._xp));
-	setTextPos(146, 36);
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("XP: %lu", _npcBuf[npcId]._xp);
-	setTextPos(227, 36);
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Speed: %d", _npcBuf[npcId]._speed);
-	setTextPos(146, 45);
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Defense: %d", getEquipmentDefense(npcId, false));
-	setTextPos(146, 54);
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Hit Points: %d", _npcBuf[npcId]._hitPoints);
-	setTextPos(146, 63);
-	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Max HP: %d", _npcBuf[npcId]._maxHP);
-	setTextPos(227, 63);
-	displayStringAtTextPos(buffer1);
-	displayCenteredString("Inventory", 144, 310, 72);
-
-	if (_menuItemCounter == 0) {
-		if (curMenuLine != -1)
-			setTextColorWhite();
-
-		displayCenteredString("Nothing Carried", 144, 310, 117);
-		setTextColorRed();
-		return;
-	}
-
-	for (int counter = 0; counter < _menuItemCounter; ++counter) {
-		if (_menuDepth == 0)
-			setTextColorGrey();
-		else {
-			if (counter == curMenuLine)
-				setTextColorWhite();
-		}
-		int16 textPosY = 81 + counter * 9;
-		int16 itemId = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref;
-		if (itemId != 0x7FFF) {
-			if (_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1 & 0x80) {
-				setTextPos(146, textPosY);
-				displayCharAtTextPos('E');
-			}
-		}
-
-		setTextPos(152, textPosY);
-		if (counter == curMenuLine) {
-			buffer1 = Common::String::format("%c>", 'A' + counter);
-		} else {
-			buffer1 = Common::String::format("%c)", 'A' + counter);
-		}
-		displayStringAtTextPos(buffer1);
-
-		if (itemId != 0x7FFF) {
-			setTextPos(168, textPosY);
-			buffer1 = Common::String::format("  %s", _items[itemId]._name);
-			displayStringAtTextPos(buffer1);
-			setTextPos(262, textPosY);
-
-			if (_items[itemId]._defense > 0) {
-				int16 stat2 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat2;
-				if (stat2 != 0xFF) {
-					buffer1 = Common::String::format("%d", 1 + stat2 / 8);
-					displayStringAtTextPos(buffer1);
-					setTextPos(286, textPosY);
-					displayStringAtTextPos("Def");
-				}
-				// useless code removed.
-				// else {
-				//	var54 = _items[_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref]._defense;
-				// {
-			} else if (_items[itemId]._uses != 0x7F) {
-				int16 stat1 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1;
-				if (stat1 != 0x7F) {
-					buffer1 = Common::String::format("%d", stat1);
-					displayStringAtTextPos(buffer1);
-					setTextPos(286, textPosY);
-					if (stat1 == 1)
-						displayStringAtTextPos("Use");
-					else
-						displayStringAtTextPos("Uses");
-				}
-			}
-		}
-		setTextColorRed();
-	}
-}
-
-void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
-	debugC(3, kDebugEngine, "displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
-
-	setTextColorRed();
-	Common::String buffer = _npcBuf[charId]._name;
-	setTextPos(146, 27);
-	displayStringAtTextPos("Name: ");
-	displayStringAtTextPos(buffer);
-	if (_menuItemCounter <= 0) {
-		if (curMenuLine != -1)
-			setTextColorWhite();
-		displayCenteredString("No Skills To Select", 144, 310, 96);
-		setTextColorRed();
-		return;
-	}
-
-	for (int counter = 0; counter < _menuItemCounter; ++counter) {
-		if (counter == curMenuLine)
-			setTextColorWhite();
-		int16 textPosY = 38 + counter * 9;
-		setTextPos(146, textPosY);
-		if (counter == curMenuLine) {
-			buffer = Common::String::format("%c>", 'A' + counter);
-		} else {
-			buffer = Common::String::format("%c)", 'A' + counter);
-		}
-
-		displayStringAtTextPos(buffer);
-		setTextPos(163, textPosY);
-		displayStringAtTextPos(kSkillArray[_menuStatItemArr[counter]]);
-		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_menuStatItemArr[counter]]);
-		setTextPos(278, textPosY);
-		displayStringAtTextPos(buffer);
-		setTextColorRed();
-	}
-}
-
-void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
-	debugC(6, kDebugEngine, "displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
-
-	drawColoredRect(144, 15, 310, 184, 0);
-	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
-	_textColor = 0x0E;
-	switch (menuId) {
-	case 0:
-		displayCenteredString("Select Item to Equip", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	case 1:
-		displayCenteredString("Select Item to Use", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	case 2:
-		displayCenteredString("Select Item to Give", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	case 3:
-		displayCenteredString("Select Item to Trade", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	case 4:
-		displayCenteredString("Select Item to Drop", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	case 5:
-		displayCenteredString("Character Information", 144, 310, 15);
-		displayCharacterInformationOrSkills(curMenuLine, npcId);
-		break;
-	case 6:
-		displayCenteredString("Passive Skills", 144, 310, 15);
-		displayCharacterInformationOrSkills(curMenuLine, npcId);
-		break;
-	case 7:
-		displayCenteredString("Active Skills", 144, 310, 15);
-		displayCharacterInformationOrSkills(curMenuLine, npcId);
-		break;
-	case 8:
-	case 9:
-		displayCenteredString("Character Summary", 144, 310, 15);
-		displayCharacterSummary(curMenuLine, npcId);
-		break;
-	default:
-		break;
-	}
-}
-
-void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
-	debugC(6, kDebugEngine, "prepareStatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
-
-	displayStatusMenu(windowId);
-
-	prepareStatusRightWindowIndexes(menuId, charId);
-	displayStatusMenuActions(menuId, curMenuLine, charId);
-
-	if (refreshFl)
-		displayFctFullScreen();
-}
-
-void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("sub18E80 %d %d %d %d", charId, windowId, menuId, curMenuLine);
-
-	for (int counter = 0; counter < 2; ++counter) {
-		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
-		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
-
-		if (counter == 0)
-			displayFctFullScreen();
-	}
-}
-
 int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
 	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 65a04aa60bc..34c9da9af2d 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -319,7 +319,6 @@ private:
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void sub15A28(int16 arg0, int16 arg2);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl);
 	int16 sub151FD(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
@@ -332,7 +331,6 @@ private:
 	void goSouthWest();
 	void handleNewRoundEffects();
 	void resetGame();
-	bool handleDeathMenu();
 	void computeMapAnimation();
 	void handleAnimations();
 	int8 sub16B08(int16 monsterId);
@@ -363,27 +361,8 @@ private:
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
-	void sub1C4CA(bool WhiteFl);
-	void displayCombatMenu(int16 charId);
-	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
-	int16 sub1DEC8(int16 groupNumber);
-	int16 getCharacterScore(int16 charId, int16 itemId);
-	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
-	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
-	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
-	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
-	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
-	void addReactionText(int16 id);
 	void sub1D8C2(int16 charId, int16 damage);
-	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
-	void displayStatusMenu(int16 windowId);
-	void prepareStatusRightWindowIndexes(int16 menuId, int16 charId);
 	int16 getXPLevel(int32 xp);
-	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
-	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
-	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
-	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
-	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
@@ -415,6 +394,16 @@ private:
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
 	bool sub1CB27();
+	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
+	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
+	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
+	void addReactionText(int16 id);
+	void sub1C4CA(bool WhiteFl);
+	int16 sub1DEC8(int16 groupNumber);
+	int16 getCharacterScore(int16 charId, int16 itemId);
+	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
+	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
+	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
@@ -466,6 +455,19 @@ private:
 	void displayWindow(uint8 *buffer, int16 posX, int16 posY, uint8 *dest);
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 
+	// Menu
+	int16 sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl);
+	bool handleDeathMenu();
+	void displayCombatMenu(int16 charId);
+	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
+	void displayStatusMenu(int16 windowId);
+	void prepareStatusRightWindowIndexes(int16 menuId, int16 charId);
+	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
+	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
+	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
+	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
+	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+
 	// Savegames
 	void synchronize(Common::Serializer &s);
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 3ca3c8e41f8..30e4f99eb6f 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1139,4 +1139,406 @@ bool EfhEngine::sub1CB27() {
 	return var4;
 }
 
+void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
+	debug("drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", forceDrawFl ? "True" : "False");
+
+	for (uint counter = 0; counter < 2; ++counter) {
+		if (counter == 0 || forceDrawFl) {
+			drawMapWindow();
+			displayCenteredString("Combat", 128, 303, 9);
+			drawColoredRect(200, 112, 278, 132, 0);
+			displayCenteredString("'T' for Terrain", 128, 303, 117);
+			sub1C219("", 1, 0, false);
+			sub1C4CA(whiteFl);
+			displayCombatMenu(charId);
+			displayLowStatusScreen(false);
+		}
+
+		if (counter == 0 && forceDrawFl)
+			displayFctFullScreen();
+	}
+}
+
+void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
+	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
+
+	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
+	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
+
+	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
+		generateSound(15);
+		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
+		_npcBuf[charId]._hitPoints += var2;
+		_npcBuf[charId]._maxHP += var2;
+		_npcBuf[charId]._infoScore[0] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[1] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[2] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
+		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
+	}
+
+	_messageToBePrinted += Common::String::format("  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
+	if (!characterSearchesMonsterCorpse(charId, monsterId))
+		_messageToBePrinted += "!";
+}
+
+bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
+	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
+
+	int16 rndVal = getRandom(100);
+	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
+		return false;
+
+	rndVal = getRandom(5) - 1;
+	int16 itemId = kEncounters[_mapMonsters[monsterId]._monsterRef]._dropItemId[rndVal];
+	if (itemId == -1)
+		return false;
+
+	if (!giveItemTo(charId, itemId, 0xFF))
+		return false;
+
+	_messageToBePrinted += Common::String::format(" and finds a %s!", _items[itemId]._name);
+	return true;
+}
+
+void EfhEngine::addReactionText(int16 id) {
+	debug("addReactionText %d", id);
+
+	int16 rand3 = getRandom(3);
+
+	switch (id) {
+	case 0:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s sways from the attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s looks dazed!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 1:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s screams from the abuse!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s wails terribly!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 2:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s falters for a moment!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s is stumbling about!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 3:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s cringes from the damage!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s shrinks from the wound!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 4:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s bellows!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s shrills!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 5:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s seems amused!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s looks concerned!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	case 6:
+		switch (rand3) {
+		case 1:
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 2:
+			_messageToBePrinted += Common::String::format("  %s%s smiles at the pathetic attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		case 3:
+			_messageToBePrinted += Common::String::format("  %s%s laughs at the ineffective assault!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+			break;
+		default:
+			break;
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+void EfhEngine::sub1C4CA(bool whiteFl) {
+	debug("sub1C4CA %s", whiteFl ? "True" : "False");
+
+	int16 textPosY = 20;
+	for (uint counter = 0; counter < 5; ++counter) {
+		if (_teamMonsterIdArray[counter] == -1)
+			continue;
+
+		int16 var6C = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
+		int16 var6E = countMonsterGroupMembers(counter);
+		if (whiteFl)
+			setTextColorWhite();
+		else
+			setTextColorGrey();
+
+		setTextPos(129, textPosY);
+		char buffer[80];
+		snprintf(buffer, 80, "%c)", 'A' + counter);
+		displayStringAtTextPos(buffer);
+		setTextColorRed();
+		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
+		if (var1 <= 0x3D) {
+			snprintf(buffer, 80, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
+			displayStringAtTextPos(buffer);
+			if (var6E > 1)
+				displayStringAtTextPos("s");
+		} else if (var1 == 0x3E) {
+			displayStringAtTextPos("(NOT DEFINED)");
+		} else if (var1 == 0x3F) {
+			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name;
+			displayStringAtTextPos(stringToDisplay);
+		}
+
+		setTextPos(228, textPosY);
+		if (unkFct_checkMonsterField8(counter, true)) {
+			_textColor = 0xE;
+			displayStringAtTextPos("Hostile");
+		} else {
+			_textColor = 0x2;
+			displayStringAtTextPos("Friendly");
+		}
+
+		setTextColorRed();
+		switch (var6C) {
+		case 1:
+			displayCenteredString("S", 290, 302, textPosY);
+			break;
+		case 2:
+			displayCenteredString("M", 290, 302, textPosY);
+			break;
+		case 3:
+			displayCenteredString("L", 290, 302, textPosY);
+			break;
+		default:
+			displayCenteredString("?", 290, 302, textPosY);
+			break;
+		}
+
+		textPosY += 9;
+	}
+}
+
+int16 EfhEngine::sub1DEC8(int16 groupNumber) {
+	debug("sub1DEC8 %d", groupNumber);
+
+	int16 var4 = -1;
+	int16 monsterId = _teamMonsterIdArray[groupNumber];
+
+	if (monsterId == -1)
+		return -1;
+
+	for (uint counter = 0; counter < 9; ++counter) {
+		if (isMonsterActive(groupNumber, counter)) {
+			var4 = counter;
+			break;
+		}
+	}
+
+	for (int16 counter = var4 + 1; counter < 9; ++counter) {
+		if (!isMonsterActive(groupNumber, counter))
+			continue;
+
+		if (_mapMonsters[monsterId]._pictureRef[var4] > _mapMonsters[monsterId]._pictureRef[counter])
+			var4 = counter;
+	}
+
+	if (_mapMonsters[monsterId]._pictureRef[var4] <= 0)
+		return -1;
+
+	return var4;
+}
+
+int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
+	debug("getCharacterScore %d %d", charId, itemId);
+
+	int16 totalScore = 0;
+	switch (_items[itemId]._range) {
+	case 0:
+		totalScore = _npcBuf[charId]._passiveScore[5] + _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
+		totalScore += _npcBuf[charId]._infoScore[0] / 5;
+		totalScore += _npcBuf[charId]._infoScore[2] * 2,
+			totalScore += _npcBuf[charId]._infoScore[6] / 5;
+		totalScore += 2 * _npcBuf[charId]._infoScore[5] / 5;
+		break;
+	case 1:
+		totalScore = _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
+		totalScore += _npcBuf[charId]._infoScore[2] * 2;
+		totalScore += _npcBuf[charId]._infoScore[1] / 5;
+		totalScore += _npcBuf[charId]._infoScore[3] / 5;
+		break;
+	case 2:
+	case 3:
+	case 4:
+		totalScore = _npcBuf[charId]._passiveScore[1];
+		totalScore += _npcBuf[charId]._infoScore[2] * 2;
+		totalScore += _npcBuf[charId]._infoScore[1] / 5;
+		totalScore += _npcBuf[charId]._infoScore[3] / 5;
+		totalScore += _npcBuf[charId]._infoScore[8] / 5;
+	default:
+		break;
+	}
+
+	int16 extraScore = 0;
+	switch (_items[itemId]._attackType) {
+	case 0:
+	case 1:
+	case 2:
+		if (itemId == 0x3F)
+			extraScore = _npcBuf[charId]._passiveScore[2];
+		else if (itemId == 0x41 || itemId == 0x42 || itemId == 0x6A || itemId == 0x6C || itemId == 0x6D)
+			extraScore = _npcBuf[charId]._passiveScore[0];
+		break;
+	case 3:
+	case 4:
+	case 6:
+		extraScore = _npcBuf[charId]._infoScore[7];
+		break;
+	case 5:
+	case 7:
+		extraScore = _npcBuf[charId]._infoScore[9];
+		break;
+	case 8:
+	case 9:
+		extraScore = _npcBuf[charId]._activeScore[12];
+		break;
+	case 10:
+		extraScore = _npcBuf[charId]._passiveScore[10];
+		break;
+	case 11:
+		extraScore = _npcBuf[charId]._passiveScore[6];
+		break;
+	case 12:
+		extraScore = _npcBuf[charId]._passiveScore[7];
+		break;
+	case 13:
+		extraScore = _npcBuf[charId]._passiveScore[8];
+		break;
+	case 14:
+		extraScore = _npcBuf[charId]._activeScore[13];
+		break;
+	case 15:
+		extraScore = _npcBuf[charId]._passiveScore[9];
+		break;
+	default:
+		break;
+	}
+
+	extraScore += _items[itemId].field_13;
+
+	int16 grandTotalScore = totalScore + extraScore;
+	if (grandTotalScore > 60)
+		grandTotalScore = 60;
+
+	int16 retVal = CLIP(grandTotalScore + 30, 5, 90);
+	return retVal;
+}
+
+bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
+	debug("checkSpecialItemsOnCurrentPlace %d", itemId);
+
+	switch (_techDataArr[_techId][_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
+	case 1:
+		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
+			return true;
+		return false;
+	case 2:
+		if ((itemId < 0x61 || itemId > 0x63) && (itemId < 0x74 || itemId > 0x76) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x5B || itemId > 0x5E) && (itemId < 0x66 || itemId > 0x68) && (itemId != 0x8C))
+			return true;
+		return false;
+	default:
+		return true;
+	}
+}
+
+bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
+	debug("hasAdequateDefense %d %d", monsterId, attackType);
+
+	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
+
+	if (_items[itemId].field_16 != 0)
+		return false;
+
+	return _items[itemId].field17_attackTypeDefense == attackType;
+}
+
+bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
+	debug("hasAdequateDefense_2 %d %d", charId, attackType);
+
+	int16 itemId = _npcBuf[charId]._unkItemId;
+
+	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+		return true;
+
+	for (uint counter = 0; counter < 10; ++counter) {
+		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || _npcBuf[charId]._inventory[counter]._stat1 == 0x80)
+			continue;
+
+		itemId = _npcBuf[charId]._inventory[counter]._ref;
+		if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+			return true;
+	}
+	return false;
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
new file mode 100644
index 00000000000..9fea7b774a5
--- /dev/null
+++ b/engines/efh/menu.cpp
@@ -0,0 +1,486 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "efh/efh.h"
+
+namespace Efh {
+
+int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl) {
+	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, displayOption, displayTeamWindowFl ? "True" : "False");
+
+	int16 varA = 0xFF;
+	int16 minX, maxX, minY, maxY;
+
+	switch (menuType) {
+	case 0:
+		minX = 129;
+		minY = 9;
+		maxX = 302;
+		maxY = 18;
+		break;
+	case 1:
+		minX = 129;
+		minY = 9;
+		maxX = 302;
+		maxY = 110;
+		break;
+	case 2:
+		minX = 129;
+		minY = 112;
+		maxX = 302;
+		maxY = 132;
+		break;
+	case 3:
+		minX = 129;
+		minY = 79;
+		maxX = 303;
+		maxY = 107;
+		break;
+	default:
+		minX = minY = 0;
+		maxX = 320;
+		maxY = 200;
+		break;
+	}
+
+	drawColoredRect(minX, minY, maxX, maxY, 0);
+	if (str.size())
+		varA = script_parse(str, minX, minY, maxX, maxY, true);
+
+	if (displayTeamWindowFl)
+		displayLowStatusScreen(false);
+
+	if (displayOption != 0) {
+		displayFctFullScreen();
+		if (_word2C87A)
+			_word2C87A = false;
+		else {
+			drawColoredRect(minX, minY, maxX, maxY, 0);
+			if (str.size())
+				script_parse(str, minX, minY, maxX, maxY, false);
+		}
+
+		if (displayTeamWindowFl)
+			displayLowStatusScreen(false);
+
+		if (displayOption >= 2)
+			getLastCharAfterAnimCount(_guessAnimationAmount);
+
+		if (displayOption == 3)
+			drawColoredRect(minX, minY, maxX, maxY, 0);
+	}
+
+	return varA;
+}
+
+bool EfhEngine::handleDeathMenu() {
+	debug("handleDeathMenu");
+
+	_saveAuthorized = false;
+
+	displayAnimFrames(20, true);
+	_imageSetSubFilesIdx = 213;
+	drawScreen();
+
+	for (uint counter = 0; counter < 2; ++counter) {
+		clearBottomTextZone(0);
+		displayCenteredString("Darkness Prevails...Death Has Taken You!", 24, 296, 153);
+		setTextPos(100, 162);
+		setTextColorWhite();
+		displayCharAtTextPos('L');
+		setTextColorRed();
+		displayStringAtTextPos("oad last saved game");
+		setTextPos(100, 171);
+		setTextColorWhite();
+		displayCharAtTextPos('R');
+		setTextColorRed();
+		displayStringAtTextPos("estart from beginning");
+		setTextPos(100, 180);
+		setTextColorWhite();
+		displayCharAtTextPos('Q');
+		setTextColorRed();
+		displayStringAtTextPos("uit for now");
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+
+	for (bool found = false; !found;) {
+		Common::KeyCode input = waitForKey();
+		switch (input) {
+		case Common::KEYCODE_l:
+			//loadEfhGame();
+			//TODO:
+			//SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point, which is fine, but it's possible to close the screen without loading.
+			//Maybe adding the _saveAuthorized flag in the savegame would do the trick and could then be used tp keep found at false and loop on the input selection?
+			//like: found = _saveAuthorized
+			saveEfhGame();
+			found = true;
+			_saveAuthorized = true;
+			break;
+		case Common::KEYCODE_q:
+			_shouldQuit = true;
+			return true;
+			break;
+		case Common::KEYCODE_r:
+			loadEfhGame();
+			resetGame();
+			found = true;
+			_saveAuthorized = true;
+			break;
+		case Common::KEYCODE_x: // mysterious and unexpected keycode ?
+			found = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	displayAnimFrames(0xFE, true);
+	return false;
+}
+
+void EfhEngine::displayCombatMenu(int16 charId) {
+	debug("displayCombatMenu %d", charId);
+
+	Common::String buffer = _npcBuf[charId]._name;
+	buffer += ":";
+	setTextColorWhite();
+	setTextPos(144, 7);
+	displayStringAtTextPos(buffer);
+	setTextPos(152, 79);
+	displayStringAtTextPos("A");
+	setTextColorRed();
+	displayStringAtTextPos("ttack");
+	setTextPos(195, 79);
+	setTextColorWhite();
+	displayStringAtTextPos("H");
+	setTextColorRed();
+	displayStringAtTextPos("ide");
+	setTextPos(152, 88);
+	setTextColorWhite();
+	displayStringAtTextPos("D");
+	setTextColorRed();
+	displayStringAtTextPos("efend");
+	setTextPos(195, 88);
+	setTextColorWhite();
+	displayStringAtTextPos("R");
+	setTextColorRed();
+	displayStringAtTextPos("un");
+	setTextPos(152, 97);
+	setTextColorWhite();
+	displayStringAtTextPos("S");
+	setTextColorRed();
+	displayStringAtTextPos("tatus");
+}
+
+void EfhEngine::displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str) {
+	debugC(6, kDebugEngine, "displayMenuItemString %d %d %d->%d %d %s", menuBoxId, thisBoxId, minX, maxX, minY, str);
+
+	if (menuBoxId == thisBoxId) {
+		if (_menuDepth == 0)
+			setTextColorWhite();
+		else
+			setTextColorGrey();
+
+		Common::String buffer = Common::String::format("> %s <", str);
+		displayCenteredString(buffer, minX, maxX, minY);
+		setTextColorRed();
+	} else {
+		if (_menuDepth == 0)
+			setTextColorRed();
+		else
+			setTextColorGrey();
+
+		displayCenteredString(str, minX, maxX, minY);
+	}
+}
+
+void EfhEngine::displayStatusMenu(int16 windowId) {
+	debugC(3, kDebugEngine, "displayStatusMenu %d", windowId);
+
+	for (uint counter = 0; counter < 9; ++counter) {
+		drawColoredRect(80, 39 + 14 * counter, 134, 47 + 14 * counter, 0);
+	}
+
+	if (_menuDepth != 0)
+		setTextColorGrey();
+
+	displayMenuItemString(windowId, 0, 80, 134, 39, "EQUIP");
+	displayMenuItemString(windowId, 1, 80, 134, 53, "USE");
+	displayMenuItemString(windowId, 2, 80, 134, 67, "GIVE");
+	displayMenuItemString(windowId, 3, 80, 134, 81, "TRADE");
+	displayMenuItemString(windowId, 4, 80, 134, 95, "DROP");
+	displayMenuItemString(windowId, 5, 80, 134, 109, "INFO.");
+	displayMenuItemString(windowId, 6, 80, 134, 123, "PASSIVE");
+	displayMenuItemString(windowId, 7, 80, 134, 137, "ACTIVE");
+	displayMenuItemString(windowId, 8, 80, 134, 151, "LEAVE");
+
+	setTextColorRed();
+}
+
+void EfhEngine::prepareStatusRightWindowIndexes(int16 menuId, int16 charId) {
+	debugC(6, kDebugEngine, "prepareStatusRightWindowIndexes %d %d", menuId, charId);
+
+	int16 maxId = 0;
+	int16 minId;
+	_menuItemCounter = 0;
+
+	switch (menuId) {
+	case 5:
+		minId = 26;
+		maxId = 36;
+		break;
+	case 6:
+		minId = 15;
+		maxId = 25;
+		break;
+	case 7:
+		minId = 0;
+		maxId = 14;
+		break;
+	default:
+		minId = -1;
+		break;
+	}
+
+	if (minId == -1) {
+		for (uint counter = 0; counter < 10; ++counter) {
+			if (_npcBuf[charId]._inventory[counter]._ref != 0x7FFF) {
+				_menuStatItemArr[_menuItemCounter++] = counter;
+			}
+		}
+	} else {
+		for (int16 counter = minId; counter < maxId; ++counter) {
+			if (_npcBuf[charId]._activeScore[counter] != 0) {
+				_menuStatItemArr[_menuItemCounter++] = counter;
+			}
+		}
+	}
+}
+
+void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
+	debugC(3, kDebugEngine, "displayCharacterSummary %d %d", curMenuLine, npcId);
+
+	setTextColorRed();
+	Common::String buffer1 = _npcBuf[npcId]._name;
+	setTextPos(146, 27);
+	displayStringAtTextPos("Name: ");
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("Level: %d", getXPLevel(_npcBuf[npcId]._xp));
+	setTextPos(146, 36);
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("XP: %lu", _npcBuf[npcId]._xp);
+	setTextPos(227, 36);
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("Speed: %d", _npcBuf[npcId]._speed);
+	setTextPos(146, 45);
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("Defense: %d", getEquipmentDefense(npcId, false));
+	setTextPos(146, 54);
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("Hit Points: %d", _npcBuf[npcId]._hitPoints);
+	setTextPos(146, 63);
+	displayStringAtTextPos(buffer1);
+	buffer1 = Common::String::format("Max HP: %d", _npcBuf[npcId]._maxHP);
+	setTextPos(227, 63);
+	displayStringAtTextPos(buffer1);
+	displayCenteredString("Inventory", 144, 310, 72);
+
+	if (_menuItemCounter == 0) {
+		if (curMenuLine != -1)
+			setTextColorWhite();
+
+		displayCenteredString("Nothing Carried", 144, 310, 117);
+		setTextColorRed();
+		return;
+	}
+
+	for (int counter = 0; counter < _menuItemCounter; ++counter) {
+		if (_menuDepth == 0)
+			setTextColorGrey();
+		else {
+			if (counter == curMenuLine)
+				setTextColorWhite();
+		}
+		int16 textPosY = 81 + counter * 9;
+		int16 itemId = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref;
+		if (itemId != 0x7FFF) {
+			if (_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1 & 0x80) {
+				setTextPos(146, textPosY);
+				displayCharAtTextPos('E');
+			}
+		}
+
+		setTextPos(152, textPosY);
+		if (counter == curMenuLine) {
+			buffer1 = Common::String::format("%c>", 'A' + counter);
+		} else {
+			buffer1 = Common::String::format("%c)", 'A' + counter);
+		}
+		displayStringAtTextPos(buffer1);
+
+		if (itemId != 0x7FFF) {
+			setTextPos(168, textPosY);
+			buffer1 = Common::String::format("  %s", _items[itemId]._name);
+			displayStringAtTextPos(buffer1);
+			setTextPos(262, textPosY);
+
+			if (_items[itemId]._defense > 0) {
+				int16 stat2 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat2;
+				if (stat2 != 0xFF) {
+					buffer1 = Common::String::format("%d", 1 + stat2 / 8);
+					displayStringAtTextPos(buffer1);
+					setTextPos(286, textPosY);
+					displayStringAtTextPos("Def");
+				}
+				// useless code removed.
+				// else {
+				//	var54 = _items[_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref]._defense;
+				// {
+			} else if (_items[itemId]._uses != 0x7F) {
+				int16 stat1 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1;
+				if (stat1 != 0x7F) {
+					buffer1 = Common::String::format("%d", stat1);
+					displayStringAtTextPos(buffer1);
+					setTextPos(286, textPosY);
+					if (stat1 == 1)
+						displayStringAtTextPos("Use");
+					else
+						displayStringAtTextPos("Uses");
+				}
+			}
+		}
+		setTextColorRed();
+	}
+}
+
+void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 charId) {
+	debugC(3, kDebugEngine, "displayCharacterInformationOrSkills %d %d", curMenuLine, charId);
+
+	setTextColorRed();
+	Common::String buffer = _npcBuf[charId]._name;
+	setTextPos(146, 27);
+	displayStringAtTextPos("Name: ");
+	displayStringAtTextPos(buffer);
+	if (_menuItemCounter <= 0) {
+		if (curMenuLine != -1)
+			setTextColorWhite();
+		displayCenteredString("No Skills To Select", 144, 310, 96);
+		setTextColorRed();
+		return;
+	}
+
+	for (int counter = 0; counter < _menuItemCounter; ++counter) {
+		if (counter == curMenuLine)
+			setTextColorWhite();
+		int16 textPosY = 38 + counter * 9;
+		setTextPos(146, textPosY);
+		if (counter == curMenuLine) {
+			buffer = Common::String::format("%c>", 'A' + counter);
+		} else {
+			buffer = Common::String::format("%c)", 'A' + counter);
+		}
+
+		displayStringAtTextPos(buffer);
+		setTextPos(163, textPosY);
+		displayStringAtTextPos(kSkillArray[_menuStatItemArr[counter]]);
+		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_menuStatItemArr[counter]]);
+		setTextPos(278, textPosY);
+		displayStringAtTextPos(buffer);
+		setTextColorRed();
+	}
+}
+
+void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId) {
+	debugC(6, kDebugEngine, "displayStatusMenuActions %d %d %d", menuId, curMenuLine, npcId);
+
+	drawColoredRect(144, 15, 310, 184, 0);
+	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
+	_textColor = 0x0E;
+	switch (menuId) {
+	case 0:
+		displayCenteredString("Select Item to Equip", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 1:
+		displayCenteredString("Select Item to Use", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 2:
+		displayCenteredString("Select Item to Give", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 3:
+		displayCenteredString("Select Item to Trade", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 4:
+		displayCenteredString("Select Item to Drop", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	case 5:
+		displayCenteredString("Character Information", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 6:
+		displayCenteredString("Passive Skills", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 7:
+		displayCenteredString("Active Skills", 144, 310, 15);
+		displayCharacterInformationOrSkills(curMenuLine, npcId);
+		break;
+	case 8:
+	case 9:
+		displayCenteredString("Character Summary", 144, 310, 15);
+		displayCharacterSummary(curMenuLine, npcId);
+		break;
+	default:
+		break;
+	}
+}
+
+void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
+	debugC(6, kDebugEngine, "prepareStatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
+
+	displayStatusMenu(windowId);
+
+	prepareStatusRightWindowIndexes(menuId, charId);
+	displayStatusMenuActions(menuId, curMenuLine, charId);
+
+	if (refreshFl)
+		displayFctFullScreen();
+}
+
+void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("sub18E80 %d %d %d %d", charId, windowId, menuId, curMenuLine);
+
+	for (int counter = 0; counter < 2; ++counter) {
+		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+}
+
+} // End of namespace Efh
+
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index 9cfeeb35953..f6d07436808 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
 	fight.o \
 	files.o \
 	graphics.o \
+	menu.o \
 	savegames.o \
 	script.o \
 	sound.o \


Commit: eaee54c0836acd893c2332b8eb323dcf9c81ff0e
    https://github.com/scummvm/scummvm/commit/eaee54c0836acd893c2332b8eb323dcf9c81ff0e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: Move more functions to menu.cpp, change savegame format, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 278859bcd3a..783376510cf 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1025,22 +1025,15 @@ void EfhEngine::drawScreen() {
 void EfhEngine::displayLowStatusScreen(bool flag) {
 	debugC(6, kDebugEngine, "displayLowStatusScreen %s", flag ? "True" : "False");
 
-	Common::String strName = "Name";
-	Common::String strDef = "DEF";
-	Common::String strHp = "HP";
-	Common::String strMaxHp = "Max HP";
-	Common::String strWeapon = "Weapon";
-	Common::String strDead = "* DEAD *";
-
 	for (int counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || flag) {
 			clearBottomTextZone(0);
 			setTextColorWhite();
-			displayCenteredString(strName, 16, 88, 152);
-			displayCenteredString(strDef, 104, 128, 152);
-			displayCenteredString(strHp, 144, 176, 152);
-			displayCenteredString(strMaxHp, 192, 224, 152);
-			displayCenteredString(strWeapon, 225, 302, 152);
+			displayCenteredString("Name", 16, 88, 152);
+			displayCenteredString("DEF", 104, 128, 152);
+			displayCenteredString("HP", 144, 176, 152);
+			displayCenteredString("Max HP", 192, 224, 152);
+			displayCenteredString("* DEAD *", 225, 302, 152);
 			setTextColorRed();
 
 			for (int i = 0; i < 3; ++i) {
@@ -1059,7 +1052,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				displayCenteredString(buffer, 192, 224, textPosY);
 
 				if (_npcBuf[charId]._hitPoints <= 0) {
-					displayCenteredString(strDead, 225, 302, textPosY);
+					displayCenteredString("* DEAD *", 225, 302, textPosY);
 					continue;
 				}
 
@@ -1260,7 +1253,7 @@ int16 EfhEngine::chooseCharacterToReplace() {
 	debug("chooseCharacterToReplace");
 
 	Common::KeyCode maxVal = (Common::KeyCode)(Common::KEYCODE_0 + _teamSize);
-	Common::KeyCode input = Common::KEYCODE_INVALID;
+	Common::KeyCode input;
 	for (;;) {
 		input = waitForKey();
 		if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0 || (input > Common::KEYCODE_1 && input <= maxVal))
@@ -2311,6 +2304,7 @@ void EfhEngine::displayImp1Text(int16 textId) {
 	bool maxReached = false;
 
 	if (textId <= 0xFE) {
+		// Clear temp text on the lower left part of the screen
 		if (_tempTextPtr) {
 			_tempTextPtr = nullptr;
 			displayMiddleLeftTempText(_tempTextPtr, true);
@@ -2461,7 +2455,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					continue;
 
 				for (uint var2 = 0; var2 < 39; ++var2) {
-					// CHECKME : the whole look doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
+					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
 					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4) {
 						displayImp1Text(_mapUnknown[var8]._field5_textId);
@@ -2822,31 +2816,6 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 	return level;
 }
 
-int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
-
-	int16 retVal = 0;
-
-	for (uint counter = 0; counter < 2; ++counter) {
-		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
-		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
-
-		if (counter == 0) {
-			script_parse(str, 28, 122, 105, 166, false);
-			displayFctFullScreen();
-		} else {
-			retVal = script_parse(str, 28, 122, 105, 166, true);
-		}
-	}
-
-	if (animFl) {
-		getLastCharAfterAnimCount(_guessAnimationAmount);
-		sub18E80(charId, windowId, menuId, curMenuLine);
-	}
-
-	return retVal;
-}
-
 bool EfhEngine::isItemCursed(int16 itemId) {
 	debugC(6, kDebugEngine, "isItemCursed %d", itemId);
 
@@ -2864,49 +2833,18 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 	return true;
 }
 
-void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("equipCursedItem %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
-
-	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
-
-	if (isItemCursed(itemId)) {
-		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
-	} else {
-		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
-	}
-
-}
-
-void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("sub191FF %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
-
-	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
-	if (hasObjectEquipped(charId, objectId)) {
-		equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
-	} else {
-		int16 var2 = _items[itemId].field_18;
-		if (var2 != 4) {
-			for (uint counter = 0; counter < 10; ++counter) {
-				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
-					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
-			}
-		}
-
-		_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
-	}
-}
-
-void EfhEngine::sub1E028(int16 id, uint8 mask, int16 groupFl) {
-	debug("sub1E028 %d 0x%X %d", id, mask, groupFl);
+void EfhEngine::setMapMonsterField8(int16 id, uint8 mask, bool groupFl) {
+	debugC(2, kDebugEngine, "setMapMonsterField8 %d 0x%X %s", id, mask, groupFl ? "True" : "False");
 
 	int16 monsterId;
-	if (groupFl) {
+	if (groupFl) { // groupFl is always True
 		monsterId = _teamMonsterIdArray[id];
 	} else {
 		monsterId = id;
 	}
 
+	mask &= 0x0F;
 	_mapMonsters[monsterId]._field_8 &= 0xF0;
 	_mapMonsters[monsterId]._field_8 |= mask;
 }
@@ -2951,932 +2889,6 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 	return (int16)input - (int16)Common::KEYCODE_1;
 }
 
-int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
-	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine, argA);
-
-	Common::String buffer1 = "";
-
-	bool varA6 = false;
-	bool retVal = false;
-
-	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
-	switch (_items[itemId].field_16 - 1) {
-	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
-		if (argA == 2) {
-			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			int16 victims = 0;
-			_messageToBePrinted += "  The item emits a low droning hum...";
-			if (getRandom(100) < 50) {
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
-						++victims;
-						_stru32686[windowId]._field0[counter] = 1;
-						_stru32686[windowId]._field2[counter] = getRandom(8);
-					}
-				}
-			} else {
-				int16 NumberOfTargets = getRandom(9);
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (NumberOfTargets == 0)
-						break;
-
-					if (isMonsterActive(windowId, counter)) {
-						++victims;
-						--NumberOfTargets;
-						_stru32686[windowId]._field0[counter] = 1;
-						_stru32686[windowId]._field2[counter] = getRandom(8);
-					}
-				}
-			}
-			// The original was duplicating this code in each branch of the previous random check.
-			if (victims > 1) {
-				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
-			} else {
-				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
-			}
-			_messageToBePrinted += buffer1;
-		}
-
-		varA6 = true;
-		break;
-	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
-		if (argA == 2) {
-			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += "  The item emits a blue beam...";
-			int16 victim = 0;
-			if (getRandom(100) < 50) {
-				for (uint varA8 = 0; varA8 < 9; ++varA8) {
-					if (isMonsterActive(windowId, varA8)) {
-						++victim;
-						_stru32686[windowId]._field0[varA8] = 2;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
-					}
-				}
-			} else {
-				int16 varAC = getRandom(9);
-				for (uint varA8 = 0; varA8 < 9; ++varA8) {
-					if (varAC == 0)
-						break;
-
-					if (isMonsterActive(windowId, varA8)) {
-						++victim;
-						--varAC;
-						_stru32686[windowId]._field0[varA8] = 2;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
-					}
-				}
-			}
-			// <CHECKME>: This part is only present in the original in the case < 50, but for me
-			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
-			if (victim > 1) {
-				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
-			} else {
-				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
-			}
-			_messageToBePrinted += buffer1;
-			// </CHECKME>
-		}
-
-		varA6 = true;
-		break;
-	case 2:
-		if (argA == 2) {
-			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
-			_unkArray2C8AA[0] = 0;
-		}
-
-		varA6 = true;
-		break;
-	case 4: // "Unholy Sinwave", "Holy Water"
-		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
-			if (getRandom(100) < 50) {
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (getRandom(100) < 50) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
-					}
-				}
-			} else {
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
-						if (getRandom(100) < 50) {
-							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
-						}
-						break;
-					}
-				}
-			}
-		}
-		varA6 = true;
-		break;
-	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
-		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			if (getRandom(100) < 50) {
-				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
-				for (uint counter = 0; counter < 9; ++counter) {
-					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
-				}
-			} else {
-				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
-					}
-				}
-			}
-		}
-
-		varA6 = true;
-		break;
-	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
-		if (argA == 2) {
-			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			sub1E028(windowId, _items[itemId].field17_attackTypeDefense, true);
-		}
-		varA6 = true;
-		break;
-	case 14: { // "Feathered Cap"
-		int16 varAA;
-		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
-		} else {
-			varAA = windowId;
-		}
-
-		if (varAA != 0x1B) {
-			buffer1 = "  The magic makes the user as quick and agile as a bird!";
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-			}
-			_word32482[varAA] -= 50;
-			if (_word32482[varAA] < 0)
-				_word32482[varAA] = 0;
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 15: { // "Regal Crown"
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else {
-			teamCharId = windowId;
-		}
-
-		if (teamCharId != 0x1B) {
-			buffer1 = "  The magic makes the user invisible!";
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-			}
-
-			_teamPctVisible[teamCharId] -= 50;
-			if (_teamPctVisible[teamCharId] < 0)
-				_teamPctVisible[teamCharId] = 0;
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 16: { // Fairy Dust
-		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
-		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
-		int16 varAE = sub15538(_mapPosX, _mapPosY);
-
-		if (_tileFact[varAE]._field0 == 0) {
-			totalPartyKill();
-			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-				retVal = true;
-			}
-			// emptyFunction(2);
-		} else {
-			if (varAE == 0 || varAE == 0x48) {
-				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
-				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-				} else {
-					_messageToBePrinted += buffer1;
-					retVal = true;
-				}
-			} else {
-				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
-				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-				} else {
-					_messageToBePrinted += buffer1;
-					retVal = true;
-				}
-			}
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 17: { // "Devil Dust"
-		_mapPosX = _items[itemId].field_19;
-		_mapPosY = _items[itemId].field_1A;
-		int16 varAE = sub15538(_mapPosX, _mapPosY);
-		if (_tileFact[varAE]._field0 == 0) {
-			totalPartyKill();
-			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-				retVal = true;
-			}
-			// emptyFunction(2);
-		} else {
-			if (varAE == 0 || varAE == 0x48) {
-				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
-				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-				} else {
-					_messageToBePrinted += buffer1;
-					retVal = true;
-				}
-			} else {
-				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
-				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-				} else {
-					_messageToBePrinted += buffer1;
-					retVal = true;
-				}
-			}
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 18:
-		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			int16 teamCharId = windowId;
-			if (teamCharId != 0x1B) {
-				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
-					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
-					_teamCharStatus[teamCharId]._status = 0;
-					_teamCharStatus[teamCharId]._duration = 0;
-				} else {
-					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
-				}
-			}
-		}
-
-		varA6 = true;
-		break;
-	case 19: // "Junk"
-		buffer1 = "  * The item breaks!";
-		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += buffer1;
-		}
-		setCharacterObjectToBroken(charId, objectId);
-		varA6 = true;
-		break;
-	case 23: // "Divining Rod"
-		buffer1 = Common::String::format("The %s says, '", _items[itemId]._name);
-		if (_items[itemId].field_19 < _mapPosX) {
-			if (_items[itemId].field_1A < _mapPosY) {
-				buffer1 += "North West!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
-				buffer1 += "South West!";
-			} else {
-				buffer1 += "West!";
-			}
-		} else if (_items[itemId].field_19 > _mapPosX) {
-			if (_items[itemId].field_1A < _mapPosY) {
-				buffer1 += "North East!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
-				buffer1 += "South East!";
-			} else {
-				buffer1 += "East!";
-			}
-		} else { // equals _mapPosX
-			if (_items[itemId].field_1A < _mapPosY) {
-				buffer1 += "North!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
-				buffer1 += "South!";
-			} else {
-				buffer1 += "Here!!!";
-			}
-		}
-		buffer1 += "'";
-		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += buffer1;
-			retVal = true;
-		}
-
-		varA6 = true;
-		break;
-	case 24: {
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else
-			teamCharId = windowId;
-
-		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 effectPoints = getRandom(_items[itemId].field_19);
-			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
-				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
-			}
-			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s increased %d points!", kSkillArray[varAE], effectPoints);
-			else
-				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
-
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-				retVal = true;
-			}
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 25: {
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else
-			teamCharId = windowId;
-
-		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 effectPoints = getRandom(_items[itemId].field_19);
-			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
-				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
-			}
-			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s lowered %d points!", kSkillArray[varAE], effectPoints);
-			else
-				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
-
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-				retVal = true;
-			}
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 26: // "Black Sphere"
-		buffer1 = "The entire party collapses, dead!!!";
-		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += buffer1;
-			retVal = true;
-		}
-		totalPartyKill();
-		// emptyFunction(2);
-		varA6 = true;
-		break;
-	case 27: { // "Magic Pyramid", "Razor Blade"
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else {
-			teamCharId = windowId;
-		}
-
-		if (teamCharId != 0x1B) {
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
-			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
-			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-			} else {
-				_messageToBePrinted += buffer1;
-				retVal = true;
-			}
-			// emptyFunction(2);
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 28: // "Bugle"
-		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
-		} else {
-			int16 teamCharId = windowId;
-			if (teamCharId != 0x1B) {
-				if (_teamCharStatus[teamCharId]._status == 0) {
-					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
-					_teamCharStatus[teamCharId]._status = 0;
-					_teamCharStatus[teamCharId]._duration = 0;
-				} else {
-					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
-				}
-			}
-		}
-
-		varA6 = true;
-		break;
-	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else {
-			teamCharId = windowId;
-		}
-
-		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
-				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
-
-			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
-			else
-				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
-		}
-
-		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += buffer1;
-			retVal = true;
-		}
-
-		varA6 = true;
-		}
-		break;
-	case 30: {
-		int16 teamCharId;
-		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
-			teamCharId = selectOtherCharFromTeam();
-		} else {
-			teamCharId = windowId;
-		}
-
-		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
-				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
-
-			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
-			else
-				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
-		}
-
-		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-		} else {
-			_messageToBePrinted += buffer1;
-			retVal = true;
-		}
-
-		varA6 = true;
-
-		}
-		break;
-	case 3:
-	case 6:
-	case 7:
-	case 8:
-	case 9:
-	case 10:
-	case 11:
-	case 13:
-	case 20:
-	case 21:
-	case 22:
-	default:
-		break;
-	}
-
-	if (varA6) {
-		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
-			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
-			if (varA1 <= 0) {
-				buffer1 = "  * The item breaks!";
-				if (argA == 2) {
-					getLastCharAfterAnimCount(_guessAnimationAmount);
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
-				} else {
-					_messageToBePrinted += buffer1;
-				}
-				setCharacterObjectToBroken(charId, objectId);
-			} else {
-				_npcBuf[charId]._inventory[objectId]._stat1 &= 0x80;
-				_npcBuf[charId]._inventory[objectId]._stat1 |= 0xA1;
-			}
-		}
-
-		if (argA == 2) {
-			getLastCharAfterAnimCount(_guessAnimationAmount);
-			sub18E80(charId, windowId, menuId, curMenuLine);
-		}
-	}
-
-	return retVal;
-}
-
-int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
-	debug("handleStatusMenu %d %d", gameMode, charId);
-
-	int16 menuId = 9;
-	int16 selectedLine = -1;
-	int16 windowId = -1;
-	int16 curMenuLine = -1;
-	bool var10 = false;
-	bool var2 = false;
-
-	saveAnimImageSetId();
-
-	_statusMenuActive = true;
-	_menuDepth = 0;
-
-	sub18E80(charId, windowId, menuId, curMenuLine);
-
-	for (;;) {
-		if (windowId != -1)
-			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
-		else
-			windowId = 0;
-
-		do {
-			Common::KeyCode var19 = handleAndMapInput(false);
-			if (_menuDepth == 0) {
-				switch (var19) {
-				case Common::KEYCODE_ESCAPE:
-					windowId = 8;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_a:
-					windowId = 7;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_d:
-					windowId = 4;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_e:
-					windowId = 0;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_g:
-					windowId = 2;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_i:
-					windowId = 5;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_l:
-					windowId = 8;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_p:
-					windowId = 6;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_t:
-					windowId = 3;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				case Common::KEYCODE_u:
-					windowId = 1;
-					var19 = Common::KEYCODE_RETURN;
-					break;
-				// case 0xFB: Joystick button 2
-				default:
-				//	warning("handleStatusMenu - unhandled keys (or joystick event?) 0xBA, 0xBB, 0xBC");
-					break;
-				}
-			} else if (_menuDepth == 1) {
-				// in the sub-menus, only a list of selectable items is displayed
-				if (var19 >= Common::KEYCODE_a && var19 <= Common::KEYCODE_z) {
-					int16 var8 = var19 - Common::KEYCODE_a;
-					if (var8 < _menuItemCounter) {
-						curMenuLine = var8;
-						var19 = Common::KEYCODE_RETURN;
-					}
-				}
-
-			}
-
-			switch (var19) {
-			case Common::KEYCODE_RETURN:
-			// case 0xFA: Joystick button 1
-				if (_menuDepth == 0) {
-					menuId = windowId;
-					if (menuId > 7)
-						var10 = true;
-					else {
-						_menuDepth = 1;
-						curMenuLine = 0;
-					}
-				} else if (_menuDepth == 1) {
-					if (_menuItemCounter == 0) {
-						_menuDepth = 0;
-						curMenuLine = -1;
-						menuId = 9;
-						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
-					} else {
-						selectedLine = curMenuLine;
-						var10 = true;
-					}
-				}
-				break;
-			case Common::KEYCODE_ESCAPE:
-				_menuDepth = 0;
-				curMenuLine = -1;
-				menuId = 9;
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
-				break;
-			case Common::KEYCODE_2:
-			case Common::KEYCODE_6:
-			// Added for ScummVM
-			case Common::KEYCODE_DOWN:
-			case Common::KEYCODE_RIGHT:
-			case Common::KEYCODE_KP2:
-			case Common::KEYCODE_KP6:
-				// Original checks joystick axis: case 0xCC, 0xCF
-				if (_menuDepth == 0) {
-					if (++windowId > 8)
-						windowId = 0;
-				} else if (_menuDepth == 1) {
-					if (_menuItemCounter != 0) {
-						++curMenuLine;
-						if (curMenuLine > _menuItemCounter - 1)
-							curMenuLine = 0;
-					}
-				}
-				break;
-			case Common::KEYCODE_4:
-			case Common::KEYCODE_8:
-			// Added for ScummVM
-			case Common::KEYCODE_LEFT:
-			case Common::KEYCODE_UP:
-			case Common::KEYCODE_KP4:
-			case Common::KEYCODE_KP8:
-			// Original checks joystick axis: case 0xC7, 0xCA
-				if (_menuDepth == 0) {
-					if (--windowId < 0)
-						windowId = 8;
-				} else if (_menuDepth == 1) {
-					if (_menuItemCounter != 0) {
-						--curMenuLine;
-						if (curMenuLine < 0)
-							curMenuLine = _menuItemCounter - 1;
-					}
-				}
-				break;
-			default:
-				break;
-			}
-
-			if (curMenuLine == -1)
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, false, true);
-			else
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
-
-		} while (!var10);
-
-		bool validationFl = true;
-
-		int16 objectId;
-		int16 itemId;
-		switch (menuId) {
-		case 0:
-			objectId = _menuStatItemArr[selectedLine];
-			itemId = _npcBuf[charId]._inventory[objectId]._ref;
-			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
-			if (gameMode == 2) {
-				restoreAnimImageSetId();
-				_statusMenuActive = false;
-				return 0x7D00;
-			}
-			break;
-		case 1:
-			objectId = _menuStatItemArr[selectedLine];
-			itemId = _npcBuf[charId]._inventory[objectId]._ref;
-			if (gameMode == 2) {
-				restoreAnimImageSetId();
-				_statusMenuActive = false;
-				return objectId;
-			}
-
-			if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
-				_statusMenuActive = false;
-				return -1;
-			}
-
-			sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
-			break;
-		case 2:
-			objectId = _menuStatItemArr[selectedLine];
-			itemId = _npcBuf[charId]._inventory[objectId]._ref;
-			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
-			} else if (hasObjectEquipped(charId, objectId)){
-				displayString_3("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
-				if (!getValidationFromUser())
-					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
-
-				if (validationFl) {
-					if (gameMode == 2) {
-						displayString_3("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
-					} else {
-						removeObject(charId, objectId);
-						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
-						if (var8 != 0) {
-							_statusMenuActive = false;
-							return -1;
-						}
-					}
-				}
-			}
-
-			break;
-		case 3:
-			objectId = _menuStatItemArr[selectedLine];
-			itemId = _npcBuf[charId]._inventory[objectId]._ref;
-			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
-			} else if (hasObjectEquipped(charId, objectId)) {
-				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
-				if (!getValidationFromUser())
-					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
-
-				if (validationFl) {
-					bool var6;
-					int16 var8;
-					do {
-						if (_teamCharId[2] != -1) {
-							var8 = displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
-							var2 = false;
-						} else if (_teamCharId[1]) {
-							var8 = 0x1A;
-							var2 = false;
-						} else {
-							var2 = true;
-							if (_teamCharId[0] == charId)
-								var8 = 1;
-							else
-								var8 = 0;
-						}
-
-						if (var8 != 0x1A && var8 != 0x1B) {
-							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
-							if (!var6) {
-								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
-								getLastCharAfterAnimCount(_guessAnimationAmount);
-							}
-						} else {
-							if (var8 == 0x1A) {
-								displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
-								getLastCharAfterAnimCount(_guessAnimationAmount);
-								var8 = 0x1B;
-							}
-							var6 = false;
-						}
-					} while (!var6 && !var2 && var8 != 0x1B);
-
-					if (var6) {
-						removeObject(charId, objectId);
-						if (gameMode == 2) {
-							restoreAnimImageSetId();
-							_statusMenuActive = false;
-							return 0x7D00;
-						}
-					}
-
-					sub18E80(charId, windowId, menuId, curMenuLine);
-				}
-			}
-			break;
-		case 4:
-			objectId = _menuStatItemArr[selectedLine];
-			itemId = _npcBuf[charId]._inventory[objectId]._ref;
-			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
-			} else if (hasObjectEquipped(charId, objectId)) {
-				displayString_3("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
-				if (!getValidationFromUser())
-					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
-
-				if (validationFl) {
-					removeObject(charId, objectId);
-					if (gameMode == 2) {
-						restoreAnimImageSetId();
-						_statusMenuActive = false;
-						return 0x7D00;
-					}
-
-					bool var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1);
-					if (var8) {
-						_statusMenuActive = false;
-						return -1;
-					}
-				}
-			}
-			break;
-		case 5:
-			objectId = _menuStatItemArr[selectedLine];
-			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
-			}
-			break;
-		case 6: // Identical to case 5?
-			objectId = _menuStatItemArr[selectedLine];
-			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
-			}
-			break;
-		case 7: // Identical to case 5?
-			objectId = _menuStatItemArr[selectedLine];
-			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
-			}
-			break;
-		default:
-			break;
-		}
-
-		if (menuId != 8) {
-			var10 = false;
-			_menuDepth = 0;
-			menuId = 9;
-			selectedLine = -1;
-			curMenuLine = -1;
-		}
-
-		if (menuId == 8) {
-			restoreAnimImageSetId();
-			_statusMenuActive = false;
-			return 0x7FFF;
-		}
-	}
-
-	return 0;
-}
-
 bool EfhEngine::checkMonsterCollision() {
 	debug("checkMonsterCollision");
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 34c9da9af2d..b59fac80aca 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -363,18 +363,13 @@ private:
 	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1D8C2(int16 charId, int16 damage);
 	int16 getXPLevel(int32 xp);
-	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
-	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	void sub1E028(int16 id, uint8 mask, int16 groupFl);
+	void setMapMonsterField8(int16 id, uint8 mask, bool groupFl);
 	bool isMonsterActive(int16 groupId, int16 id);
 	int16 sub15538(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
 	int16 selectOtherCharFromTeam();
-	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
-	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	bool checkMonsterCollision();
 
 	// Fight
@@ -467,6 +462,11 @@ private:
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
 	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 handleStatusMenu(int16 gameMode, int16 charId);
+	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 
 	// Savegames
 	void synchronize(Common::Serializer &s);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 30e4f99eb6f..0e375cafaea 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -456,7 +456,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				if (isMonsterActive(groupId, var7E) && var6E) {
 					int16 var5C;
 					if (unkFct_checkMonsterField8(groupId, true)) {
-						sub1E028(groupId, 9, true);
+						setMapMonsterField8(groupId, 9, true);
 						_unkArray2C8AA[0] += 500;
 						var5C = -1;
 					} else
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 9fea7b774a5..5ed31e12ad8 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -62,7 +62,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOptio
 	}
 
 	drawColoredRect(minX, minY, maxX, maxY, 0);
-	if (str.size())
+	if (!str.empty())
 		varA = script_parse(str, minX, minY, maxX, maxY, true);
 
 	if (displayTeamWindowFl)
@@ -74,7 +74,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOptio
 			_word2C87A = false;
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
-			if (str.size())
+			if (!str.empty())
 				script_parse(str, minX, minY, maxX, maxY, false);
 		}
 
@@ -92,7 +92,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOptio
 }
 
 bool EfhEngine::handleDeathMenu() {
-	debug("handleDeathMenu");
+	debugC(3, kDebugEngine, "handleDeathMenu");
 
 	_saveAuthorized = false;
 
@@ -126,14 +126,12 @@ bool EfhEngine::handleDeathMenu() {
 		Common::KeyCode input = waitForKey();
 		switch (input) {
 		case Common::KEYCODE_l:
-			//loadEfhGame();
-			//TODO:
-			//SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point, which is fine, but it's possible to close the screen without loading.
-			//Maybe adding the _saveAuthorized flag in the savegame would do the trick and could then be used tp keep found at false and loop on the input selection?
-			//like: found = _saveAuthorized
+			// SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point (_saveAuthorizd is false).
+			// If the user actually loads a savegame, it'll get _saveAuthorized from the savegame (always true) and will set 'found' to true.
+			// If 'found' remains false, it means the user cancelled the loading and still needs to take a decision
+			// Original is calling loadEfhGame() because there's only one savegame, so it's not ambiguous
 			saveEfhGame();
-			found = true;
-			_saveAuthorized = true;
+			found = _saveAuthorized;
 			break;
 		case Common::KEYCODE_q:
 			_shouldQuit = true;
@@ -158,10 +156,9 @@ bool EfhEngine::handleDeathMenu() {
 }
 
 void EfhEngine::displayCombatMenu(int16 charId) {
-	debug("displayCombatMenu %d", charId);
+	debugC(6, kDebugEngine, "displayCombatMenu %d", charId);
 
-	Common::String buffer = _npcBuf[charId]._name;
-	buffer += ":";
+	Common::String buffer = Common::String::format("%s:", _npcBuf[charId]._name);
 	setTextColorWhite();
 	setTextPos(144, 7);
 	displayStringAtTextPos(buffer);
@@ -482,5 +479,978 @@ void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMe
 	}
 }
 
+int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+
+	int16 retVal = 0;
+
+	for (uint counter = 0; counter < 2; ++counter) {
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
+
+		if (counter == 0) {
+			script_parse(str, 28, 122, 105, 166, false);
+			displayFctFullScreen();
+		} else {
+			retVal = script_parse(str, 28, 122, 105, 166, true);
+		}
+	}
+
+	if (animFl) {
+		getLastCharAfterAnimCount(_guessAnimationAmount);
+		sub18E80(charId, windowId, menuId, curMenuLine);
+	}
+
+	return retVal;
+}
+
+int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
+	debug("handleStatusMenu %d %d", gameMode, charId);
+
+	int16 menuId = 9;
+	int16 selectedLine = -1;
+	int16 windowId = -1;
+	int16 curMenuLine = -1;
+	bool var10 = false;
+	bool var2 = false;
+
+	saveAnimImageSetId();
+
+	_statusMenuActive = true;
+	_menuDepth = 0;
+
+	sub18E80(charId, windowId, menuId, curMenuLine);
+
+	for (;;) {
+		if (windowId != -1)
+			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+		else
+			windowId = 0;
+
+		do {
+			Common::KeyCode var19 = handleAndMapInput(false);
+			if (_menuDepth == 0) {
+				switch (var19) {
+				case Common::KEYCODE_ESCAPE:
+					windowId = 8;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_a:
+					windowId = 7;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_d:
+					windowId = 4;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_e:
+					windowId = 0;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_g:
+					windowId = 2;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_i:
+					windowId = 5;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_l:
+					windowId = 8;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_p:
+					windowId = 6;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_t:
+					windowId = 3;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				case Common::KEYCODE_u:
+					windowId = 1;
+					var19 = Common::KEYCODE_RETURN;
+					break;
+				// case 0xFB: Joystick button 2
+				default:
+					//	warning("handleStatusMenu - unhandled keys (or joystick event?) 0xBA, 0xBB, 0xBC");
+					break;
+				}
+			} else if (_menuDepth == 1) {
+				// in the sub-menus, only a list of selectable items is displayed
+				if (var19 >= Common::KEYCODE_a && var19 <= Common::KEYCODE_z) {
+					int16 var8 = var19 - Common::KEYCODE_a;
+					if (var8 < _menuItemCounter) {
+						curMenuLine = var8;
+						var19 = Common::KEYCODE_RETURN;
+					}
+				}
+			}
+
+			switch (var19) {
+			case Common::KEYCODE_RETURN:
+				// case 0xFA: Joystick button 1
+				if (_menuDepth == 0) {
+					menuId = windowId;
+					if (menuId > 7)
+						var10 = true;
+					else {
+						_menuDepth = 1;
+						curMenuLine = 0;
+					}
+				} else if (_menuDepth == 1) {
+					if (_menuItemCounter == 0) {
+						_menuDepth = 0;
+						curMenuLine = -1;
+						menuId = 9;
+						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+					} else {
+						selectedLine = curMenuLine;
+						var10 = true;
+					}
+				}
+				break;
+			case Common::KEYCODE_ESCAPE:
+				_menuDepth = 0;
+				curMenuLine = -1;
+				menuId = 9;
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+				break;
+			case Common::KEYCODE_2:
+			case Common::KEYCODE_6:
+			// Added for ScummVM
+			case Common::KEYCODE_DOWN:
+			case Common::KEYCODE_RIGHT:
+			case Common::KEYCODE_KP2:
+			case Common::KEYCODE_KP6:
+				// Original checks joystick axis: case 0xCC, 0xCF
+				if (_menuDepth == 0) {
+					if (++windowId > 8)
+						windowId = 0;
+				} else if (_menuDepth == 1) {
+					if (_menuItemCounter != 0) {
+						++curMenuLine;
+						if (curMenuLine > _menuItemCounter - 1)
+							curMenuLine = 0;
+					}
+				}
+				break;
+			case Common::KEYCODE_4:
+			case Common::KEYCODE_8:
+			// Added for ScummVM
+			case Common::KEYCODE_LEFT:
+			case Common::KEYCODE_UP:
+			case Common::KEYCODE_KP4:
+			case Common::KEYCODE_KP8:
+				// Original checks joystick axis: case 0xC7, 0xCA
+				if (_menuDepth == 0) {
+					if (--windowId < 0)
+						windowId = 8;
+				} else if (_menuDepth == 1) {
+					if (_menuItemCounter != 0) {
+						--curMenuLine;
+						if (curMenuLine < 0)
+							curMenuLine = _menuItemCounter - 1;
+					}
+				}
+				break;
+			default:
+				break;
+			}
+
+			if (curMenuLine == -1)
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, false, true);
+			else
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+
+		} while (!var10);
+
+		bool validationFl = true;
+
+		int16 objectId;
+		int16 itemId;
+		switch (menuId) {
+		case 0:
+			objectId = _menuStatItemArr[selectedLine];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref; // CHECKME: Useless?
+			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
+			if (gameMode == 2) {
+				restoreAnimImageSetId();
+				_statusMenuActive = false;
+				return 0x7D00;
+			}
+			break;
+		case 1:
+			objectId = _menuStatItemArr[selectedLine];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (gameMode == 2) {
+				restoreAnimImageSetId();
+				_statusMenuActive = false;
+				return objectId;
+			}
+
+			if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
+				_statusMenuActive = false;
+				return -1;
+			}
+
+			sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
+			break;
+		case 2:
+			objectId = _menuStatItemArr[selectedLine];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)) {
+				displayString_3("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					if (gameMode == 2) {
+						displayString_3("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
+					} else {
+						removeObject(charId, objectId);
+						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
+						if (var8 != 0) {
+							_statusMenuActive = false;
+							return -1;
+						}
+					}
+				}
+			}
+
+			break;
+		case 3:
+			objectId = _menuStatItemArr[selectedLine];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)) {
+				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					bool var6;
+					int16 var8;
+					do {
+						if (_teamCharId[2] != -1) {
+							var8 = displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
+							var2 = false;
+						} else if (_teamCharId[1]) {
+							var8 = 0x1A;
+							var2 = false;
+						} else {
+							var2 = true;
+							if (_teamCharId[0] == charId)
+								var8 = 1;
+							else
+								var8 = 0;
+						}
+
+						if (var8 != 0x1A && var8 != 0x1B) {
+							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
+							if (!var6) {
+								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
+								getLastCharAfterAnimCount(_guessAnimationAmount);
+							}
+						} else {
+							if (var8 == 0x1A) {
+								displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
+								getLastCharAfterAnimCount(_guessAnimationAmount);
+								var8 = 0x1B;
+							}
+							var6 = false;
+						}
+					} while (!var6 && !var2 && var8 != 0x1B);
+
+					if (var6) {
+						removeObject(charId, objectId);
+						if (gameMode == 2) {
+							restoreAnimImageSetId();
+							_statusMenuActive = false;
+							return 0x7D00;
+						}
+					}
+
+					sub18E80(charId, windowId, menuId, curMenuLine);
+				}
+			}
+			break;
+		case 4:
+			objectId = _menuStatItemArr[selectedLine];
+			itemId = _npcBuf[charId]._inventory[objectId]._ref;
+			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
+				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+			} else if (hasObjectEquipped(charId, objectId)) {
+				displayString_3("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
+				if (!getValidationFromUser())
+					validationFl = false;
+				sub18E80(charId, windowId, menuId, curMenuLine);
+
+				if (validationFl) {
+					removeObject(charId, objectId);
+					if (gameMode == 2) {
+						restoreAnimImageSetId();
+						_statusMenuActive = false;
+						return 0x7D00;
+					}
+
+					bool var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1);
+					if (var8) {
+						_statusMenuActive = false;
+						return -1;
+					}
+				}
+			}
+			break;
+		case 5:
+			objectId = _menuStatItemArr[selectedLine];
+			if (gameMode == 2) {
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_statusMenuActive = false;
+					return -1;
+				}
+			}
+			break;
+		case 6: // Identical to case 5?
+			objectId = _menuStatItemArr[selectedLine];
+			if (gameMode == 2) {
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_statusMenuActive = false;
+					return -1;
+				}
+			}
+			break;
+		case 7: // Identical to case 5?
+			objectId = _menuStatItemArr[selectedLine];
+			if (gameMode == 2) {
+				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
+			} else {
+				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
+				if (var8) {
+					_statusMenuActive = false;
+					return -1;
+				}
+			}
+			break;
+		default:
+			break;
+		}
+
+		if (menuId != 8) {
+			var10 = false;
+			_menuDepth = 0;
+			menuId = 9;
+			selectedLine = -1;
+			curMenuLine = -1;
+		}
+
+		if (menuId == 8) {
+			restoreAnimImageSetId();
+			_statusMenuActive = false;
+			return 0x7FFF;
+		}
+	}
+
+	return 0;
+}
+
+void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("equipCursedItem %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+
+	if (isItemCursed(itemId)) {
+		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
+	} else {
+		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
+	}
+}
+
+void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("sub191FF %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+
+	if (hasObjectEquipped(charId, objectId)) {
+		equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+	} else {
+		int16 var2 = _items[itemId].field_18;
+		if (var2 != 4) {
+			for (uint counter = 0; counter < 10; ++counter) {
+				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
+					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+			}
+		}
+
+		_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
+	}
+}
+
+int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
+	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine, argA);
+
+	Common::String buffer1 = "";
+
+	bool varA6 = false;
+	bool retVal = false;
+
+	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
+	switch (_items[itemId].field_16 - 1) {
+	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
+		if (argA == 2) {
+			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 victims = 0;
+			_messageToBePrinted += "  The item emits a low droning hum...";
+			if (getRandom(100) < 50) {
+				for (uint counter = 0; counter < 9; ++counter) {
+					if (isMonsterActive(windowId, counter)) {
+						++victims;
+						_stru32686[windowId]._field0[counter] = 1;
+						_stru32686[windowId]._field2[counter] = getRandom(8);
+					}
+				}
+			} else {
+				int16 NumberOfTargets = getRandom(9);
+				for (uint counter = 0; counter < 9; ++counter) {
+					if (NumberOfTargets == 0)
+						break;
+
+					if (isMonsterActive(windowId, counter)) {
+						++victims;
+						--NumberOfTargets;
+						_stru32686[windowId]._field0[counter] = 1;
+						_stru32686[windowId]._field2[counter] = getRandom(8);
+					}
+				}
+			}
+			// The original was duplicating this code in each branch of the previous random check.
+			if (victims > 1) {
+				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+			} else {
+				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+			}
+			_messageToBePrinted += buffer1;
+		}
+
+		varA6 = true;
+		break;
+	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
+		if (argA == 2) {
+			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += "  The item emits a blue beam...";
+			int16 victim = 0;
+			if (getRandom(100) < 50) {
+				for (uint varA8 = 0; varA8 < 9; ++varA8) {
+					if (isMonsterActive(windowId, varA8)) {
+						++victim;
+						_stru32686[windowId]._field0[varA8] = 2;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			} else {
+				int16 varAC = getRandom(9);
+				for (uint varA8 = 0; varA8 < 9; ++varA8) {
+					if (varAC == 0)
+						break;
+
+					if (isMonsterActive(windowId, varA8)) {
+						++victim;
+						--varAC;
+						_stru32686[windowId]._field0[varA8] = 2;
+						_stru32686[windowId]._field2[varA8] = getRandom(8);
+					}
+				}
+			}
+			// <CHECKME>: This part is only present in the original in the case < 50, but for me
+			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
+			if (victim > 1) {
+				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+			} else {
+				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+			}
+			_messageToBePrinted += buffer1;
+			// </CHECKME>
+		}
+
+		varA6 = true;
+		break;
+	case 2:
+		if (argA == 2) {
+			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
+			_unkArray2C8AA[0] = 0;
+		}
+
+		varA6 = true;
+		break;
+	case 4: // "Unholy Sinwave", "Holy Water"
+		if (argA == 2) {
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
+			if (getRandom(100) < 50) {
+				for (uint counter = 0; counter < 9; ++counter) {
+					if (getRandom(100) < 50) {
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+					}
+				}
+			} else {
+				for (uint counter = 0; counter < 9; ++counter) {
+					if (isMonsterActive(windowId, counter)) {
+						if (getRandom(100) < 50) {
+							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+						}
+						break;
+					}
+				}
+			}
+		}
+		varA6 = true;
+		break;
+	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
+		if (argA == 2) {
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			if (getRandom(100) < 50) {
+				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
+				for (uint counter = 0; counter < 9; ++counter) {
+					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+				}
+			} else {
+				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
+				for (uint counter = 0; counter < 9; ++counter) {
+					if (isMonsterActive(windowId, counter)) {
+						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+					}
+				}
+			}
+		}
+
+		varA6 = true;
+		break;
+	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
+		if (argA == 2) {
+			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
+			setMapMonsterField8(windowId, _items[itemId].field17_attackTypeDefense, true);
+		}
+		varA6 = true;
+		break;
+	case 14: { // "Feathered Cap"
+		int16 varAA;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			varAA = selectOtherCharFromTeam();
+		} else {
+			varAA = windowId;
+		}
+
+		if (varAA != 0x1B) {
+			buffer1 = "  The magic makes the user as quick and agile as a bird!";
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+			}
+			_word32482[varAA] -= 50;
+			if (_word32482[varAA] < 0)
+				_word32482[varAA] = 0;
+		}
+
+		varA6 = true;
+	} break;
+	case 15: { // "Regal Crown"
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else {
+			teamCharId = windowId;
+		}
+
+		if (teamCharId != 0x1B) {
+			buffer1 = "  The magic makes the user invisible!";
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+			}
+
+			_teamPctVisible[teamCharId] -= 50;
+			if (_teamPctVisible[teamCharId] < 0)
+				_teamPctVisible[teamCharId] = 0;
+		}
+
+		varA6 = true;
+	} break;
+	case 16: { // Fairy Dust
+		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
+		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
+		int16 varAE = sub15538(_mapPosX, _mapPosY);
+
+		if (_tileFact[varAE]._field0 == 0) {
+			totalPartyKill();
+			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+				retVal = true;
+			}
+			// emptyFunction(2);
+		} else {
+			if (varAE == 0 || varAE == 0x48) {
+				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					_messageToBePrinted += buffer1;
+					retVal = true;
+				}
+			} else {
+				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					_messageToBePrinted += buffer1;
+					retVal = true;
+				}
+			}
+		}
+
+		varA6 = true;
+	} break;
+	case 17: { // "Devil Dust"
+		_mapPosX = _items[itemId].field_19;
+		_mapPosY = _items[itemId].field_1A;
+		int16 varAE = sub15538(_mapPosX, _mapPosY);
+		if (_tileFact[varAE]._field0 == 0) {
+			totalPartyKill();
+			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+				retVal = true;
+			}
+			// emptyFunction(2);
+		} else {
+			if (varAE == 0 || varAE == 0x48) {
+				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					_messageToBePrinted += buffer1;
+					retVal = true;
+				}
+			} else {
+				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
+				if (argA == 2) {
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					_messageToBePrinted += buffer1;
+					retVal = true;
+				}
+			}
+		}
+
+		varA6 = true;
+	} break;
+	case 18:
+		if (argA == 2) {
+			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 teamCharId = windowId;
+			if (teamCharId != 0x1B) {
+				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
+					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
+					_teamCharStatus[teamCharId]._status = 0;
+					_teamCharStatus[teamCharId]._duration = 0;
+				} else {
+					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
+				}
+			}
+		}
+
+		varA6 = true;
+		break;
+	case 19: // "Junk"
+		buffer1 = "  * The item breaks!";
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += buffer1;
+		}
+		setCharacterObjectToBroken(charId, objectId);
+		varA6 = true;
+		break;
+	case 23: // "Divining Rod"
+		buffer1 = Common::String::format("The %s says, '", _items[itemId]._name);
+		if (_items[itemId].field_19 < _mapPosX) {
+			if (_items[itemId].field_1A < _mapPosY) {
+				buffer1 += "North West!";
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				buffer1 += "South West!";
+			} else {
+				buffer1 += "West!";
+			}
+		} else if (_items[itemId].field_19 > _mapPosX) {
+			if (_items[itemId].field_1A < _mapPosY) {
+				buffer1 += "North East!";
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				buffer1 += "South East!";
+			} else {
+				buffer1 += "East!";
+			}
+		} else { // equals _mapPosX
+			if (_items[itemId].field_1A < _mapPosY) {
+				buffer1 += "North!";
+			} else if (_items[itemId].field_1A > _mapPosY) {
+				buffer1 += "South!";
+			} else {
+				buffer1 += "Here!!!";
+			}
+		}
+		buffer1 += "'";
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += buffer1;
+			retVal = true;
+		}
+
+		varA6 = true;
+		break;
+	case 24: {
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else
+			teamCharId = windowId;
+
+		if (teamCharId != 0x1B) {
+			uint8 varAE = _items[itemId].field17_attackTypeDefense;
+			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
+				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
+			}
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s increased %d points!", kSkillArray[varAE], effectPoints);
+			else
+				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
+
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+				retVal = true;
+			}
+		}
+
+		varA6 = true;
+	} break;
+	case 25: {
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else
+			teamCharId = windowId;
+
+		if (teamCharId != 0x1B) {
+			uint8 varAE = _items[itemId].field17_attackTypeDefense;
+			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
+				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
+			}
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s lowered %d points!", kSkillArray[varAE], effectPoints);
+			else
+				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
+
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+				retVal = true;
+			}
+		}
+
+		varA6 = true;
+	} break;
+	case 26: // "Black Sphere"
+		buffer1 = "The entire party collapses, dead!!!";
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += buffer1;
+			retVal = true;
+		}
+		totalPartyKill();
+		// emptyFunction(2);
+		varA6 = true;
+		break;
+	case 27: { // "Magic Pyramid", "Razor Blade"
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else {
+			teamCharId = windowId;
+		}
+
+		if (teamCharId != 0x1B) {
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
+			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
+			if (argA == 2) {
+				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			} else {
+				_messageToBePrinted += buffer1;
+				retVal = true;
+			}
+			// emptyFunction(2);
+		}
+
+		varA6 = true;
+	} break;
+	case 28: // "Bugle"
+		if (argA == 2) {
+			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+		} else {
+			int16 teamCharId = windowId;
+			if (teamCharId != 0x1B) {
+				if (_teamCharStatus[teamCharId]._status == 0) {
+					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
+					_teamCharStatus[teamCharId]._status = 0;
+					_teamCharStatus[teamCharId]._duration = 0;
+				} else {
+					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
+				}
+			}
+		}
+
+		varA6 = true;
+		break;
+	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else {
+			teamCharId = windowId;
+		}
+
+		if (teamCharId != 0x1B) {
+			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
+				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
+
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
+			else
+				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
+		}
+
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += buffer1;
+			retVal = true;
+		}
+
+		varA6 = true;
+	} break;
+	case 30: {
+		int16 teamCharId;
+		if (argA == 2) {
+			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			teamCharId = selectOtherCharFromTeam();
+		} else {
+			teamCharId = windowId;
+		}
+
+		if (teamCharId != 0x1B) {
+			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
+			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
+				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
+
+			if (effectPoints > 1)
+				buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
+			else
+				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
+		}
+
+		if (argA == 2) {
+			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+		} else {
+			_messageToBePrinted += buffer1;
+			retVal = true;
+		}
+
+		varA6 = true;
+
+	} break;
+	case 3:
+	case 6:
+	case 7:
+	case 8:
+	case 9:
+	case 10:
+	case 11:
+	case 13:
+	case 20:
+	case 21:
+	case 22:
+	default:
+		break;
+	}
+
+	if (varA6) {
+		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
+			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
+			if (varA1 <= 0) {
+				buffer1 = "  * The item breaks!";
+				if (argA == 2) {
+					getLastCharAfterAnimCount(_guessAnimationAmount);
+					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				} else {
+					_messageToBePrinted += buffer1;
+				}
+				setCharacterObjectToBroken(charId, objectId);
+			} else {
+				_npcBuf[charId]._inventory[objectId]._stat1 &= 0x80;
+				_npcBuf[charId]._inventory[objectId]._stat1 |= 0xA1;
+			}
+		}
+
+		if (argA == 2) {
+			getLastCharAfterAnimCount(_guessAnimationAmount);
+			sub18E80(charId, windowId, menuId, curMenuLine);
+		}
+	}
+
+	return retVal;
+}
+
 } // End of namespace Efh
 
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 55eaf2198aa..1c7b3bd556d 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -219,6 +219,8 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		s.syncAsByte(_npcBuf[i].field_84);
 		s.syncAsByte(_npcBuf[i].field_85);
 	}
+
+	s.syncAsByte(_saveAuthorized);
 }
 
 } // End of namespace Efh


Commit: f0044571570f8c77885f52cbdcb49e588995efb5
    https://github.com/scummvm/scummvm/commit/f0044571570f8c77885f52cbdcb49e588995efb5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:42+01:00

Commit Message:
EFH: turn _unk2C8AA into a int16, lot of renaming related to monster moves

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 783376510cf..bff05a2791f 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -256,13 +256,13 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_fullPlaceId = 0xFF;
 	_guessAnimationAmount = 9;
 	_largeMapFlag = 0xFFFF;
+	_unk2C8AA = 0;
 	_teamCharId[0] = 0;
 	_teamCharId[1] = _teamCharId[2] = -1;
 
 	for (int i = 0; i < 3; ++i) {
 		_teamCharStatus[i]._status = 0;
 		_teamCharStatus[i]._duration = 0;
-		_unkArray2C8AA[i] = 0;
 		_teamPctVisible[i] = 0;
 		_word32482[i] = 0;
 		_teamNextAttack[i] = -1;
@@ -275,7 +275,6 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_stru32686[i].init();
 	}
 
-	_unkArray2C8AA[2] = 1;
 	_teamSize = 1;
 	_word2C872 = 0;
 	_imageSetSubFilesIdx = 144;
@@ -538,7 +537,7 @@ Common::Error EfhEngine::run() {
 		}
 
 		if (!_shouldQuit) {
-			sub174A0();
+			handleMapMonsterMoves();
 		}
 
 		if (_redrawNeededFl && !_shouldQuit) {
@@ -556,8 +555,8 @@ Common::Error EfhEngine::run() {
 			}
 		}
 
-		if (--_unkArray2C8AA[0] < 0 && !_shouldQuit)
-			_unkArray2C8AA[0] = 0;
+		if (_unk2C8AA > 0)
+			--_unk2C8AA;
 
 		if (isTPK()) {
 			if (handleDeathMenu())
@@ -806,7 +805,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapMonsters[i]._itemId_Weapon = mapMonstersPtr[29 * i + 5];
 		_mapMonsters[i]._field_6 = mapMonstersPtr[29 * i + 6];
 		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
-		_mapMonsters[i]._field_8 = mapMonstersPtr[29 * i + 8];
+		_mapMonsters[i]._moveInfo = mapMonstersPtr[29 * i + 8];
 		_mapMonsters[i]._field9_textId = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
@@ -1593,7 +1592,7 @@ void EfhEngine::resetGame() {
 	_oldMapPosX = _mapPosX = 31;
 	_oldMapPosY = _mapPosY = 31;
 	_unkRelatedToAnimImageSetId = 0;
-	_unkArray2C8AA[0] = 0;
+	_unk2C8AA = 0;
 }
 
 void EfhEngine::computeMapAnimation() {
@@ -1807,8 +1806,8 @@ bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 	return retVal;
 }
 
-bool EfhEngine::moveMonsterGroup(int16 monsterId) {
-	debugC(2, kDebugEngine, "moveMonsterGroup %d", monsterId);
+bool EfhEngine::moveMonsterGroupRandom(int16 monsterId) {
+	debugC(2, kDebugEngine, "moveMonsterGroupRandom %d", monsterId);
 
 	int16 rand100 = getRandom(100);
 
@@ -1846,20 +1845,17 @@ bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
 	return true;
 }
 
-bool EfhEngine::unkFct_checkMonsterField8(int16 id, bool teamFlag) {
-	debugC(6, kDebugEngine, "unkFct_checkMonsterField8 %d %s", id, teamFlag ? "True" : "False");
+bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
+	debugC(6, kDebugEngine, "checkMonsterMovementType %d %s", id, teamFlag ? "True" : "False");
 
 	int16 monsterId = id;
 	if (teamFlag)
 		monsterId = _teamMonsterIdArray[id];
 
-	if ((_mapMonsters[monsterId]._field_8 & 0xF) >= 8)
+	if ((_mapMonsters[monsterId]._moveInfo & 0xF) >= 8)
 		return true;
 
-	if (_unkArray2C8AA[0] == 0)
-		return false;
-
-	if ((_mapMonsters[monsterId]._field_8 & 0x80) != 0)
+	if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._moveInfo & 0x80) != 0)
 		return true;
 
 	return false;
@@ -1872,7 +1868,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 		return true;
 
 	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId && unkFct_checkMonsterField8(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon))
+		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon))
 			return false;
 	}
 
@@ -1897,14 +1893,11 @@ bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
 	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
 }
 
-void EfhEngine::sub174A0() {
-	debug("sub174A0");
-
-	static int16 sub174A0_monsterPosX = -1;
-	static int16 sub174A0_monsterPosY = -1;
+void EfhEngine::handleMapMonsterMoves() {
+	debug("handleMapMonsterMoves");
 
 	_redrawNeededFl = true;
-	int16 unkMonsterId = -1;
+	int16 attackMonsterId = -1;
 	int16 mapSize = _largeMapFlag ? 63 : 23;
 	int16 minDisplayedMapX = CLIP<int16>(_mapPosX - 10, 0, mapSize);
 	int16 minDisplayedMapY = CLIP<int16>(_mapPosY - 9, 0, mapSize);
@@ -1921,82 +1914,79 @@ void EfhEngine::sub174A0() {
 		if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 			continue;
 
-		int16 var4 = _mapMonsters[monsterId]._posX;
-		int16 var2 = _mapMonsters[monsterId]._posY;
+		int16 previousPosX = _mapMonsters[monsterId]._posX;
+		int16 previousPosY = _mapMonsters[monsterId]._posY;
 
-		if (var4 < minDisplayedMapX || var4 > maxDisplayedMapX || var2 < minDisplayedMapY || var2 > maxDisplayedMapY)
+		if (previousPosX < minDisplayedMapX || previousPosX > maxDisplayedMapX || previousPosY < minDisplayedMapY || previousPosY > maxDisplayedMapY)
 			continue;
 
 		bool monsterMovedFl = false;
 		int16 lastRangeCheck = 0;
 
-		sub174A0_monsterPosX = _mapMonsters[monsterId]._posX;
-		sub174A0_monsterPosY = _mapMonsters[monsterId]._posY;
-		int8 var1C = _mapMonsters[monsterId]._field_8 & 0xF;
+		int8 monsterMoveType = _mapMonsters[monsterId]._moveInfo & 0xF; // 0000 1111
 
-		if (_unkArray2C8AA[0] != 0 && (_mapMonsters[monsterId]._field_8 & 0x80))
-			var1C = 9;
+		if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._moveInfo & 0x80)) // 1000 0000
+			monsterMoveType = 9;
 
-		int16 var1E = _mapMonsters[monsterId]._field_8 & 0x70;
-		var1E >>= 4;
+		int16 randomModPct = _mapMonsters[monsterId]._moveInfo & 0x70; // 0111 0000
+		randomModPct >>= 4; // Max 7 (0111)
 
-		int16 var16 = var1E;
+		int16 retryCounter = randomModPct;
 		do {
-			switch (var1C - 1) {
+			switch (monsterMoveType - 1) {
 			case 0:
-				if (getRandom(100) >= 0xE - var1E)
+				if (getRandom(100) >= 14 - randomModPct)
 					monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 				else
-					monsterMovedFl = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 1:
-				if (getRandom(100) >= 0xE - var1E)
+				if (getRandom(100) >= 14 - randomModPct)
 					monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 				else
-					monsterMovedFl = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 2:
 				monsterMovedFl = moveMonsterGroupOther(monsterId, getRandom(8));
 				break;
 			case 3:
-				monsterMovedFl = moveMonsterGroup(monsterId);
+				monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 4:
-				if (getRandom(100) > 0x32 - var1E)
+				if (getRandom(100) > 50 - randomModPct)
 					monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 				else
-					monsterMovedFl = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 5:
-				if (getRandom(100) > 0x32 - var1E)
+				if (getRandom(100) > 50 - randomModPct)
 					monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 				else
-					monsterMovedFl = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 6:
-				if (getRandom(100) >= 0x32 - var1E)
-					monsterMovedFl = moveMonsterGroup(monsterId);
+				if (getRandom(100) >= 50 - randomModPct)
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			case 7:
-				// var14 is not a typo.
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				break;
 			case 8:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				if (lastRangeCheck == 0) {
-					if (getRandom(100) >= 0xE - var1E)
+					if (getRandom(100) >= 14 - randomModPct)
 						monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 					else
-						monsterMovedFl = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				}
 				break;
 			case 9:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				if (lastRangeCheck == 0) {
-					if (getRandom(100) >= 0xE - var1E)
+					if (getRandom(100) >= 14 - randomModPct)
 						monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 					else
-						monsterMovedFl = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				}
 				break;
 			case 10:
@@ -2008,31 +1998,31 @@ void EfhEngine::sub174A0() {
 			case 11:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				if (lastRangeCheck == 0) {
-					monsterMovedFl = moveMonsterGroup(monsterId);
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				}
 				break;
 			case 12:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				if (lastRangeCheck == 0) {
-					if (getRandom(100) >= 0x32 - var1E)
+					if (getRandom(100) >= 50 - randomModPct)
 						monsterMovedFl = moveMonsterTowardsTeam(monsterId);
 					else
-						monsterMovedFl = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				}
 				break;
 			case 13:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
 				if (lastRangeCheck == 0) {
-					if (getRandom(100) >= 0x32 - var1E)
+					if (getRandom(100) >= 50 - randomModPct)
 						monsterMovedFl = moveMonsterAwayFromTeam(monsterId);
 					else
-						monsterMovedFl = moveMonsterGroup(monsterId);
+						monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				}
 				break;
 			case 14:
 				lastRangeCheck = checkMonsterWeaponRange(monsterId);
-				if (lastRangeCheck == 0 && getRandom(100) >= 0x32 - var1E)
-					monsterMovedFl = moveMonsterGroup(monsterId);
+				if (lastRangeCheck == 0 && getRandom(100) >= 50 - randomModPct)
+					monsterMovedFl = moveMonsterGroupRandom(monsterId);
 				break;
 			default:
 				break;
@@ -2043,35 +2033,35 @@ void EfhEngine::sub174A0() {
 					if (lastRangeCheck == 0) {
 						monsterMovedFl = true;
 					} else {
-						unkMonsterId = monsterId;
+						attackMonsterId = monsterId;
 						monsterMovedFl = true;
 					}
 				} else {
 					int8 var18 = sub16B08(monsterId);
 
 					if (var18 == 0) {
-						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
-						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
+						_mapMonsters[monsterId]._posX = previousPosX;
+						_mapMonsters[monsterId]._posY = previousPosY;
 						monsterMovedFl = false;
-						--var16;
+						--retryCounter;
 					} else if (var18 == 2) {
-						_mapMonsters[monsterId]._posX = sub174A0_monsterPosX;
-						_mapMonsters[monsterId]._posY = sub174A0_monsterPosY;
+						_mapMonsters[monsterId]._posX = previousPosX;
+						_mapMonsters[monsterId]._posY = previousPosY;
 					}
 				}
 
-				if (!monsterMovedFl && var16 == 1 && var1E > 1) {
+				if (!monsterMovedFl && retryCounter == 1 && randomModPct > 1) {
 					monsterMovedFl = moveMonsterGroupOther(monsterId, getRandom(8));
 					continue;
 				}
 
 				break;
 			}
-		} while (!monsterMovedFl && var16 > 0);
+		} while (!monsterMovedFl && retryCounter > 0);
 	}
 
-	if (unkMonsterId != -1)
-		handleFight(unkMonsterId);
+	if (attackMonsterId != -1)
+		handleFight(attackMonsterId);
 }
 
 bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
@@ -2723,7 +2713,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 		if (monsterId == -1)
 			continue;
 
-		if (!unkFct_checkMonsterField8(monsterId, false))
+		if (!checkMonsterMovementType(monsterId, false))
 			continue;
 
 		retVal = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
@@ -2834,8 +2824,8 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 }
 
 
-void EfhEngine::setMapMonsterField8(int16 id, uint8 mask, bool groupFl) {
-	debugC(2, kDebugEngine, "setMapMonsterField8 %d 0x%X %s", id, mask, groupFl ? "True" : "False");
+void EfhEngine::setMapMonsterField8(int16 id, uint8 movementType, bool groupFl) {
+	debugC(2, kDebugEngine, "setMapMonsterField8 %d 0x%X %s", id, movementType, groupFl ? "True" : "False");
 
 	int16 monsterId;
 	if (groupFl) { // groupFl is always True
@@ -2844,9 +2834,9 @@ void EfhEngine::setMapMonsterField8(int16 id, uint8 mask, bool groupFl) {
 		monsterId = id;
 	}
 
-	mask &= 0x0F;
-	_mapMonsters[monsterId]._field_8 &= 0xF0;
-	_mapMonsters[monsterId]._field_8 |= mask;
+	movementType &= 0x0F;
+	_mapMonsters[monsterId]._moveInfo &= 0xF0;
+	_mapMonsters[monsterId]._moveInfo |= movementType;
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
@@ -3068,7 +3058,7 @@ void EfhEngine::loadEfhGame() {
 
 	_teamSize = f.readSint16LE();
 
-	_unkArray2C8AA[0] = f.readSint16LE();
+	_unk2C8AA = f.readSint16LE();
 
 	_word2C872 = f.readSint16LE();
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b59fac80aca..2e9e1eb2659 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -211,7 +211,7 @@ struct MapMonster {
 	uint8 _itemId_Weapon;
 	uint8 _field_6;
 	uint8 _monsterRef;
-	uint8 _field_8;
+	uint8 _moveInfo; // abbb cccc a: special move flag, bbb: Pct modifier for random move, cccc movement type
 	uint8 _field9_textId;
 	uint8 _groupSize;
 	int16 _pictureRef[9];
@@ -337,14 +337,14 @@ private:
 	bool moveMonsterAwayFromTeam(int16 monsterId);
 	bool moveMonsterTowardsTeam(int16 monsterId);
 	bool moveMonsterGroupOther(int16 monsterId, int16 direction);
-	bool moveMonsterGroup(int16 monsterId);
+	bool moveMonsterGroupRandom(int16 monsterId);
 	int16 computeMonsterGroupDistance(int16 monsterId);
 	bool checkWeaponRange(int16 monsterId, int16 weaponId);
-	bool unkFct_checkMonsterField8(int16 id, bool teamFlag);
+	bool checkMonsterMovementType(int16 id, bool teamFlag);
 	bool checkTeamWeaponRange(int16 monsterId);
 	bool checkIfMonsterOnSameLargeMapPlace(int16 monsterId);
 	bool checkMonsterWeaponRange(int16 monsterId);
-	void sub174A0();
+	void handleMapMonsterMoves();
 	bool checkPictureRefAvailability(int16 monsterId);
 	void displayMonsterAnim(int16 monsterId);
 	int16 countPictureRef(int16 id, bool teamMemberFl);
@@ -365,7 +365,7 @@ private:
 	int16 getXPLevel(int32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
-	void setMapMonsterField8(int16 id, uint8 mask, bool groupFl);
+	void setMapMonsterField8(int16 id, uint8 movementType, bool groupFl);
 	bool isMonsterActive(int16 groupId, int16 id);
 	int16 sub15538(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
@@ -571,7 +571,7 @@ private:
 
 	int16 _teamMonsterIdArray[5];
 	CharStatus _teamCharStatus[3];
-	int16 _unkArray2C8AA[3];
+	int16 _unk2C8AA;
 	int16 _teamLastAction[3];
 	int16 _teamSize;
 	int16 _word2C872;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 0e375cafaea..0a5946051a7 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -157,7 +157,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 						break;
 					}
 				}
-			} else if (unkFct_checkMonsterField8(monsterGroupIdOrMonsterId, true)) {
+			} else if (checkMonsterMovementType(monsterGroupIdOrMonsterId, true)) {
 				// handleFight - Loop on var86 - Start
 				for (uint var86 = 0; var86 < 9; ++var86) {
 					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
@@ -367,7 +367,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			}
 		}
 
-		sub174A0();
+		handleMapMonsterMoves();
 		sub1BE9A(monsterId);
 	}
 
@@ -455,9 +455,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
 				if (isMonsterActive(groupId, var7E) && var6E) {
 					int16 var5C;
-					if (unkFct_checkMonsterField8(groupId, true)) {
+					if (checkMonsterMovementType(groupId, true)) {
 						setMapMonsterField8(groupId, 9, true);
-						_unkArray2C8AA[0] += 500;
+						_unk2C8AA += 500;
 						var5C = -1;
 					} else
 						var5C = 0;
@@ -1351,7 +1351,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		}
 
 		setTextPos(228, textPosY);
-		if (unkFct_checkMonsterField8(counter, true)) {
+		if (checkMonsterMovementType(counter, true)) {
 			_textColor = 0xE;
 			displayStringAtTextPos("Hostile");
 		} else {
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 5ed31e12ad8..08a9cc0218e 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -992,7 +992,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
-			_unkArray2C8AA[0] = 0;
+			_unk2C8AA = 0;
 		}
 
 		varA6 = true;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 1c7b3bd556d..776a96b4ff8 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -138,7 +138,7 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 	}
 
 	s.syncAsSint16LE(_teamSize);
-	s.syncAsSint16LE(_unkArray2C8AA[0]);
+	s.syncAsSint16LE(_unk2C8AA);
 	s.syncAsSint16LE(_word2C872);
 	s.syncAsSint16LE(_imageSetSubFilesIdx);
 	s.syncAsSint16LE(_mapPosX);
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index be42723e2f5..81d6c5be309 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -311,7 +311,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x11:
 			if (flag)
-				_unkArray2C8AA[0] = 0;
+				_unk2C8AA = 0;
 			break;
 		case 0x12:
 			// Guess : disable special tile { }
@@ -465,7 +465,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x1F:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag)
-				_unkArray2C8AA[0] = scriptNumberArray[0];
+				_unk2C8AA = scriptNumberArray[0];
 
 			break;
 		case 0x20:


Commit: 1708c03287ef5193472d456a71b60360715b5733
    https://github.com/scummvm/scummvm/commit/1708c03287ef5193472d456a71b60360715b5733
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Fix endian issue, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index bff05a2791f..8a2e7305403 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1394,7 +1394,7 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 
 	for (int16 var4 = varC; var4 <= var8; ++var4) {
 		for (int16 var2 = varA; var2 <= var6; ++var2) {
-			_techDataArr[_techId][var2 + var4 * 64] = varD;
+			WRITE_LE_INT16(&_techDataArr[_techId][var2 + var4 * 64], varD);
 		}
 	}
 }
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 81d6c5be309..3cc258f5b86 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -59,7 +59,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 
 	bool doneFlag = false;
 	int16 var_F2 = -1;
-	int16 var_F0 = 0xFF;
+	int16 retVal = 0xFF;
 	int16 var_EE = 0xFF;
 	uint16 curLineNb = 0;
 	int16 numbLines = (1 + maxY - posY) / 9;
@@ -288,9 +288,9 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				}
 
 				if (found)
-					var_F0 = scriptNumberArray[1];
+					retVal = scriptNumberArray[1];
 				else
-					var_F0 = scriptNumberArray[2];
+					retVal = scriptNumberArray[2];
 			}
 			break;
 		case 0x0F:
@@ -298,15 +298,15 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (flag) {
 				int16 var110 = scriptNumberArray[0];
 				if (isCharacterATeamMember(var110))
-					var_F0 = scriptNumberArray[1];
+					retVal = scriptNumberArray[1];
 				else
-					var_F0 = scriptNumberArray[2];
+					retVal = scriptNumberArray[2];
 			}
 			break;
 		case 0x10:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag)
-				var_F0 = scriptNumberArray[0];
+				retVal = scriptNumberArray[0];
 
 			break;
 		case 0x11:
@@ -328,7 +328,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				loadPlacesFile(scriptNumberArray[0], false);
 				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
 				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
-				var_F0 = -1;
+				retVal = -1;
 			}
 			break;
 		case 0x14:
@@ -338,7 +338,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				int16 var110 = scriptNumberArray[0];
 				if (!isCharacterATeamMember(var110))
 					var_EE = var110;
-				var_F0 = -1;
+				retVal = -1;
 			}
 			break;
 		case 0x15:
@@ -457,9 +457,9 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
 				if (_history[scriptNumberArray[0]] == 0)
-					var_F0 = scriptNumberArray[2];
+					retVal = scriptNumberArray[2];
 				else
-					var_F0 = scriptNumberArray[1];
+					retVal = scriptNumberArray[1];
 			}
 			break;
 		case 0x1F:
@@ -490,7 +490,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		refreshTeamSize();
 	}
 
-	return var_F0;
+	return retVal;
 }
 
 } // End of namespace Efh


Commit: 6aea8334bc04e261a0b61790e33b9a1aa266c070
    https://github.com/scummvm/scummvm/commit/6aea8334bc04e261a0b61790e33b9a1aa266c070
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Verify some more functions, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8a2e7305403..9b131dc0dd0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -163,8 +163,8 @@ void Stru32686::init() {
 	}
 }
 
-void Stru3244C::init() {
-	_field0 = _field2 = 0;
+void InitiativeStruct::init() {
+	_id = _initiative = 0;
 }
 
 void TileFactStruct::init() {
@@ -307,7 +307,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 
 	_messageToBePrinted = "";
 	for (int i = 0; i < 8; ++i)
-		_stru3244C[i].init();
+		_initiatives[i].init();
 
 	memset(_bufferCharBM, 0, ARRAYSIZE(_bufferCharBM));
 	for (int i = 0; i < 3; ++i)
@@ -749,7 +749,7 @@ void EfhEngine::initEngine() {
 }
 
 void EfhEngine::initMapMonsters() {
-	debug("initMapMonsters");
+	debugC(3, kDebugEngine, "initMapMonsters");
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
 		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
@@ -760,8 +760,11 @@ void EfhEngine::initMapMonsters() {
 
 		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
 		if (groupSize == 0)
-			groupSize = getRandom(10);
+			groupSize = getRandom(10) - 1;
 
+		if (groupSize == 0)
+			continue;
+		
 		for (uint counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
 			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._monsterRef]._pictureRef;
@@ -780,7 +783,7 @@ void EfhEngine::initMapMonsters() {
 }
 
 void EfhEngine::loadMapArrays(int idx) {
-	debug("loadMapArrays %d", idx);
+	debugC(6, kDebugEngine, "loadMapArrays %d", idx);
 
 	uint8 *_mapUnknownPtr = &_mapArr[idx][2];
 
@@ -798,7 +801,7 @@ void EfhEngine::loadMapArrays(int idx) {
 
 	for (int i = 0; i < 64; ++i) {
 		_mapMonsters[i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
-		_mapMonsters[i]._field_1 = mapMonstersPtr[29 * i + 1];
+		_mapMonsters[i]._npcId = mapMonstersPtr[29 * i + 1];
 		_mapMonsters[i]._guess_fullPlaceId = mapMonstersPtr[29 * i + 2];
 		_mapMonsters[i]._posX = mapMonstersPtr[29 * i + 3];
 		_mapMonsters[i]._posY = mapMonstersPtr[29 * i + 4];
@@ -983,7 +986,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 				int16 var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
 				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
 
-				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._field_1))
+				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._npcId))
 					continue;
 
 				int16 drawPosX = 128 + (posX - minX) * 16;
@@ -1685,7 +1688,7 @@ int8 EfhEngine::sub16B08(int16 monsterId) {
 			return 0;
 	}
 
-	return sub15581(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, 0);
+	return sub15581(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, false);
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
@@ -2139,10 +2142,10 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		return true;
 	}
 
-	if (isCharacterATeamMember(_mapMonsters[monsterId]._field_1))
+	if (isCharacterATeamMember(_mapMonsters[monsterId]._npcId))
 		return false;
 
-	int16 var58 = _mapMonsters[monsterId]._field_1;
+	int16 var58 = _mapMonsters[monsterId]._npcId;
 	switch (_npcBuf[var58].field_10 - 0xEE) {
 	case 0:
 		if (arg2 == 4 && _npcBuf[var58].field_11 == itemId) {
@@ -2487,15 +2490,15 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	return false;
 }
 
-int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
-	debug("sub15581 %d-%d %d", mapPosX, mapPosY, arg4);
+int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, bool arg4) {
+	debug("sub15581 %d-%d %s", mapPosX, mapPosY, arg4 ? "true" : "false");
 
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
 	imageSetId *= 72;
 	imageSetId += curTileInfo % 72;
 
-	if (arg4 == 1) {
+	if (arg4) {
 		sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, imageSetId);
 	}
 
@@ -2504,7 +2507,7 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 		return -1;
 	}
 	if (_tileFact[imageSetId]._field1 != 0xFF && !_dbgForceMonsterBlock) {
-		if ((arg4 == 1) || (arg4 == 0 && imageSetId != 128 && imageSetId != 121)) {
+		if ((arg4) || (!arg4 && imageSetId != 128 && imageSetId != 121)) {
 			if (_largeMapFlag) {
 				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
 			} else {
@@ -2521,36 +2524,36 @@ int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, int16 arg4) {
 	return _tileFact[imageSetId]._field0;
 }
 
-void EfhEngine::sub1CDFA() {
-	debug("sub1CDFA"); // Initiatives
+void EfhEngine::computeInitiatives() {
+	debugC(6, kDebugEngine, "computeInitiatives");
 
 	for (int counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
-			_stru3244C[counter]._field0 = counter + 1000;
-			_stru3244C[counter]._field2 = _npcBuf[_teamCharId[counter]]._infoScore[3];
+			_initiatives[counter]._id = counter + 1000;
+			_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3];
 		} else {
-			_stru3244C[counter]._field0 = -1;
-			_stru3244C[counter]._field2 = -1;
+			_initiatives[counter]._id = -1;
+			_initiatives[counter]._initiative = -1;
 		}
 	}
 
 	for (int counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == -1) {
-			_stru3244C[counter + 3]._field0 = -1;
-			_stru3244C[counter + 3]._field2 = -1;
+			_initiatives[counter + 3]._id = -1;
+			_initiatives[counter + 3]._initiative = -1;
 		} else {
-			_stru3244C[counter + 3]._field0 = counter;
-			_stru3244C[counter + 3]._field2 = _mapMonsters[_teamMonsterIdArray[counter]]._field_1 + getRandom(20);
+			_initiatives[counter + 3]._id = counter;
+			_initiatives[counter + 3]._initiative = _mapMonsters[_teamMonsterIdArray[counter]]._npcId + getRandom(20);
 		}
 	}
 
 	for (uint counter = 0; counter < 8; ++counter) {
 		for (uint counter2 = 0; counter2 < 8; ++counter2) {
-			if (_stru3244C[counter]._field2 >= _stru3244C[counter2]._field2)
+			if (_initiatives[counter]._initiative >= _initiatives[counter2]._initiative)
 				continue;
 
-			SWAP(_stru3244C[counter]._field0, _stru3244C[counter2]._field0);
-			SWAP(_stru3244C[counter]._field2, _stru3244C[counter2]._field2);
+			SWAP(_initiatives[counter]._id, _initiatives[counter2]._id);
+			SWAP(_initiatives[counter]._initiative, _initiatives[counter2]._initiative);
 		}
 	}
 }
@@ -2652,7 +2655,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 				if (_mapMonsters[counter1]._guess_fullPlaceId == 0xFF)
 					continue;
 
-				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._field_1)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._npcId)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(counter1)) {
 						bool var6 = false;
 						for (uint counter2 = 0; counter2 < 9; ++counter2) {
@@ -2892,7 +2895,7 @@ bool EfhEngine::checkMonsterCollision() {
 			continue;
 
 		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
-		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isCharacterATeamMember(_mapMonsters[monsterId]._field_1)))
+		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isCharacterATeamMember(_mapMonsters[monsterId]._npcId)))
 			continue;
 
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
@@ -2926,7 +2929,7 @@ bool EfhEngine::checkMonsterCollision() {
 					dest = "(NOT DEFINED)";
 				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
 					// Special character name
-					dest = _npcBuf[_mapMonsters[monsterId]._field_1]._name;
+					dest = _npcBuf[_mapMonsters[monsterId]._npcId]._name;
 					buffer = Common::String("with ") + dest;
 				}
 
@@ -2988,7 +2991,7 @@ bool EfhEngine::checkMonsterCollision() {
 		return true;
 	}
 
-	int8 check = sub15581(_mapPosX, _mapPosY, 1);
+	int8 check = sub15581(_mapPosX, _mapPosY, true);
 	if (check == 0 || check == 2)
 		return false;
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 2e9e1eb2659..cb927cc8220 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -204,7 +204,7 @@ struct CharStatus {
 
 struct MapMonster {
 	uint8 _possessivePronounSHL6;
-	uint8 _field_1;
+	uint8 _npcId;
 	uint8 _guess_fullPlaceId; // unsigned? Magic values are 0xFF and 0xFE
 	uint8 _posX;
 	uint8 _posY;
@@ -224,9 +224,9 @@ struct Stru32686 {
 	void init();
 };
 
-struct Stru3244C {
-	int16 _field0;
-	int16 _field2;
+struct InitiativeStruct {
+	int16 _id;
+	int16 _initiative;
 
 	void init();
 };
@@ -353,8 +353,8 @@ private:
 	void sub221D2(int16 monsterId);
 	void displayImp1Text(int16 textId);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
-	int8 sub15581(int16 mapPosX, int16 mapPosY, int16 arg4);
-	void sub1CDFA();
+	int8 sub15581(int16 mapPosX, int16 mapPosY, bool arg4);
+	void computeInitiatives();
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
 	void sub1CAB6(int16 charId);
@@ -605,7 +605,7 @@ private:
 
 	int16 _menuStatItemArr[15];
 	Stru32686 _stru32686[5];
-	Stru3244C _stru3244C[8];
+	InitiativeStruct _initiatives[8];
 };
 
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 0a5946051a7..7e391f61460 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -40,7 +40,7 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 				continue;
 
-			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._field_1)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._npcId)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
 				continue;
 
 			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
@@ -128,11 +128,11 @@ bool EfhEngine::handleFight(int16 monsterId) {
 				mainLoopCond = true;
 		}
 
-		sub1CDFA();
+		computeInitiatives();
 		sub1C219("", 2, 1, false);
 
 		for (uint counter = 0; counter < 8; ++counter) {
-			int16 monsterGroupIdOrMonsterId = _stru3244C[counter]._field0;
+			int16 monsterGroupIdOrMonsterId = _initiatives[counter]._id;
 			if (monsterGroupIdOrMonsterId == -1)
 				continue;
 			if (monsterGroupIdOrMonsterId > 999) { // Team Member
@@ -195,7 +195,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 hitPoints = 0;
 								int16 originalDamage = 0;
 								int16 damagePointsAbsorbed = 0;
-								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._field_1 * _items[unk_monsterField5_itemId]._attacks;
+								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[unk_monsterField5_itemId]._attacks;
 								for (int var84 = 0; var84 < var64; ++var84) {
 									// handleFight - Loop var84 on var64 (objectId) - Start
 									if (getRandom(100) > _word32482[var7E])
@@ -1346,7 +1346,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		} else if (var1 == 0x3E) {
 			displayStringAtTextPos("(NOT DEFINED)");
 		} else if (var1 == 0x3F) {
-			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._field_1]._name;
+			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._npcId]._name;
 			displayStringAtTextPos(stringToDisplay);
 		}
 


Commit: 968499e2dc670cb2f8d4a137242fb7485a91f8db
    https://github.com/scummvm/scummvm/commit/968499e2dc670cb2f8d4a137242fb7485a91f8db
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Renaming, validate some more functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/menu.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9b131dc0dd0..af7c9f7e1fb 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -168,7 +168,7 @@ void InitiativeStruct::init() {
 }
 
 void TileFactStruct::init() {
-	_field0 = _field1 = 0;
+	_field0 = _tileId = 0;
 }
 
 EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) {
@@ -947,11 +947,11 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 		int16 drawPosX = 128;
 		for (int16 counterX = minX; counterX <= maxX; ++counterX) {
 			if (largeMapFl) {
-				int16 idx = _mapGameMap[counterX][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[idx], drawPosX, drawPosY);
+				int16 curTile = _mapGameMap[counterX][counterY];
+				displayRawDataAtPos(_imageSetSubFilesArray[curTile], drawPosX, drawPosY);
 			} else {
-				int16 idx = _curPlace[counterX][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[idx], drawPosX, drawPosY);
+				int16 curTile = _curPlace[counterX][counterY];
+				displayRawDataAtPos(_imageSetSubFilesArray[curTile], drawPosX, drawPosY);
 			}
 			drawPosX += 16;
 		}
@@ -1345,32 +1345,32 @@ void EfhEngine::displayMiddleLeftTempText(uint8 *impArray, bool flag) {
 	}
 }
 
-void EfhEngine::sub15A28(int16 arg0, int16 arg2) {
-	debug("sub15A28 %d %d", arg0, arg2);
+void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
+	debug("transitionMap %d %d", centerX, centerY);
 
 	_drawHeroOnMapFl = false;
-	int16 varE = arg0 - 11;
-	int16 varC = arg2 - 11;
+	int16 minX = centerX - 11;
+	int16 minY = centerY - 11;
 
-	if (varE < 0)
-		varE = 0;
-	if (varC < 0)
-		varC = 0;
+	if (minX < 0)
+		minX = 0;
+	if (minY < 0)
+		minY = 0;
 
-	for (uint counter = 0; counter <= 23; counter += 2) {
-		for (uint var8 = 0; var8 <= 23; ++var8) {
-			int16 var4 = counter + varE;
-			int16 var2 = var8 + varC;
-			_mapGameMap[var4][var2] = _curPlace[counter][var8];
+	for (uint counterX = 0; counterX <= 23; counterX += 2) {
+		for (uint counterY = 0; counterY <= 23; ++counterY) {
+			int16 curX = counterX + minX;
+			int16 curY = counterY + minY;
+			_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
 
-	for (uint counter = 1; counter <= 23; counter += 2) {
-		for (uint var8 = 0; var8 <= 23; ++var8) {
-			int16 var4 = counter + varE;
-			int16 var2 = var8 + varC;
-			_mapGameMap[var4][var2] = _curPlace[counter][var8];
+	for (uint counterX = 1; counterX <= 23; counterX += 2) {
+		for (uint counterY = 0; counterY <= 23; ++counterY) {
+			int16 curX = counterX + minX;
+			int16 curY = counterY + minY;
+			_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
@@ -1603,43 +1603,31 @@ void EfhEngine::computeMapAnimation() {
 
 	const int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
-	int16 minMapX = _mapPosX - 5;
-	int16 minMapY = _mapPosY - 4;
-
-	if (minMapX < 0)
-		minMapX = 0;
-	if (minMapY < 0)
-		minMapY = 0;
-
-	int16 maxMapX = minMapX + 10;
-	int16 maxMapY = minMapY + 7;
-
-	if (maxMapX > maxMapBlocks)
-		maxMapX = maxMapBlocks;
-	if (maxMapY > maxMapBlocks)
-		maxMapY = maxMapBlocks;
+	int16 minMapX = CLIP<int16>(_mapPosX - 5, 0, maxMapBlocks);
+	int16 minMapY = CLIP<int16>(_mapPosY - 4, 0, maxMapBlocks);
+	int16 maxMapX = CLIP<int16>(minMapX + 10, 0, maxMapBlocks);
+	int16 maxMapY = CLIP<int16>(minMapY + 7, 0, maxMapBlocks);
 
 	for (int16 counterY = minMapY; counterY < maxMapY; ++counterY) {
 		for (int16 counterX = minMapX; counterX < maxMapX; ++counterX) {
+			if (_currentTileBankImageSetId[0] != 0)
+				continue;
+
 			if (_largeMapFlag) {
-				if (_currentTileBankImageSetId[0] != 0)
-					continue;
-				uint8 var4 = _mapGameMap[counterX][counterY];
-				if (var4 >= 1 && var4 <= 0xF) {
+				uint8 curTile = _mapGameMap[counterX][counterY];
+				if (curTile >= 1 && curTile <= 0xF) {
 					if (getRandom(100) < 50)
 						_mapGameMap[counterX][counterY] += 0xC5;
-				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
+				} else if (curTile >= 0xC6 && curTile <= 0xD5) {
 					if (getRandom(100) < 50)
 						_mapGameMap[counterX][counterY] -= 0xC5;
 				}
 			} else {
-				if (_currentTileBankImageSetId[0] != 0)
-					continue;
-				uint8 var4 = _curPlace[counterX][counterY];
-				if (var4 >= 1 && var4 <= 0xF) {
+				uint8 curTile = _curPlace[counterX][counterY];
+				if (curTile >= 1 && curTile <= 0xF) {
 					if (getRandom(100) < 50)
 						_curPlace[counterX][counterY] += 0xC5;
-				} else if (var4 >= 0xC6 && var4 <= 0xD5) {
+				} else if (curTile >= 0xC6 && curTile <= 0xD5) {
 					if (getRandom(100) < 50)
 						_curPlace[counterX][counterY] -= 0xC5;
 				}
@@ -1665,8 +1653,8 @@ void EfhEngine::handleAnimations() {
 	computeMapAnimation();
 }
 
-int8 EfhEngine::sub16B08(int16 monsterId) {
-	debugC(3, kDebugEngine,"sub16B08 %d", monsterId);
+int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
+	debugC(3, kDebugEngine,"checkMonsterMoveCollisionAndTileTexture %d", monsterId);
 
 	int16 maxSize = _largeMapFlag ? 63 : 23;
 	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
@@ -1688,7 +1676,7 @@ int8 EfhEngine::sub16B08(int16 monsterId) {
 			return 0;
 	}
 
-	return sub15581(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, false);
+	return checkTileStatus(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, false);
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
@@ -1897,7 +1885,7 @@ bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
 }
 
 void EfhEngine::handleMapMonsterMoves() {
-	debug("handleMapMonsterMoves");
+	debugC(3, kDebugEngine, "handleMapMonsterMoves");
 
 	_redrawNeededFl = true;
 	int16 attackMonsterId = -1;
@@ -2040,14 +2028,14 @@ void EfhEngine::handleMapMonsterMoves() {
 						monsterMovedFl = true;
 					}
 				} else {
-					int8 var18 = sub16B08(monsterId);
+					int8 checkMoveFl = checkMonsterMoveCollisionAndTileTexture(monsterId);
 
-					if (var18 == 0) {
+					if (checkMoveFl == 0) { // Blocked
 						_mapMonsters[monsterId]._posX = previousPosX;
 						_mapMonsters[monsterId]._posY = previousPosY;
 						monsterMovedFl = false;
 						--retryCounter;
-					} else if (var18 == 2) {
+					} else if (checkMoveFl == 2) { // Wall
 						_mapMonsters[monsterId]._posX = previousPosX;
 						_mapMonsters[monsterId]._posY = previousPosY;
 					}
@@ -2145,36 +2133,36 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	if (isCharacterATeamMember(_mapMonsters[monsterId]._npcId))
 		return false;
 
-	int16 var58 = _mapMonsters[monsterId]._npcId;
-	switch (_npcBuf[var58].field_10 - 0xEE) {
+	int16 npcId = _mapMonsters[monsterId]._npcId;
+	switch (_npcBuf[npcId].field_10 - 0xEE) {
 	case 0:
-		if (arg2 == 4 && _npcBuf[var58].field_11 == itemId) {
+		if (arg2 == 4 && _npcBuf[npcId].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			displayImp1Text(_npcBuf[var58].field14_textId);
+			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
 		break;
 	case 1:
-		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
+		if (arg2 == 2 && _npcBuf[npcId].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			displayImp1Text(_npcBuf[var58].field14_textId);
+			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
 		break;
 	case 2:
-		if (arg2 == 1 && _npcBuf[var58].field_11 == itemId) {
+		if (arg2 == 1 && _npcBuf[npcId].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			displayImp1Text(_npcBuf[var58].field14_textId);
+			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
 		break;
 	case 3:
-		if (_history[_npcBuf[var58].field_11] != 0) {
+		if (_history[_npcBuf[npcId].field_11] != 0) {
 			displayMonsterAnim(monsterId);
-			displayImp1Text(_npcBuf[var58].field14_textId);
+			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2182,10 +2170,10 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 4:
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field_11) {
 					removeObject(_teamCharId[counter], charId);
 					displayMonsterAnim(monsterId);
-					displayImp1Text(_npcBuf[var58].field14_textId);
+					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
 					return true;
 				}
@@ -2193,9 +2181,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 5:
-		if (arg2 == 2 && _npcBuf[var58].field_11 == itemId) {
+		if (arg2 == 2 && _npcBuf[npcId].field_11 == itemId) {
 			displayMonsterAnim(monsterId);
-			displayImp1Text(_npcBuf[var58].field14_textId);
+			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
 			return true;
 		}
@@ -2203,9 +2191,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 6:
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[var58].field_11) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field_11) {
 					displayMonsterAnim(monsterId);
-					displayImp1Text(_npcBuf[var58].field14_textId);
+					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
 					return true;
 				}
@@ -2214,10 +2202,10 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 7:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
 				removeCharacterFromTeam(counter);
 				displayMonsterAnim(monsterId);
-				displayImp1Text(_npcBuf[var58].field14_textId);
+				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
 				return true;
 			}
@@ -2225,9 +2213,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 8:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
-				_enemyNamePt2 = _npcBuf[var58]._name;
+				_enemyNamePt2 = _npcBuf[npcId]._name;
 				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
 				Common::String buffer = Common::String::format("%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
 				for (uint i = 0; i < 2; ++i) {
@@ -2243,7 +2231,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 				Common::KeyCode input = mapInputCode(waitForKey());
 				if (input == Common::KEYCODE_y) {
 					removeCharacterFromTeam(counter);
-					displayImp1Text(_npcBuf[var58].field14_textId);
+					displayImp1Text(_npcBuf[npcId].field14_textId);
 				}
 				displayAnimFrames(0xFE, true);
 				return true;
@@ -2252,9 +2240,9 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 9:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[var58].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
-				displayImp1Text(_npcBuf[var58].field14_textId);
+				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
 				return true;
 			}
@@ -2262,7 +2250,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 16:
 		displayMonsterAnim(monsterId);
-		displayImp1Text(_npcBuf[var58].field14_textId);
+		displayImp1Text(_npcBuf[npcId].field14_textId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	default:
@@ -2270,11 +2258,11 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	}
 
-	if (_npcBuf[var58].field12_textId == 0x7FFF || arg2 != 5)
+	if (_npcBuf[npcId].field12_textId == 0x7FFF || arg2 != 5)
 		return false;
 
 	displayMonsterAnim(monsterId);
-	displayImp1Text(_npcBuf[var58].field12_textId);
+	displayImp1Text(_npcBuf[npcId].field12_textId);
 	displayAnimFrames(0xFE, true);
 	return true;
 }
@@ -2490,38 +2478,37 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	return false;
 }
 
-int8 EfhEngine::sub15581(int16 mapPosX, int16 mapPosY, bool arg4) {
-	debug("sub15581 %d-%d %s", mapPosX, mapPosY, arg4 ? "true" : "false");
+int8 EfhEngine::checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4) {
+	debugC(3, kDebugEngine, "checkTileStatus %d-%d %s", mapPosX, mapPosY, arg4 ? "true" : "false");
 
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
-	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72];
-	imageSetId *= 72;
-	imageSetId += curTileInfo % 72;
+	int16 tileFactId = _currentTileBankImageSetId[curTileInfo / 72] * 72;
+	tileFactId += curTileInfo % 72;
 
 	if (arg4) {
-		sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, imageSetId);
+		sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, tileFactId);
 	}
 
 	if (_word2C880) {
 		_word2C880 = false;
 		return -1;
 	}
-	if (_tileFact[imageSetId]._field1 != 0xFF && !_dbgForceMonsterBlock) {
-		if ((arg4) || (!arg4 && imageSetId != 128 && imageSetId != 121)) {
+	if (_tileFact[tileFactId]._tileId != 0xFF && !_dbgForceMonsterBlock) {
+		if ((arg4) || (!arg4 && tileFactId != 128 && tileFactId != 121)) {
 			if (_largeMapFlag) {
-				_mapGameMap[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
+				_mapGameMap[mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
 			} else {
-				_curPlace[mapPosX][mapPosY] = _tileFact[imageSetId]._field1;
+				_curPlace[mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
 			}
 
 			_redrawNeededFl = true;
-			if (_tileFact[imageSetId]._field0 == 0)
+			if (_tileFact[tileFactId]._field0 == 0)
 				return 2;
 			return 1;
 		}
 	}
 
-	return _tileFact[imageSetId]._field0;
+	return _tileFact[tileFactId]._field0;
 }
 
 void EfhEngine::computeInitiatives() {
@@ -2850,13 +2837,14 @@ bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	return false;
 }
 
-int16 EfhEngine::sub15538(int16 mapPosX, int16 mapPosY) {
-	debug("sub15538 %d-%d", mapPosX, mapPosY);
+int16 EfhEngine::getTileFactId(int16 mapPosX, int16 mapPosY) {
+	debug("getTileFactId %d-%d", mapPosX, mapPosY);
 
-	int16 mapTileInfo = getMapTileInfo(mapPosX, mapPosY);
-	int16 imageSetId = mapTileInfo / 72;
+	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
+	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72] * 72;
+	imageSetId += curTileInfo % 72;
 
-	return (_currentTileBankImageSetId[imageSetId] * 72) + (mapTileInfo % 72);
+	return imageSetId;
 }
 
 void EfhEngine::setCharacterObjectToBroken(int16 charId, int16 objectId) {
@@ -2991,7 +2979,7 @@ bool EfhEngine::checkMonsterCollision() {
 		return true;
 	}
 
-	int8 check = sub15581(_mapPosX, _mapPosY, true);
+	int8 check = checkTileStatus(_mapPosX, _mapPosY, true);
 	if (check == 0 || check == 2)
 		return false;
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index cb927cc8220..cb8b2265012 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -233,7 +233,7 @@ struct InitiativeStruct {
 
 struct TileFactStruct {
 	uint8 _field0;
-	uint8 _field1;
+	uint8 _tileId;
 
 	void init();
 };
@@ -317,7 +317,7 @@ private:
 	int16 handleCharacterJoining();
 	void drawText(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
-	void sub15A28(int16 arg0, int16 arg2);
+	void transitionMap(int16 centerX, int16 centerY);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
 	int16 sub151FD(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
@@ -333,7 +333,7 @@ private:
 	void resetGame();
 	void computeMapAnimation();
 	void handleAnimations();
-	int8 sub16B08(int16 monsterId);
+	int8 checkMonsterMoveCollisionAndTileTexture(int16 monsterId);
 	bool moveMonsterAwayFromTeam(int16 monsterId);
 	bool moveMonsterTowardsTeam(int16 monsterId);
 	bool moveMonsterGroupOther(int16 monsterId, int16 direction);
@@ -353,7 +353,7 @@ private:
 	void sub221D2(int16 monsterId);
 	void displayImp1Text(int16 textId);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
-	int8 sub15581(int16 mapPosX, int16 mapPosY, bool arg4);
+	int8 checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4);
 	void computeInitiatives();
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
@@ -367,7 +367,7 @@ private:
 	bool hasObjectEquipped(int16 charId, int16 objectId);
 	void setMapMonsterField8(int16 id, uint8 movementType, bool groupFl);
 	bool isMonsterActive(int16 groupId, int16 id);
-	int16 sub15538(int16 mapPosX, int16 mapPosY);
+	int16 getTileFactId(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
 	int16 selectOtherCharFromTeam();
 	bool checkMonsterCollision();
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index e43026a2b1c..c80db8c20a0 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -249,7 +249,7 @@ void EfhEngine::readTileFact() {
 
 	for (int i = 0; i < 432; ++i) {
 		_tileFact[i]._field0 = f.readByte();
-		_tileFact[i]._field1 = f.readByte();
+		_tileFact[i]._tileId = f.readByte();
 	}
 }
 
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 08a9cc0218e..fcbfe23624a 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1101,9 +1101,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 16: { // Fairy Dust
 		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
 		_mapPosY = getRandom(_largeMapFlag ? 63 : 23);
-		int16 varAE = sub15538(_mapPosX, _mapPosY);
+		int16 tileFactId = getTileFactId(_mapPosX, _mapPosY);
 
-		if (_tileFact[varAE]._field0 == 0) {
+		if (_tileFact[tileFactId]._field0 == 0) {
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
@@ -1112,9 +1112,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
-			// emptyFunction(2);
 		} else {
-			if (varAE == 0 || varAE == 0x48) {
+			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
@@ -1138,8 +1137,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 17: { // "Devil Dust"
 		_mapPosX = _items[itemId].field_19;
 		_mapPosY = _items[itemId].field_1A;
-		int16 varAE = sub15538(_mapPosX, _mapPosY);
-		if (_tileFact[varAE]._field0 == 0) {
+		int16 tileFactId = getTileFactId(_mapPosX, _mapPosY);
+		if (_tileFact[tileFactId]._field0 == 0) {
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
@@ -1148,9 +1147,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
-			// emptyFunction(2);
 		} else {
-			if (varAE == 0 || varAE == 0x48) {
+			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
 					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
@@ -1305,7 +1303,6 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			retVal = true;
 		}
 		totalPartyKill();
-		// emptyFunction(2);
 		varA6 = true;
 		break;
 	case 27: { // "Magic Pyramid", "Razor Blade"
@@ -1326,7 +1323,6 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				_messageToBePrinted += buffer1;
 				retVal = true;
 			}
-			// emptyFunction(2);
 		}
 
 		varA6 = true;
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 3cc258f5b86..336caa9cc43 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -326,7 +326,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (flag && _largeMapFlag) {
 				_word2C87A = true;
 				loadPlacesFile(scriptNumberArray[0], false);
-				sub15A28(scriptNumberArray[1], scriptNumberArray[2]);
+				transitionMap(scriptNumberArray[1], scriptNumberArray[2]);
 				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
 				retVal = -1;
 			}


Commit: 88c3402688770e58ca59e4626dd8d851b27fd783
    https://github.com/scummvm/scummvm/commit/88c3402688770e58ca59e4626dd8d851b27fd783
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Move initialization code to init.cpp, fix bug in script_parse (case 6), renaming

Changed paths:
  A engines/efh/init.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/module.mk
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index af7c9f7e1fb..82fa304ab4e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -22,33 +22,14 @@
 #include "common/system.h"
 #include "common/random.h"
 #include "common/error.h"
-#include "common/config-manager.h"
 #include "common/events.h"
 #include "engines/util.h"
-#include "graphics/palette.h"
 
 #include "efh/efh.h"
 #include "efh/constants.h"
 
 namespace Efh {
 
-EfhEngine *EfhEngine::s_Engine = nullptr;
-
-EfhGraphicsStruct::EfhGraphicsStruct() {
-	_vgaLineBuffer = nullptr;
-	_shiftValue = 0;
-	_width = 0;
-	_height = 0;
-	_area = Common::Rect(0, 0, 0, 0);
-}
-EfhGraphicsStruct::EfhGraphicsStruct(int8 **lineBuf, int16 x, int16 y, int16 width, int16 height) {
-	_vgaLineBuffer = lineBuf;
-	_shiftValue = 0;
-	_width = width;
-	_height = height;
-	_area = Common::Rect(x, y, x + width - 1, y + height - 1);
-}
-
 void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
 	// Same buffer address
 	_vgaLineBuffer = src->_vgaLineBuffer;
@@ -58,296 +39,6 @@ void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
 	_area = src->_area;
 }
 
-void InvObject::init() {
-	_ref = 0;
-	_stat1 = 0;
-	_stat2 = 0;
-}
-
-void UnkMapStruct::init() {
-	_placeId = _posX = _posY = _field3 = _field4 = 0;
-	_field5_textId = _field7_textId = 0;
-}
-
-void UnkAnimStruct::init() {
-	memset(_field, 0, 4);
-}
-
-void AnimInfo::init() {
-	for (int i = 0; i < 15; ++i)
-		_unkAnimArray[i].init();
-
-	for (int i = 0; i < 10; ++i) {
-		_field3C_startY[i] = 0;
-		_field46_startX[i] = 0;
-	}
-}
-
-void ItemStruct::init() {
-	for (uint idx = 0; idx < 15; ++idx)
-		_name[idx] = 0;
-
-	_damage = 0;
-	_defense = 0;
-	_attacks = 0;
-	_uses = 0;
-	field_13 = 0;
-	_range = 0;
-	_attackType = 0;
-	field_16 = 0;
-	field17_attackTypeDefense = 0;
-	field_18 = 0;
-	field_19 = 0;
-	field_1A = 0;
-}
-
-void NPCStruct::init() {
-	for (int i = 0; i < 11; ++i)
-		_name[i] =  0;
-	fieldB_textId = 0;
-	field_C = 0;
-	field_D = 0;
-	fieldE_textId = 0;
-	field_F = 0;
-	field_10 = 0;
-	field_11 = 0;
-	field12_textId = 0;
-	field14_textId = 0;
-	_xp = 0;
-
-	for (int i = 0; i < 15; ++i)
-		_activeScore[i] = 0;
-
-	for (int i = 0; i < 11; ++i) {
-		_passiveScore[i] = 0;
-		_infoScore[i] = 0;
-	}
-
-	field_3F = 0;
-	field_40 = 0;
-
-	for (int i = 0; i < 10; ++i)
-		_inventory[i].init();
-
-	_possessivePronounSHL6 = 0;
-	_speed = 0;
-	field_6B = 0;
-	field_6C = 0;
-	field_6D = 0;
-	_unkItemId = 0;
-	field_6F = 0;
-	field_70 = 0;
-	field_71 = 0;
-	field_72 = 0;
-	field_73 = 0;
-	_hitPoints = 0;
-	_maxHP = 0;
-	field_78 = 0;
-	field_79 = 0;
-	field_7B = 0;
-	field_7D = 0;
-	field_7E = 0;
-	field_7F = 0;
-	field_80 = 0;
-	field_81 = 0;
-	field_82 = 0;
-	field_83 = 0;
-	field_84 = 0;
-	field_85 = 0;
-}
-
-void Stru32686::init() {
-	for (int i = 0; i < 9; ++i) {
-		_field0[i] = 0;
-		_field2[i] = 0;
-	}
-}
-
-void InitiativeStruct::init() {
-	_id = _initiative = 0;
-}
-
-void TileFactStruct::init() {
-	_field0 = _tileId = 0;
-}
-
-EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) {
-	const Common::FSNode gameDataDir(ConfMan.get("path"));
-
-	SearchMan.addSubDirectoryMatching(gameDataDir, "gendata");
-	SearchMan.addSubDirectoryMatching(gameDataDir, "images");
-	SearchMan.addSubDirectoryMatching(gameDataDir, "imp");
-	SearchMan.addSubDirectoryMatching(gameDataDir, "maps");
-
-	_system = syst;
-	_rnd = nullptr;
-
-	_shouldQuit = false;
-	_eventMan = nullptr;
-	_lastTime = 0;
-	_platform = Common::kPlatformUnknown;
-	_mainSurface = nullptr;
-
-	_vgaGraphicsStruct1 = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
-	_vgaGraphicsStruct2 = new EfhGraphicsStruct();
-
-	_videoMode = 0;
-	_graphicsStruct = nullptr;
-
-	for (int i = 0; i < 19; ++i)
-		_mapBitmapRefArr[i] = nullptr;
-
-	_defaultBoxColor = 0;
-
-	_fontDescr._widthArray = nullptr;
-	_fontDescr._extraLines = nullptr;
-	_fontDescr._fontData = nullptr;
-	_fontDescr._charHeight = 0;
-	_fontDescr._extraHorizontalSpace = _fontDescr._extraVerticalSpace = 0;
-
-	_introDoneFl = false;
-	_oldAnimImageSetId = -1;
-	_animImageSetId = 0xFE;
-	_paletteTransformationConstant = 10;
-
-	for (int i = 0; i < 12; ++i)
-		_circleImageSubFileArray[i] = nullptr;
-
-	_imageDataPtr._dataPtr = nullptr;
-	_imageDataPtr._width = 0;
-	_imageDataPtr._startX = _imageDataPtr._startY = 0;
-	_imageDataPtr._height = 0;
-	_imageDataPtr._lineDataSize = 0;
-	_imageDataPtr._paletteTransformation = 0;
-	_imageDataPtr._fieldD = 0;
-
-	for (int i = 0; i < 3; ++i)
-		_currentTileBankImageSetId[i] = -1;
-
-	_unkRelatedToAnimImageSetId = 0;
-	_techId = 0;
-	_currentAnimImageSetId = 0xFF;
-
-	for (int i = 0; i < 20; ++i) {
-		_portraitSubFilesArray[i] = nullptr;
-	}
-
-	_characterNamePt1 = "";
-	_characterNamePt2 = "";
-	_enemyNamePt1 = "";
-	_enemyNamePt2 = "";
-	_nameBuffer = "";
-	_attackBuffer = "";
-
-	for (int i = 0; i < 100; ++i) {
-		_imp1PtrArray[i] = nullptr;
-		_mapUnknown[i].init();
-	}
-
-	for (int i = 0; i < 432; ++i)
-		_imp2PtrArray[i] = nullptr;
-
-	_unkAnimRelatedIndex = -1;
-
-	_initRect = Common::Rect(0, 0, 0, 0);
-	_engineInitPending = true;
-	_textColor = 0x0E; // Yellow
-	_protectionPassed = false;
-	_fullPlaceId = 0xFF;
-	_guessAnimationAmount = 9;
-	_largeMapFlag = 0xFFFF;
-	_unk2C8AA = 0;
-	_teamCharId[0] = 0;
-	_teamCharId[1] = _teamCharId[2] = -1;
-
-	for (int i = 0; i < 3; ++i) {
-		_teamCharStatus[i]._status = 0;
-		_teamCharStatus[i]._duration = 0;
-		_teamPctVisible[i] = 0;
-		_word32482[i] = 0;
-		_teamNextAttack[i] = -1;
-		_word31780[i] = 0;
-		_teamLastAction[i] = 0;
-	}
-
-	for (int i = 0; i < 5; ++i) {
-		_teamMonsterIdArray[i] = -1;
-		_stru32686[i].init();
-	}
-
-	_teamSize = 1;
-	_word2C872 = 0;
-	_imageSetSubFilesIdx = 144;
-	_oldImageSetSubFilesIdx = 143;
-
-	_mapPosX = _mapPosY = 31;
-	_oldMapPosX = _oldMapPosY = 31;
-	_techDataId_MapPosX = _techDataId_MapPosY = 31;
-
-	_textPosX = 0;
-	_textPosY = 0;
-
-	_lastMainPlaceId = 0;
-	_tempTextDelay = 0;
-	_tempTextPtr = nullptr;
-	_word2C880 = false;
-	_redrawNeededFl = false;
-	_drawHeroOnMapFl = true;
-	_drawMonstersOnMapFl = true;
-	_word2C87A = false;
-	_dbgForceMonsterBlock = false;
-	_ongoingFightFl = false;
-	_statusMenuActive = false;
-	_menuDepth = 0;
-	_menuItemCounter = 0;
-
-	for (int i = 0; i < 15; ++i) {
-		_menuStatItemArr[i] = 0;
-	}
-
-	_messageToBePrinted = "";
-	for (int i = 0; i < 8; ++i)
-		_initiatives[i].init();
-
-	memset(_bufferCharBM, 0, ARRAYSIZE(_bufferCharBM));
-	for (int i = 0; i < 3; ++i)
-		memset(_tileBank[i], 0, ARRAYSIZE(_tileBank[i]));
-	memset(_circleImageBuf, 0, ARRAYSIZE(_circleImageBuf));
-	memset(_portraitBuf, 0, ARRAYSIZE(_portraitBuf));
-	memset(_hiResImageBuf, 0, ARRAYSIZE(_hiResImageBuf));
-	memset(_loResImageBuf, 0, ARRAYSIZE(_loResImageBuf));
-	memset(_menuBuf, 0, ARRAYSIZE(_menuBuf));
-	memset(_windowWithBorderBuf, 0, ARRAYSIZE(_windowWithBorderBuf));
-	memset(_places, 0, ARRAYSIZE(_places));
-	for (int i = 0; i < 24; ++i)
-		memset(_curPlace[i], 0, ARRAYSIZE(_curPlace[i]));
-	memset(_npcBuf, 0, ARRAYSIZE(_npcBuf));
-	memset(_imp1, 0, ARRAYSIZE(_imp1));
-	memset(_imp2, 0, ARRAYSIZE(_imp2));
-	memset(_titleSong, 0, ARRAYSIZE(_titleSong));
-	memset(_items, 0, ARRAYSIZE(_items));
-	memset(_tileFact, 0, ARRAYSIZE(_tileFact));
-	memset(_animInfo, 0, ARRAYSIZE(_animInfo));
-	memset(_history, 0, ARRAYSIZE(_history));
-	for (int i = 0; i < 19; ++i) {
-		memset(_techDataArr[i], 0, ARRAYSIZE(_techDataArr[i]));
-		memset(_mapArr[i], 0, ARRAYSIZE(_mapArr[i]));
-	}
-	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
-	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
-	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
-
-	// If requested, load a savegame instead of showing the intro
-	_loadSaveSlot = -1;
-	_saveAuthorized = false;
-
-	if (ConfMan.hasKey("save_slot")) {
-		int saveSlot = ConfMan.getInt("save_slot");
-		if (saveSlot >= 0 && saveSlot <= 999)
-			_loadSaveSlot = saveSlot;
-	}
-}
-
 EfhEngine::~EfhEngine() {
 	delete _rnd;
 	delete _graphicsStruct;
@@ -363,7 +54,7 @@ void EfhEngine::syncSoundSettings() {
 
 Common::Error EfhEngine::run() {
 	debug("run");
-	s_Engine = this;
+
 	initialize();
 	initGraphics(320, 200);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index cb8b2265012..0acda53c6f9 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -275,8 +275,6 @@ protected:
 	Common::Error run() override;
 
 private:
-	static EfhEngine *s_Engine;
-
 	Common::Platform _platform;
 	int _loadSaveSlot;
 	bool _saveAuthorized;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
new file mode 100644
index 00000000000..0b357862987
--- /dev/null
+++ b/engines/efh/init.cpp
@@ -0,0 +1,332 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "common/config-manager.h"
+#include "efh/efh.h"
+
+namespace Efh {
+EfhGraphicsStruct::EfhGraphicsStruct() {
+	_vgaLineBuffer = nullptr;
+	_shiftValue = 0;
+	_width = 0;
+	_height = 0;
+	_area = Common::Rect(0, 0, 0, 0);
+}
+EfhGraphicsStruct::EfhGraphicsStruct(int8 **lineBuf, int16 x, int16 y, int16 width, int16 height) {
+	_vgaLineBuffer = lineBuf;
+	_shiftValue = 0;
+	_width = width;
+	_height = height;
+	_area = Common::Rect(x, y, x + width - 1, y + height - 1);
+}
+
+void InvObject::init() {
+	_ref = 0;
+	_stat1 = 0;
+	_stat2 = 0;
+}
+
+void UnkMapStruct::init() {
+	_placeId = _posX = _posY = _field3 = _field4 = 0;
+	_field5_textId = _field7_textId = 0;
+}
+
+void UnkAnimStruct::init() {
+	memset(_field, 0, 4);
+}
+
+void AnimInfo::init() {
+	for (int i = 0; i < 15; ++i)
+		_unkAnimArray[i].init();
+
+	for (int i = 0; i < 10; ++i) {
+		_field3C_startY[i] = 0;
+		_field46_startX[i] = 0;
+	}
+}
+
+void ItemStruct::init() {
+	for (uint idx = 0; idx < 15; ++idx)
+		_name[idx] = 0;
+
+	_damage = 0;
+	_defense = 0;
+	_attacks = 0;
+	_uses = 0;
+	field_13 = 0;
+	_range = 0;
+	_attackType = 0;
+	field_16 = 0;
+	field17_attackTypeDefense = 0;
+	field_18 = 0;
+	field_19 = 0;
+	field_1A = 0;
+}
+
+void NPCStruct::init() {
+	for (int i = 0; i < 11; ++i)
+		_name[i] = 0;
+	fieldB_textId = 0;
+	field_C = 0;
+	field_D = 0;
+	fieldE_textId = 0;
+	field_F = 0;
+	field_10 = 0;
+	field_11 = 0;
+	field12_textId = 0;
+	field14_textId = 0;
+	_xp = 0;
+
+	for (int i = 0; i < 15; ++i)
+		_activeScore[i] = 0;
+
+	for (int i = 0; i < 11; ++i) {
+		_passiveScore[i] = 0;
+		_infoScore[i] = 0;
+	}
+
+	field_3F = 0;
+	field_40 = 0;
+
+	for (int i = 0; i < 10; ++i)
+		_inventory[i].init();
+
+	_possessivePronounSHL6 = 0;
+	_speed = 0;
+	field_6B = 0;
+	field_6C = 0;
+	field_6D = 0;
+	_unkItemId = 0;
+	field_6F = 0;
+	field_70 = 0;
+	field_71 = 0;
+	field_72 = 0;
+	field_73 = 0;
+	_hitPoints = 0;
+	_maxHP = 0;
+	field_78 = 0;
+	field_79 = 0;
+	field_7B = 0;
+	field_7D = 0;
+	field_7E = 0;
+	field_7F = 0;
+	field_80 = 0;
+	field_81 = 0;
+	field_82 = 0;
+	field_83 = 0;
+	field_84 = 0;
+	field_85 = 0;
+}
+
+void Stru32686::init() {
+	for (int i = 0; i < 9; ++i) {
+		_field0[i] = 0;
+		_field2[i] = 0;
+	}
+}
+
+void InitiativeStruct::init() {
+	_id = _initiative = 0;
+}
+
+void TileFactStruct::init() {
+	_field0 = _tileId = 0;
+}
+
+EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) {
+	const Common::FSNode gameDataDir(ConfMan.get("path"));
+
+	SearchMan.addSubDirectoryMatching(gameDataDir, "gendata");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "images");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "imp");
+	SearchMan.addSubDirectoryMatching(gameDataDir, "maps");
+
+	_system = syst;
+	_rnd = nullptr;
+
+	_shouldQuit = false;
+	_eventMan = nullptr;
+	_lastTime = 0;
+	_platform = Common::kPlatformUnknown;
+	_mainSurface = nullptr;
+
+	_vgaGraphicsStruct1 = new EfhGraphicsStruct(_vgaLineBuffer, 0, 0, 320, 200);
+	_vgaGraphicsStruct2 = new EfhGraphicsStruct();
+
+	_videoMode = 0;
+	_graphicsStruct = nullptr;
+
+	for (int i = 0; i < 19; ++i)
+		_mapBitmapRefArr[i] = nullptr;
+
+	_defaultBoxColor = 0;
+
+	_fontDescr._widthArray = nullptr;
+	_fontDescr._extraLines = nullptr;
+	_fontDescr._fontData = nullptr;
+	_fontDescr._charHeight = 0;
+	_fontDescr._extraHorizontalSpace = _fontDescr._extraVerticalSpace = 0;
+
+	_introDoneFl = false;
+	_oldAnimImageSetId = -1;
+	_animImageSetId = 0xFE;
+	_paletteTransformationConstant = 10;
+
+	for (int i = 0; i < 12; ++i)
+		_circleImageSubFileArray[i] = nullptr;
+
+	_imageDataPtr._dataPtr = nullptr;
+	_imageDataPtr._width = 0;
+	_imageDataPtr._startX = _imageDataPtr._startY = 0;
+	_imageDataPtr._height = 0;
+	_imageDataPtr._lineDataSize = 0;
+	_imageDataPtr._paletteTransformation = 0;
+	_imageDataPtr._fieldD = 0;
+
+	for (int i = 0; i < 3; ++i)
+		_currentTileBankImageSetId[i] = -1;
+
+	_unkRelatedToAnimImageSetId = 0;
+	_techId = 0;
+	_currentAnimImageSetId = 0xFF;
+
+	for (int i = 0; i < 20; ++i) {
+		_portraitSubFilesArray[i] = nullptr;
+	}
+
+	_characterNamePt1 = "";
+	_characterNamePt2 = "";
+	_enemyNamePt1 = "";
+	_enemyNamePt2 = "";
+	_nameBuffer = "";
+	_attackBuffer = "";
+
+	for (int i = 0; i < 100; ++i) {
+		_imp1PtrArray[i] = nullptr;
+		_mapUnknown[i].init();
+	}
+
+	for (int i = 0; i < 432; ++i)
+		_imp2PtrArray[i] = nullptr;
+
+	_unkAnimRelatedIndex = -1;
+
+	_initRect = Common::Rect(0, 0, 0, 0);
+	_engineInitPending = true;
+	_textColor = 0x0E; // Yellow
+	_protectionPassed = false;
+	_fullPlaceId = 0xFF;
+	_guessAnimationAmount = 9;
+	_largeMapFlag = 0xFFFF;
+	_unk2C8AA = 0;
+	_teamCharId[0] = 0;
+	_teamCharId[1] = _teamCharId[2] = -1;
+
+	for (int i = 0; i < 3; ++i) {
+		_teamCharStatus[i]._status = 0;
+		_teamCharStatus[i]._duration = 0;
+		_teamPctVisible[i] = 0;
+		_word32482[i] = 0;
+		_teamNextAttack[i] = -1;
+		_word31780[i] = 0;
+		_teamLastAction[i] = 0;
+	}
+
+	for (int i = 0; i < 5; ++i) {
+		_teamMonsterIdArray[i] = -1;
+		_stru32686[i].init();
+	}
+
+	_teamSize = 1;
+	_word2C872 = 0;
+	_imageSetSubFilesIdx = 144;
+	_oldImageSetSubFilesIdx = 143;
+
+	_mapPosX = _mapPosY = 31;
+	_oldMapPosX = _oldMapPosY = 31;
+	_techDataId_MapPosX = _techDataId_MapPosY = 31;
+
+	_textPosX = 0;
+	_textPosY = 0;
+
+	_lastMainPlaceId = 0;
+	_tempTextDelay = 0;
+	_tempTextPtr = nullptr;
+	_word2C880 = false;
+	_redrawNeededFl = false;
+	_drawHeroOnMapFl = true;
+	_drawMonstersOnMapFl = true;
+	_word2C87A = false;
+	_dbgForceMonsterBlock = false;
+	_ongoingFightFl = false;
+	_statusMenuActive = false;
+	_menuDepth = 0;
+	_menuItemCounter = 0;
+
+	for (int i = 0; i < 15; ++i) {
+		_menuStatItemArr[i] = 0;
+	}
+
+	_messageToBePrinted = "";
+	for (int i = 0; i < 8; ++i)
+		_initiatives[i].init();
+
+	memset(_bufferCharBM, 0, ARRAYSIZE(_bufferCharBM));
+	for (int i = 0; i < 3; ++i)
+		memset(_tileBank[i], 0, ARRAYSIZE(_tileBank[i]));
+	memset(_circleImageBuf, 0, ARRAYSIZE(_circleImageBuf));
+	memset(_portraitBuf, 0, ARRAYSIZE(_portraitBuf));
+	memset(_hiResImageBuf, 0, ARRAYSIZE(_hiResImageBuf));
+	memset(_loResImageBuf, 0, ARRAYSIZE(_loResImageBuf));
+	memset(_menuBuf, 0, ARRAYSIZE(_menuBuf));
+	memset(_windowWithBorderBuf, 0, ARRAYSIZE(_windowWithBorderBuf));
+	memset(_places, 0, ARRAYSIZE(_places));
+	for (int i = 0; i < 24; ++i)
+		memset(_curPlace[i], 0, ARRAYSIZE(_curPlace[i]));
+	memset(_npcBuf, 0, ARRAYSIZE(_npcBuf));
+	memset(_imp1, 0, ARRAYSIZE(_imp1));
+	memset(_imp2, 0, ARRAYSIZE(_imp2));
+	memset(_titleSong, 0, ARRAYSIZE(_titleSong));
+	memset(_items, 0, ARRAYSIZE(_items));
+	memset(_tileFact, 0, ARRAYSIZE(_tileFact));
+	memset(_animInfo, 0, ARRAYSIZE(_animInfo));
+	memset(_history, 0, ARRAYSIZE(_history));
+	for (int i = 0; i < 19; ++i) {
+		memset(_techDataArr[i], 0, ARRAYSIZE(_techDataArr[i]));
+		memset(_mapArr[i], 0, ARRAYSIZE(_mapArr[i]));
+	}
+	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
+	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
+	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
+
+	// If requested, load a savegame instead of showing the intro
+	_loadSaveSlot = -1;
+	_saveAuthorized = false;
+
+	if (ConfMan.hasKey("save_slot")) {
+		int saveSlot = ConfMan.getInt("save_slot");
+		if (saveSlot >= 0 && saveSlot <= 999)
+			_loadSaveSlot = saveSlot;
+	}
+}
+
+} // End of namespace Efh
+
diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index f6d07436808..a81d60c278d 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -6,6 +6,7 @@ MODULE_OBJS = \
 	fight.o \
 	files.o \
 	graphics.o \
+	init.o \
 	menu.o \
 	savegames.o \
 	script.o \
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 336caa9cc43..354c9bcf639 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -162,11 +162,11 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x03:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[2] - scriptNumberArray[0];
-				int16 var10E = scriptNumberArray[3] - scriptNumberArray[1];
+				int16 rangeX = scriptNumberArray[2] - scriptNumberArray[0];
+				int16 rangeY = scriptNumberArray[3] - scriptNumberArray[1];
 
-				_mapPosX = getRandom(var110) + scriptNumberArray[0] - 1;
-				_mapPosY = getRandom(var10E) + scriptNumberArray[1] - 1;
+				_mapPosX = getRandom(rangeX) + scriptNumberArray[0] - 1;
+				_mapPosY = getRandom(rangeY) + scriptNumberArray[1] - 1;
 				_word2C880 = true;
 				_redrawNeededFl = true;
 			}
@@ -183,28 +183,27 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x05:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = scriptNumberArray[1];
-					_npcBuf[var110]._activeScore[var10E] += scriptNumberArray[2] & 0xFF;
-					_npcBuf[var110]._activeScore[var10E] -= scriptNumberArray[3] & 0xFF;
+				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				if (npcId != -1) {
+					int16 scoreId = scriptNumberArray[1];
+					_npcBuf[npcId]._activeScore[scoreId] += scriptNumberArray[2] & 0xFF;
+					_npcBuf[npcId]._activeScore[scoreId] -= scriptNumberArray[3] & 0xFF;
 				}
 			}
 			break;
 		case 0x06:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = scriptNumberArray[1];
-					_npcBuf[var110]._activeScore[var10E] = scriptNumberArray[1];
+				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				if (npcId != -1) {
+					int16 scoreId = scriptNumberArray[1];
+					_npcBuf[npcId]._activeScore[scoreId] = scriptNumberArray[2] & 0xFF;
 				}
 			}
 			break;
 		case 0x07:
 			if (flag) {
 				totalPartyKill();
-				// emptyFunction(2);
 			}
 			break;
 		case 0x08:
@@ -216,44 +215,42 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x09:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = getRandom(scriptNumberArray[1]);
-					_npcBuf[var110]._hitPoints += var10E;
-					if (_npcBuf[var110]._hitPoints > _npcBuf[var110]._maxHP)
-						_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				if (npcId != -1) {
+					_npcBuf[npcId]._hitPoints += getRandom(scriptNumberArray[1]);
+					if (_npcBuf[npcId]._hitPoints > _npcBuf[npcId]._maxHP)
+						_npcBuf[npcId]._hitPoints = _npcBuf[npcId]._maxHP;
 				}
 			}
 			break;
 		case 0x0A:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					_npcBuf[var110]._hitPoints = _npcBuf[var110]._maxHP;
+				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				if (npcId != -1) {
+					_npcBuf[npcId]._hitPoints = _npcBuf[npcId]._maxHP;
 				}
 			}
 			break;
 		case 0x0B:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = _teamCharId[scriptNumberArray[0]];
-				if (var110 != -1) {
-					int16 var10E = getRandom(scriptNumberArray[1]);
-					_npcBuf[var110]._hitPoints -= var10E;
-					if (_npcBuf[var110]._hitPoints < 0)
-						_npcBuf[var110]._hitPoints = 0;
+				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				if (npcId != -1) {
+					_npcBuf[npcId]._hitPoints -= getRandom(scriptNumberArray[1]);
+					if (_npcBuf[npcId]._hitPoints < 0)
+						_npcBuf[npcId]._hitPoints = 0;
 				}
 			}
 			break;
 		case 0x0C:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
+				int16 scriptItemId = scriptNumberArray[0];
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
 					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
 							removeObject(_teamCharId[counter], objectId);
 							found = true;
 							break;
@@ -266,9 +263,9 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			// Put item in inventory { objectId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
+				int16 scriptObjectId = scriptNumberArray[0];
 				for (int counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], var110, 0xFF))
+					if (giveItemTo(_teamCharId[counter], scriptObjectId, 0xFF))
 						break;
 				}
 			}
@@ -276,11 +273,11 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0E:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
+				int16 scriptItemId = scriptNumberArray[0];
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
 					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == var110) {
+						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
 							found = true;
 							break;
 						}
@@ -296,8 +293,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0F:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				if (isCharacterATeamMember(var110))
+				if (isCharacterATeamMember(scriptNumberArray[0]))
 					retVal = scriptNumberArray[1];
 				else
 					retVal = scriptNumberArray[2];
@@ -335,9 +331,9 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			// Add character to team { charId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				if (!isCharacterATeamMember(var110))
-					var_EE = var110;
+				int16 scriptNpcId = scriptNumberArray[0];
+				if (!isCharacterATeamMember(scriptNpcId))
+					var_EE = scriptNpcId;
 				retVal = -1;
 			}
 			break;
@@ -353,11 +349,11 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x16:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[0];
+				int16 scriptNpcId = scriptNumberArray[0];
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
-				if (isCharacterATeamMember(var110)) {
+				if (isCharacterATeamMember(scriptNpcId)) {
 					for (uint counter = 0; counter < 3; ++counter) {
-						if (_teamCharId[counter] == var110) {
+						if (_teamCharId[counter] == scriptNpcId) {
 							removeCharacterFromTeam(counter);
 							break;
 						}
@@ -375,12 +371,11 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x18:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = scriptNumberArray[1] - scriptNumberArray[0] + 1;
 				bool found = false;
-				var110 = getRandom(var110) + scriptNumberArray[0] - 1;
+				int16 scriptRandomItemId = getRandom(scriptNumberArray[1] - scriptNumberArray[0] + 1) + scriptNumberArray[0] - 1;
 				int16 counter;
 				for (counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], var110, 0xFF)) {
+					if (giveItemTo(_teamCharId[counter], scriptRandomItemId, 0xFF)) {
 						found = true;
 						break;
 					}
@@ -390,22 +385,22 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219("Nothing...", 1, 2, true);
+					scriptRandomItemId = sub1C219("Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
 					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
-					_nameBuffer = _items[var110]._name;
+					_nameBuffer = _items[scriptRandomItemId]._name;
 					curLine = Common::String::format("%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					var110 = sub1C219(curLine, 1, 2, true);
+					scriptRandomItemId = sub1C219(curLine, 1, 2, true);
 					displayFctFullScreen();
 				}
 
-				var110 = sub151FD(_mapPosX, _mapPosY);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
+				int16 mapUnkId = sub151FD(_mapPosX, _mapPosY);
+				if (mapUnkId != -1) {
+					_mapUnknown[mapUnkId]._posX = 0xFF;
 				}
 				_redrawNeededFl = true;
 			}
@@ -423,18 +418,18 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x1A:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
+				int16 mapUnkId = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (mapUnkId != -1) {
+					_mapUnknown[mapUnkId]._posX = 0xFF;
 				}
 			}
 			break;
 		case 0x1B:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				int16 var110 = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (var110 != -1) {
-					_mapUnknown[var110]._posX = 0xFF;
+				int16 mapUnkId = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
+				if (mapUnkId != -1) {
+					_mapUnknown[mapUnkId]._posX = 0xFF;
 				}
 				_mapUnknown[scriptNumberArray[2]]._posX = scriptNumberArray[0];
 				_mapUnknown[scriptNumberArray[2]]._posY = scriptNumberArray[1];


Commit: d705fe97769d096e134429e67eb414a80782f417
    https://github.com/scummvm/scummvm/commit/d705fe97769d096e134429e67eb414a80782f417
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Fix bugs in handleFight_lastAction_A(), renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 82fa304ab4e..adb3c555071 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2299,15 +2299,15 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 
 		for (uint counter2 = 0; counter2 < 9; ++counter2) {
 			_mapMonsters[_teamMonsterIdArray[counter1]]._pictureRef[counter2] = 0;
-			_stru32686[counter1]._field0[counter2] = 0;
-			_stru32686[counter1]._field2[counter2] = 0;
+			_teamMonsterEffects[counter1]._effect[counter2] = 0;
+			_teamMonsterEffects[counter1]._duration[counter2] = 0;
 		}
 
 		_teamMonsterIdArray[counter1] = -1;
 		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
 			for (uint var8 = 0; var8 < 9; ++var8) {
-				_stru32686[counter1]._field0[var8] = _stru32686[counter2]._field0[var8];
-				_stru32686[counter1]._field2[var8] = _stru32686[counter2]._field2[var8];
+				_teamMonsterEffects[counter1]._effect[var8] = _teamMonsterEffects[counter2]._effect[var8];
+				_teamMonsterEffects[counter1]._duration[var8] = _teamMonsterEffects[counter2]._duration[var8];
 			}
 			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
 		}
@@ -2356,11 +2356,11 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 
 						// The original at this point was doing a loop on counter1, which is not a good idea as
 						// it was resetting the counter1 to 9 whatever its value before the loop.
-						// Furthermore, it was accessing _stru32686[counter1]._field0[counter1] which doesn't make
+						// Furthermore, it was accessing _teamMonsterEffects[counter1]._effect[counter1] which doesn't make
 						// sense...
 						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
 						for (uint counter2 = 0; counter2 < 9; ++counter2) {
-							_stru32686[counter1]._field0[counter2] = 0;
+							_teamMonsterEffects[counter1]._effect[counter2] = 0;
 						}
 
 						if (++var4 >= 5)
@@ -2379,7 +2379,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	for (int16 counter1 = var4; counter1 < 5; ++counter1) {
 		_teamMonsterIdArray[counter1] = -1;
 		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_stru32686[counter1]._field0[counter2] = (int16)0x8000;
+			_teamMonsterEffects[counter1]._effect[counter2] = (int16)0x8000;
 		}
 	}
 	// sub1BE9A - last loop counter1_monsterId - End
@@ -2490,7 +2490,7 @@ int16 EfhEngine::getXPLevel(int32 xp) {
 bool EfhEngine::isItemCursed(int16 itemId) {
 	debugC(6, kDebugEngine, "isItemCursed %d", itemId);
 
-	if (_items[itemId].field_16 == 21 || _items[itemId].field_16 == 22 || _items[itemId].field_16 == 23)
+	if (_items[itemId]._specialEffect == 21 || _items[itemId]._specialEffect == 22 || _items[itemId]._specialEffect == 23)
 		return true;
 
 	return false;
@@ -2523,7 +2523,7 @@ void EfhEngine::setMapMonsterField8(int16 id, uint8 movementType, bool groupFl)
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	debugC(5, kDebugEngine, "isMonsterActive %d %d", groupId, id);
 
-	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _stru32686[groupId]._field0[id] == 0)
+	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
 		return true;
 	return false;
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0acda53c6f9..02b020b4c06 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -81,7 +81,7 @@ public:
 
 struct InvObject {
 	int16 _ref;
-	uint8 _stat1;
+	uint8 _stat1; // abbb bbbb - a: equipped b: durability
 	uint8 _stat2;
 
 	void init();
@@ -121,7 +121,7 @@ struct ItemStruct {
 	int8 field_13; // data contains values from -8 to +8
 	uint8 _range;
 	uint8 _attackType;
-	uint8 field_16;
+	uint8 _specialEffect;
 	uint8 field17_attackTypeDefense;
 	uint8 field_18;
 	uint8 field_19;
@@ -218,8 +218,8 @@ struct MapMonster {
 };
 
 struct Stru32686 {
-	int16 _field0[9];
-	int16 _field2[9];
+	int16 _effect[9];
+	int16 _duration[9];
 
 	void init();
 };
@@ -462,7 +462,7 @@ private:
 	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
-	void equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
 
@@ -602,7 +602,7 @@ private:
 	int16 _word31780[3];
 
 	int16 _menuStatItemArr[15];
-	Stru32686 _stru32686[5];
+	Stru32686 _teamMonsterEffects[5];
 	InitiativeStruct _initiatives[8];
 };
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 7e391f61460..98a94f63738 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -303,7 +303,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									// handleFight - Check armor - end
 
 									// handleFight - Check effect - start
-									switch (_items[unk_monsterField5_itemId].field_16) {
+									switch (_items[unk_monsterField5_itemId]._specialEffect) {
 									case 1:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
@@ -337,9 +337,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							}
 							// handleFight - Loop on var7E - End
 						}
-					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
-						--_stru32686[monsterGroupIdOrMonsterId]._field2[var86];
-						if (_stru32686[monsterGroupIdOrMonsterId]._field2[var86] <= 0) {
+					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
+						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86];
+						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86] <= 0) {
 							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
@@ -347,7 +347,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							else
 								_enemyNamePt1 = "";
 
-							switch (_stru32686[monsterGroupIdOrMonsterId]._field0[var86]) {
+							switch (_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
 							case 1:
 								_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
@@ -358,7 +358,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							}
-							_stru32686[monsterGroupIdOrMonsterId]._field0[var86] = 0;
+							_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86] = 0;
 							sub1C219(_messageToBePrinted, 1, 2, true);
 						}
 					}
@@ -472,7 +472,6 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
 					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
 					int16 var62 = 0;
-					int16 hitPoints = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
 					int16 var64 = _items[unk_monsterField5_itemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
@@ -498,7 +497,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					if (originalDamage < 0)
 						originalDamage = 0;
 
-					hitPoints = originalDamage + damagePointsAbsorbed;
+					int16 hitPoints = originalDamage + damagePointsAbsorbed;
 
 					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
 						var62 = 0;
@@ -603,15 +602,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[unk_monsterField5_itemId].field_16 == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+						if (_items[unk_monsterField5_itemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
 							if (getRandom(100) < 35) {
-								_stru32686[var7E]._field0[groupId] = 1;
-								_stru32686[var7E]._field2[groupId] = getRandom(10);
+								_teamMonsterEffects[groupId]._effect[var7E] = 1;
+								_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[unk_monsterField5_itemId].field_16 == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							_stru32686[var7E]._field0[groupId] = 2;
-							_stru32686[var7E]._field2[groupId] = getRandom(10);
+						} else if (_items[unk_monsterField5_itemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+							_teamMonsterEffects[groupId]._effect[var7E] = 2;
+							_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						// Action A - Check effect - End
@@ -707,8 +706,8 @@ void EfhEngine::reset_stru32686() {
 	debug("reset_stru32686");
 	for (uint counter1 = 0; counter1 < 5; ++counter1) {
 		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_stru32686[counter1]._field0[counter2] = 0;
-			_stru32686[counter1]._field2[counter2] = 0;
+			_teamMonsterEffects[counter1]._effect[counter2] = 0;
+			_teamMonsterEffects[counter1]._duration[counter2] = 0;
 		}
 	}
 }
@@ -1516,7 +1515,7 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 
 	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
 
-	if (_items[itemId].field_16 != 0)
+	if (_items[itemId]._specialEffect != 0)
 		return false;
 
 	return _items[itemId].field17_attackTypeDefense == attackType;
@@ -1527,7 +1526,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 
 	int16 itemId = _npcBuf[charId]._unkItemId;
 
-	if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+	if (_items[itemId]._specialEffect == 0 && _items[itemId].field17_attackTypeDefense == attackType)
 		return true;
 
 	for (uint counter = 0; counter < 10; ++counter) {
@@ -1535,7 +1534,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 			continue;
 
 		itemId = _npcBuf[charId]._inventory[counter]._ref;
-		if (_items[itemId].field_16 == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+		if (_items[itemId]._specialEffect == 0 && _items[itemId].field17_attackTypeDefense == attackType)
 			return true;
 	}
 	return false;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index c80db8c20a0..ccae0802e5d 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -148,13 +148,13 @@ void EfhEngine::readItems() {
 		_items[i].field_13 = f.readByte();
 		_items[i]._range = f.readByte();
 		_items[i]._attackType = f.readByte();
-		_items[i].field_16 = f.readByte();
+		_items[i]._specialEffect = f.readByte();
 		_items[i].field17_attackTypeDefense = f.readByte();
 		_items[i].field_18 = f.readByte();
 		_items[i].field_19 = f.readByte();
 		_items[i].field_1A = f.readByte();
 
-		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i].field_16, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
 	}
 }
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 0b357862987..1cc26d9713a 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -74,7 +74,7 @@ void ItemStruct::init() {
 	field_13 = 0;
 	_range = 0;
 	_attackType = 0;
-	field_16 = 0;
+	_specialEffect = 0;
 	field17_attackTypeDefense = 0;
 	field_18 = 0;
 	field_19 = 0;
@@ -138,8 +138,8 @@ void NPCStruct::init() {
 
 void Stru32686::init() {
 	for (int i = 0; i < 9; ++i) {
-		_field0[i] = 0;
-		_field2[i] = 0;
+		_effect[i] = 0;
+		_duration[i] = 0;
 	}
 }
 
@@ -252,7 +252,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 
 	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
-		_stru32686[i].init();
+		_teamMonsterEffects[i].init();
 	}
 
 	_teamSize = 1;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index fcbfe23624a..b6ea94c1cbb 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -865,14 +865,15 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	return 0;
 }
 
-void EfhEngine::equipCursedItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("equipCursedItem %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+void EfhEngine::unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debugC(6,kDebugEngine, "unequipItem %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
 	if (isItemCursed(itemId)) {
 		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
 	} else {
+		// Original message. "Cursed item can't be unequipped" would make more sense, imho
 		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
 	}
 }
@@ -883,16 +884,17 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
 	if (hasObjectEquipped(charId, objectId)) {
-		equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+		unequipItem(charId, objectId, windowId, menuId, curMenuLine);
 	} else {
 		int16 var2 = _items[itemId].field_18;
 		if (var2 != 4) {
 			for (uint counter = 0; counter < 10; ++counter) {
 				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
-					equipCursedItem(charId, objectId, windowId, menuId, curMenuLine);
+					unequipItem(charId, objectId, windowId, menuId, curMenuLine);
 			}
 		}
 
+		// Set item as Equipped
 		_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
 	}
 }
@@ -906,7 +908,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	bool retVal = false;
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
-	switch (_items[itemId].field_16 - 1) {
+	switch (_items[itemId]._specialEffect - 1) {
 	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
 		if (argA == 2) {
 			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
@@ -917,8 +919,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(windowId, counter)) {
 						++victims;
-						_stru32686[windowId]._field0[counter] = 1;
-						_stru32686[windowId]._field2[counter] = getRandom(8);
+						_teamMonsterEffects[windowId]._effect[counter] = 1;
+						_teamMonsterEffects[windowId]._duration[counter] = getRandom(8);
 					}
 				}
 			} else {
@@ -930,8 +932,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					if (isMonsterActive(windowId, counter)) {
 						++victims;
 						--NumberOfTargets;
-						_stru32686[windowId]._field0[counter] = 1;
-						_stru32686[windowId]._field2[counter] = getRandom(8);
+						_teamMonsterEffects[windowId]._effect[counter] = 1;
+						_teamMonsterEffects[windowId]._duration[counter] = getRandom(8);
 					}
 				}
 			}
@@ -956,8 +958,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				for (uint varA8 = 0; varA8 < 9; ++varA8) {
 					if (isMonsterActive(windowId, varA8)) {
 						++victim;
-						_stru32686[windowId]._field0[varA8] = 2;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
+						_teamMonsterEffects[windowId]._effect[varA8] = 2;
+						_teamMonsterEffects[windowId]._duration[varA8] = getRandom(8);
 					}
 				}
 			} else {
@@ -969,8 +971,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 					if (isMonsterActive(windowId, varA8)) {
 						++victim;
 						--varAC;
-						_stru32686[windowId]._field0[varA8] = 2;
-						_stru32686[windowId]._field2[varA8] = getRandom(8);
+						_teamMonsterEffects[windowId]._effect[varA8] = 2;
+						_teamMonsterEffects[windowId]._duration[varA8] = getRandom(8);
 					}
 				}
 			}


Commit: ec7bafa22398cc8ed349b4e7989c7ec0dff906e5
    https://github.com/scummvm/scummvm/commit/ec7bafa22398cc8ed349b4e7989c7ec0dff906e5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Renaming, fix bug in sub1BE9A()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index adb3c555071..4a268d24d37 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2290,8 +2290,6 @@ void EfhEngine::sub1CAB6(int16 charId) {
 void EfhEngine::sub1BE9A(int16 monsterId) {
 	debug("sub1BE9A %d", monsterId);
 
-	int16 var4 = 1;
-
 	// sub1BE9A - 1rst loop counter1_monsterId - Start
 	for (uint counter1 = 0; counter1 < 5; ++counter1) {
 		if (countMonsterGroupMembers(counter1))
@@ -2304,6 +2302,9 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 		}
 
 		_teamMonsterIdArray[counter1] = -1;
+
+		// CHECKME: counter1 is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
+		// if the purpose is compact the array, it should be handle differently
 		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
 			for (uint var8 = 0; var8 < 9; ++var8) {
 				_teamMonsterEffects[counter1]._effect[var8] = _teamMonsterEffects[counter2]._effect[var8];
@@ -2315,55 +2316,53 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	}
 	// sub1BE9A - 1rst loop counter1_monsterId - End
 
-	var4 = -1;
+	int16 teamMonsterId = -1;
 	for (uint counter1 = 0; counter1 < 5; ++counter1) {
 		if (_teamMonsterIdArray[counter1] == -1) {
-			var4 = counter1;
+			teamMonsterId = counter1;
 			break;
 		}
 	}
 
-	if (var4 != -1) {
+	if (teamMonsterId != -1) {
 		// sub1BE9A - loop var2 - Start
 		for (int var2 = 1; var2 < 3; ++var2) {
-			if (var4 >= 5)
+			if (teamMonsterId >= 5)
 				break;
 
-			for (uint counter1 = 0; counter1 < 64; ++counter1) {
-				if (_mapMonsters[counter1]._guess_fullPlaceId == 0xFF)
+			for (uint ctrMapMonsterId = 0; ctrMapMonsterId < 64; ++ctrMapMonsterId) {
+				if (_mapMonsters[ctrMapMonsterId]._guess_fullPlaceId == 0xFF)
 					continue;
 
-				if (((_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[counter1]._npcId)) || (_mapMonsters[counter1]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
-					if (checkIfMonsterOnSameLargeMapPlace(counter1)) {
-						bool var6 = false;
-						for (uint counter2 = 0; counter2 < 9; ++counter2) {
-							if (_mapMonsters[counter1]._pictureRef[counter2] > 0) {
-								var6 = true;
+				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
+						bool monsterActiveFound = false;
+						for (uint ctrSubId = 0; ctrSubId < 9; ++ctrSubId) {
+							if (_mapMonsters[ctrMapMonsterId]._pictureRef[ctrSubId] > 0) {
+								monsterActiveFound = true;
 								break;
 							}
 						}
 
-						if (!var6)
+						if (!monsterActiveFound)
 							continue;
 
-						if (computeMonsterGroupDistance(counter1) > var2)
+						if (computeMonsterGroupDistance(ctrMapMonsterId) > var2)
 							continue;
 
-						if (sub1BC74(counter1, var4))
+						if (sub1BC74(ctrMapMonsterId, teamMonsterId))
 							continue;
 
-						_teamMonsterIdArray[var4] = counter1;
+						_teamMonsterIdArray[teamMonsterId] = ctrMapMonsterId;
 
 						// The original at this point was doing a loop on counter1, which is not a good idea as
 						// it was resetting the counter1 to 9 whatever its value before the loop.
-						// Furthermore, it was accessing _teamMonsterEffects[counter1]._effect[counter1] which doesn't make
-						// sense...
 						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
-						for (uint counter2 = 0; counter2 < 9; ++counter2) {
-							_teamMonsterEffects[counter1]._effect[counter2] = 0;
+						for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+							_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 0;
 						}
 
-						if (++var4 >= 5)
+						if (++teamMonsterId >= 5)
 							break;
 					}
 				}
@@ -2372,14 +2371,14 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 		// sub1BE9A - loop var2 - End
 	}
 
-	if (var4 == -1 || var4 > 4)
+	if (teamMonsterId == -1 || teamMonsterId > 4)
 		return;
 
 	// sub1BE9A - last loop counter1_monsterId - Start
-	for (int16 counter1 = var4; counter1 < 5; ++counter1) {
-		_teamMonsterIdArray[counter1] = -1;
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_teamMonsterEffects[counter1]._effect[counter2] = (int16)0x8000;
+	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
+		_teamMonsterIdArray[ctrTeamMonsterId] = -1;
+		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+			_teamMonsterEffects[ctrTeamMonsterId]._effect[ctrEffectId] = (int16)0x8000;
 		}
 	}
 	// sub1BE9A - last loop counter1_monsterId - End
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 02b020b4c06..a03df2a9b19 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -464,7 +464,7 @@ private:
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA);
+	int16 sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA);
 
 	// Savegames
 	void synchronize(Common::Serializer &s);
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index b6ea94c1cbb..6950fed3b5f 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -899,8 +899,8 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 	}
 }
 
-int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine, int16 argA) {
-	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine, argA);
+int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA) {
+	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, teamMonsterId, menuId, curMenuLine, argA);
 
 	Common::String buffer1 = "";
 
@@ -911,37 +911,37 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	switch (_items[itemId]._specialEffect - 1) {
 	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
 		if (argA == 2) {
-			displayString_3("The item emits a low droning hum...", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("The item emits a low droning hum...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 victims = 0;
 			_messageToBePrinted += "  The item emits a low droning hum...";
 			if (getRandom(100) < 50) {
-				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
+				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
 						++victims;
-						_teamMonsterEffects[windowId]._effect[counter] = 1;
-						_teamMonsterEffects[windowId]._duration[counter] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 1;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
 					}
 				}
 			} else {
 				int16 NumberOfTargets = getRandom(9);
-				for (uint counter = 0; counter < 9; ++counter) {
+				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
 					if (NumberOfTargets == 0)
 						break;
 
-					if (isMonsterActive(windowId, counter)) {
+					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
 						++victims;
 						--NumberOfTargets;
-						_teamMonsterEffects[windowId]._effect[counter] = 1;
-						_teamMonsterEffects[windowId]._duration[counter] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 1;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
 					}
 				}
 			}
 			// The original was duplicating this code in each branch of the previous random check.
 			if (victims > 1) {
-				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 		}
@@ -950,38 +950,38 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
 		if (argA == 2) {
-			displayString_3("The item grows very cold for a moment...", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("The item grows very cold for a moment...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The item emits a blue beam...";
 			int16 victim = 0;
 			if (getRandom(100) < 50) {
-				for (uint varA8 = 0; varA8 < 9; ++varA8) {
-					if (isMonsterActive(windowId, varA8)) {
+				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
 						++victim;
-						_teamMonsterEffects[windowId]._effect[varA8] = 2;
-						_teamMonsterEffects[windowId]._duration[varA8] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 2;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
 					}
 				}
 			} else {
 				int16 varAC = getRandom(9);
-				for (uint varA8 = 0; varA8 < 9; ++varA8) {
+				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
 					if (varAC == 0)
 						break;
 
-					if (isMonsterActive(windowId, varA8)) {
+					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
 						++victim;
 						--varAC;
-						_teamMonsterEffects[windowId]._effect[varA8] = 2;
-						_teamMonsterEffects[windowId]._duration[varA8] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 2;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
 					}
 				}
 			}
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[windowId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 			// </CHECKME>
@@ -991,7 +991,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	case 2:
 		if (argA == 2) {
-			displayString_3("A serene feeling passes through the air...", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("A serene feeling passes through the air...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
 			_unk2C8AA = 0;
@@ -1001,20 +1001,20 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	case 4: // "Unholy Sinwave", "Holy Water"
 		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
 					}
 				}
 			} else {
 				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
+					if (isMonsterActive(teamMonsterId, counter)) {
 						if (getRandom(100) < 50) {
-							_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+							_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
 						}
 						break;
 					}
@@ -1025,18 +1025,18 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
 		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			if (getRandom(100) < 50) {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
 				for (uint counter = 0; counter < 9; ++counter) {
-					_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+					_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
 				}
 			} else {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
 				for (uint counter = 0; counter < 9; ++counter) {
-					if (isMonsterActive(windowId, counter)) {
-						_mapMonsters[_teamMonsterIdArray[windowId]]._pictureRef[counter] = 0;
+					if (isMonsterActive(teamMonsterId, counter)) {
+						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
 					}
 				}
 			}
@@ -1046,26 +1046,26 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		break;
 	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
 		if (argA == 2) {
-			displayString_3("There is no apparent affect!", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterField8(windowId, _items[itemId].field17_attackTypeDefense, true);
+			setMapMonsterField8(teamMonsterId, _items[itemId].field17_attackTypeDefense, true);
 		}
 		varA6 = true;
 		break;
 	case 14: { // "Feathered Cap"
 		int16 varAA;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			varAA = selectOtherCharFromTeam();
 		} else {
-			varAA = windowId;
+			varAA = teamMonsterId;
 		}
 
 		if (varAA != 0x1B) {
 			buffer1 = "  The magic makes the user as quick and agile as a bird!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -1079,16 +1079,16 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 15: { // "Regal Crown"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 		}
 
 		if (teamCharId != 0x1B) {
 			buffer1 = "  The magic makes the user invisible!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -1109,7 +1109,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1118,7 +1118,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1126,7 +1126,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1144,7 +1144,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1153,7 +1153,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1161,7 +1161,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1173,9 +1173,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	} break;
 	case 18:
 		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
-			int16 teamCharId = windowId;
+			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
@@ -1192,7 +1192,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 19: // "Junk"
 		buffer1 = "  * The item breaks!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 		}
@@ -1228,7 +1228,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 		buffer1 += "'";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1239,10 +1239,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 24: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId].field17_attackTypeDefense;
@@ -1257,7 +1257,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1269,10 +1269,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 25: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId].field17_attackTypeDefense;
@@ -1287,7 +1287,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1299,7 +1299,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 26: // "Black Sphere"
 		buffer1 = "The entire party collapses, dead!!!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1310,17 +1310,17 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 27: { // "Magic Pyramid", "Razor Blade"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 		}
 
 		if (teamCharId != 0x1B) {
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1331,9 +1331,9 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	} break;
 	case 28: // "Bugle"
 		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
-			int16 teamCharId = windowId;
+			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
 				if (_teamCharStatus[teamCharId]._status == 0) {
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
@@ -1350,10 +1350,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 		}
 
 		if (teamCharId != 0x1B) {
@@ -1369,7 +1369,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1380,10 +1380,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 	case 30: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, windowId, menuId, curMenuLine);
+			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
-			teamCharId = windowId;
+			teamCharId = teamMonsterId;
 		}
 
 		if (teamCharId != 0x1B) {
@@ -1399,7 +1399,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1430,7 +1430,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 				buffer1 = "  * The item breaks!";
 				if (argA == 2) {
 					getLastCharAfterAnimCount(_guessAnimationAmount);
-					displayString_3(buffer1, false, charId, windowId, menuId, curMenuLine);
+					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 				}
@@ -1443,7 +1443,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 windowId, int16 me
 
 		if (argA == 2) {
 			getLastCharAfterAnimCount(_guessAnimationAmount);
-			sub18E80(charId, windowId, menuId, curMenuLine);
+			sub18E80(charId, teamMonsterId, menuId, curMenuLine);
 		}
 	}
 


Commit: 88ad3db32d9e67ef84e69759413b7a403c2b4076
    https://github.com/scummvm/scummvm/commit/88ad3db32d9e67ef84e69759413b7a403c2b4076
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Review giveItemTo(), renaming + fix a bug in handleStatusMenu()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4a268d24d37..7626903f103 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -920,7 +920,7 @@ void EfhEngine::handleWinSequence() {
 }
 
 bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
-	debug("giveItemTo %d %d %d", charId, objectId, altCharId);
+	debugC(3, kDebugEngine, "giveItemTo %d %d %d", charId, objectId, altCharId);
 
 	for (uint newObjectId = 0; newObjectId < 10; ++newObjectId) {
 		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
@@ -933,7 +933,7 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
 		} else {
 			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[altCharId]._inventory[newObjectId]._ref;
 			_npcBuf[charId]._inventory[newObjectId]._stat2 = _npcBuf[altCharId]._inventory[newObjectId]._stat2;
-			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[altCharId]._inventory[newObjectId]._stat1 & 0x7F;
+			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[altCharId]._inventory[newObjectId]._stat1 & 0x7F; // not equipped as the upper bit isn't set (0x80)
 		}
 
 		return true;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 6950fed3b5f..f0bb55f25df 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -734,40 +734,41 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				sub18E80(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
-					bool var6;
-					int16 var8;
+					bool givenFl;
+					int16 destCharId;
 					do {
 						if (_teamCharId[2] != -1) {
-							var8 = displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
+							displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
+							destCharId = selectOtherCharFromTeam();
 							var2 = false;
 						} else if (_teamCharId[1]) {
-							var8 = 0x1A;
+							destCharId = 0x1A;
 							var2 = false;
 						} else {
 							var2 = true;
 							if (_teamCharId[0] == charId)
-								var8 = 1;
+								destCharId = 1;
 							else
-								var8 = 0;
+								destCharId = 0;
 						}
 
-						if (var8 != 0x1A && var8 != 0x1B) {
-							var6 = giveItemTo(_teamCharId[var8], objectId, charId);
-							if (!var6) {
+						if (destCharId != 0x1A && destCharId != 0x1B) {
+							givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
+							if (!givenFl) {
 								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
 								getLastCharAfterAnimCount(_guessAnimationAmount);
 							}
 						} else {
-							if (var8 == 0x1A) {
+							if (destCharId == 0x1A) {
 								displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
 								getLastCharAfterAnimCount(_guessAnimationAmount);
-								var8 = 0x1B;
+								destCharId = 0x1B;
 							}
-							var6 = false;
+							givenFl = false;
 						}
-					} while (!var6 && !var2 && var8 != 0x1B);
+					} while (!givenFl && !var2 && destCharId != 0x1B);
 
-					if (var6) {
+					if (givenFl) {
 						removeObject(charId, objectId);
 						if (gameMode == 2) {
 							restoreAnimImageSetId();


Commit: 4a9ac53f03c226dbd47b465118ff0b8451aa4705
    https://github.com/scummvm/scummvm/commit/4a9ac53f03c226dbd47b465118ff0b8451aa4705
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Validate some more functions, more renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7626903f103..29d444725cc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -447,7 +447,7 @@ void EfhEngine::initMapMonsters() {
 			continue;
 
 		for (uint counter = 0; counter < 9; ++counter)
-			_mapMonsters[monsterId]._pictureRef[counter] = 0;
+			_mapMonsters[monsterId]._hitPoints[counter] = 0;
 
 		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
 		if (groupSize == 0)
@@ -462,12 +462,12 @@ void EfhEngine::initMapMonsters() {
 
 			if (rand100 <= 25) {
 				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef - delta;
+				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef - delta;
 			} else if (rand100 <= 75) {
-				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef;
+				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef;
 			} else {
 				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[monsterId]._pictureRef[counter] = pictureRef + delta;
+				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef + delta;
 			}
 		}
 	}
@@ -503,7 +503,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapMonsters[i]._field9_textId = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
-			_mapMonsters[i]._pictureRef[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
+			_mapMonsters[i]._hitPoints[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
 	}
 
 	uint8 *mapPtr = &_mapArr[idx][2758];
@@ -667,7 +667,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 					continue;
 
 				for (uint counterY = 0; counterY < 9 && !var4; ++counterY) {
-					if (_mapMonsters[var16]._pictureRef[counterY] > 0)
+					if (_mapMonsters[var16]._hitPoints[counterY] > 0)
 						var4 = true;
 				}
 
@@ -677,7 +677,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 				int16 var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
 				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
 
-				if (var1 == 0x3F && isCharacterATeamMember(_mapMonsters[var16]._npcId))
+				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[var16]._npcId))
 					continue;
 
 				int16 drawPosX = 128 + (posX - minX) * 16;
@@ -826,8 +826,8 @@ void EfhEngine::refreshTeamSize() {
 	}
 }
 
-bool EfhEngine::isCharacterATeamMember(int16 id) {
-	debugC(6, kDebugEngine,"isCharacterATeamMember %d", id);
+bool EfhEngine::isNpcATeamMember(int16 id) {
+	debugC(6, kDebugEngine,"isNpcATeamMember %d", id);
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
 		if (_teamCharId[counter] == id)
@@ -1753,7 +1753,7 @@ bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
 		return false;
 
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
+		if (_mapMonsters[monsterId]._hitPoints[counter] > 0)
 			return true;
 	}
 
@@ -1767,19 +1767,15 @@ void EfhEngine::displayMonsterAnim(int16 monsterId) {
 	displayAnimFrames(animId, true);
 }
 
-int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
-	debug("countPictureRef %d %s", id, teamMemberFl ? "True" : "False");
+// The original is using an additional bool parameter which was only passed as 'False'.
+// It has been removed as well as the associated code
+int16 EfhEngine::countAliveMonsters(int16 id) {
+	debugC(6, kDebugEngine, "countAliveMonsters %d", id);
 
 	int16 count = 0;
-	int16 monsterId;
-
-	if (teamMemberFl)
-		monsterId = _teamMonsterIdArray[id];
-	else
-		monsterId = id;
 
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[monsterId]._pictureRef[counter] > 0)
+		if (_mapMonsters[id]._hitPoints[counter] > 0)
 			++count;
 	}
 
@@ -1787,7 +1783,7 @@ int16 EfhEngine::countPictureRef(int16 id, bool teamMemberFl) {
 }
 
 bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
-	debug("checkMonsterGroupDistance1OrLess %d", monsterId);
+	debugC(6,kDebugEngine, "checkMonsterGroupDistance1OrLess %d", monsterId);
 
 	if (computeMonsterGroupDistance(monsterId) > 1)
 		return false;
@@ -1802,7 +1798,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
-	if (countPictureRef(monsterId, false) < 1)
+	if (countAliveMonsters(monsterId) < 1)
 		return false;
 
 	if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
@@ -1821,7 +1817,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		return true;
 	}
 
-	if (isCharacterATeamMember(_mapMonsters[monsterId]._npcId))
+	if (isNpcATeamMember(_mapMonsters[monsterId]._npcId))
 		return false;
 
 	int16 npcId = _mapMonsters[monsterId]._npcId;
@@ -2296,7 +2292,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 			continue;
 
 		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_mapMonsters[_teamMonsterIdArray[counter1]]._pictureRef[counter2] = 0;
+			_mapMonsters[_teamMonsterIdArray[counter1]]._hitPoints[counter2] = 0;
 			_teamMonsterEffects[counter1]._effect[counter2] = 0;
 			_teamMonsterEffects[counter1]._duration[counter2] = 0;
 		}
@@ -2334,11 +2330,11 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 				if (_mapMonsters[ctrMapMonsterId]._guess_fullPlaceId == 0xFF)
 					continue;
 
-				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isCharacterATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
 						bool monsterActiveFound = false;
 						for (uint ctrSubId = 0; ctrSubId < 9; ++ctrSubId) {
-							if (_mapMonsters[ctrMapMonsterId]._pictureRef[ctrSubId] > 0) {
+							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrSubId] > 0) {
 								monsterActiveFound = true;
 								break;
 							}
@@ -2350,7 +2346,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 						if (computeMonsterGroupDistance(ctrMapMonsterId) > var2)
 							continue;
 
-						if (sub1BC74(ctrMapMonsterId, teamMonsterId))
+						if (isMonsterAlreadyFighting(ctrMapMonsterId, teamMonsterId))
 							continue;
 
 						_teamMonsterIdArray[teamMonsterId] = ctrMapMonsterId;
@@ -2522,7 +2518,7 @@ void EfhEngine::setMapMonsterField8(int16 id, uint8 movementType, bool groupFl)
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	debugC(5, kDebugEngine, "isMonsterActive %d %d", groupId, id);
 
-	if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
+	if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
 		return true;
 	return false;
 }
@@ -2573,7 +2569,7 @@ bool EfhEngine::checkMonsterCollision() {
 			continue;
 
 		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
-		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isCharacterATeamMember(_mapMonsters[monsterId]._npcId)))
+		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isNpcATeamMember(_mapMonsters[monsterId]._npcId)))
 			continue;
 
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
@@ -2587,7 +2583,7 @@ bool EfhEngine::checkMonsterCollision() {
 
 		int16 var6A = 0;
 		for (uint var6C = 0; var6C < 9; ++var6C) {
-			if (_mapMonsters[monsterId]._pictureRef[var6C])
+			if (_mapMonsters[monsterId]._hitPoints[var6C])
 				++var6A;
 		}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a03df2a9b19..c24cc3c3c2f 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -214,7 +214,7 @@ struct MapMonster {
 	uint8 _moveInfo; // abbb cccc a: special move flag, bbb: Pct modifier for random move, cccc movement type
 	uint8 _field9_textId;
 	uint8 _groupSize;
-	int16 _pictureRef[9];
+	int16 _hitPoints[9];
 };
 
 struct Stru32686 {
@@ -308,7 +308,7 @@ private:
 	void totalPartyKill();
 	void removeCharacterFromTeam(int16 teamMemberId);
 	void refreshTeamSize();
-	bool isCharacterATeamMember(int16 id);
+	bool isNpcATeamMember(int16 id);
 	void handleWinSequence();
 	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
 	int16 chooseCharacterToReplace();
@@ -345,7 +345,7 @@ private:
 	void handleMapMonsterMoves();
 	bool checkPictureRefAvailability(int16 monsterId);
 	void displayMonsterAnim(int16 monsterId);
-	int16 countPictureRef(int16 id, bool teamMemberFl);
+	int16 countAliveMonsters(int16 id);
 	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
 	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
 	void sub221D2(int16 monsterId);
@@ -378,9 +378,9 @@ private:
 	void handleFight_lastAction_H(int16 teamCharId);
 	void handleFight_lastAction_U(int16 teamCharId);
 	bool isTPK();
-	bool sub1BC74(int16 monsterId, int16 teamMonsterId);
-	void sub1BCA7(int16 monsterTeamId);
-	void reset_stru32686();
+	bool isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId);
+	void createOpponentList(int16 monsterTeamId);
+	void resetTeamMonsterEffects();
 	void sub1BE89(int16 monsterId);
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 98a94f63738..a7504082dc8 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -23,11 +23,11 @@
 
 namespace Efh {
 
-void EfhEngine::sub1BCA7(int16 monsterTeamId) {
-	debug("sub1BCA7 %d", monsterTeamId);
+void EfhEngine::createOpponentList(int16 monsterTeamId) {
+	debugC(3, kDebugEngine, "createOpponentList %d", monsterTeamId);
 
 	int16 counter = 0;
-	if (monsterTeamId != -1 && countPictureRef(monsterTeamId, false) > 0) {
+	if (monsterTeamId != -1 && countAliveMonsters(monsterTeamId) > 0) {
 		counter = 1;
 		_teamMonsterIdArray[0] = monsterTeamId;
 	}
@@ -40,22 +40,22 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 				continue;
 
-			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isCharacterATeamMember(_mapMonsters[monsterId]._npcId)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[monsterId]._npcId)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
 				continue;
 
 			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 				continue;
 
 			bool found = false;
-			for (uint counter3 = 0; counter3 < 9; ++counter3) {
-				if (_mapMonsters[monsterId]._pictureRef[counter3] > 0) {
+			for (uint subId = 0; subId < 9; ++subId) {
+				if (_mapMonsters[monsterId]._hitPoints[subId] > 0) {
 					found = true;
 					break;
 				}
 			}
 
 			if (found) {
-				if (computeMonsterGroupDistance(monsterId) <= counter2 && !sub1BC74(monsterId, counter)) {
+				if (computeMonsterGroupDistance(monsterId) <= counter2 && !isMonsterAlreadyFighting(monsterId, counter)) {
 					_teamMonsterIdArray[counter] = monsterId;
 					if (++counter >= 5)
 						break;
@@ -73,8 +73,8 @@ void EfhEngine::sub1BCA7(int16 monsterTeamId) {
 
 void EfhEngine::sub1BE89(int16 monsterId) {
 	debug("sub1BE89 %d", monsterId);
-	sub1BCA7(monsterId);
-	reset_stru32686();
+	createOpponentList(monsterId);
+	resetTeamMonsterEffects();
 }
 
 bool EfhEngine::handleFight(int16 monsterId) {
@@ -337,7 +337,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							}
 							// handleFight - Loop on var7E - End
 						}
-					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._pictureRef[var86] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
+					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[var86] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
 						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86];
 						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86] <= 0) {
 							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
@@ -470,7 +470,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					varInt = _teamMonsterIdArray[groupId];
 					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
-					int16 var80 = _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E];
+					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E];
 					int16 var62 = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
@@ -503,7 +503,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						var62 = 0;
 
 					if (var62 > 0) {
-						_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] -= originalDamage;
+						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] -= originalDamage;
 						if (var62 > 1) {
 							_attackBuffer = Common::String::format("%d times ", var62);
 						} else {
@@ -535,7 +535,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -543,7 +543,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							}
 						} else {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] <= 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -553,19 +553,19 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check damages - End
 
 						// Action A - Add reaction text - Start
-						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] - 5 <= originalDamage) {
+						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] - 5 <= originalDamage) {
 								addReactionText(0);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 8) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 8) {
 								addReactionText(1);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 4) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 4) {
 								addReactionText(2);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 2) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 2) {
 								addReactionText(3);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] < var80 / 3) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 3) {
 								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
 								addReactionText(4);
-							} else if (var80 / 8 >= originalDamage) {
+							} else if (hitPointsBefore / 8 >= originalDamage) {
 								addReactionText(5);
 							} else if (originalDamage == 0 && getRandom(100) < 35) {
 								addReactionText(6);
@@ -574,7 +574,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add reaction text - End
 
 						// Action A - Add armor absorb text - Start
-						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
 							if (damagePointsAbsorbed <= 1)
 								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							else
@@ -602,13 +602,13 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[unk_monsterField5_itemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+						if (_items[unk_monsterField5_itemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
 							if (getRandom(100) < 35) {
 								_teamMonsterEffects[groupId]._effect[var7E] = 1;
 								_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[unk_monsterField5_itemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._pictureRef[var7E] > 0) {
+						} else if (_items[unk_monsterField5_itemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
 							_teamMonsterEffects[groupId]._effect[var7E] = 2;
 							_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -692,8 +692,8 @@ bool EfhEngine::isTPK() {
 	return zeroedChar == _teamSize;
 }
 
-bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
-	debug("sub1BC74 %d %d", monsterId, teamMonsterId);
+bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
+	debug("isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
 
 	for (int counter = 0; counter < teamMonsterId; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId)
@@ -702,12 +702,12 @@ bool EfhEngine::sub1BC74(int16 monsterId, int16 teamMonsterId) {
 	return false;
 }
 
-void EfhEngine::reset_stru32686() {
-	debug("reset_stru32686");
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_teamMonsterEffects[counter1]._effect[counter2] = 0;
-			_teamMonsterEffects[counter1]._duration[counter2] = 0;
+void EfhEngine::resetTeamMonsterEffects() {
+	debugC(6, kDebugEngine, "resetTeamMonsterEffects");
+	for (uint ctrMonsterId = 0; ctrMonsterId < 5; ++ctrMonsterId) {
+		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+			_teamMonsterEffects[ctrMonsterId]._effect[ctrEffectId] = 0;
+			_teamMonsterEffects[ctrMonsterId]._duration[ctrEffectId] = 0;
 		}
 	}
 }
@@ -1398,11 +1398,11 @@ int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 		if (!isMonsterActive(groupNumber, counter))
 			continue;
 
-		if (_mapMonsters[monsterId]._pictureRef[var4] > _mapMonsters[monsterId]._pictureRef[counter])
+		if (_mapMonsters[monsterId]._hitPoints[var4] > _mapMonsters[monsterId]._hitPoints[counter])
 			var4 = counter;
 	}
 
-	if (_mapMonsters[monsterId]._pictureRef[var4] <= 0)
+	if (_mapMonsters[monsterId]._hitPoints[var4] <= 0)
 		return -1;
 
 	return var4;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index f0bb55f25df..43f4610d71b 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1008,14 +1008,14 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
-						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
+						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 					}
 				}
 			} else {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
 						if (getRandom(100) < 50) {
-							_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
+							_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 						}
 						break;
 					}
@@ -1031,13 +1031,13 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			if (getRandom(100) < 50) {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
 				for (uint counter = 0; counter < 9; ++counter) {
-					_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
+					_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 				}
 			} else {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
-						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._pictureRef[counter] = 0;
+						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 					}
 				}
 			}
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 354c9bcf639..aa901340a64 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -293,7 +293,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0F:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				if (isCharacterATeamMember(scriptNumberArray[0]))
+				if (isNpcATeamMember(scriptNumberArray[0]))
 					retVal = scriptNumberArray[1];
 				else
 					retVal = scriptNumberArray[2];
@@ -332,7 +332,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (flag) {
 				int16 scriptNpcId = scriptNumberArray[0];
-				if (!isCharacterATeamMember(scriptNpcId))
+				if (!isNpcATeamMember(scriptNpcId))
 					var_EE = scriptNpcId;
 				retVal = -1;
 			}
@@ -351,7 +351,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (flag) {
 				int16 scriptNpcId = scriptNumberArray[0];
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
-				if (isCharacterATeamMember(scriptNpcId)) {
+				if (isNpcATeamMember(scriptNpcId)) {
 					for (uint counter = 0; counter < 3; ++counter) {
 						if (_teamCharId[counter] == scriptNpcId) {
 							removeCharacterFromTeam(counter);


Commit: a28c93becf1a9a805467fa1aadd49306e900ca00
    https://github.com/scummvm/scummvm/commit/a28c93becf1a9a805467fa1aadd49306e900ca00
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Fix display of low status window

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 29d444725cc..30c089d8685 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -726,7 +726,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 			displayCenteredString("DEF", 104, 128, 152);
 			displayCenteredString("HP", 144, 176, 152);
 			displayCenteredString("Max HP", 192, 224, 152);
-			displayCenteredString("* DEAD *", 225, 302, 152);
+			displayCenteredString("Weapon", 225, 302, 152);
 			setTextColorRed();
 
 			for (int i = 0; i < 3; ++i) {


Commit: 2042def6a0c897abe0682acefd49a168853144fd
    https://github.com/scummvm/scummvm/commit/2042def6a0c897abe0682acefd49a168853144fd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Validate some more functions, more renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 30c089d8685..7ef03b234a6 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -483,7 +483,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapUnknown[i]._posX = _mapUnknownPtr[9 * i + 1];
 		_mapUnknown[i]._posY = _mapUnknownPtr[9 * i + 2];
 		_mapUnknown[i]._field3 = _mapUnknownPtr[9 * i + 3];
-		_mapUnknown[i]._field4 = _mapUnknownPtr[9 * i + 4];
+		_mapUnknown[i]._field4_NpcId = _mapUnknownPtr[9 * i + 4];
 		_mapUnknown[i]._field5_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
 		_mapUnknown[i]._field7_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
 	}
@@ -802,7 +802,7 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	_npcBuf[charId].field12_textId = _npcBuf[charId].fieldB_textId;
 	_npcBuf[charId].field14_textId = _npcBuf[charId].fieldE_textId;
 	_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
-	_npcBuf[charId].field_11 = _npcBuf[charId].field_D;
+	_npcBuf[charId].field11_NpcId = _npcBuf[charId].field_D;
 
 	_teamCharId[teamMemberId] = -1;
 	_teamCharStatus[teamMemberId]._status = 0;
@@ -1358,7 +1358,7 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 		if (counter == monsterId)
 			continue;
 
-		if (!checkPictureRefAvailability(counter))
+		if (!checkMapMonsterAvailability(counter))
 			continue;
 
 		if (_mapMonsters[monsterId]._guess_fullPlaceId == _mapMonsters[counter]._guess_fullPlaceId
@@ -1587,7 +1587,7 @@ void EfhEngine::handleMapMonsterMoves() {
 	int16 maxDisplayedMapY = CLIP<int16>(minDisplayedMapY + 17, 0, mapSize);
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-		if (!checkPictureRefAvailability(monsterId))
+		if (!checkMapMonsterAvailability(monsterId))
 			continue;
 
 		if (!checkTeamWeaponRange(monsterId))
@@ -1746,8 +1746,8 @@ void EfhEngine::handleMapMonsterMoves() {
 		handleFight(attackMonsterId);
 }
 
-bool EfhEngine::checkPictureRefAvailability(int16 monsterId) {
-	debugC(6, kDebugEngine, "checkPictureRefAvailability %d", monsterId);
+bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
+	debugC(6, kDebugEngine, "checkMapMonsterAvailability %d", monsterId);
 
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
@@ -1791,10 +1791,9 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 	return true;
 }
 
-bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
-	debug("sub21820 %d %d %d", monsterId, arg2, itemId);
+bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
+	debug("handleTalk %d %d %d", monsterId, arg2, itemId);
 
-	uint8 var51 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
 	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
 		return false;
 
@@ -1807,7 +1806,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	if (!checkMonsterGroupDistance1OrLess(monsterId))
 		return false;
 
-	if (var51 != 0x3F) {
+	if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F) {
 		if (_mapMonsters[monsterId]._field9_textId == 0xFF || arg2 != 5) {
 			return false;
 		}
@@ -1823,7 +1822,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	int16 npcId = _mapMonsters[monsterId]._npcId;
 	switch (_npcBuf[npcId].field_10 - 0xEE) {
 	case 0:
-		if (arg2 == 4 && _npcBuf[npcId].field_11 == itemId) {
+		if (arg2 == 4 && _npcBuf[npcId].field11_NpcId == itemId) {
 			displayMonsterAnim(monsterId);
 			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
@@ -1831,7 +1830,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 1:
-		if (arg2 == 2 && _npcBuf[npcId].field_11 == itemId) {
+		if (arg2 == 2 && _npcBuf[npcId].field11_NpcId == itemId) {
 			displayMonsterAnim(monsterId);
 			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
@@ -1839,7 +1838,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 2:
-		if (arg2 == 1 && _npcBuf[npcId].field_11 == itemId) {
+		if (arg2 == 1 && _npcBuf[npcId].field11_NpcId == itemId) {
 			displayMonsterAnim(monsterId);
 			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
@@ -1847,7 +1846,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 3:
-		if (_history[_npcBuf[npcId].field_11] != 0) {
+		if (_history[_npcBuf[npcId].field11_NpcId] != 0) {
 			displayMonsterAnim(monsterId);
 			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
@@ -1857,7 +1856,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 4:
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field_11) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field11_NpcId) {
 					removeObject(_teamCharId[counter], charId);
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
@@ -1868,7 +1867,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 5:
-		if (arg2 == 2 && _npcBuf[npcId].field_11 == itemId) {
+		if (arg2 == 2 && _npcBuf[npcId].field11_NpcId == itemId) {
 			displayMonsterAnim(monsterId);
 			displayImp1Text(_npcBuf[npcId].field14_textId);
 			displayAnimFrames(0xFE, true);
@@ -1878,7 +1877,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	case 6:
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field_11) {
+				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field11_NpcId) {
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
@@ -1889,7 +1888,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 7:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
 				removeCharacterFromTeam(counter);
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
@@ -1900,7 +1899,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 8:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[npcId]._name;
 				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
@@ -1927,7 +1926,7 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 9:
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field_11 == _teamCharId[counter]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
@@ -1954,12 +1953,12 @@ bool EfhEngine::sub21820(int16 monsterId, int16 arg2, int16 itemId) {
 	return true;
 }
 
-void EfhEngine::sub221D2(int16 monsterId) {
-	debug("sub221D2 %d", monsterId);
+void EfhEngine::startTalkMenu(int16 monsterId) {
+	debugC(6, kDebugEngine, "startTalkMenu %d", monsterId);
 
 	if (monsterId != -1) {
 		_tempTextPtr = nullptr;
-		sub21820(monsterId, 5, -1);
+		handleTalk(monsterId, 5, -1);
 	}
 }
 
@@ -2098,7 +2097,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
-				if (_teamCharId[counter] == _mapUnknown[var8]._field4) {
+				if (_teamCharId[counter] == _mapUnknown[var8]._field4_NpcId) {
 					displayImp1Text(_mapUnknown[var8]._field5_textId);
 					return true;
 				}
@@ -2109,7 +2108,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4) {
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4_NpcId) {
 						displayImp1Text(_mapUnknown[var8]._field5_textId);
 						return true;
 					}
@@ -2125,7 +2124,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				for (uint var2 = 0; var2 < 39; ++var2) {
 					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4) {
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4_NpcId) {
 						displayImp1Text(_mapUnknown[var8]._field5_textId);
 						return true;
 					}
@@ -2134,7 +2133,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		}
 	} else {
 		if ((_mapUnknown[var8]._field3 == 0xFA && arg8 == 1) || (_mapUnknown[var8]._field3 == 0xFC && arg8 == 2) || (_mapUnknown[var8]._field3 == 0xFB && arg8 == 3)) {
-			if (_mapUnknown[var8]._field4 == itemId) {
+			if (_mapUnknown[var8]._field4_NpcId == itemId) {
 				displayImp1Text(_mapUnknown[var8]._field5_textId);
 				return true;
 			}
@@ -2142,7 +2141,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			int16 var6 = _mapUnknown[var8]._field3;
 			if (var6 >= 0x7B && var6 <= 0xEF) {
 				var6 -= 0x78;
-				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknown[var8]._field4 <= _npcBuf[charId]._activeScore[itemId]) {
+				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknown[var8]._field4_NpcId <= _npcBuf[charId]._activeScore[itemId]) {
 					displayImp1Text(_mapUnknown[var8]._field5_textId);
 					return true;
 				}
@@ -2151,7 +2150,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	}
 
 	for (uint counter = 0; counter < 64; ++counter) {
-		if (!sub21820(counter, arg8, itemId))
+		if (!handleTalk(counter, arg8, itemId))
 			return true;
 	}
 
@@ -2557,19 +2556,18 @@ int16 EfhEngine::selectOtherCharFromTeam() {
 }
 
 bool EfhEngine::checkMonsterCollision() {
-	debug("checkMonsterCollision");
-
-	int16 var68 = 0;
+	debugC(3, kDebugEngine, "checkMonsterCollision");
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-		if (!checkPictureRefAvailability(monsterId))
+		if (!checkMapMonsterAvailability(monsterId))
 			continue;
 
-		if (!(_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE) && !(!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId))
+		if (!(_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
+		 && !(!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId))
 			continue;
 
 		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
-		&& !(((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) == 0x3F) && !isNpcATeamMember(_mapMonsters[monsterId]._npcId)))
+		 && ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[monsterId]._npcId)))
 			continue;
 
 		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
@@ -2581,30 +2579,34 @@ bool EfhEngine::checkMonsterCollision() {
 			_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
 		_redrawNeededFl = true;
 
-		int16 var6A = 0;
-		for (uint var6C = 0; var6C < 9; ++var6C) {
-			if (_mapMonsters[monsterId]._hitPoints[var6C])
-				++var6A;
+		int16 mobsterCount = 0;
+		for (uint mobsterCounter = 0; mobsterCounter < 9; ++mobsterCounter) {
+			if (_mapMonsters[monsterId]._hitPoints[mobsterCounter])
+				++mobsterCount;
 		}
 
-		Common::String buffer = "";
+		bool endLoop = false;
+		Common::String buffer;
 		do {
-			for (uint var6C = 0; var6C < 2; ++var6C) {
-				int16 var1 = _mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F;
+			for (uint displayCounter = 0; displayCounter < 2; ++displayCounter) {
 				Common::String dest;
-				if (var1 <= 0x3D) {
-					dest = kEncounters[_mapMonsters[monsterId]._monsterRef]._name;
-					if (var6A > 1)
-						dest += "s";
-
-					buffer = Common::String::format("with %d ", var6A) + dest;
-				} else if (var1 == 0x3E) {
+				switch (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) {
+				case 0x3E:
 					buffer = "(NOT DEFINED)";
 					dest = "(NOT DEFINED)";
-				} else if (var1 == 0x3F) { // Useless check, it's the last possible value
+					break;
+				case 0x3F:
 					// Special character name
 					dest = _npcBuf[_mapMonsters[monsterId]._npcId]._name;
 					buffer = Common::String("with ") + dest;
+					break;
+				default:
+					dest = kEncounters[_mapMonsters[monsterId]._monsterRef]._name;
+					if (mobsterCount > 1)
+						dest += "s";
+
+					buffer = Common::String::format("with %d ", mobsterCount) + dest;
+					break;
 				}
 
 				clearBottomTextZone(0);
@@ -2633,7 +2635,7 @@ bool EfhEngine::checkMonsterCollision() {
 				displayStringAtTextPos("L");
 				setTextColorRed();
 				displayStringAtTextPos("eave");
-				if (var6C == 0)
+				if (displayCounter == 0)
 					displayFctFullScreen();
 			}
 
@@ -2641,28 +2643,28 @@ bool EfhEngine::checkMonsterCollision() {
 
 			switch (input) {
 			case Common::KEYCODE_a: // Attack
-				var6A = handleFight(monsterId);
-				var68 = true;
+				handleFight(monsterId);
+				endLoop = true;
 				break;
 			case Common::KEYCODE_ESCAPE:
 			case Common::KEYCODE_l: // Leave
-				var68 = true;
+				endLoop = true;
 				break;
 			case Common::KEYCODE_s: // Status
-				var6A = handleStatusMenu(1, _teamCharId[0]);
-				var68 = true;
+				handleStatusMenu(1, _teamCharId[0]);
+				endLoop = true;
 				_tempTextPtr = nullptr;
 				drawGameScreenAndTempText(true);
 				break;
 			case Common::KEYCODE_t: // Talk
-				sub221D2(monsterId);
-				var68 = true;
+				startTalkMenu(monsterId);
+				endLoop = true;
 				break;
 			default:
 				break;
 			}
-		} while (!var68);
-		return true;
+		} while (!endLoop);
+		return false;
 	}
 
 	int8 check = checkTileStatus(_mapPosX, _mapPosY, true);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index c24cc3c3c2f..911f3e81509 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -92,7 +92,7 @@ struct UnkMapStruct {
 	uint8 _posX;
 	uint8 _posY;
 	uint8 _field3;
-	uint8 _field4;
+	uint8 _field4_NpcId;
 	uint16 _field5_textId;
 	uint16 _field7_textId;
 
@@ -138,7 +138,7 @@ struct NPCStruct {
 	uint8 fieldE_textId;
 	uint8 field_F;
 	uint8 field_10;
-	uint8 field_11;
+	uint8 field11_NpcId;
 	uint16 field12_textId;
 	uint16 field14_textId;
 	uint32 _xp;
@@ -203,7 +203,7 @@ struct CharStatus {
 };
 
 struct MapMonster {
-	uint8 _possessivePronounSHL6;
+	uint8 _possessivePronounSHL6; // aabb bbbb aa:Possessive Pronoun, bb bbbb: unknown
 	uint8 _npcId;
 	uint8 _guess_fullPlaceId; // unsigned? Magic values are 0xFF and 0xFE
 	uint8 _posX;
@@ -343,12 +343,12 @@ private:
 	bool checkIfMonsterOnSameLargeMapPlace(int16 monsterId);
 	bool checkMonsterWeaponRange(int16 monsterId);
 	void handleMapMonsterMoves();
-	bool checkPictureRefAvailability(int16 monsterId);
+	bool checkMapMonsterAvailability(int16 monsterId);
 	void displayMonsterAnim(int16 monsterId);
 	int16 countAliveMonsters(int16 id);
 	bool checkMonsterGroupDistance1OrLess(int16 monsterId);
-	bool sub21820(int16 monsterId, int16 arg2, int16 itemId);
-	void sub221D2(int16 monsterId);
+	bool handleTalk(int16 monsterId, int16 arg2, int16 itemId);
+	void startTalkMenu(int16 monsterId);
 	void displayImp1Text(int16 textId);
 	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4);
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index ccae0802e5d..b346cb46c5c 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -270,7 +270,7 @@ void EfhEngine::loadNPCS() {
 		_npcBuf[i].fieldE_textId = f.readByte();
 		_npcBuf[i].field_F = f.readByte();
 		_npcBuf[i].field_10 = f.readByte();
-		_npcBuf[i].field_11 = f.readByte();
+		_npcBuf[i].field11_NpcId = f.readByte();
 		_npcBuf[i].field12_textId = f.readUint16LE();
 		_npcBuf[i].field14_textId = f.readUint16LE();
 		_npcBuf[i]._xp = f.readUint32LE();
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 1cc26d9713a..f99328bf78e 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -45,7 +45,7 @@ void InvObject::init() {
 }
 
 void UnkMapStruct::init() {
-	_placeId = _posX = _posY = _field3 = _field4 = 0;
+	_placeId = _posX = _posY = _field3 = _field4_NpcId = 0;
 	_field5_textId = _field7_textId = 0;
 }
 
@@ -90,7 +90,7 @@ void NPCStruct::init() {
 	fieldE_textId = 0;
 	field_F = 0;
 	field_10 = 0;
-	field_11 = 0;
+	field11_NpcId = 0;
 	field12_textId = 0;
 	field14_textId = 0;
 	_xp = 0;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 776a96b4ff8..8b9239d6bc3 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -173,7 +173,7 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		s.syncAsByte(_npcBuf[i].fieldE_textId);
 		s.syncAsByte(_npcBuf[i].field_F);
 		s.syncAsByte(_npcBuf[i].field_10);
-		s.syncAsByte(_npcBuf[i].field_11);
+		s.syncAsByte(_npcBuf[i].field11_NpcId);
 		s.syncAsSint16LE(_npcBuf[i].field12_textId);
 		s.syncAsSint16LE(_npcBuf[i].field14_textId);
 		s.syncAsSint32LE(_npcBuf[i]._xp);


Commit: fea76a97247c3e3688ca71d04521d4224bed8763
    https://github.com/scummvm/scummvm/commit/fea76a97247c3e3688ca71d04521d4224bed8763
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Review two more functions, small refactoring and some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7ef03b234a6..0db5323d082 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1257,27 +1257,28 @@ void EfhEngine::goSouthWest() {
 }
 
 void EfhEngine::handleNewRoundEffects() {
-	debug("handleNewRoundEffects");
-
-	static int16 regenCounter = 0;
+	debugC(6, kDebugEngine, "handleNewRoundEffects");
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
-		if (_teamCharStatus[counter]._status == 0) // normal
+		CharStatus *curStatus = &_teamCharStatus[counter];
+		if (curStatus->_status == 0) // normal
 			continue;
-		if (--_teamCharStatus[counter]._duration <= 0) {
-			_teamCharStatus[counter]._status = 0;
-			_teamCharStatus[counter]._duration = 0;
+
+		if (--curStatus->_duration <= 0) {
+			curStatus->_status = 0;
+			curStatus->_duration = 0;
 		}
 	}
 
-	if (++regenCounter <= 8)
+	if (++_regenCounter <= 8)
 		return;
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
-		if (++_npcBuf[_teamCharId[counter]]._hitPoints > _npcBuf[_teamCharId[counter]]._maxHP)
-			_npcBuf[_teamCharId[counter]]._hitPoints = _npcBuf[_teamCharId[counter]]._maxHP;
+		NPCStruct *curNpc = &_npcBuf[_teamCharId[counter]];
+		if (curNpc->_hitPoints < curNpc->_maxHP)
+			++curNpc->_hitPoints = curNpc->_maxHP;
 	}
-	regenCounter = 0;
+	_regenCounter = 0;
 }
 
 void EfhEngine::resetGame() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 911f3e81509..41e43422426 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -604,6 +604,8 @@ private:
 	int16 _menuStatItemArr[15];
 	Stru32686 _teamMonsterEffects[5];
 	InitiativeStruct _initiatives[8];
+
+	int16 _regenCounter;
 };
 
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index a7504082dc8..23eb055cc28 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1159,16 +1159,16 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 }
 
 void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
-	debug("getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
+	debugC(3, kDebugEngine, "getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
 
-	int16 xpLevel = getXPLevel(_npcBuf[charId]._xp);
+	int16 oldXpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 
-	if (getXPLevel(_npcBuf[charId]._xp) > xpLevel) {
+	if (getXPLevel(_npcBuf[charId]._xp) > oldXpLevel) {
 		generateSound(15);
-		int16 var2 = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
-		_npcBuf[charId]._hitPoints += var2;
-		_npcBuf[charId]._maxHP += var2;
+		int16 hpGain = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
+		_npcBuf[charId]._hitPoints += hpGain;
+		_npcBuf[charId]._maxHP += hpGain;
 		_npcBuf[charId]._infoScore[0] += getRandom(3) - 1;
 		_npcBuf[charId]._infoScore[1] += getRandom(3) - 1;
 		_npcBuf[charId]._infoScore[2] += getRandom(3) - 1;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index f99328bf78e..4f3609c856d 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -316,6 +316,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
 	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
 	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
+	_regenCounter = 0;
 
 	// If requested, load a savegame instead of showing the intro
 	_loadSaveSlot = -1;


Commit: 4eb3e39efeafe0ba6c3c6a8cee48ffa4875c2dd4
    https://github.com/scummvm/scummvm/commit/4eb3e39efeafe0ba6c3c6a8cee48ffa4875c2dd4
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: Fix a (likely) original bug, renaming and partial refactoring of ItemStruct (pronoun)

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0db5323d082..59ae1b042e4 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2418,21 +2418,20 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	debug("sub1D8C2 %d %d", charId, damage);
 
 	int16 destroyCounter = 0;
-	int16 var40 = _npcBuf[charId]._possessivePronounSHL6 / 64;
+	int16 pronoun = _npcBuf[charId].getPronoun();
 
-	if (var40 > 2) {
-		var40 = 2;
+	if (pronoun > 2) {
+		pronoun = 2;
 	}
 
-	if (damage > 50)
-		damage = 50;
+	int16 curDamage = CLIP<int16>(damage, 0, 50);
 
 	for (uint objectId = 0; objectId < 10; ++objectId) {
-		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || (_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0 && _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
+		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || (_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0 || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
 			continue;
 
-		int16 var44 = damage - _npcBuf[charId]._inventory[objectId]._stat2;
-		_npcBuf[charId]._inventory[objectId]._stat2 -= damage;
+		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._stat2;
+		_npcBuf[charId]._inventory[objectId]._stat2 -= curDamage;
 
 		if (_npcBuf[charId]._inventory[objectId]._stat2 <= 0) {
 			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
@@ -2440,15 +2439,19 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 
 			if (destroyCounter == 0) {
 				destroyCounter = 1;
-				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[var40]) + buffer2;
+				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[pronoun]) + buffer2;
 			} else {
 				++destroyCounter;
 				_messageToBePrinted += Common::String(", ") + buffer2;
 			}
 		}
 
-		if (var44 > 0)
-			damage = var44;
+		if (remainingDamage > 0)
+			curDamage = remainingDamage;
+		// The original doesn't contain this Else clause. But logically, if the remainingDamage is less than 0, it doesn't make sense to keep damaging equipment with the previous damage.
+		// As it looks like an original bug, I just added the code to stop damaging equipped protections.
+		else
+			break;
 	}
 
 	if (destroyCounter == 0) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 41e43422426..bef29d43925 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -122,10 +122,10 @@ struct ItemStruct {
 	uint8 _range;
 	uint8 _attackType;
 	uint8 _specialEffect;
-	uint8 field17_attackTypeDefense;
+	uint8 _field17_attackTypeDefense;
 	uint8 field_18;
-	uint8 field_19;
-	uint8 field_1A;
+	uint8 _field19_mapPosX_or_maxDeltaPoints;
+	uint8 _mapPosY;
 
 	void init();
 };
@@ -175,6 +175,7 @@ struct NPCStruct {
 	uint8 field_85;
 
 	void init();
+	uint8 getPronoun();
 };
 
 struct FontDescr {
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 23eb055cc28..a37a838c305 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -187,8 +187,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
 								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
-								int16 var70 = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
-								int16 var5E = _npcBuf[_teamCharId[var7E]]._possessivePronounSHL6 >> 6;
+								int16 ennemyPronoun = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
+								int16 characterPronoun = _npcBuf[_teamCharId[var7E]].getPronoun();
 								varInt = _items[unk_monsterField5_itemId].field_13;
 								_word32482[var7E] += (varInt * 5);
 								int16 var62 = 0;
@@ -235,12 +235,12 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
 								int16 var6A = getRandom(3);
-								if (var5E == 2)
+								if (characterPronoun == 2)
 									_characterNamePt1 = "The ";
 								else
 									_characterNamePt1 = "";
 
-								if (var7E == 2)
+								if (ennemyPronoun == 2)
 									_enemyNamePt1 = "The ";
 								else
 									_enemyNamePt1 = "";
@@ -251,17 +251,17 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 									} else if (hitPoints <= 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 									} else if (hitPoints == 1) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
 											_messageToBePrinted += "!";
 									} else {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str(), hitPoints);
+										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
 											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
 										else
@@ -330,7 +330,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									}
 									// handleFight - Check effect - end
 								} else {
-									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
 								sub1C219(_messageToBePrinted, 1, 2, true);
@@ -389,7 +389,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
 	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
-	if ((_npcBuf[_teamCharId[charId]]._possessivePronounSHL6 >> 6) == 2) {
+	if (_npcBuf[_teamCharId[charId]].getPronoun() == 2) {
 		_enemyNamePt1 = "The ";
 	} else {
 		_enemyNamePt1 = "";
@@ -464,8 +464,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
 					int16 varInt = _teamCharId[teamCharId];
-					int16 var51 = _npcBuf[varInt]._possessivePronounSHL6;
-					var51 >>= 6;
+					int16 var51 = _npcBuf[varInt].getPronoun();
 					int16 var70 = var51;
 					varInt = _teamMonsterIdArray[groupId];
 					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
@@ -631,14 +630,15 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 
 	_word32482[teamCharId] -= 40;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
 
-	if (var70 == 2)
+	uint8 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+
+	if (pronoun == 2)
 		_enemyNamePt1 = "The ";
 	else
 		_enemyNamePt1 = "";
 
-	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -650,14 +650,14 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 
 	_teamPctVisible[teamCharId] -= 50;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
+	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
 
-	if (var70 == 2)
+	if (pronoun == 2)
 		_enemyNamePt1 = "The ";
 	else
 		_enemyNamePt1 = "";
 
-	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[var70]);
+	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -670,13 +670,13 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	_nameBuffer = _items[itemId]._name;
-	int16 var70 = _npcBuf[_teamCharId[teamCharId]]._possessivePronounSHL6 >> 6;
-	if (var70 == 2)
+	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+	if (pronoun == 2)
 		_enemyNamePt1 = "The ";
 	else
 		_enemyNamePt1 = "";
 
-	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
@@ -713,7 +713,7 @@ void EfhEngine::resetTeamMonsterEffects() {
 }
 
 void EfhEngine::resetTeamMonsterIdArray() {
-	debug("resetTeamMonsterIdArray");
+	debugC(6, kDebugEngine, "resetTeamMonsterIdArray");
 
 	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
@@ -1518,7 +1518,7 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	if (_items[itemId]._specialEffect != 0)
 		return false;
 
-	return _items[itemId].field17_attackTypeDefense == attackType;
+	return _items[itemId]._field17_attackTypeDefense == attackType;
 }
 
 bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
@@ -1526,7 +1526,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 
 	int16 itemId = _npcBuf[charId]._unkItemId;
 
-	if (_items[itemId]._specialEffect == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+	if (_items[itemId]._specialEffect == 0 && _items[itemId]._field17_attackTypeDefense == attackType)
 		return true;
 
 	for (uint counter = 0; counter < 10; ++counter) {
@@ -1534,7 +1534,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 			continue;
 
 		itemId = _npcBuf[charId]._inventory[counter]._ref;
-		if (_items[itemId]._specialEffect == 0 && _items[itemId].field17_attackTypeDefense == attackType)
+		if (_items[itemId]._specialEffect == 0 && _items[itemId]._field17_attackTypeDefense == attackType)
 			return true;
 	}
 	return false;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index b346cb46c5c..1e0980ddd47 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -149,12 +149,12 @@ void EfhEngine::readItems() {
 		_items[i]._range = f.readByte();
 		_items[i]._attackType = f.readByte();
 		_items[i]._specialEffect = f.readByte();
-		_items[i].field17_attackTypeDefense = f.readByte();
+		_items[i]._field17_attackTypeDefense = f.readByte();
 		_items[i].field_18 = f.readByte();
-		_items[i].field_19 = f.readByte();
-		_items[i].field_1A = f.readByte();
+		_items[i]._field19_mapPosX_or_maxDeltaPoints = f.readByte();
+		_items[i]._mapPosY = f.readByte();
 
-		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i].field17_attackTypeDefense, _items[i].field_18, _items[i].field_19, _items[i].field_1A);
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i]._field17_attackTypeDefense, _items[i].field_18, _items[i]._field19_mapPosX_or_maxDeltaPoints, _items[i]._mapPosY);
 	}
 }
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 4f3609c856d..7080f8e796b 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -75,10 +75,10 @@ void ItemStruct::init() {
 	_range = 0;
 	_attackType = 0;
 	_specialEffect = 0;
-	field17_attackTypeDefense = 0;
+	_field17_attackTypeDefense = 0;
 	field_18 = 0;
-	field_19 = 0;
-	field_1A = 0;
+	_field19_mapPosX_or_maxDeltaPoints = 0;
+	_mapPosY = 0;
 }
 
 void NPCStruct::init() {
@@ -136,6 +136,11 @@ void NPCStruct::init() {
 	field_85 = 0;
 }
 
+uint8 NPCStruct::getPronoun() {
+	return _possessivePronounSHL6 >> 6;
+}
+
+
 void Stru32686::init() {
 	for (int i = 0; i < 9; ++i) {
 		_effect[i] = 0;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 43f4610d71b..ffbf12e8d8d 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1050,7 +1050,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			displayString_3("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterField8(teamMonsterId, _items[itemId].field17_attackTypeDefense, true);
+			setMapMonsterField8(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
 		}
 		varA6 = true;
 		break;
@@ -1138,8 +1138,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 		varA6 = true;
 	} break;
 	case 17: { // "Devil Dust"
-		_mapPosX = _items[itemId].field_19;
-		_mapPosY = _items[itemId].field_1A;
+		_mapPosX = _items[itemId]._field19_mapPosX_or_maxDeltaPoints;
+		_mapPosY = _items[itemId]._mapPosY;
 		int16 tileFactId = getTileFactId(_mapPosX, _mapPosY);
 		if (_tileFact[tileFactId]._field0 == 0) {
 			totalPartyKill();
@@ -1202,26 +1202,26 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 		break;
 	case 23: // "Divining Rod"
 		buffer1 = Common::String::format("The %s says, '", _items[itemId]._name);
-		if (_items[itemId].field_19 < _mapPosX) {
-			if (_items[itemId].field_1A < _mapPosY) {
+		if (_items[itemId]._field19_mapPosX_or_maxDeltaPoints < _mapPosX) {
+			if (_items[itemId]._mapPosY < _mapPosY) {
 				buffer1 += "North West!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
+			} else if (_items[itemId]._mapPosY > _mapPosY) {
 				buffer1 += "South West!";
 			} else {
 				buffer1 += "West!";
 			}
-		} else if (_items[itemId].field_19 > _mapPosX) {
-			if (_items[itemId].field_1A < _mapPosY) {
+		} else if (_items[itemId]._field19_mapPosX_or_maxDeltaPoints > _mapPosX) {
+			if (_items[itemId]._mapPosY < _mapPosY) {
 				buffer1 += "North East!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
+			} else if (_items[itemId]._mapPosY > _mapPosY) {
 				buffer1 += "South East!";
 			} else {
 				buffer1 += "East!";
 			}
 		} else { // equals _mapPosX
-			if (_items[itemId].field_1A < _mapPosY) {
+			if (_items[itemId]._mapPosY < _mapPosY) {
 				buffer1 += "North!";
-			} else if (_items[itemId].field_1A > _mapPosY) {
+			} else if (_items[itemId]._mapPosY > _mapPosY) {
 				buffer1 += "South!";
 			} else {
 				buffer1 += "Here!!!";
@@ -1246,8 +1246,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
+			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
 			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
@@ -1276,8 +1276,8 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId].field17_attackTypeDefense;
-			uint8 effectPoints = getRandom(_items[itemId].field_19);
+			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
+			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
 			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
 				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
@@ -1358,7 +1358,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 		}
 
 		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
 				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
@@ -1388,7 +1388,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 		}
 
 		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId].field17_attackTypeDefense);
+			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
 			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
 				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;


Commit: 9a293d2074da08097f2ce902d9c48cfe9dfe7d36
    https://github.com/scummvm/scummvm/commit/9a293d2074da08097f2ce902d9c48cfe9dfe7d36
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:43+01:00

Commit Message:
EFH: finish pronoun refactoring, some renaming

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index bef29d43925..6b19eab7d90 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -216,6 +216,8 @@ struct MapMonster {
 	uint8 _field9_textId;
 	uint8 _groupSize;
 	int16 _hitPoints[9];
+
+	uint8 getPronoun();
 };
 
 struct Stru32686 {
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index a37a838c305..bdc354d0420 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -732,18 +732,18 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	debug("getDeathTypeDescription %d %d", attackerId, victimId);
 
-	int16 possessivePronoun;
+	int16 pronoun;
 
 	if (attackerId > 999) {
 		int16 charId = _teamCharId[attackerId - 1000];
-		possessivePronoun = _npcBuf[charId]._possessivePronounSHL6 >> 6;
+		pronoun = _npcBuf[charId].getPronoun();
 	} else {
 		int16 charId = _teamMonsterIdArray[attackerId];
-		possessivePronoun = _mapMonsters[charId]._possessivePronounSHL6 >> 6;
+		pronoun = _mapMonsters[charId].getPronoun();
 	}
 
-	if (possessivePronoun > 2)
-		possessivePronoun = 2;
+	if (pronoun > 2)
+		pronoun = 2;
 
 	int16 deathType;
 	if (getRandom(100) < 20) {
@@ -774,13 +774,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 0:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", killing %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", killing %s!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", slaughtering %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", slaughtering %s!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", annihilating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", annihilating %s!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -789,13 +789,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 1:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", cutting %s in two!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", cutting %s in two!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", dicing %s into small cubes!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", dicing %s into small cubes!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", butchering %s into lamb chops!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", butchering %s into lamb chops!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -804,13 +804,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 2:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", leaving %s a spouting mass of blood!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving %s a spouting mass of blood!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", popping %s like a zit!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", popping %s like a zit!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -819,13 +819,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 3:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", pulping %s head over a wide area!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", pulping %s head over a wide area!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", smashing %s into a meat patty!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", smashing %s into a meat patty!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", squashing %s like a ripe tomato!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", squashing %s like a ripe tomato!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -834,10 +834,10 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 4:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", totally incinerating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", totally incinerating %s!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", reducing %s to a pile of ash!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", reducing %s to a pile of ash!", kPersonal[pronoun]);
 			break;
 		case 2:
 			tmpStr = Common::String::format(", leaving a blistered mass of flesh behind!");
@@ -850,13 +850,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		switch (rndDescrForDeathType) {
 		case 0:
 			// The original has a typo: popscicle
-			tmpStr = Common::String::format(", turning %s into a popsicle!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a popsicle!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", encasing %s in a block of ice!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", encasing %s in a block of ice!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", shattering %s into shards!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", shattering %s into shards!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -868,10 +868,10 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 			tmpStr = Common::String::format(", leaving pudding for brains");
 			break;
 		case 1:
-			tmpStr = Common::String::format(", bursting %s head like a bubble!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", bursting %s head like a bubble!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", turning %s into a mindless vegetable", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a mindless vegetable", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -880,13 +880,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 7:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", reducing %s to an oozing pile of flesh!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", reducing %s to an oozing pile of flesh!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", melting %s like an ice cube in hot coffee!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", melting %s like an ice cube in hot coffee!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", vaporizing %s into a steaming cloud!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", vaporizing %s into a steaming cloud!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -895,13 +895,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 8:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", engulfing %s in black smoke puffs!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", engulfing %s in black smoke puffs!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", sucking %s into eternity!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", sucking %s into eternity!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", turning %s into a mindless zombie!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", turning %s into a mindless zombie!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -912,13 +912,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 11:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", completely disintegrating %s!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", completely disintegrating %s!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", spreading %s into a fine mist!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", spreading %s into a fine mist!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", leaving a smoking crater in %s place!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving a smoking crater in %s place!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -929,13 +929,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 14:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", blowing %s brains out!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", blowing %s brains out!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", exploding %s entire chest!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", exploding %s entire chest!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -944,13 +944,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 15:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", choking %s to death!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", choking %s to death!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", melting %s lungs!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", melting %s lungs!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", leaving %s gasping for air as %s collapses!", kPersonal[possessivePronoun], kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", leaving %s gasping for air as %s collapses!", kPersonal[pronoun], kPersonal[pronoun]);
 			break;
 		default:
 			break;
@@ -959,13 +959,13 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	case 16:
 		switch (rndDescrForDeathType) {
 		case 0:
-			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", tearing a chunk out of %s back!", kPersonal[pronoun]);
 			break;
 		case 1:
-			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", piercing %s heart!", kPersonal[pronoun]);
 			break;
 		case 2:
-			tmpStr = Common::String::format(", impaling %s brain!", kPersonal[possessivePronoun]);
+			tmpStr = Common::String::format(", impaling %s brain!", kPersonal[pronoun]);
 			break;
 		default:
 			break;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 7080f8e796b..e7c3fd48f68 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -140,6 +140,9 @@ uint8 NPCStruct::getPronoun() {
 	return _possessivePronounSHL6 >> 6;
 }
 
+uint8 MapMonster::getPronoun() {
+	return _possessivePronounSHL6 >> 6;
+}
 
 void Stru32686::init() {
 	for (int i = 0; i < 9; ++i) {


Commit: 204f23ba1bc255d77f1c7f5f04f496930acf02e1
    https://github.com/scummvm/scummvm/commit/204f23ba1bc255d77f1c7f5f04f496930acf02e1
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: refactor the use of InvObject._stat1, fix a bug in hasAdequateDefense_2(), in sub19E2E() and in  displayCharacterSummary()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 59ae1b042e4..ddd54fda2e2 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -39,6 +39,14 @@ void EfhGraphicsStruct::copy(EfhGraphicsStruct *src) {
 	_area = src->_area;
 }
 
+bool InvObject::isEquipped() {
+	return (_stat1 & 0x80) != 0;
+}
+
+int8 InvObject::getUsesLeft() {
+	return _stat1 & 0x7F;
+}
+
 EfhEngine::~EfhEngine() {
 	delete _rnd;
 	delete _graphicsStruct;
@@ -530,7 +538,7 @@ int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
 		if (_npcBuf[charId]._inventory[i]._ref == 0x7FFF)
 			continue;
 
-		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
+		if (!_npcBuf[charId]._inventory[i].isEquipped())
 			continue;
 
 		int16 curDef = _npcBuf[charId]._inventory[i]._stat2;
@@ -554,7 +562,7 @@ uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
 	debugC(2, kDebugEngine, "sub1C80A %d %d %s", charId, field18, flag ? "True" : "False");
 
 	for (int i = 0; i < 10; ++i) {
-		if ((_npcBuf[charId]._inventory[i]._stat1 & 0x80) == 0)
+		if (!_npcBuf[charId]._inventory[i].isEquipped())
 			continue;
 
 		int16 itemId = _npcBuf[charId]._inventory[i]._ref;
@@ -919,21 +927,21 @@ void EfhEngine::handleWinSequence() {
 	free(winSeqBuf4);
 }
 
-bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 altCharId) {
-	debugC(3, kDebugEngine, "giveItemTo %d %d %d", charId, objectId, altCharId);
+bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 fromCharId) {
+	debugC(3, kDebugEngine, "giveItemTo %d %d %d", charId, objectId, fromCharId);
 
 	for (uint newObjectId = 0; newObjectId < 10; ++newObjectId) {
 		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
 			continue;
 
-		if (altCharId == 0xFF) {
+		if (fromCharId == 0xFF) {
 			_npcBuf[charId]._inventory[newObjectId]._ref = objectId;
 			_npcBuf[charId]._inventory[newObjectId]._stat2 = _items[objectId]._defense;
 			_npcBuf[charId]._inventory[newObjectId]._stat1 = _items[objectId]._uses;
 		} else {
-			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[altCharId]._inventory[newObjectId]._ref;
-			_npcBuf[charId]._inventory[newObjectId]._stat2 = _npcBuf[altCharId]._inventory[newObjectId]._stat2;
-			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[altCharId]._inventory[newObjectId]._stat1 & 0x7F; // not equipped as the upper bit isn't set (0x80)
+			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[fromCharId]._inventory[newObjectId]._ref;
+			_npcBuf[charId]._inventory[newObjectId]._stat2 = _npcBuf[fromCharId]._inventory[newObjectId]._stat2;
+			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[fromCharId]._inventory[newObjectId].getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
 		}
 
 		return true;
@@ -2427,7 +2435,7 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 	int16 curDamage = CLIP<int16>(damage, 0, 50);
 
 	for (uint objectId = 0; objectId < 10; ++objectId) {
-		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || (_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0 || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
+		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || !_npcBuf[charId]._inventory[objectId].isEquipped() || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
 			continue;
 
 		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._stat2;
@@ -2496,10 +2504,7 @@ bool EfhEngine::isItemCursed(int16 itemId) {
 
 bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 	debugC(6, kDebugEngine, "hasObjectEquipped %d %d", charId, objectId);
-	if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x80) == 0)
-		return false;
-
-	return true;
+	return _npcBuf[charId]._inventory[objectId].isEquipped();
 }
 
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 6b19eab7d90..fb0e03ef4ef 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -81,10 +81,12 @@ public:
 
 struct InvObject {
 	int16 _ref;
-	uint8 _stat1; // abbb bbbb - a: equipped b: durability
+	uint8 _stat1; // abbb bbbb - a: equipped b: uses left
 	uint8 _stat2;
 
 	void init();
+	bool isEquipped();
+	int8 getUsesLeft();
 };
 
 struct UnkMapStruct {
@@ -313,7 +315,7 @@ private:
 	void refreshTeamSize();
 	bool isNpcATeamMember(int16 id);
 	void handleWinSequence();
-	bool giveItemTo(int16 charId, int16 objectId, int16 altCharId);
+	bool giveItemTo(int16 charId, int16 objectId, int16 fromCharId);
 	int16 chooseCharacterToReplace();
 	int16 handleCharacterJoining();
 	void drawText(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index bdc354d0420..a505c666df7 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -464,8 +464,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
 					int16 varInt = _teamCharId[teamCharId];
-					int16 var51 = _npcBuf[varInt].getPronoun();
-					int16 var70 = var51;
+					int16 var70 = _npcBuf[varInt].getPronoun();
 					varInt = _teamMonsterIdArray[groupId];
 					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
@@ -587,15 +586,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - Start
 						varInt = _teamCharId[teamCharId];
 						var64 = sub1C80A(varInt, 9, false);
-						if (var64 != 0x7FFF && (_npcBuf[varInt]._inventory[var64]._stat1 & 0x7F) != 0x7F) {
-							var51 = _npcBuf[varInt]._inventory[var64]._stat1 & 0x7F;
-							--var51;
-							if (var51 <= 0) {
+						if (var64 != 0x7FFF && _npcBuf[varInt]._inventory[var64].getUsesLeft() != 0x7F) {
+							int16 usesLeft = _npcBuf[varInt]._inventory[var64].getUsesLeft();
+							--usesLeft;
+							if (usesLeft <= 0) {
 								_messageToBePrinted += Common::String::format("  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
 								setCharacterObjectToBroken(varInt, var64);
 								var6E = false;
 							} else {
-								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + var51;
+								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + usesLeft;
 							}
 						}
 						// Action A - Check item durability - End
@@ -732,7 +731,7 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	debug("getDeathTypeDescription %d %d", attackerId, victimId);
 
-	int16 pronoun;
+	uint8 pronoun;
 
 	if (attackerId > 999) {
 		int16 charId = _teamCharId[attackerId - 1000];
@@ -1530,7 +1529,7 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 		return true;
 
 	for (uint counter = 0; counter < 10; ++counter) {
-		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || _npcBuf[charId]._inventory[counter]._stat1 == 0x80)
+		if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF || !_npcBuf[charId]._inventory[counter].isEquipped())
 			continue;
 
 		itemId = _npcBuf[charId]._inventory[counter]._ref;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index ffbf12e8d8d..fbf7b697c87 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -320,7 +320,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 		int16 textPosY = 81 + counter * 9;
 		int16 itemId = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref;
 		if (itemId != 0x7FFF) {
-			if (_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1 & 0x80) {
+			if (_npcBuf[npcId]._inventory[_menuStatItemArr[counter]].isEquipped()) {
 				setTextPos(146, textPosY);
 				displayCharAtTextPos('E');
 			}
@@ -353,7 +353,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 				//	var54 = _items[_npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._ref]._defense;
 				// {
 			} else if (_items[itemId]._uses != 0x7F) {
-				int16 stat1 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat1;
+				int16 stat1 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]].getUsesLeft();
 				if (stat1 != 0x7F) {
 					buffer1 = Common::String::format("%d", stat1);
 					displayStringAtTextPos(buffer1);
@@ -1425,9 +1425,10 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 	}
 
 	if (varA6) {
-		if ((_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) != 0x7F) {
-			int8 varA1 = (_npcBuf[charId]._inventory[objectId]._stat1 & 0x7F) - 1;
-			if (varA1 <= 0) {
+		int16 usesLeft = _npcBuf[charId]._inventory[objectId].getUsesLeft();
+		if (usesLeft != 0x7F) {
+			--usesLeft;
+			if (usesLeft <= 0) {
 				buffer1 = "  * The item breaks!";
 				if (argA == 2) {
 					getLastCharAfterAnimCount(_guessAnimationAmount);
@@ -1438,7 +1439,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 				setCharacterObjectToBroken(charId, objectId);
 			} else {
 				_npcBuf[charId]._inventory[objectId]._stat1 &= 0x80;
-				_npcBuf[charId]._inventory[objectId]._stat1 |= 0xA1;
+				_npcBuf[charId]._inventory[objectId]._stat1 |= usesLeft;
 			}
 		}
 


Commit: 946b1740a55b7d8ae414d77cc2caf6f40e4aaca0
    https://github.com/scummvm/scummvm/commit/946b1740a55b7d8ae414d77cc2caf6f40e4aaca0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Fix a (likely) bug in sub1D8C2()

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ddd54fda2e2..6f266abdacc 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2439,9 +2439,11 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 			continue;
 
 		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._stat2;
-		_npcBuf[charId]._inventory[objectId]._stat2 -= curDamage;
+		// not in the original: this int16 is used to test if the result is negative. Otherwise _stat2 (uint8) turns it into a "large" positive value.
+		int16 newDurability = _npcBuf[charId]._inventory[objectId]._stat2 - curDamage;
+		_npcBuf[charId]._inventory[objectId]._stat2 = newDurability;
 
-		if (_npcBuf[charId]._inventory[objectId]._stat2 <= 0) {
+		if (newDurability <= 0) {
 			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
 			removeObject(charId, objectId);
 


Commit: 594156ae6451a16648d5e2f6bc43ffa0f75f1f05
    https://github.com/scummvm/scummvm/commit/594156ae6451a16648d5e2f6bc43ffa0f75f1f05
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Fix a bug in handleFight, fix handleFight_lastAction_U, rename (between others) useObject()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6f266abdacc..1a91cebaa35 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -541,7 +541,7 @@ int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
 		if (!_npcBuf[charId]._inventory[i].isEquipped())
 			continue;
 
-		int16 curDef = _npcBuf[charId]._inventory[i]._stat2;
+		int16 curDef = _npcBuf[charId]._inventory[i]._curHitPoints;
 		if (curDef == 0xFF)
 			curDef = _items[_npcBuf[charId]._inventory[i]._ref]._defense;
 
@@ -791,7 +791,7 @@ void EfhEngine::removeObject(int16 charId, int16 objectId) {
 	debugC(6, kDebugEngine, "removeObject %d %d", charId, objectId);
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 	_npcBuf[charId]._inventory[objectId]._stat1 = 0;
-	_npcBuf[charId]._inventory[objectId]._stat2 = 0;
+	_npcBuf[charId]._inventory[objectId]._curHitPoints = 0;
 }
 
 void EfhEngine::totalPartyKill() {
@@ -936,11 +936,11 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 fromCharId) {
 
 		if (fromCharId == 0xFF) {
 			_npcBuf[charId]._inventory[newObjectId]._ref = objectId;
-			_npcBuf[charId]._inventory[newObjectId]._stat2 = _items[objectId]._defense;
+			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _items[objectId]._defense;
 			_npcBuf[charId]._inventory[newObjectId]._stat1 = _items[objectId]._uses;
 		} else {
 			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[fromCharId]._inventory[newObjectId]._ref;
-			_npcBuf[charId]._inventory[newObjectId]._stat2 = _npcBuf[fromCharId]._inventory[newObjectId]._stat2;
+			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _npcBuf[fromCharId]._inventory[newObjectId]._curHitPoints;
 			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[fromCharId]._inventory[newObjectId].getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
 		}
 
@@ -2438,10 +2438,10 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || !_npcBuf[charId]._inventory[objectId].isEquipped() || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
 			continue;
 
-		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._stat2;
-		// not in the original: this int16 is used to test if the result is negative. Otherwise _stat2 (uint8) turns it into a "large" positive value.
-		int16 newDurability = _npcBuf[charId]._inventory[objectId]._stat2 - curDamage;
-		_npcBuf[charId]._inventory[objectId]._stat2 = newDurability;
+		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._curHitPoints;
+		// not in the original: this int16 is used to test if the result is negative. Otherwise _curHitPoints (uint8) turns it into a "large" positive value.
+		int16 newDurability = _npcBuf[charId]._inventory[objectId]._curHitPoints - curDamage;
+		_npcBuf[charId]._inventory[objectId]._curHitPoints = newDurability;
 
 		if (newDurability <= 0) {
 			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index fb0e03ef4ef..74972893b43 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -82,7 +82,7 @@ public:
 struct InvObject {
 	int16 _ref;
 	uint8 _stat1; // abbb bbbb - a: equipped b: uses left
-	uint8 _stat2;
+	uint8 _curHitPoints;
 
 	void init();
 	bool isEquipped();
@@ -222,7 +222,7 @@ struct MapMonster {
 	uint8 getPronoun();
 };
 
-struct Stru32686 {
+struct TeamMonsterEffect {
 	int16 _effect[9];
 	int16 _duration[9];
 
@@ -381,7 +381,7 @@ private:
 	void handleFight_lastAction_A(int16 teamCharId);
 	void handleFight_lastAction_D(int16 teamCharId);
 	void handleFight_lastAction_H(int16 teamCharId);
-	void handleFight_lastAction_U(int16 teamCharId);
+	bool handleFight_lastAction_U(int16 teamCharId);
 	bool isTPK();
 	bool isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId);
 	void createOpponentList(int16 monsterTeamId);
@@ -469,7 +469,7 @@ private:
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA);
+	int16 useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA);
 
 	// Savegames
 	void synchronize(Common::Serializer &s);
@@ -607,7 +607,7 @@ private:
 	int16 _word31780[3];
 
 	int16 _menuStatItemArr[15];
-	Stru32686 _teamMonsterEffects[5];
+	TeamMonsterEffect _teamMonsterEffects[5];
 	InitiativeStruct _initiatives[8];
 
 	int16 _regenCounter;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index a505c666df7..e61fa8662a0 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -151,7 +151,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 						handleFight_lastAction_H(monsterGroupIdOrMonsterId);
 						break;
 					case 0x55: // 'U'se
-						handleFight_lastAction_U(monsterGroupIdOrMonsterId);
+						mainLoopCond = handleFight_lastAction_U(monsterGroupIdOrMonsterId);
 						break;
 					default:
 						break;
@@ -660,7 +660,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	sub1C219(_messageToBePrinted, 1, 2, true);
 }
 
-void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
+bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	debug("handleFight_lastAction_U %d", teamCharId);
 
 	// Fight - Action 'U' - Use Item
@@ -676,7 +676,10 @@ void EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 		_enemyNamePt1 = "";
 
 	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
+	bool retVal = useObject(_teamCharId[teamCharId], _word31780[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
 	sub1C219(_messageToBePrinted, 1, 2, true);
+
+	return retVal;
 }
 
 bool EfhEngine::isTPK() {
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 1e0980ddd47..54f0446fa9e 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -288,7 +288,7 @@ void EfhEngine::loadNPCS() {
 		for (int idx = 0; idx < 10; ++idx) {
 			_npcBuf[i]._inventory[idx]._ref = f.readSint16LE();
 			_npcBuf[i]._inventory[idx]._stat1 = f.readByte();
-			_npcBuf[i]._inventory[idx]._stat2 = f.readByte();
+			_npcBuf[i]._inventory[idx]._curHitPoints = f.readByte();
 		}
 		_npcBuf[i]._possessivePronounSHL6 = f.readByte();
 		_npcBuf[i]._speed = f.readByte();
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index e7c3fd48f68..e5839e9e68b 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -41,7 +41,7 @@ EfhGraphicsStruct::EfhGraphicsStruct(int8 **lineBuf, int16 x, int16 y, int16 wid
 void InvObject::init() {
 	_ref = 0;
 	_stat1 = 0;
-	_stat2 = 0;
+	_curHitPoints = 0;
 }
 
 void UnkMapStruct::init() {
@@ -144,7 +144,7 @@ uint8 MapMonster::getPronoun() {
 	return _possessivePronounSHL6 >> 6;
 }
 
-void Stru32686::init() {
+void TeamMonsterEffect::init() {
 	for (int i = 0; i < 9; ++i) {
 		_effect[i] = 0;
 		_duration[i] = 0;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index fbf7b697c87..b1efb776a2a 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -341,9 +341,9 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 			setTextPos(262, textPosY);
 
 			if (_items[itemId]._defense > 0) {
-				int16 stat2 = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._stat2;
-				if (stat2 != 0xFF) {
-					buffer1 = Common::String::format("%d", 1 + stat2 / 8);
+				int16 curHitPoints = _npcBuf[npcId]._inventory[_menuStatItemArr[counter]]._curHitPoints;
+				if (curHitPoints != 0xFF) {
+					buffer1 = Common::String::format("%d", 1 + curHitPoints / 8);
 					displayStringAtTextPos(buffer1);
 					setTextPos(286, textPosY);
 					displayStringAtTextPos("Def");
@@ -694,7 +694,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				return -1;
 			}
 
-			sub19E2E(charId, objectId, windowId, menuId, curMenuLine, 2);
+			useObject(charId, objectId, windowId, menuId, curMenuLine, 2);
 			break;
 		case 2:
 			objectId = _menuStatItemArr[selectedLine];
@@ -900,12 +900,12 @@ void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 men
 	}
 }
 
-int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA) {
-	debug("sub19E2E %d %d %d %d %d %d", charId, objectId, teamMonsterId, menuId, curMenuLine, argA);
+int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA) {
+	debug("useObject %d %d %d %d %d %d", charId, objectId, teamMonsterId, menuId, curMenuLine, argA);
 
 	Common::String buffer1 = "";
 
-	bool varA6 = false;
+	bool objectUsedFl = false;
 	bool retVal = false;
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
@@ -947,7 +947,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			_messageToBePrinted += buffer1;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
 		if (argA == 2) {
@@ -988,7 +988,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			// </CHECKME>
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 2:
 		if (argA == 2) {
@@ -998,7 +998,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			_unk2C8AA = 0;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 4: // "Unholy Sinwave", "Holy Water"
 		if (argA == 2) {
@@ -1022,7 +1022,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 				}
 			}
 		}
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
 		if (argA == 2) {
@@ -1043,7 +1043,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
 		if (argA == 2) {
@@ -1052,7 +1052,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
 			setMapMonsterField8(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
 		}
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 14: { // "Feathered Cap"
 		int16 varAA;
@@ -1075,7 +1075,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 				_word32482[varAA] = 0;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 15: { // "Regal Crown"
 		int16 teamCharId;
@@ -1099,7 +1099,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 				_teamPctVisible[teamCharId] = 0;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 16: { // Fairy Dust
 		_mapPosX = getRandom(_largeMapFlag ? 63 : 23);
@@ -1135,7 +1135,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 17: { // "Devil Dust"
 		_mapPosX = _items[itemId]._field19_mapPosX_or_maxDeltaPoints;
@@ -1170,7 +1170,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 18:
 		if (argA == 2) {
@@ -1188,7 +1188,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 19: // "Junk"
 		buffer1 = "  * The item breaks!";
@@ -1198,7 +1198,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			_messageToBePrinted += buffer1;
 		}
 		setCharacterObjectToBroken(charId, objectId);
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 23: // "Divining Rod"
 		buffer1 = Common::String::format("The %s says, '", _items[itemId]._name);
@@ -1235,7 +1235,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			retVal = true;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 24: {
 		int16 teamCharId;
@@ -1265,7 +1265,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 25: {
 		int16 teamCharId;
@@ -1295,7 +1295,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 26: // "Black Sphere"
 		buffer1 = "The entire party collapses, dead!!!";
@@ -1306,7 +1306,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			retVal = true;
 		}
 		totalPartyKill();
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 27: { // "Magic Pyramid", "Razor Blade"
 		int16 teamCharId;
@@ -1328,7 +1328,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 28: // "Bugle"
 		if (argA == 2) {
@@ -1346,7 +1346,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			}
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 		break;
 	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
 		int16 teamCharId;
@@ -1376,7 +1376,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			retVal = true;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 	} break;
 	case 30: {
 		int16 teamCharId;
@@ -1406,7 +1406,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 			retVal = true;
 		}
 
-		varA6 = true;
+		objectUsedFl = true;
 
 	} break;
 	case 3:
@@ -1424,7 +1424,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 		break;
 	}
 
-	if (varA6) {
+	if (objectUsedFl) {
 		int16 usesLeft = _npcBuf[charId]._inventory[objectId].getUsesLeft();
 		if (usesLeft != 0x7F) {
 			--usesLeft;
@@ -1438,6 +1438,7 @@ int16 EfhEngine::sub19E2E(int16 charId, int16 objectId, int16 teamMonsterId, int
 				}
 				setCharacterObjectToBroken(charId, objectId);
 			} else {
+				// Keep the Equipped bit and set the new number of uses
 				_npcBuf[charId]._inventory[objectId]._stat1 &= 0x80;
 				_npcBuf[charId]._inventory[objectId]._stat1 |= usesLeft;
 			}
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 8b9239d6bc3..00b9ea278f5 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -191,7 +191,7 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		for (int idx = 0; idx < 10; ++idx) {
 			s.syncAsSint16LE(_npcBuf[i]._inventory[idx]._ref);
 			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat1);
-			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat2);
+			s.syncAsByte(_npcBuf[i]._inventory[idx]._curHitPoints);
 		}
 		s.syncAsByte(_npcBuf[i]._possessivePronounSHL6);
 		s.syncAsByte(_npcBuf[i]._speed);


Commit: 69e5fb04cb3ee612cbcee9233a5e0813155badac
    https://github.com/scummvm/scummvm/commit/69e5fb04cb3ee612cbcee9233a5e0813155badac
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Validate 2 functions, renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 1a91cebaa35..3df4c7c9ad0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2056,7 +2056,7 @@ void EfhEngine::displayImp1Text(int16 textId) {
 								displayFctFullScreen();
 						}
 
-						nextTextId = sub1C219(_messageToBePrinted, 1, 1, true);
+						nextTextId = displayBoxWithText(_messageToBePrinted, 1, 1, true);
 						if (nextTextId != 0xFF)
 							curTextId = nextTextId;
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 74972893b43..ce4b283c767 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -454,7 +454,7 @@ private:
 	void displayColoredMenuBox(int16 minX, int16 minY, int16 maxX, int16 maxY, int16 color);
 
 	// Menu
-	int16 sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl);
+	int16 displayBoxWithText(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl);
 	bool handleDeathMenu();
 	void displayCombatMenu(int16 charId);
 	void displayMenuItemString(int16 menuBoxId, int16 thisBoxId, int16 minX, int16 maxX, int16 minY, const char *str);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index e61fa8662a0..8dcae3e79e3 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -129,7 +129,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		}
 
 		computeInitiatives();
-		sub1C219("", 2, 1, false);
+		displayBoxWithText("", 2, 1, false);
 
 		for (uint counter = 0; counter < 8; ++counter) {
 			int16 monsterGroupIdOrMonsterId = _initiatives[counter]._id;
@@ -333,7 +333,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 								}
 								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
-								sub1C219(_messageToBePrinted, 1, 2, true);
+								displayBoxWithText(_messageToBePrinted, 1, 2, true);
 							}
 							// handleFight - Loop on var7E - End
 						}
@@ -359,7 +359,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								break;
 							}
 							_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86] = 0;
-							sub1C219(_messageToBePrinted, 1, 2, true);
+							displayBoxWithText(_messageToBePrinted, 1, 2, true);
 						}
 					}
 				}
@@ -412,7 +412,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	_teamCharStatus[charId]._status = 0;
 
 	// Finally, display the message
-	sub1C219(_messageToBePrinted, 1, 2, true);
+	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 }
 
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
@@ -617,7 +617,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					}
 
 					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
-					sub1C219(_messageToBePrinted, 1, 2, true);
+					displayBoxWithText(_messageToBePrinted, 1, 2, true);
 				}
 			}
 		}
@@ -638,11 +638,11 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 		_enemyNamePt1 = "";
 
 	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
-	sub1C219(_messageToBePrinted, 1, 2, true);
+	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 }
 
 void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
-	debug("handleFight_lastAction_H %d", teamCharId);
+	debugC(3, kDebugEngine, "handleFight_lastAction_H %d", teamCharId);
 
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -657,7 +657,7 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 		_enemyNamePt1 = "";
 
 	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
-	sub1C219(_messageToBePrinted, 1, 2, true);
+	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 }
 
 bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
@@ -677,7 +677,7 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 
 	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
 	bool retVal = useObject(_teamCharId[teamCharId], _word31780[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
-	sub1C219(_messageToBePrinted, 1, 2, true);
+	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 
 	return retVal;
 }
@@ -1009,7 +1009,7 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 		for (uint counter = 0; counter < 2; ++counter) {
 			drawCombatScreen(charId, true, false);
 			if (_teamMonsterIdArray[1] != -1)
-				sub1C219("Select Monster Group:", 3, 0, false);
+				displayBoxWithText("Select Monster Group:", 3, 0, false);
 
 			if (counter == 0)
 				displayFctFullScreen();
@@ -1105,7 +1105,7 @@ bool EfhEngine::sub1CB27() {
 					case 28:
 					case 29:
 					case 30:
-						sub1C219("Select Character:", 3, 1, false);
+						displayBoxWithText("Select Character:", 3, 1, false);
 						_teamNextAttack[counter1] = selectOtherCharFromTeam();
 						break;
 
@@ -1149,7 +1149,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 			displayCenteredString("Combat", 128, 303, 9);
 			drawColoredRect(200, 112, 278, 132, 0);
 			displayCenteredString("'T' for Terrain", 128, 303, 117);
-			sub1C219("", 1, 0, false);
+			displayBoxWithText("", 1, 0, false);
 			sub1C4CA(whiteFl);
 			displayCombatMenu(charId);
 			displayLowStatusScreen(false);
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index b1efb776a2a..25fa0b0cbb0 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -23,10 +23,10 @@
 
 namespace Efh {
 
-int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl) {
-	debug("sub1C219 %s %d %d %s", str.c_str(), menuType, displayOption, displayTeamWindowFl ? "True" : "False");
+int16 EfhEngine::displayBoxWithText(Common::String str, int16 menuType, int16 displayOption, bool displayTeamWindowFl) {
+	debugC(3, kDebugEngine, "displayBoxWithText %s %d %d %s", str.c_str(), menuType, displayOption, displayTeamWindowFl ? "True" : "False");
 
-	int16 varA = 0xFF;
+	int16 retVal = 0xFF;
 	int16 minX, maxX, minY, maxY;
 
 	switch (menuType) {
@@ -63,7 +63,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOptio
 
 	drawColoredRect(minX, minY, maxX, maxY, 0);
 	if (!str.empty())
-		varA = script_parse(str, minX, minY, maxX, maxY, true);
+		retVal = script_parse(str, minX, minY, maxX, maxY, true);
 
 	if (displayTeamWindowFl)
 		displayLowStatusScreen(false);
@@ -88,7 +88,7 @@ int16 EfhEngine::sub1C219(Common::String str, int16 menuType, int16 displayOptio
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 	}
 
-	return varA;
+	return retVal;
 }
 
 bool EfhEngine::handleDeathMenu() {
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index aa901340a64..2f650d87ff9 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -385,7 +385,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					scriptRandomItemId = sub1C219("Nothing...", 1, 2, true);
+					scriptRandomItemId = displayBoxWithText("Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
 					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
@@ -394,7 +394,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 					drawMapWindow();
 					displayFctFullScreen();
 					drawMapWindow();
-					scriptRandomItemId = sub1C219(curLine, 1, 2, true);
+					scriptRandomItemId = displayBoxWithText(curLine, 1, 2, true);
 					displayFctFullScreen();
 				}
 


Commit: 231a5bca12c718426787068b96fd1664e926c48f
    https://github.com/scummvm/scummvm/commit/231a5bca12c718426787068b96fd1664e926c48f
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Fix bug in tryToggleEquipped, renaming and validation of some more functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 3df4c7c9ad0..641e5592f95 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -558,22 +558,23 @@ int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
 	return altDef;
 }
 
-uint16 EfhEngine::sub1C80A(int16 charId, int16 field18, bool flag) {
-	debugC(2, kDebugEngine, "sub1C80A %d %d %s", charId, field18, flag ? "True" : "False");
+uint16 EfhEngine::getEquippedExclusiveType(int16 charId, int16 exclusiveType, bool flag) {
+	debugC(2, kDebugEngine, "getEquippedExclusiveType %d %d %s", charId, exclusiveType, flag ? "True" : "False");
 
 	for (int i = 0; i < 10; ++i) {
 		if (!_npcBuf[charId]._inventory[i].isEquipped())
 			continue;
 
-		int16 itemId = _npcBuf[charId]._inventory[i]._ref;
+		int16 curItemId = _npcBuf[charId]._inventory[i]._ref;
 
-		if (_items[itemId].field_18 != field18)
+		if (_items[curItemId]._exclusiveType != exclusiveType)
 			continue;
 
+		// If flag is set, returns the ItemId, otherwise return the inventory slot number
 		if (!flag)
 			return i;
 
-		return itemId;
+		return curItemId;
 	}
 
 	return 0x7FFF;
@@ -759,11 +760,11 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 
 				switch (_teamCharStatus[i]._status) {
 				case 0: {
-					uint16 var4 = sub1C80A(charId, 9, true);
-					if (var4 == 0x7FFF)
+					uint16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
+					if (exclusiveItemId == 0x7FFF)
 						_nameBuffer = "(NONE)";
 					else
-						_nameBuffer = _items[var4]._name;
+						_nameBuffer = _items[exclusiveItemId]._name;
 					}
 					break;
 				case 1:
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index ce4b283c767..b8bf9a66ebe 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -125,7 +125,7 @@ struct ItemStruct {
 	uint8 _attackType;
 	uint8 _specialEffect;
 	uint8 _field17_attackTypeDefense;
-	uint8 field_18;
+	uint8 _exclusiveType;
 	uint8 _field19_mapPosX_or_maxDeltaPoints;
 	uint8 _mapPosY;
 
@@ -292,7 +292,7 @@ private:
 	void loadMapArrays(int idx);
 	void saveAnimImageSetId();
 	int16 getEquipmentDefense(int16 charId, bool flag);
-	uint16 sub1C80A(int16 charId, int16 field18, bool flag);
+	uint16 getEquippedExclusiveType(int16 charId, int16 exclusiveType, bool flag);
 	void displayLowStatusScreen(bool flag);
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
 	void restoreAnimImageSetId();
@@ -463,12 +463,12 @@ private:
 	void displayCharacterSummary(int16 curMenuLine, int16 npcId);
 	void displayCharacterInformationOrSkills(int16 curMenuLine, int16 npcId);
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
-	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl);
-	void sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool refreshFl);
+	void displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	void sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
+	void tryToggleEquipped(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA);
 
 	// Savegames
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 8dcae3e79e3..88cc1edca0f 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -421,9 +421,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 
-	int16 unk_monsterField5_itemId = sub1C80A(_teamCharId[teamCharId], 9, true);
-	if (unk_monsterField5_itemId == 0x7FFF)
-		unk_monsterField5_itemId = 0x3F;
+	int16 teamCharItemId = getEquippedExclusiveType(_teamCharId[teamCharId], 9, true);
+	if (teamCharItemId == 0x7FFF)
+		teamCharItemId = 0x3F;
 	int16 monsterGroupNumber = _teamNextAttack[teamCharId];
 	if (monsterGroupNumber == 0x64)
 		monsterGroupNumber = 0;
@@ -431,14 +431,14 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	if (monsterGroupNumber == -1)
 		return;
 	int16 var58;
-	if (_items[unk_monsterField5_itemId]._range == 4)
+	if (_items[teamCharItemId]._range == 4)
 		var58 = 5;
 	else
 		var58 = monsterGroupNumber + 1;
 
 	int16 var54;
 	int16 teamMemberId;
-	if (_items[unk_monsterField5_itemId]._range < 3) {
+	if (_items[teamCharItemId]._range < 3) {
 		teamMemberId = sub1DEC8(monsterGroupNumber);
 		var54 = teamMemberId + 1;
 	} else {
@@ -467,19 +467,19 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 var70 = _npcBuf[varInt].getPronoun();
 					varInt = _teamMonsterIdArray[groupId];
 					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
-					int16 charScore = getCharacterScore(_teamCharId[teamCharId], unk_monsterField5_itemId);
+					int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
 					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E];
 					int16 var62 = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
-					int16 var64 = _items[unk_monsterField5_itemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
+					int16 var64 = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
 
 					// Action A - Loop var84 - Start
 					for (int var84 = 0; var84 < var64; ++var84) {
 						if (getRandom(100) < charScore) {
 							++var62;
-							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[unk_monsterField5_itemId]._attackType)) {
-								int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
+								int16 var7C = getRandom(_items[teamCharItemId]._damage);
 								varInt = var7C - var76;
 								if (varInt > 0) {
 									originalDamage += varInt;
@@ -497,7 +497,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 					int16 hitPoints = originalDamage + damagePointsAbsorbed;
 
-					if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+					if (!checkSpecialItemsOnCurrentPlace(teamCharItemId))
 						var62 = 0;
 
 					if (var62 > 0) {
@@ -508,7 +508,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							_attackBuffer = "";
 						}
 					}
-					int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+					int16 var68 = _items[teamCharItemId]._attackType + 1;
 					int16 var6A = getRandom(3) - 1;
 					if (var5E == 2) {
 						_characterNamePt1 = "The ";
@@ -524,8 +524,8 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
 					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-					_nameBuffer = _items[unk_monsterField5_itemId]._name;
-					if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+					_nameBuffer = _items[teamCharItemId]._name;
+					if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
 						// Action A - Check damages - Start
 						if (var62 == 0) {
 							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
@@ -585,7 +585,9 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 						// Action A - Check item durability - Start
 						varInt = _teamCharId[teamCharId];
-						var64 = sub1C80A(varInt, 9, false);
+
+						// get equipped inventory slot with exclusiveType == 9
+						var64 = getEquippedExclusiveType(varInt, 9, false);
 						if (var64 != 0x7FFF && _npcBuf[varInt]._inventory[var64].getUsesLeft() != 0x7F) {
 							int16 usesLeft = _npcBuf[varInt]._inventory[var64].getUsesLeft();
 							--usesLeft;
@@ -600,13 +602,13 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[unk_monsterField5_itemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
+						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
 							if (getRandom(100) < 35) {
 								_teamMonsterEffects[groupId]._effect[var7E] = 1;
 								_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[unk_monsterField5_itemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
+						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
 							_teamMonsterEffects[groupId]._effect[var7E] = 2;
 							_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -616,7 +618,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
 					}
 
-					genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+					genericGenerateSound(_items[teamCharItemId]._attackType, var62);
 					displayBoxWithText(_messageToBePrinted, 1, 2, true);
 				}
 			}
@@ -756,11 +758,11 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 			if (charId == -1)
 				deathType = 0;
 			else {
-				int16 var6 = sub1C80A(charId, 9, true);
-				if (var6 == 0x7FFF)
+				int16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
+				if (exclusiveItemId == 0x7FFF)
 					deathType = 0;
 				else
-					deathType = _items[var6]._attackType + 1;
+					deathType = _items[exclusiveItemId]._attackType + 1;
 			}
 		} else if (_teamMonsterIdArray[victimId] == -1)
 			deathType = 0;
@@ -985,17 +987,19 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 
 	int16 varE = -1;
 
-	int16 var6 = sub1C80A(charId, unkFied18Val, true);
+	int16 curItemId = getEquippedExclusiveType(charId, unkFied18Val, true);
 	int16 range = 0;
-	if (var6 != 0x7FFF)
-		range = _items[var6]._range;
+	if (curItemId != 0x7FFF)
+		range = _items[curItemId]._range;
 
 	switch (range) {
 	case 3:
 	case 2:
 		++range;
+		// no break on purpose
 	case 1:
 		++range;
+		// no break on purpose
 	case 0:
 		++range;
 		break;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 54f0446fa9e..aa5ed2e9f1c 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -150,11 +150,11 @@ void EfhEngine::readItems() {
 		_items[i]._attackType = f.readByte();
 		_items[i]._specialEffect = f.readByte();
 		_items[i]._field17_attackTypeDefense = f.readByte();
-		_items[i].field_18 = f.readByte();
+		_items[i]._exclusiveType = f.readByte();
 		_items[i]._field19_mapPosX_or_maxDeltaPoints = f.readByte();
 		_items[i]._mapPosY = f.readByte();
 
-		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i]._field17_attackTypeDefense, _items[i].field_18, _items[i]._field19_mapPosX_or_maxDeltaPoints, _items[i]._mapPosY);
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i]._field17_attackTypeDefense, _items[i]._exclusiveType, _items[i]._field19_mapPosX_or_maxDeltaPoints, _items[i]._mapPosY);
 	}
 }
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index e5839e9e68b..e5a9af06e93 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -76,7 +76,7 @@ void ItemStruct::init() {
 	_attackType = 0;
 	_specialEffect = 0;
 	_field17_attackTypeDefense = 0;
-	field_18 = 0;
+	_exclusiveType = 0;
 	_field19_mapPosX_or_maxDeltaPoints = 0;
 	_mapPosY = 0;
 }
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 25fa0b0cbb0..cc52561ca43 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -455,7 +455,7 @@ void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16
 	}
 }
 
-void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool unusedFl, bool refreshFl) {
+void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool refreshFl) {
 	debugC(6, kDebugEngine, "prepareStatusMenu %d %d %d %d %s", windowId, menuId, curMenuLine, charId, refreshFl ? "True" : "False");
 
 	displayStatusMenu(windowId);
@@ -467,12 +467,12 @@ void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLin
 		displayFctFullScreen();
 }
 
-void EfhEngine::sub18E80(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("sub18E80 %d %d %d %d", charId, windowId, menuId, curMenuLine);
+void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayWindowAndStatusMenu %d %d %d %d", charId, windowId, menuId, curMenuLine);
 
 	for (int counter = 0; counter < 2; ++counter) {
 		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
-		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, false);
 
 		if (counter == 0)
 			displayFctFullScreen();
@@ -485,7 +485,7 @@ int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId,
 	int16 retVal = 0;
 
 	for (uint counter = 0; counter < 2; ++counter) {
-		prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, false);
+		prepareStatusMenu(windowId, menuId, curMenuLine, charId, false);
 		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
 
 		if (counter == 0) {
@@ -498,7 +498,7 @@ int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId,
 
 	if (animFl) {
 		getLastCharAfterAnimCount(_guessAnimationAmount);
-		sub18E80(charId, windowId, menuId, curMenuLine);
+		displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 	}
 
 	return retVal;
@@ -519,11 +519,11 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	_statusMenuActive = true;
 	_menuDepth = 0;
 
-	sub18E80(charId, windowId, menuId, curMenuLine);
+	displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 
 	for (;;) {
 		if (windowId != -1)
-			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 		else
 			windowId = 0;
 
@@ -603,7 +603,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						_menuDepth = 0;
 						curMenuLine = -1;
 						menuId = 9;
-						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 					} else {
 						selectedLine = curMenuLine;
 						var10 = true;
@@ -614,7 +614,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				_menuDepth = 0;
 				curMenuLine = -1;
 				menuId = 9;
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 				break;
 			case Common::KEYCODE_2:
 			case Common::KEYCODE_6:
@@ -658,10 +658,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				break;
 			}
 
-			if (curMenuLine == -1)
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, false, true);
-			else
-				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true, true);
+			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 
 		} while (!var10);
 
@@ -673,7 +670,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		case 0:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref; // CHECKME: Useless?
-			sub191FF(charId, objectId, windowId, menuId, curMenuLine);
+			tryToggleEquipped(charId, objectId, windowId, menuId, curMenuLine);
 			if (gameMode == 2) {
 				restoreAnimImageSetId();
 				_statusMenuActive = false;
@@ -705,7 +702,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				displayString_3("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
+				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
 					if (gameMode == 2) {
@@ -731,7 +728,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
+				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
 					bool givenFl;
@@ -777,7 +774,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						}
 					}
 
-					sub18E80(charId, windowId, menuId, curMenuLine);
+					displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 				}
 			}
 			break;
@@ -790,7 +787,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				displayString_3("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
-				sub18E80(charId, windowId, menuId, curMenuLine);
+				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
 					removeObject(charId, objectId);
@@ -879,24 +876,26 @@ void EfhEngine::unequipItem(int16 charId, int16 objectId, int16 windowId, int16
 	}
 }
 
-void EfhEngine::sub191FF(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("sub191FF %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
+void EfhEngine::tryToggleEquipped(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debugC(3, kDebugEngine, "tryToggleEquipped %d %d %d %d %d", charId, objectId, windowId, menuId, curMenuLine);
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
 	if (hasObjectEquipped(charId, objectId)) {
 		unequipItem(charId, objectId, windowId, menuId, curMenuLine);
 	} else {
-		int16 var2 = _items[itemId].field_18;
-		if (var2 != 4) {
+		int16 curType = _items[itemId]._exclusiveType;
+		if (curType != 4) {
 			for (uint counter = 0; counter < 10; ++counter) {
-				if (var2 == _items[_npcBuf[charId]._inventory[counter]._ref].field_18)
+				if (curType == _items[_npcBuf[charId]._inventory[counter]._ref]._exclusiveType)
 					unequipItem(charId, objectId, windowId, menuId, curMenuLine);
 			}
 		}
 
-		// Set item as Equipped
-		_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
+		if (curType != 0) {
+			// Set item as Equipped
+			_npcBuf[charId]._inventory[objectId]._stat1 |= 0x80;
+		}
 	}
 }
 
@@ -1446,7 +1445,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 
 		if (argA == 2) {
 			getLastCharAfterAnimCount(_guessAnimationAmount);
-			sub18E80(charId, teamMonsterId, menuId, curMenuLine);
+			displayWindowAndStatusMenu(charId, teamMonsterId, menuId, curMenuLine);
 		}
 	}
 


Commit: 7122fd549bb54ab57fe311d1be5b8ee9e0fc60b0
    https://github.com/scummvm/scummvm/commit/7122fd549bb54ab57fe311d1be5b8ee9e0fc60b0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: More renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 641e5592f95..bc8264880c9 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -451,7 +451,7 @@ void EfhEngine::initMapMonsters() {
 	debugC(3, kDebugEngine, "initMapMonsters");
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-		if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+		if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
 			continue;
 
 		for (uint counter = 0; counter < 9; ++counter)
@@ -501,11 +501,11 @@ void EfhEngine::loadMapArrays(int idx) {
 	for (int i = 0; i < 64; ++i) {
 		_mapMonsters[i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
 		_mapMonsters[i]._npcId = mapMonstersPtr[29 * i + 1];
-		_mapMonsters[i]._guess_fullPlaceId = mapMonstersPtr[29 * i + 2];
+		_mapMonsters[i]._fullPlaceId = mapMonstersPtr[29 * i + 2];
 		_mapMonsters[i]._posX = mapMonstersPtr[29 * i + 3];
 		_mapMonsters[i]._posY = mapMonstersPtr[29 * i + 4];
-		_mapMonsters[i]._itemId_Weapon = mapMonstersPtr[29 * i + 5];
-		_mapMonsters[i]._field_6 = mapMonstersPtr[29 * i + 6];
+		_mapMonsters[i]._weaponItemId = mapMonstersPtr[29 * i + 5];
+		_mapMonsters[i]._maxDamageAbsorption = mapMonstersPtr[29 * i + 6];
 		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
 		_mapMonsters[i]._moveInfo = mapMonstersPtr[29 * i + 8];
 		_mapMonsters[i]._field9_textId = mapMonstersPtr[29 * i + 9];
@@ -667,7 +667,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 
 	if (drawMonstersFl) {
 		for (uint var16 = 0; var16 < 64; ++var16) {
-			if ((_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._guess_fullPlaceId == _fullPlaceId)){
+			if ((_largeMapFlag && _mapMonsters[var16]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._fullPlaceId == _fullPlaceId)){
 				bool var4 = false;
 				int16 posX = _mapMonsters[var16]._posX;
 				int16 posY = _mapMonsters[var16]._posY;
@@ -1371,7 +1371,7 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 		if (!checkMapMonsterAvailability(counter))
 			continue;
 
-		if (_mapMonsters[monsterId]._guess_fullPlaceId == _mapMonsters[counter]._guess_fullPlaceId
+		if (_mapMonsters[monsterId]._fullPlaceId == _mapMonsters[counter]._fullPlaceId
 		 && _mapMonsters[monsterId]._posX == _mapMonsters[counter]._posX
 		 && _mapMonsters[monsterId]._posY == _mapMonsters[counter]._posY)
 			return 0;
@@ -1560,7 +1560,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 		return true;
 
 	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon))
+		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._weaponItemId))
 			return false;
 	}
 
@@ -1570,10 +1570,10 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkIfMonsterOnSameLargeMapPlace %d", monsterId);
 
-	if (_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
+	if (_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == 0xFE)
 		return true;
 
-	if (!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId)
+	if (!_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == _fullPlaceId)
 		return true;
 
 	return false;
@@ -1582,7 +1582,7 @@ bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMonsterWeaponRange %d", monsterId);
 
-	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._itemId_Weapon);
+	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._weaponItemId);
 }
 
 void EfhEngine::handleMapMonsterMoves() {
@@ -1759,7 +1759,7 @@ void EfhEngine::handleMapMonsterMoves() {
 bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMapMonsterAvailability %d", monsterId);
 
-	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+	if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
 		return false;
 
 	for (uint counter = 0; counter < 9; ++counter) {
@@ -1804,7 +1804,7 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	debug("handleTalk %d %d %d", monsterId, arg2, itemId);
 
-	if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+	if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
 		return false;
 
 	if (countAliveMonsters(monsterId) < 1)
@@ -2336,7 +2336,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 				break;
 
 			for (uint ctrMapMonsterId = 0; ctrMapMonsterId < 64; ++ctrMapMonsterId) {
-				if (_mapMonsters[ctrMapMonsterId]._guess_fullPlaceId == 0xFF)
+				if (_mapMonsters[ctrMapMonsterId]._fullPlaceId == 0xFF)
 					continue;
 
 				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
@@ -2511,8 +2511,8 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 }
 
 
-void EfhEngine::setMapMonsterField8(int16 id, uint8 movementType, bool groupFl) {
-	debugC(2, kDebugEngine, "setMapMonsterField8 %d 0x%X %s", id, movementType, groupFl ? "True" : "False");
+void EfhEngine::setMapMonsterMovementType(int16 id, uint8 movementType, bool groupFl) {
+	debugC(2, kDebugEngine, "setMapMonsterMovementType %d 0x%X %s", id, movementType, groupFl ? "True" : "False");
 
 	int16 monsterId;
 	if (groupFl) { // groupFl is always True
@@ -2574,8 +2574,8 @@ bool EfhEngine::checkMonsterCollision() {
 		if (!checkMapMonsterAvailability(monsterId))
 			continue;
 
-		if (!(_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == 0xFE)
-		 && !(!_largeMapFlag && _mapMonsters[monsterId]._guess_fullPlaceId == _fullPlaceId))
+		if (!(_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == 0xFE)
+		 && !(!_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == _fullPlaceId))
 			continue;
 
 		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b8bf9a66ebe..a3030fe2358 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -208,11 +208,11 @@ struct CharStatus {
 struct MapMonster {
 	uint8 _possessivePronounSHL6; // aabb bbbb aa:Possessive Pronoun, bb bbbb: unknown
 	uint8 _npcId;
-	uint8 _guess_fullPlaceId; // unsigned? Magic values are 0xFF and 0xFE
+	uint8 _fullPlaceId; // unsigned? Magic values are 0xFF and 0xFE
 	uint8 _posX;
 	uint8 _posY;
-	uint8 _itemId_Weapon;
-	uint8 _field_6;
+	uint8 _weaponItemId;
+	uint8 _maxDamageAbsorption;
 	uint8 _monsterRef;
 	uint8 _moveInfo; // abbb cccc a: special move flag, bbb: Pct modifier for random move, cccc movement type
 	uint8 _field9_textId;
@@ -368,7 +368,7 @@ private:
 	int16 getXPLevel(int32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
-	void setMapMonsterField8(int16 id, uint8 movementType, bool groupFl);
+	void setMapMonsterMovementType(int16 id, uint8 movementType, bool groupFl);
 	bool isMonsterActive(int16 groupId, int16 id);
 	int16 getTileFactId(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 88cc1edca0f..14dbd0eff20 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -37,7 +37,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 			break;
 
 		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if (_mapMonsters[monsterId]._guess_fullPlaceId == 0xFF)
+			if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
 				continue;
 
 			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[monsterId]._npcId)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
@@ -161,15 +161,15 @@ bool EfhEngine::handleFight(int16 monsterId) {
 				// handleFight - Loop on var86 - Start
 				for (uint var86 = 0; var86 < 9; ++var86) {
 					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
-						int16 unk_monsterField5_itemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._itemId_Weapon;
-						if (unk_monsterField5_itemId == 0xFF)
-							unk_monsterField5_itemId = 0x3F;
+						int16 monsterWeaponItemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._weaponItemId;
+						if (monsterWeaponItemId == 0xFF)
+							monsterWeaponItemId = 0x3F;
 						int16 teamMemberId = -1;
 						int16 var54;
-						if (_items[unk_monsterField5_itemId]._range < 3) {
+						if (_items[monsterWeaponItemId]._range < 3) {
 							for (uint var84 = 0; var84 < 10; ++var84) {
 								teamMemberId = getRandom(_teamSize) - 1;
-								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], unk_monsterField5_itemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _teamPctVisible[teamMemberId]) {
+								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], monsterWeaponItemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _teamPctVisible[teamMemberId]) {
 									break;
 								}
 								teamMemberId = -1;
@@ -189,13 +189,13 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
 								int16 ennemyPronoun = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 								int16 characterPronoun = _npcBuf[_teamCharId[var7E]].getPronoun();
-								varInt = _items[unk_monsterField5_itemId].field_13;
+								varInt = _items[monsterWeaponItemId].field_13;
 								_word32482[var7E] += (varInt * 5);
 								int16 var62 = 0;
 								int16 hitPoints = 0;
 								int16 originalDamage = 0;
 								int16 damagePointsAbsorbed = 0;
-								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[unk_monsterField5_itemId]._attacks;
+								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[monsterWeaponItemId]._attacks;
 								for (int var84 = 0; var84 < var64; ++var84) {
 									// handleFight - Loop var84 on var64 (objectId) - Start
 									if (getRandom(100) > _word32482[var7E])
@@ -203,10 +203,10 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 									++var62;
 
-									if (hasAdequateDefense_2(_teamCharId[var7E], _items[unk_monsterField5_itemId]._attackType))
+									if (hasAdequateDefense_2(_teamCharId[var7E], _items[monsterWeaponItemId]._attackType))
 										continue;
 
-									int16 var7C = getRandom(_items[unk_monsterField5_itemId]._damage);
+									int16 var7C = getRandom(_items[monsterWeaponItemId]._damage);
 									varInt = var7C - var76;
 
 									if (varInt > 0) {
@@ -222,7 +222,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									originalDamage = 0;
 
 								hitPoints = originalDamage + damagePointsAbsorbed;
-								if (!checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId))
+								if (!checkSpecialItemsOnCurrentPlace(monsterWeaponItemId))
 									var62 = 0;
 
 								if (var62 > 0) {
@@ -233,7 +233,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										_attackBuffer = "";
 								}
 
-								int16 var68 = _items[unk_monsterField5_itemId]._attackType + 1;
+								int16 var68 = _items[monsterWeaponItemId]._attackType + 1;
 								int16 var6A = getRandom(3);
 								if (characterPronoun == 2)
 									_characterNamePt1 = "The ";
@@ -247,8 +247,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
-								_nameBuffer = _items[unk_monsterField5_itemId]._name;
-								if (checkSpecialItemsOnCurrentPlace(unk_monsterField5_itemId)) {
+								_nameBuffer = _items[monsterWeaponItemId]._name;
+								if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
 									// handleFight - check damages - Start
 									if (var62 == 0) {
 										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
@@ -303,7 +303,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									// handleFight - Check armor - end
 
 									// handleFight - Check effect - start
-									switch (_items[unk_monsterField5_itemId]._specialEffect) {
+									switch (_items[monsterWeaponItemId]._specialEffect) {
 									case 1:
 										if (getRandom(100) < 20) {
 											_teamCharStatus[var7E]._status = 1;
@@ -332,7 +332,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								} else {
 									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 								}
-								genericGenerateSound(_items[unk_monsterField5_itemId]._attackType, var62);
+								genericGenerateSound(_items[monsterWeaponItemId]._attackType, var62);
 								displayBoxWithText(_messageToBePrinted, 1, 2, true);
 							}
 							// handleFight - Loop on var7E - End
@@ -452,35 +452,34 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			if (_teamMonsterIdArray[groupId] == -1)
 				continue;
 
-			for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
-				if (isMonsterActive(groupId, var7E) && var6E) {
-					int16 var5C;
+			for (int16 mobsterCounter = teamMemberId; mobsterCounter < var54; ++mobsterCounter) {
+				if (isMonsterActive(groupId, mobsterCounter) && var6E) {
+					bool noticedFl;
 					if (checkMonsterMovementType(groupId, true)) {
-						setMapMonsterField8(groupId, 9, true);
+						setMapMonsterMovementType(groupId, 9, true);
 						_unk2C8AA += 500;
-						var5C = -1;
+						noticedFl = true;
 					} else
-						var5C = 0;
+						noticedFl = false;
 
-					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._field_6);
-					int16 varInt = _teamCharId[teamCharId];
-					int16 var70 = _npcBuf[varInt].getPronoun();
-					varInt = _teamMonsterIdArray[groupId];
-					int16 var5E = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
+					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
+					int16 ennemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+					int16 monsterId = _teamMonsterIdArray[groupId];
+					int16 characterPronoun = kEncounters[_mapMonsters[monsterId]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
-					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E];
-					int16 var62 = 0;
+					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter];
+					int16 hitCount = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
-					int16 var64 = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
+					int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
 
 					// Action A - Loop var84 - Start
-					for (int var84 = 0; var84 < var64; ++var84) {
+					for (int var84 = 0; var84 < attackSpeed; ++var84) {
 						if (getRandom(100) < charScore) {
-							++var62;
+							++hitCount;
 							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
 								int16 var7C = getRandom(_items[teamCharItemId]._damage);
-								varInt = var7C - var76;
+								int16 varInt = var7C - var76;
 								if (varInt > 0) {
 									originalDamage += varInt;
 									damagePointsAbsorbed += var76;
@@ -498,25 +497,24 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 hitPoints = originalDamage + damagePointsAbsorbed;
 
 					if (!checkSpecialItemsOnCurrentPlace(teamCharItemId))
-						var62 = 0;
+						hitCount = 0;
 
-					if (var62 > 0) {
-						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] -= originalDamage;
-						if (var62 > 1) {
-							_attackBuffer = Common::String::format("%d times ", var62);
+					if (hitCount > 0) {
+						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] -= originalDamage;
+						if (hitCount > 1) {
+							_attackBuffer = Common::String::format("%d times ", hitCount);
 						} else {
 							_attackBuffer = "";
 						}
 					}
-					int16 var68 = _items[teamCharItemId]._attackType + 1;
-					int16 var6A = getRandom(3) - 1;
-					if (var5E == 2) {
+					int16 verbId = (3 * _items[teamCharItemId]._attackType + 1) + getRandom(3) - 1;
+					if (characterPronoun == 2) {
 						_characterNamePt1 = "The ";
 					} else {
 						_characterNamePt1 = "";
 					}
 
-					if (var70 == 2) {
+					if (ennemyPronoun == 2) {
 						_enemyNamePt1 = "The ";
 					} else {
 						_enemyNamePt1 = "";
@@ -527,21 +525,21 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					_nameBuffer = _items[teamCharItemId]._name;
 					if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
 						// Action A - Check damages - Start
-						if (var62 == 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+						if (hitCount == 0) {
+							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 						} else if (hitPoints <= 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str());
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] <= 0) {
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
 								_messageToBePrinted += "!";
 							}
 						} else {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[(var68 * 3) + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[var70], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] <= 0) {
+							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -551,16 +549,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check damages - End
 
 						// Action A - Add reaction text - Start
-						if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] - 5 <= originalDamage) {
+						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] - 5 <= originalDamage) {
 								addReactionText(0);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 8) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 8) {
 								addReactionText(1);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 4) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 4) {
 								addReactionText(2);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 2) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 2) {
 								addReactionText(3);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] < hitPointsBefore / 3) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 3) {
 								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
 								addReactionText(4);
 							} else if (hitPointsBefore / 8 >= originalDamage) {
@@ -572,7 +570,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add reaction text - End
 
 						// Action A - Add armor absorb text - Start
-						if (var76 && var62 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
+						if (var76 && hitCount && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
 							if (damagePointsAbsorbed <= 1)
 								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							else
@@ -580,45 +578,45 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						}
 						// Action A - Add armor absorb text - End
 
-						if (var5C)
+						if (noticedFl)
 							_messageToBePrinted += Common::String("  Your actions do not go un-noticed...");
 
 						// Action A - Check item durability - Start
-						varInt = _teamCharId[teamCharId];
+						int16 npcId = _teamCharId[teamCharId];
 
 						// get equipped inventory slot with exclusiveType == 9
-						var64 = getEquippedExclusiveType(varInt, 9, false);
-						if (var64 != 0x7FFF && _npcBuf[varInt]._inventory[var64].getUsesLeft() != 0x7F) {
-							int16 usesLeft = _npcBuf[varInt]._inventory[var64].getUsesLeft();
+						uint16 exclusiveInventoryId = getEquippedExclusiveType(npcId, 9, false);
+						if (exclusiveInventoryId != 0x7FFF && _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft() != 0x7F) {
+							int16 usesLeft = _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft();
 							--usesLeft;
 							if (usesLeft <= 0) {
 								_messageToBePrinted += Common::String::format("  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
-								setCharacterObjectToBroken(varInt, var64);
+								setCharacterObjectToBroken(npcId, exclusiveInventoryId);
 								var6E = false;
 							} else {
-								_npcBuf[varInt]._inventory[var64]._stat1 = (_npcBuf[varInt]._inventory[var64]._stat1 & 80) + usesLeft;
+								_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 = (_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 & 80) + usesLeft;
 							}
 						}
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
+						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
 							if (getRandom(100) < 35) {
-								_teamMonsterEffects[groupId]._effect[var7E] = 1;
-								_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
+								_teamMonsterEffects[groupId]._effect[mobsterCounter] = 1;
+								_teamMonsterEffects[groupId]._duration[mobsterCounter] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[var7E] > 0) {
-							_teamMonsterEffects[groupId]._effect[var7E] = 2;
-							_teamMonsterEffects[groupId]._duration[var7E] = getRandom(10);
+						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
+							_teamMonsterEffects[groupId]._effect[mobsterCounter] = 2;
+							_teamMonsterEffects[groupId]._duration[mobsterCounter] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						// Action A - Check effect - End
 					} else {
-						_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[var70], _nameBuffer.c_str());
+						_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 					}
 
-					genericGenerateSound(_items[teamCharItemId]._attackType, var62);
+					genericGenerateSound(_items[teamCharItemId]._attackType, hitCount);
 					displayBoxWithText(_messageToBePrinted, 1, 2, true);
 				}
 			}
@@ -767,7 +765,7 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 		} else if (_teamMonsterIdArray[victimId] == -1)
 			deathType = 0;
 		else {
-			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._itemId_Weapon;
+			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._weaponItemId;
 			deathType = _items[itemId]._attackType;
 		}
 	}
@@ -1519,7 +1517,7 @@ bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	debug("hasAdequateDefense %d %d", monsterId, attackType);
 
-	int16 itemId = _mapMonsters[monsterId]._itemId_Weapon;
+	int16 itemId = _mapMonsters[monsterId]._weaponItemId;
 
 	if (_items[itemId]._specialEffect != 0)
 		return false;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index cc52561ca43..323811b0254 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1049,7 +1049,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			displayString_3("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterField8(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
+			setMapMonsterMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
 		}
 		objectUsedFl = true;
 		break;


Commit: 0d8ba6ba74e0dfba202ccfde9e7fc2a1fe4d594a
    https://github.com/scummvm/scummvm/commit/0d8ba6ba74e0dfba202ccfde9e7fc2a1fe4d594a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Rename last field in MapMonster structure

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index bc8264880c9..27fcf188bcd 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -508,7 +508,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapMonsters[i]._maxDamageAbsorption = mapMonstersPtr[29 * i + 6];
 		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
 		_mapMonsters[i]._moveInfo = mapMonstersPtr[29 * i + 8];
-		_mapMonsters[i]._field9_textId = mapMonstersPtr[29 * i + 9];
+		_mapMonsters[i]._talkTextId = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
 			_mapMonsters[i]._hitPoints[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
@@ -1817,11 +1817,11 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		return false;
 
 	if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F) {
-		if (_mapMonsters[monsterId]._field9_textId == 0xFF || arg2 != 5) {
+		if (_mapMonsters[monsterId]._talkTextId == 0xFF || arg2 != 5) {
 			return false;
 		}
 		displayMonsterAnim(monsterId);
-		displayImp1Text(_mapMonsters[monsterId]._field9_textId);
+		displayImp1Text(_mapMonsters[monsterId]._talkTextId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	}
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a3030fe2358..77d4deb21ca 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -215,7 +215,7 @@ struct MapMonster {
 	uint8 _maxDamageAbsorption;
 	uint8 _monsterRef;
 	uint8 _moveInfo; // abbb cccc a: special move flag, bbb: Pct modifier for random move, cccc movement type
-	uint8 _field9_textId;
+	uint8 _talkTextId;
 	uint8 _groupSize;
 	int16 _hitPoints[9];
 


Commit: c28ff1990e4eb8e108e4515c296c0818e117e9e2
    https://github.com/scummvm/scummvm/commit/c28ff1990e4eb8e108e4515c296c0818e117e9e2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: refactor findMapSpecialTileIndex, validate a couple of functions, more renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 27fcf188bcd..0d64f7b4e4c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -484,16 +484,16 @@ void EfhEngine::initMapMonsters() {
 void EfhEngine::loadMapArrays(int idx) {
 	debugC(6, kDebugEngine, "loadMapArrays %d", idx);
 
-	uint8 *_mapUnknownPtr = &_mapArr[idx][2];
+	uint8 *mapSpecialTilePtr = &_mapArr[idx][2];
 
 	for (int i = 0; i < 100; ++i) {
-		_mapUnknown[i]._placeId = _mapUnknownPtr[9 * i];
-		_mapUnknown[i]._posX = _mapUnknownPtr[9 * i + 1];
-		_mapUnknown[i]._posY = _mapUnknownPtr[9 * i + 2];
-		_mapUnknown[i]._field3 = _mapUnknownPtr[9 * i + 3];
-		_mapUnknown[i]._field4_NpcId = _mapUnknownPtr[9 * i + 4];
-		_mapUnknown[i]._field5_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 5]);
-		_mapUnknown[i]._field7_textId = READ_LE_UINT16(&_mapUnknownPtr[9 * i + 7]);
+		_mapSpecialTile[i]._placeId = mapSpecialTilePtr[9 * i];
+		_mapSpecialTile[i]._posX = mapSpecialTilePtr[9 * i + 1];
+		_mapSpecialTile[i]._posY = mapSpecialTilePtr[9 * i + 2];
+		_mapSpecialTile[i]._field3 = mapSpecialTilePtr[9 * i + 3];
+		_mapSpecialTile[i]._field4_NpcId = mapSpecialTilePtr[9 * i + 4];
+		_mapSpecialTile[i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
+		_mapSpecialTile[i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
 	}
 
 	uint8 *mapMonstersPtr = &_mapArr[idx][902];
@@ -1102,20 +1102,16 @@ void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
 	}
 }
 
-int16 EfhEngine::sub151FD(int16 posX, int16 posY) {
-	debug("sub151FD %d %d", posX, posY);
+int16 EfhEngine::findMapSpecialTileIndex(int16 posX, int16 posY) {
+	debugC(5, kDebugEngine, "findMapSpecialTileIndex %d %d", posX, posY);
 
-	if (_largeMapFlag) {
-		for (uint counter = 0; counter < 100; ++counter) {
-			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == 0xFE)
-				return counter;
-		}
-	} else {
-		for (uint counter = 0; counter < 100; ++counter) {
-			if (_mapUnknown[counter]._posX == posX && _mapUnknown[counter]._posY == posY && _mapUnknown[counter]._placeId == _fullPlaceId)
-				return counter;
-		}
+	uint16 searchPlaceId = _largeMapFlag ? 0xFE : _fullPlaceId;
+	
+	for (uint counter = 0; counter < 100; ++counter) {
+		if (_mapSpecialTile[counter]._posX == posX && _mapSpecialTile[counter]._posY == posY && _mapSpecialTile[counter]._placeId == searchPlaceId)
+			return counter;
 	}
+
 	return -1;
 }
 
@@ -2092,41 +2088,41 @@ void EfhEngine::displayImp1Text(int16 textId) {
 bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
 	debug("sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
 
-	int16 var8 = sub151FD(mapPosX, mapPosY);
+	int16 tileId = findMapSpecialTileIndex(mapPosX, mapPosY);
 
-	if (var8 == -1) {
+	if (tileId == -1) {
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (arg8 == 0) {
-		if (_mapUnknown[var8]._field3 == 0xFF) {
-			displayImp1Text(_mapUnknown[var8]._field5_textId); // word!
+		if (_mapSpecialTile[tileId]._field3 == 0xFF) {
+			displayImp1Text(_mapSpecialTile[tileId]._field5_textId); // word!
 			return true;
 		}
 
-		if (_mapUnknown[var8]._field3 == 0xFE) {
+		if (_mapSpecialTile[tileId]._field3 == 0xFE) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
-				if (_teamCharId[counter] == _mapUnknown[var8]._field4_NpcId) {
-					displayImp1Text(_mapUnknown[var8]._field5_textId);
+				if (_teamCharId[counter] == _mapSpecialTile[tileId]._field4_NpcId) {
+					displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 					return true;
 				}
 			}
-		} else if (_mapUnknown[var8]._field3 == 0xFD) {
+		} else if (_mapSpecialTile[tileId]._field3 == 0xFD) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapUnknown[var8]._field4_NpcId) {
-						displayImp1Text(_mapUnknown[var8]._field5_textId);
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTile[tileId]._field4_NpcId) {
+						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		// original makes a useless check on (_mapUnknownPtr[var8 * 9 + 3] > 0x7F)
-		} else if (_mapUnknown[var8]._field3 <= 0x77) {
-			int16 var6 = _mapUnknown[var8]._field3;
+		} else if (_mapSpecialTile[tileId]._field3 <= 0x77) {
+			int16 var6 = _mapSpecialTile[tileId]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
@@ -2134,25 +2130,25 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				for (uint var2 = 0; var2 < 39; ++var2) {
 					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapUnknown[var8]._field4_NpcId) {
-						displayImp1Text(_mapUnknown[var8]._field5_textId);
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTile[tileId]._field4_NpcId) {
+						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		}
 	} else {
-		if ((_mapUnknown[var8]._field3 == 0xFA && arg8 == 1) || (_mapUnknown[var8]._field3 == 0xFC && arg8 == 2) || (_mapUnknown[var8]._field3 == 0xFB && arg8 == 3)) {
-			if (_mapUnknown[var8]._field4_NpcId == itemId) {
-				displayImp1Text(_mapUnknown[var8]._field5_textId);
+		if ((_mapSpecialTile[tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTile[tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTile[tileId]._field3 == 0xFB && arg8 == 3)) {
+			if (_mapSpecialTile[tileId]._field4_NpcId == itemId) {
+				displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 				return true;
 			}
 		} else if (arg8 == 4) {
-			int16 var6 = _mapUnknown[var8]._field3;
+			int16 var6 = _mapSpecialTile[tileId]._field3;
 			if (var6 >= 0x7B && var6 <= 0xEF) {
 				var6 -= 0x78;
-				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapUnknown[var8]._field4_NpcId <= _npcBuf[charId]._activeScore[itemId]) {
-					displayImp1Text(_mapUnknown[var8]._field5_textId);
+				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTile[tileId]._field4_NpcId <= _npcBuf[charId]._activeScore[itemId]) {
+					displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 					return true;
 				}
 			}
@@ -2164,10 +2160,11 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			return true;
 	}
 
-	if ((arg8 == 4 && _mapUnknown[var8]._field3 < 0xFA) || arg8 != 4) {
-		if (_mapUnknown[var8]._field7_textId > 0xFE)
+	// CHECKME: there's suspiciously no check on tileId
+	if ((arg8 == 4 && _mapSpecialTile[tileId]._field3 < 0xFA) || arg8 != 4) {
+		if (_mapSpecialTile[tileId]._field7_textId > 0xFE)
 			return false;
-		displayImp1Text(_mapUnknown[var8]._field7_textId);
+		displayImp1Text(_mapSpecialTile[tileId]._field7_textId);
 		return true;
 	}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 77d4deb21ca..695e629b3b2 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -89,7 +89,7 @@ struct InvObject {
 	int8 getUsesLeft();
 };
 
-struct UnkMapStruct {
+struct MapSpecialTileStruct {
 	uint8 _placeId;
 	uint8 _posX;
 	uint8 _posY;
@@ -322,7 +322,7 @@ private:
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void transitionMap(int16 centerX, int16 centerY);
 	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
-	int16 sub151FD(int16 posX, int16 posY);
+	int16 findMapSpecialTileIndex(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
 	void goNorth();
@@ -537,7 +537,7 @@ private:
 	Common::String _messageToBePrinted;
 
 	uint8 *_mapBitmapRefArr[19];
-	UnkMapStruct _mapUnknown[100];
+	MapSpecialTileStruct _mapSpecialTile[100];
 	MapMonster _mapMonsters[64];
 	uint8 _mapGameMap[64][64];
 
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index aa5ed2e9f1c..51d4a60b170 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -196,7 +196,7 @@ void EfhEngine::loadHistory() {
 }
 
 void EfhEngine::loadTechMapImp(int16 fileId) {
-	debug("loadTechMapImp %d", fileId);
+	debugC(3, kDebugEngine, "loadTechMapImp %d", fileId);
 
 	if (fileId == 0xFF)
 		return;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index e5a9af06e93..2f10413fcf0 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -44,7 +44,7 @@ void InvObject::init() {
 	_curHitPoints = 0;
 }
 
-void UnkMapStruct::init() {
+void MapSpecialTileStruct::init() {
 	_placeId = _posX = _posY = _field3 = _field4_NpcId = 0;
 	_field5_textId = _field7_textId = 0;
 }
@@ -229,7 +229,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 
 	for (int i = 0; i < 100; ++i) {
 		_imp1PtrArray[i] = nullptr;
-		_mapUnknown[i].init();
+		_mapSpecialTile[i].init();
 	}
 
 	for (int i = 0; i < 432; ++i)
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 2f650d87ff9..7d6a74e46f4 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -310,11 +310,11 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				_unk2C8AA = 0;
 			break;
 		case 0x12:
-			// Guess : disable special tile { }
+			// Disable special tile
 			if (flag) {
-				int16 var110 = sub151FD(_mapPosX, _mapPosY);
-				if (var110 != -1)
-					_mapUnknown[var110]._posX = 0xFF;
+				int16 tileId = findMapSpecialTileIndex(_mapPosX, _mapPosY);
+				if (tileId != -1)
+					_mapSpecialTile[tileId]._posX = 0xFF;
 			}
 			break;
 		case 0x13:
@@ -398,9 +398,10 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 					displayFctFullScreen();
 				}
 
-				int16 mapUnkId = sub151FD(_mapPosX, _mapPosY);
-				if (mapUnkId != -1) {
-					_mapUnknown[mapUnkId]._posX = 0xFF;
+				int16 tileId = findMapSpecialTileIndex(_mapPosX, _mapPosY);
+				if (tileId != -1) {
+					// Disable special tile
+					_mapSpecialTile[tileId]._posX = 0xFF;
 				}
 				_redrawNeededFl = true;
 			}
@@ -418,21 +419,23 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x1A:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (flag) {
-				int16 mapUnkId = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (mapUnkId != -1) {
-					_mapUnknown[mapUnkId]._posX = 0xFF;
+				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
+				if (tileId != -1) {
+					// Disable tile
+					_mapSpecialTile[tileId]._posX = 0xFF;
 				}
 			}
 			break;
 		case 0x1B:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (flag) {
-				int16 mapUnkId = sub151FD(scriptNumberArray[0], scriptNumberArray[1]);
-				if (mapUnkId != -1) {
-					_mapUnknown[mapUnkId]._posX = 0xFF;
+				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
+				if (tileId != -1) {
+					// Disable tile
+					_mapSpecialTile[tileId]._posX = 0xFF;
 				}
-				_mapUnknown[scriptNumberArray[2]]._posX = scriptNumberArray[0];
-				_mapUnknown[scriptNumberArray[2]]._posY = scriptNumberArray[1];
+				_mapSpecialTile[scriptNumberArray[2]]._posX = scriptNumberArray[0];
+				_mapSpecialTile[scriptNumberArray[2]]._posY = scriptNumberArray[1];
 			}
 			break;
 		case 0x1C:


Commit: 36ea4314d2274bfb4fcd600bf9f6c566c9614244
    https://github.com/scummvm/scummvm/commit/36ea4314d2274bfb4fcd600bf9f6c566c9614244
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: WIP sound code

Changed paths:
    engines/efh/constants.cpp
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index 6d1d01c6ee9..dfcb5704fbf 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -446,4 +446,23 @@ const char kAttackVerbs[51][20] = {
 	"shoots",
 	"shoots"
 };
+
+const int16 kSoundFrequency[72] = {
+	18356, 17292, 16344, 15297, 14551,
+	13714, 12829, 12175, 11472, 10847,
+	10198, 9700,  9108,  8584,  8116, // last 3 : C, C#, D
+	7648,  7231,  6818,  6449,  6087, // D#, E, F, F#, G
+	5736,  5423,  5120,  4830,  4554, // G#, A, A#, B, Middle C
+	4307,  4058,  3836,  3615,  3418, // C#, D, D#
+	3224,  3043,  2875,  2711,  2560,  
+	2415,  2281,  2153,  2032,  1918,  
+	1810,  1709,  1612,  1521,  1435,  
+	1355,  1280,  1207,  1139,  1075,  
+	1015,  958,   897,   854,   806,   
+	760,   718,   677,   639,   603,   
+	570,   538,   507,   479,   452,   
+	427,   403,   380,   359,   338,   
+	319,   301
+};
+
 } // End of namespace Efh
diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index d90cab882f5..c08ade3e690 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -39,6 +39,8 @@ struct Encounter {
 	uint8 _nameArticle;
 };
 
+#define kDefaultNoteDuration 616;
+
 extern const uint8 kFontWidthArray[96];
 extern const uint8 kFontExtraLinesArray[96];
 extern const Font kFontData[96];
@@ -48,6 +50,7 @@ extern const uint8 kByte2C7D0[60];
 extern const char kPossessive[3][4];
 extern const char kPersonal[3][4];
 extern const char kAttackVerbs[51][20];
+extern const int16 kSoundFrequency[72];
 
 } // End of namespace Efh
 
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0d64f7b4e4c..a6f36f5dbeb 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -273,12 +273,65 @@ void EfhEngine::initialize() {
 	_shouldQuit = false;
 }
 
+void EfhEngine::songDelay(int delay) {
+	debug("songDelay %d", delay);
+
+	int remainingDelay = delay * kDefaultNoteDuration;
+	Common::KeyCode input = Common::KEYCODE_INVALID;
+	Common::Event event;
+	while (input == Common::KEYCODE_INVALID && remainingDelay > 0 && !shouldQuit()) {
+		_system->delayMillis(20);
+		remainingDelay -= 20;
+
+		_system->getEventManager()->pollEvent(event);
+		if (event.type == Common::EVENT_KEYUP) {
+			input = event.kbd.keycode;
+		}
+	}
+}
+
+void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
+	debug("playNote %d %d", frequencyIndex, totalDelay);
+}
+
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
-	warning("STUB: playSong");
+	debug("playSong");
+
+	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
+	int32 totalDelay = 0;
+
+	uint8 varC = *buffer++;
+	int8 stopFl = *buffer & 0x3F;
+	while (stopFl != 0) {
+		int32 delay = stopFl * varC * 0x2200 / 1000;
+		if (*buffer > 0x7F)
+			delay /= 2;
+		if (*buffer & 0x40)
+			delay = (delay * 2) / 3;
+		int8 frequencyIndex = *++buffer & 0xF;
+		++buffer;
+
+		if (frequencyIndex > 0x7F)
+			totalDelay += delay;
+		else if (frequencyIndex == 0)
+			songDelay(delay);
+		else {
+			playNote(frequencyIndex, totalDelay + delay);
+			totalDelay = 0;
+		}
 
-	_system->delayMillis(1000);
+		songDelay(10);
+		Common::Event event;
+		_system->getEventManager()->pollEvent(event);
+		if (event.type == Common::EVENT_KEYUP) {
+			inputChar = event.kbd.keycode;
+		}
 
-	return Common::KEYCODE_INVALID;
+		if (inputChar != Common::KEYCODE_INVALID)
+			stopFl = 0;
+	}
+	
+	return inputChar;
 }
 
 void EfhEngine::playIntro() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 695e629b3b2..332b6c68d3a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -285,6 +285,8 @@ private:
 	bool _saveAuthorized;
 
 	void initialize();
+	void songDelay(int delay);
+	void playNote(int frequencyIndex, int totalDelay);
 	Common::KeyCode playSong(uint8 *buffer);
 	void playIntro();
 	void initEngine();


Commit: d5eb4d85a41117d5b08a840c57c8ca8ce1000e3a
    https://github.com/scummvm/scummvm/commit/d5eb4d85a41117d5b08a840c57c8ca8ce1000e3a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: fix a bug in sub22293(), validate 2 functions, some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/init.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a6f36f5dbeb..e46e1daa0bf 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -274,7 +274,7 @@ void EfhEngine::initialize() {
 }
 
 void EfhEngine::songDelay(int delay) {
-	debug("songDelay %d", delay);
+	debug("songDelay %ld", delay);
 
 	int remainingDelay = delay * kDefaultNoteDuration;
 	Common::KeyCode input = Common::KEYCODE_INVALID;
@@ -291,12 +291,14 @@ void EfhEngine::songDelay(int delay) {
 }
 
 void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
-	debug("playNote %d %d", frequencyIndex, totalDelay);
+	debug("playNote %d %ld", frequencyIndex, totalDelay);
 }
 
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	debug("playSong");
 
+	return Common::KEYCODE_INVALID;
+	
 	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
 	int32 totalDelay = 0;
 
@@ -544,7 +546,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapSpecialTile[i]._posX = mapSpecialTilePtr[9 * i + 1];
 		_mapSpecialTile[i]._posY = mapSpecialTilePtr[9 * i + 2];
 		_mapSpecialTile[i]._field3 = mapSpecialTilePtr[9 * i + 3];
-		_mapSpecialTile[i]._field4_NpcId = mapSpecialTilePtr[9 * i + 4];
+		_mapSpecialTile[i]._triggerId = mapSpecialTilePtr[9 * i + 4];
 		_mapSpecialTile[i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
 		_mapSpecialTile[i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
 	}
@@ -1851,7 +1853,7 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 }
 
 bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
-	debug("handleTalk %d %d %d", monsterId, arg2, itemId);
+	debugC(6, kDebugEngine, "handleTalk %d %d %d", monsterId, arg2, itemId);
 
 	if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
 		return false;
@@ -2139,7 +2141,7 @@ void EfhEngine::displayImp1Text(int16 textId) {
 }
 
 bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
-	debug("sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
+	debugC(3, kDebugEngine, "sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
 
 	int16 tileId = findMapSpecialTileIndex(mapPosX, mapPosY);
 
@@ -2148,7 +2150,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (arg8 == 0) {
 		if (_mapSpecialTile[tileId]._field3 == 0xFF) {
-			displayImp1Text(_mapSpecialTile[tileId]._field5_textId); // word!
+			displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 			return true;
 		}
 
@@ -2156,7 +2158,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
-				if (_teamCharId[counter] == _mapSpecialTile[tileId]._field4_NpcId) {
+				if (_teamCharId[counter] == _mapSpecialTile[tileId]._triggerId) {
 					displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 					return true;
 				}
@@ -2167,13 +2169,13 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTile[tileId]._field4_NpcId) {
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTile[tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
-		// original makes a useless check on (_mapUnknownPtr[var8 * 9 + 3] > 0x7F)
+		// original makes a useless check on (_mapSpecialTile[tileId]._field3 > 0x7F)
 		} else if (_mapSpecialTile[tileId]._field3 <= 0x77) {
 			int16 var6 = _mapSpecialTile[tileId]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
@@ -2183,33 +2185,34 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				for (uint var2 = 0; var2 < 39; ++var2) {
 					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTile[tileId]._field4_NpcId) {
+					warning("sub22293 - _activeScore[%d]", var6);
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTile[tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		}
-	} else {
-		if ((_mapSpecialTile[tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTile[tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTile[tileId]._field3 == 0xFB && arg8 == 3)) {
-			if (_mapSpecialTile[tileId]._field4_NpcId == itemId) {
+	} else if ((_mapSpecialTile[tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTile[tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTile[tileId]._field3 == 0xFB && arg8 == 3)) {
+		if (_mapSpecialTile[tileId]._triggerId == itemId) {
+			displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+			return true;
+		}
+	} else if (arg8 == 4) {
+		int16 var6 = _mapSpecialTile[tileId]._field3;
+		if (var6 >= 0x78 && var6 <= 0xEF) {
+			var6 -= 0x78;
+			warning("sub22293 - _activeScore[%d]", var6);
+			// The 2 checks on var6 are useless, as [0x78..0xEF] - 0x78 => [0x00..0x77]
+			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTile[tileId]._triggerId <= _npcBuf[charId]._activeScore[itemId]) {
 				displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
 				return true;
 			}
-		} else if (arg8 == 4) {
-			int16 var6 = _mapSpecialTile[tileId]._field3;
-			if (var6 >= 0x7B && var6 <= 0xEF) {
-				var6 -= 0x78;
-				if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTile[tileId]._field4_NpcId <= _npcBuf[charId]._activeScore[itemId]) {
-					displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
-					return true;
-				}
-			}
 		}
 	}
 
 	for (uint counter = 0; counter < 64; ++counter) {
-		if (!handleTalk(counter, arg8, itemId))
+		if (handleTalk(counter, arg8, itemId))
 			return true;
 	}
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 332b6c68d3a..20515d7acbb 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -94,7 +94,7 @@ struct MapSpecialTileStruct {
 	uint8 _posX;
 	uint8 _posY;
 	uint8 _field3;
-	uint8 _field4_NpcId;
+	uint8 _triggerId;
 	uint16 _field5_textId;
 	uint16 _field7_textId;
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 2f10413fcf0..db1a4b2f746 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -45,7 +45,7 @@ void InvObject::init() {
 }
 
 void MapSpecialTileStruct::init() {
-	_placeId = _posX = _posY = _field3 = _field4_NpcId = 0;
+	_placeId = _posX = _posY = _field3 = _triggerId = 0;
 	_field5_textId = _field7_textId = 0;
 }
 


Commit: 8f3ad37290942247a5bd54ceb6751d7c983ca34c
    https://github.com/scummvm/scummvm/commit/8f3ad37290942247a5bd54ceb6751d7c983ca34c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Fix a bug in handleFight_lastAction_A, validate multiple functions, renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e46e1daa0bf..ca1d9f81cd9 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1822,7 +1822,7 @@ bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
 }
 
 void EfhEngine::displayMonsterAnim(int16 monsterId) {
-	debug("displayMonsterAnim %d", monsterId);
+	debugC(6, kDebugEngine, "displayMonsterAnim %d", monsterId);
 
 	int16 animId = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
 	displayAnimFrames(animId, true);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 20515d7acbb..e8f5f265bd2 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -388,13 +388,13 @@ private:
 	bool isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId);
 	void createOpponentList(int16 monsterTeamId);
 	void resetTeamMonsterEffects();
-	void sub1BE89(int16 monsterId);
+	void initFight(int16 monsterId);
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
 	void getDeathTypeDescription(int16 attackerId, int16 victimId);
 	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
 	bool sub1CB27();
-	void drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl);
+	void drawCombatScreen(int16 charId, bool whiteFl, bool drawFl);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void addReactionText(int16 id);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 14dbd0eff20..32b862109cd 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -71,8 +71,8 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 		_teamMonsterIdArray[id] = -1;
 }
 
-void EfhEngine::sub1BE89(int16 monsterId) {
-	debug("sub1BE89 %d", monsterId);
+void EfhEngine::initFight(int16 monsterId) {
+	debugC(3, kDebugEngine, "initFight %d", monsterId);
 	createOpponentList(monsterId);
 	resetTeamMonsterEffects();
 }
@@ -82,7 +82,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 	_ongoingFightFl = true;
 
-	sub1BE89(monsterId);
+	initFight(monsterId);
 
 	if (_teamMonsterIdArray[0] == -1) {
 		resetTeamMonsterIdArray();
@@ -455,7 +455,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			for (int16 mobsterCounter = teamMemberId; mobsterCounter < var54; ++mobsterCounter) {
 				if (isMonsterActive(groupId, mobsterCounter) && var6E) {
 					bool noticedFl;
-					if (checkMonsterMovementType(groupId, true)) {
+					if (!checkMonsterMovementType(groupId, true)) {
 						setMapMonsterMovementType(groupId, 9, true);
 						_unk2C8AA += 500;
 						noticedFl = true;
@@ -695,7 +695,7 @@ bool EfhEngine::isTPK() {
 }
 
 bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
-	debug("isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
+	debugC(6, kDebugEngine, "isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
 
 	for (int counter = 0; counter < teamMonsterId; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId)
@@ -1142,11 +1142,11 @@ bool EfhEngine::sub1CB27() {
 	return var4;
 }
 
-void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
-	debug("drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", forceDrawFl ? "True" : "False");
+void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {
+	debugC(6, kDebugEngine, "drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", drawFl ? "True" : "False");
 
 	for (uint counter = 0; counter < 2; ++counter) {
-		if (counter == 0 || forceDrawFl) {
+		if (counter == 0 || drawFl) {
 			drawMapWindow();
 			displayCenteredString("Combat", 128, 303, 9);
 			drawColoredRect(200, 112, 278, 132, 0);
@@ -1157,7 +1157,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool forceDrawFl) {
 			displayLowStatusScreen(false);
 		}
 
-		if (counter == 0 && forceDrawFl)
+		if (counter == 0 && drawFl)
 			displayFctFullScreen();
 	}
 }
@@ -1321,30 +1321,29 @@ void EfhEngine::addReactionText(int16 id) {
 }
 
 void EfhEngine::sub1C4CA(bool whiteFl) {
-	debug("sub1C4CA %s", whiteFl ? "True" : "False");
+	debugC(5, kDebugEngine, "sub1C4CA %s", whiteFl ? "True" : "False");
 
 	int16 textPosY = 20;
 	for (uint counter = 0; counter < 5; ++counter) {
 		if (_teamMonsterIdArray[counter] == -1)
 			continue;
 
-		int16 var6C = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
-		int16 var6E = countMonsterGroupMembers(counter);
+		int16 monsterDistance = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
+		int16 mobsterCount = countMonsterGroupMembers(counter);
 		if (whiteFl)
 			setTextColorWhite();
 		else
 			setTextColorGrey();
 
 		setTextPos(129, textPosY);
-		char buffer[80];
-		snprintf(buffer, 80, "%c)", 'A' + counter);
+		Common::String buffer = Common::String::format("%c)", 'A' + counter);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
 		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
 		if (var1 <= 0x3D) {
-			snprintf(buffer, 80, "%d %s", var6E, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
+			buffer = Common::String::format("%d %s", mobsterCount, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
 			displayStringAtTextPos(buffer);
-			if (var6E > 1)
+			if (mobsterCount > 1)
 				displayStringAtTextPos("s");
 		} else if (var1 == 0x3E) {
 			displayStringAtTextPos("(NOT DEFINED)");
@@ -1363,7 +1362,7 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		}
 
 		setTextColorRed();
-		switch (var6C) {
+		switch (monsterDistance) {
 		case 1:
 			displayCenteredString("S", 290, 302, textPosY);
 			break;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 51d4a60b170..dfc475f313f 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -174,7 +174,7 @@ void EfhEngine::loadNewPortrait() {
 }
 
 void EfhEngine::loadAnimImageSet() {
-	debug("loadAnimImageSet");
+	debugC(3, kDebugEngine, "loadAnimImageSet");
 
 	if (_currentAnimImageSetId == _animImageSetId || _animImageSetId == 0xFF)
 		return;
@@ -189,7 +189,7 @@ void EfhEngine::loadAnimImageSet() {
 }
 
 void EfhEngine::loadHistory() {
-	debug("loadHistory");
+	debugC(2, kDebugEngine, "loadHistory");
 
 	Common::String fileName = "history";
 	readFileToBuffer(fileName, _history);


Commit: cb8897d782fe26d926668b96679525da528faa41
    https://github.com/scummvm/scummvm/commit/cb8897d782fe26d926668b96679525da528faa41
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: More renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ca1d9f81cd9..9cf0b58d201 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -562,7 +562,7 @@ void EfhEngine::loadMapArrays(int idx) {
 		_mapMonsters[i]._weaponItemId = mapMonstersPtr[29 * i + 5];
 		_mapMonsters[i]._maxDamageAbsorption = mapMonstersPtr[29 * i + 6];
 		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
-		_mapMonsters[i]._moveInfo = mapMonstersPtr[29 * i + 8];
+		_mapMonsters[i]._additionalInfo = mapMonstersPtr[29 * i + 8];
 		_mapMonsters[i]._talkTextId = mapMonstersPtr[29 * i + 9];
 		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
 		for (int j = 0; j < 9; ++j)
@@ -1595,10 +1595,10 @@ bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	if (teamFlag)
 		monsterId = _teamMonsterIdArray[id];
 
-	if ((_mapMonsters[monsterId]._moveInfo & 0xF) >= 8)
+	if ((_mapMonsters[monsterId]._additionalInfo & 0xF) >= 8)
 		return true;
 
-	if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._moveInfo & 0x80) != 0)
+	if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._additionalInfo & 0x80) != 0)
 		return true;
 
 	return false;
@@ -1666,12 +1666,12 @@ void EfhEngine::handleMapMonsterMoves() {
 		bool monsterMovedFl = false;
 		int16 lastRangeCheck = 0;
 
-		int8 monsterMoveType = _mapMonsters[monsterId]._moveInfo & 0xF; // 0000 1111
+		int8 monsterMoveType = _mapMonsters[monsterId]._additionalInfo & 0xF; // 0000 1111
 
-		if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._moveInfo & 0x80)) // 1000 0000
+		if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._additionalInfo & 0x80)) // 1000 0000
 			monsterMoveType = 9;
 
-		int16 randomModPct = _mapMonsters[monsterId]._moveInfo & 0x70; // 0111 0000
+		int16 randomModPct = _mapMonsters[monsterId]._additionalInfo & 0x70; // 0111 0000
 		randomModPct >>= 4; // Max 7 (0111)
 
 		int16 retryCounter = randomModPct;
@@ -2564,8 +2564,8 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 }
 
 
-void EfhEngine::setMapMonsterMovementType(int16 id, uint8 movementType, bool groupFl) {
-	debugC(2, kDebugEngine, "setMapMonsterMovementType %d 0x%X %s", id, movementType, groupFl ? "True" : "False");
+void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask, bool groupFl) {
+	debugC(2, kDebugEngine, "setMapMonsterAggressivenessAndMovementType %d 0x%X %s", id, mask, groupFl ? "True" : "False");
 
 	int16 monsterId;
 	if (groupFl) { // groupFl is always True
@@ -2574,9 +2574,9 @@ void EfhEngine::setMapMonsterMovementType(int16 id, uint8 movementType, bool gro
 		monsterId = id;
 	}
 
-	movementType &= 0x0F;
-	_mapMonsters[monsterId]._moveInfo &= 0xF0;
-	_mapMonsters[monsterId]._moveInfo |= movementType;
+	mask &= 0x0F;
+	_mapMonsters[monsterId]._additionalInfo &= 0xF0;
+	_mapMonsters[monsterId]._additionalInfo |= mask;
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e8f5f265bd2..00dc53d39de 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -214,7 +214,7 @@ struct MapMonster {
 	uint8 _weaponItemId;
 	uint8 _maxDamageAbsorption;
 	uint8 _monsterRef;
-	uint8 _moveInfo; // abbb cccc a: special move flag, bbb: Pct modifier for random move, cccc movement type
+	uint8 _additionalInfo; // abbb cddd a: special move flag, bbb: Pct modifier for random move, c aggressiveness, ddd movetype
 	uint8 _talkTextId;
 	uint8 _groupSize;
 	int16 _hitPoints[9];
@@ -370,7 +370,7 @@ private:
 	int16 getXPLevel(int32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
-	void setMapMonsterMovementType(int16 id, uint8 movementType, bool groupFl);
+	void setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask, bool groupFl);
 	bool isMonsterActive(int16 groupId, int16 id);
 	int16 getTileFactId(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 32b862109cd..092b032b6f6 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -456,7 +456,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				if (isMonsterActive(groupId, mobsterCounter) && var6E) {
 					bool noticedFl;
 					if (!checkMonsterMovementType(groupId, true)) {
-						setMapMonsterMovementType(groupId, 9, true);
+						setMapMonsterAggressivenessAndMovementType(groupId, 9, true);
 						_unk2C8AA += 500;
 						noticedFl = true;
 					} else
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 323811b0254..91f034dfd51 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1049,7 +1049,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			displayString_3("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
+			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
 		}
 		objectUsedFl = true;
 		break;


Commit: 3dbb8bb1a0d4700ec78c84a1949e4b1f0f338b85
    https://github.com/scummvm/scummvm/commit/3dbb8bb1a0d4700ec78c84a1949e4b1f0f338b85
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:44+01:00

Commit Message:
EFH: Fix implementation of checkSpecialItemsOnCurrentPlace(), modify displayCharacterInformationOrSkills() so it doesn't rely on out of bonds reads, validate some functions and add comments

Changed paths:
    engines/efh/constants.cpp
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/constants.cpp b/engines/efh/constants.cpp
index dfcb5704fbf..a261703b8f4 100644
--- a/engines/efh/constants.cpp
+++ b/engines/efh/constants.cpp
@@ -342,6 +342,7 @@ const Encounter kEncounters[] {
 };
 
 const char kSkillArray[37][20] = {
+// Active Scores
 	"Flying",
 	"Swimming",
 	"Electrical",
@@ -357,6 +358,7 @@ const char kSkillArray[37][20] = {
 	"Explosives",
 	"Chemistry",
 	"Steal",
+// Passive Scores
 	"Dueling",
 	"Marksmanship",
 	"Fist Fighting",
@@ -368,6 +370,7 @@ const char kSkillArray[37][20] = {
 	"Automatic/SMG",
 	"Archery",
 	"Rocket Lncher",
+// Info Scores
 	"Strength",
 	"Intelligence",
 	"Piety",
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9cf0b58d201..ff852d02b41 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2266,7 +2266,7 @@ void EfhEngine::computeInitiatives() {
 	for (int counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] != -1 && counter < _teamSize) {
 			_initiatives[counter]._id = counter + 1000;
-			_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3];
+			_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3]; // "Agility"
 		} else {
 			_initiatives[counter]._id = -1;
 			_initiatives[counter]._initiative = -1;
@@ -2344,104 +2344,6 @@ void EfhEngine::sub1CAB6(int16 charId) {
 	}
 }
 
-// The parameter isn't used in the original
-void EfhEngine::sub1BE9A(int16 monsterId) {
-	debug("sub1BE9A %d", monsterId);
-
-	// sub1BE9A - 1rst loop counter1_monsterId - Start
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		if (countMonsterGroupMembers(counter1))
-			continue;
-
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_mapMonsters[_teamMonsterIdArray[counter1]]._hitPoints[counter2] = 0;
-			_teamMonsterEffects[counter1]._effect[counter2] = 0;
-			_teamMonsterEffects[counter1]._duration[counter2] = 0;
-		}
-
-		_teamMonsterIdArray[counter1] = -1;
-
-		// CHECKME: counter1 is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
-		// if the purpose is compact the array, it should be handle differently
-		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
-			for (uint var8 = 0; var8 < 9; ++var8) {
-				_teamMonsterEffects[counter1]._effect[var8] = _teamMonsterEffects[counter2]._effect[var8];
-				_teamMonsterEffects[counter1]._duration[var8] = _teamMonsterEffects[counter2]._duration[var8];
-			}
-			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
-		}
-
-	}
-	// sub1BE9A - 1rst loop counter1_monsterId - End
-
-	int16 teamMonsterId = -1;
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		if (_teamMonsterIdArray[counter1] == -1) {
-			teamMonsterId = counter1;
-			break;
-		}
-	}
-
-	if (teamMonsterId != -1) {
-		// sub1BE9A - loop var2 - Start
-		for (int var2 = 1; var2 < 3; ++var2) {
-			if (teamMonsterId >= 5)
-				break;
-
-			for (uint ctrMapMonsterId = 0; ctrMapMonsterId < 64; ++ctrMapMonsterId) {
-				if (_mapMonsters[ctrMapMonsterId]._fullPlaceId == 0xFF)
-					continue;
-
-				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
-					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
-						bool monsterActiveFound = false;
-						for (uint ctrSubId = 0; ctrSubId < 9; ++ctrSubId) {
-							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrSubId] > 0) {
-								monsterActiveFound = true;
-								break;
-							}
-						}
-
-						if (!monsterActiveFound)
-							continue;
-
-						if (computeMonsterGroupDistance(ctrMapMonsterId) > var2)
-							continue;
-
-						if (isMonsterAlreadyFighting(ctrMapMonsterId, teamMonsterId))
-							continue;
-
-						_teamMonsterIdArray[teamMonsterId] = ctrMapMonsterId;
-
-						// The original at this point was doing a loop on counter1, which is not a good idea as
-						// it was resetting the counter1 to 9 whatever its value before the loop.
-						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
-						for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-							_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 0;
-						}
-
-						if (++teamMonsterId >= 5)
-							break;
-					}
-				}
-			}
-		}
-		// sub1BE9A - loop var2 - End
-	}
-
-	if (teamMonsterId == -1 || teamMonsterId > 4)
-		return;
-
-	// sub1BE9A - last loop counter1_monsterId - Start
-	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
-		_teamMonsterIdArray[ctrTeamMonsterId] = -1;
-		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-			_teamMonsterEffects[ctrTeamMonsterId]._effect[ctrEffectId] = (int16)0x8000;
-		}
-	}
-	// sub1BE9A - last loop counter1_monsterId - End
-}
-
 int16 EfhEngine::getTeamMonsterAnimId() {
 	debug("getTeamMonsterAnimId");
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 00dc53d39de..b343fd88297 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -363,7 +363,6 @@ private:
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
 	void sub1CAB6(int16 charId);
-	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1D8C2(int16 charId, int16 damage);
@@ -404,6 +403,7 @@ private:
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
+	void sub1BE9A(int16 monsterId);
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 092b032b6f6..69f4b8d5b5b 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -24,7 +24,7 @@
 namespace Efh {
 
 void EfhEngine::createOpponentList(int16 monsterTeamId) {
-	debugC(3, kDebugEngine, "createOpponentList %d", monsterTeamId);
+	debugC(3, kDebugFight, "createOpponentList %d", monsterTeamId);
 
 	int16 counter = 0;
 	if (monsterTeamId != -1 && countAliveMonsters(monsterTeamId) > 0) {
@@ -72,7 +72,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 }
 
 void EfhEngine::initFight(int16 monsterId) {
-	debugC(3, kDebugEngine, "initFight %d", monsterId);
+	debugC(3, kDebugFight, "initFight %d", monsterId);
 	createOpponentList(monsterId);
 	resetTeamMonsterEffects();
 }
@@ -642,7 +642,7 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
-	debugC(3, kDebugEngine, "handleFight_lastAction_H %d", teamCharId);
+	debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
 
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -695,7 +695,7 @@ bool EfhEngine::isTPK() {
 }
 
 bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
-	debugC(6, kDebugEngine, "isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
+	debugC(6, kDebugFight, "isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
 
 	for (int counter = 0; counter < teamMonsterId; ++counter) {
 		if (_teamMonsterIdArray[counter] == monsterId)
@@ -705,7 +705,7 @@ bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
 }
 
 void EfhEngine::resetTeamMonsterEffects() {
-	debugC(6, kDebugEngine, "resetTeamMonsterEffects");
+	debugC(6, kDebugFight, "resetTeamMonsterEffects");
 	for (uint ctrMonsterId = 0; ctrMonsterId < 5; ++ctrMonsterId) {
 		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
 			_teamMonsterEffects[ctrMonsterId]._effect[ctrEffectId] = 0;
@@ -715,7 +715,7 @@ void EfhEngine::resetTeamMonsterEffects() {
 }
 
 void EfhEngine::resetTeamMonsterIdArray() {
-	debugC(6, kDebugEngine, "resetTeamMonsterIdArray");
+	debugC(6, kDebugFight, "resetTeamMonsterIdArray");
 
 	for (int i = 0; i < 5; ++i) {
 		_teamMonsterIdArray[i] = -1;
@@ -1143,7 +1143,7 @@ bool EfhEngine::sub1CB27() {
 }
 
 void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {
-	debugC(6, kDebugEngine, "drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", drawFl ? "True" : "False");
+	debugC(6, kDebugFight, "drawCombatScreen %d %s %s", charId, whiteFl ? "True" : "False", drawFl ? "True" : "False");
 
 	for (uint counter = 0; counter < 2; ++counter) {
 		if (counter == 0 || drawFl) {
@@ -1163,20 +1163,25 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {
 }
 
 void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
-	debugC(3, kDebugEngine, "getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
+	debugC(3, kDebugFight, "getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
 
 	int16 oldXpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
 
 	if (getXPLevel(_npcBuf[charId]._xp) > oldXpLevel) {
 		generateSound(15);
-		int16 hpGain = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]);
+		int16 hpGain = getRandom(20) + getRandom(_npcBuf[charId]._infoScore[4]); // "Stamina"
 		_npcBuf[charId]._hitPoints += hpGain;
 		_npcBuf[charId]._maxHP += hpGain;
+		// "Strength",
 		_npcBuf[charId]._infoScore[0] += getRandom(3) - 1;
+		// "Intelligence",
 		_npcBuf[charId]._infoScore[1] += getRandom(3) - 1;
+		// "Piety",
 		_npcBuf[charId]._infoScore[2] += getRandom(3) - 1;
+		// "Agility",
 		_npcBuf[charId]._infoScore[3] += getRandom(3) - 1;
+		// "Stamina",
 		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
 	}
 
@@ -1321,7 +1326,7 @@ void EfhEngine::addReactionText(int16 id) {
 }
 
 void EfhEngine::sub1C4CA(bool whiteFl) {
-	debugC(5, kDebugEngine, "sub1C4CA %s", whiteFl ? "True" : "False");
+	debugC(5, kDebugFight, "sub1C4CA %s", whiteFl ? "True" : "False");
 
 	int16 textPosY = 20;
 	for (uint counter = 0; counter < 5; ++counter) {
@@ -1412,7 +1417,7 @@ int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 }
 
 int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
-	debug("getCharacterScore %d %d", charId, itemId);
+	debugC(3, kDebugFight, "getCharacterScore %d %d", charId, itemId);
 
 	int16 totalScore = 0;
 	switch (_items[itemId]._range) {
@@ -1420,7 +1425,7 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 		totalScore = _npcBuf[charId]._passiveScore[5] + _npcBuf[charId]._passiveScore[3] + _npcBuf[charId]._passiveScore[4];
 		totalScore += _npcBuf[charId]._infoScore[0] / 5;
 		totalScore += _npcBuf[charId]._infoScore[2] * 2,
-			totalScore += _npcBuf[charId]._infoScore[6] / 5;
+		totalScore += _npcBuf[charId]._infoScore[6] / 5;
 		totalScore += 2 * _npcBuf[charId]._infoScore[5] / 5;
 		break;
 	case 1:
@@ -1488,12 +1493,9 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 
 	extraScore += _items[itemId].field_13;
 
-	int16 grandTotalScore = totalScore + extraScore;
-	if (grandTotalScore > 60)
-		grandTotalScore = 60;
+	int16 grandTotalScore = CLIP(totalScore + extraScore + 30, 5, 90);
 
-	int16 retVal = CLIP(grandTotalScore + 30, 5, 90);
-	return retVal;
+	return grandTotalScore;
 }
 
 bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
@@ -1501,13 +1503,13 @@ bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 
 	switch (_techDataArr[_techId][_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
 	case 1:
-		if ((itemId < 0x58 || itemId > 0x68) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x74 || itemId > 0x76) && (itemId != 0x8C))
-			return true;
-		return false;
+		if ((itemId >= 0x58 && itemId <= 0x68) || (itemId >= 0x86 && itemId <= 0x89) || (itemId >= 0x74 && itemId <= 0x76) || itemId == 0x8C)
+			return false;
+		return true;
 	case 2:
-		if ((itemId < 0x61 || itemId > 0x63) && (itemId < 0x74 || itemId > 0x76) && (itemId < 0x86 || itemId > 0x89) && (itemId < 0x5B || itemId > 0x5E) && (itemId < 0x66 || itemId > 0x68) && (itemId != 0x8C))
-			return true;
-		return false;
+		if ((itemId >= 0x61 && itemId <= 0x63) || (itemId >= 0x74 && itemId <= 0x76) || (itemId >= 0x86 && itemId <= 0x89) || itemId == 0x5B || itemId == 0x5E || itemId == 0x66 || itemId == 0x68 || itemId == 0x8C)
+			return false;
+		return true;
 	default:
 		return true;
 	}
@@ -1543,4 +1545,101 @@ bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
 	return false;
 }
 
+// The parameter isn't used in the original
+void EfhEngine::sub1BE9A(int16 monsterId) {
+	debug("sub1BE9A %d", monsterId);
+
+	// sub1BE9A - 1rst loop counter1_monsterId - Start
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
+		if (countMonsterGroupMembers(counter1))
+			continue;
+
+		for (uint counter2 = 0; counter2 < 9; ++counter2) {
+			_mapMonsters[_teamMonsterIdArray[counter1]]._hitPoints[counter2] = 0;
+			_teamMonsterEffects[counter1]._effect[counter2] = 0;
+			_teamMonsterEffects[counter1]._duration[counter2] = 0;
+		}
+
+		_teamMonsterIdArray[counter1] = -1;
+
+		// CHECKME: counter1 is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
+		// if the purpose is compact the array, it should be handle differently
+		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
+			for (uint var8 = 0; var8 < 9; ++var8) {
+				_teamMonsterEffects[counter1]._effect[var8] = _teamMonsterEffects[counter2]._effect[var8];
+				_teamMonsterEffects[counter1]._duration[var8] = _teamMonsterEffects[counter2]._duration[var8];
+			}
+			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
+		}
+	}
+	// sub1BE9A - 1rst loop counter1_monsterId - End
+
+	int16 teamMonsterId = -1;
+	for (uint counter1 = 0; counter1 < 5; ++counter1) {
+		if (_teamMonsterIdArray[counter1] == -1) {
+			teamMonsterId = counter1;
+			break;
+		}
+	}
+
+	if (teamMonsterId != -1) {
+		// sub1BE9A - loop var2 - Start
+		for (int var2 = 1; var2 < 3; ++var2) {
+			if (teamMonsterId >= 5)
+				break;
+
+			for (uint ctrMapMonsterId = 0; ctrMapMonsterId < 64; ++ctrMapMonsterId) {
+				if (_mapMonsters[ctrMapMonsterId]._fullPlaceId == 0xFF)
+					continue;
+
+				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
+						bool monsterActiveFound = false;
+						for (uint ctrSubId = 0; ctrSubId < 9; ++ctrSubId) {
+							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrSubId] > 0) {
+								monsterActiveFound = true;
+								break;
+							}
+						}
+
+						if (!monsterActiveFound)
+							continue;
+
+						if (computeMonsterGroupDistance(ctrMapMonsterId) > var2)
+							continue;
+
+						if (isMonsterAlreadyFighting(ctrMapMonsterId, teamMonsterId))
+							continue;
+
+						_teamMonsterIdArray[teamMonsterId] = ctrMapMonsterId;
+
+						// The original at this point was doing a loop on counter1, which is not a good idea as
+						// it was resetting the counter1 to 9 whatever its value before the loop.
+						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
+						for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+							_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 0;
+						}
+
+						if (++teamMonsterId >= 5)
+							break;
+					}
+				}
+			}
+		}
+		// sub1BE9A - loop var2 - End
+	}
+
+	if (teamMonsterId == -1 || teamMonsterId > 4)
+		return;
+
+	// sub1BE9A - last loop counter1_monsterId - Start
+	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
+		_teamMonsterIdArray[ctrTeamMonsterId] = -1;
+		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+			_teamMonsterEffects[ctrTeamMonsterId]._effect[ctrEffectId] = (int16)0x8000;
+		}
+	}
+	// sub1BE9A - last loop counter1_monsterId - End
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 91f034dfd51..a6e84154fe0 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -398,8 +398,14 @@ void EfhEngine::displayCharacterInformationOrSkills(int16 curMenuLine, int16 cha
 
 		displayStringAtTextPos(buffer);
 		setTextPos(163, textPosY);
-		displayStringAtTextPos(kSkillArray[_menuStatItemArr[counter]]);
-		buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_menuStatItemArr[counter]]);
+		int16 scoreId = _menuStatItemArr[counter];
+		displayStringAtTextPos(kSkillArray[scoreId]);
+		if (scoreId < 15)
+			buffer = Common::String::format("%d", _npcBuf[charId]._activeScore[_menuStatItemArr[counter]]);
+		else if (scoreId < 26)
+			buffer = Common::String::format("%d", _npcBuf[charId]._passiveScore[_menuStatItemArr[counter] - 15]);
+		else if (scoreId < 37)
+			buffer = Common::String::format("%d", _npcBuf[charId]._infoScore[_menuStatItemArr[counter] - 26]);
 		setTextPos(278, textPosY);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
@@ -468,7 +474,7 @@ void EfhEngine::prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLin
 }
 
 void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayWindowAndStatusMenu %d %d %d %d", charId, windowId, menuId, curMenuLine);
+	debugC(6, kDebugEngine, "displayWindowAndStatusMenu %d %d %d %d", charId, windowId, menuId, curMenuLine);
 
 	for (int counter = 0; counter < 2; ++counter) {
 		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);


Commit: 1f15de9b97551eab5b07c026126051abd0226c25
    https://github.com/scummvm/scummvm/commit/1f15de9b97551eab5b07c026126051abd0226c25
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Move getTeamMonsterAnimId to fight.cpp (and validate it), some renaming in script_parse

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ff852d02b41..dfffbc38f11 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -538,6 +538,7 @@ void EfhEngine::initMapMonsters() {
 
 void EfhEngine::loadMapArrays(int idx) {
 	debugC(6, kDebugEngine, "loadMapArrays %d", idx);
+	debug("TODO : rewrite the pre-loadign of data and loadMapArrays in order to avoid to lose info when changing map");
 
 	uint8 *mapSpecialTilePtr = &_mapArr[idx][2];
 
@@ -2344,28 +2345,6 @@ void EfhEngine::sub1CAB6(int16 charId) {
 	}
 }
 
-int16 EfhEngine::getTeamMonsterAnimId() {
-	debug("getTeamMonsterAnimId");
-
-	int16 retVal = 0xFF;
-	for (uint counter = 0; counter < 5; ++counter) {
-		int16 monsterId = _teamMonsterIdArray[counter];
-		if (monsterId == -1)
-			continue;
-
-		if (!checkMonsterMovementType(monsterId, false))
-			continue;
-
-		retVal = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
-		break;
-	}
-
-	if (retVal == 0xFF)
-		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._monsterRef]._animId;
-
-	return retVal;
-}
-
 int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	debugC(9, kDebugEngine, "countMonsterGroupMembers %d", monsterGroup);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b343fd88297..0eb8db566a6 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -363,7 +363,6 @@ private:
 	void redrawScreenForced();
 	int16 selectMonsterGroup();
 	void sub1CAB6(int16 charId);
-	int16 getTeamMonsterAnimId();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1D8C2(int16 charId, int16 damage);
 	int16 getXPLevel(int32 xp);
@@ -404,6 +403,7 @@ private:
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
 	void sub1BE9A(int16 monsterId);
+	int16 getTeamMonsterAnimId();
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
@@ -479,7 +479,7 @@ private:
 	// Script
 	uint8 *script_readNumberArray(uint8 *buffer, int16 destArraySize, int16 *destArray);
 	uint8 *script_getNumber(uint8 *srcBuffer, int16 *retBuf);
-	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
+	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool scriptExecuteFlag);
 
 	// Sound
 	void generateSound1(int arg0, int arg2, int duration);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 69f4b8d5b5b..5f01a494b14 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1642,4 +1642,26 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	// sub1BE9A - last loop counter1_monsterId - End
 }
 
+int16 EfhEngine::getTeamMonsterAnimId() {
+	debugC(6, kDebugFight, "getTeamMonsterAnimId");
+
+	int16 retVal = 0xFF;
+	for (uint counter = 0; counter < 5; ++counter) {
+		int16 monsterId = _teamMonsterIdArray[counter];
+		if (monsterId == -1)
+			continue;
+
+		if (!checkMonsterMovementType(monsterId, false))
+			continue;
+
+		retVal = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
+		break;
+	}
+
+	if (retVal == 0xFF)
+		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._monsterRef]._animId;
+
+	return retVal;
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index a6e84154fe0..c052aeb2a8b 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -893,6 +893,10 @@ void EfhEngine::tryToggleEquipped(int16 charId, int16 objectId, int16 windowId,
 		int16 curType = _items[itemId]._exclusiveType;
 		if (curType != 4) {
 			for (uint counter = 0; counter < 10; ++counter) {
+				if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF) {
+					warning("CHECKME : hack");
+					continue;
+				}
 				if (curType == _items[_npcBuf[charId]._inventory[counter]._ref]._exclusiveType)
 					unequipItem(charId, objectId, windowId, menuId, curMenuLine);
 			}
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 7d6a74e46f4..ca57a000d01 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -54,13 +54,14 @@ uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retBuf) {
 	return buffer;
 }
 
-int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag) {
-	debug("script_parse %s %d-%d %d-%d %s", stringBuffer.c_str(), posX, posY, maxX, maxY, flag ? "True" : "False");
+int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool scriptExecuteFlag) {
+	debug("script_parse stringBuffer %d-%d %d-%d %s", posX, posY, maxX, maxY, scriptExecuteFlag ? "True" : "False");
+	debugC(6, kDebugScript, "%s", stringBuffer.c_str());
 
 	bool doneFlag = false;
-	int16 var_F2 = -1;
+	bool noTextFlag = true;
 	int16 retVal = 0xFF;
-	int16 var_EE = 0xFF;
+	int16 joiningNpcId = 0xFF;
 	uint16 curLineNb = 0;
 	int16 numbLines = (1 + maxY - posY) / 9;
 	int16 width = maxX - posX;
@@ -74,28 +75,28 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 
 	while (!doneFlag) {
 		uint8 curChar = *buffer;
-		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) {
-			var_F2 = 0;
+		if (curChar != 0x5E && curChar != 0x20 && curChar != 0 && curChar != 0x7C) { // '^', ' ', NUL, '|'
+			noTextFlag = false;
 			nextWord[curWordPos++] = curChar;
 			++buffer;
 			continue;
 		}
 
-		if (curChar != 0x5E) {
+		if (curChar != 0x5E) { // '^'
 			if (curChar == 0)
 				doneFlag = true;
-			else if (curChar == 0x7C)
-				var_F2 = 0;
+			else if (curChar == 0x7C) // '|'
+				noTextFlag = false;
 
 			nextWord[curWordPos] = 0;
 			int16 widthNextWord = getStringWidth(nextWord);
 			int16 widthCurrentLine = spaceWidth + getStringWidth(curLine.c_str());
 
-			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) {
+			if (widthCurrentLine + widthNextWord > width || curChar == 0x7C) { // '|'
 				if (curLineNb >= numbLines) {
 					doneFlag = true;
 				} else {
-					if (var_F2 == 0)
+					if (!noTextFlag)
 						displayStringAtTextPos(curLine);
 
 					curLine = Common::String(nextWord) + " ";
@@ -111,7 +112,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			continue;
 		}
 
-		// At this point, curChar == 0x5E
+		// At this point, curChar == 0x5E '^'
 		++buffer;
 		int16 opCode = 0;
 		buffer = script_getNumber(buffer, &opCode);
@@ -122,7 +123,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x00:
 			// Enter room { full Place Id, posX, posY }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				if (_largeMapFlag) {
 					_largeMapFlag = false;
 					_techDataId_MapPosX = _mapPosX;
@@ -137,7 +138,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x01:
 			// Exit room { }
-			if (flag) {
+			if (scriptExecuteFlag) {
 				_largeMapFlag = true;
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
 				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
@@ -148,7 +149,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x02:
 			// Change map. { map number, posX, posY }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				writeTechAndMapFiles();
 				_oldMapPosX = _mapPosX = scriptNumberArray[1];
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
@@ -161,7 +162,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x03:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 rangeX = scriptNumberArray[2] - scriptNumberArray[0];
 				int16 rangeY = scriptNumberArray[3] - scriptNumberArray[1];
 
@@ -173,7 +174,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x04:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				_mapPosX = scriptNumberArray[0];
 				_mapPosY = scriptNumberArray[1];
 				_word2C880 = true;
@@ -182,7 +183,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x05:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 npcId = _teamCharId[scriptNumberArray[0]];
 				if (npcId != -1) {
 					int16 scoreId = scriptNumberArray[1];
@@ -193,7 +194,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x06:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 npcId = _teamCharId[scriptNumberArray[0]];
 				if (npcId != -1) {
 					int16 scoreId = scriptNumberArray[1];
@@ -202,19 +203,19 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			}
 			break;
 		case 0x07:
-			if (flag) {
+			if (scriptExecuteFlag) {
 				totalPartyKill();
 			}
 			break;
 		case 0x08:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag && scriptNumberArray[0] != -1) {
+			if (scriptExecuteFlag && scriptNumberArray[0] != -1) {
 				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
 			}
 			break;
 		case 0x09:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 npcId = _teamCharId[scriptNumberArray[0]];
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints += getRandom(scriptNumberArray[1]);
@@ -225,7 +226,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x0A:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 npcId = _teamCharId[scriptNumberArray[0]];
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints = _npcBuf[npcId]._maxHP;
@@ -234,7 +235,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x0B:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 npcId = _teamCharId[scriptNumberArray[0]];
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints -= getRandom(scriptNumberArray[1]);
@@ -245,7 +246,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x0C:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 scriptItemId = scriptNumberArray[0];
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
@@ -262,7 +263,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0D:
 			// Put item in inventory { objectId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 scriptObjectId = scriptNumberArray[0];
 				for (int counter = 0; counter < _teamSize; ++counter) {
 					if (giveItemTo(_teamCharId[counter], scriptObjectId, 0xFF))
@@ -272,7 +273,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x0E:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 scriptItemId = scriptNumberArray[0];
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
@@ -292,7 +293,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x0F:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				if (isNpcATeamMember(scriptNumberArray[0]))
 					retVal = scriptNumberArray[1];
 				else
@@ -301,17 +302,17 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x10:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag)
+			if (scriptExecuteFlag)
 				retVal = scriptNumberArray[0];
 
 			break;
 		case 0x11:
-			if (flag)
+			if (scriptExecuteFlag)
 				_unk2C8AA = 0;
 			break;
 		case 0x12:
 			// Disable special tile
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 tileId = findMapSpecialTileIndex(_mapPosX, _mapPosY);
 				if (tileId != -1)
 					_mapSpecialTile[tileId]._posX = 0xFF;
@@ -319,7 +320,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x13:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag && _largeMapFlag) {
+			if (scriptExecuteFlag && _largeMapFlag) {
 				_word2C87A = true;
 				loadPlacesFile(scriptNumberArray[0], false);
 				transitionMap(scriptNumberArray[1], scriptNumberArray[2]);
@@ -330,16 +331,16 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x14:
 			// Add character to team { charId }
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 scriptNpcId = scriptNumberArray[0];
 				if (!isNpcATeamMember(scriptNpcId))
-					var_EE = scriptNpcId;
+					joiningNpcId = scriptNpcId;
 				retVal = -1;
 			}
 			break;
 		case 0x15:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				_oldMapPosX = _mapPosX = scriptNumberArray[0];
 				_oldMapPosY = _mapPosY = scriptNumberArray[1];
 				_largeMapFlag = true;
@@ -348,7 +349,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x16:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 scriptNpcId = scriptNumberArray[0];
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
 				if (isNpcATeamMember(scriptNpcId)) {
@@ -363,14 +364,14 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x17:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
-				int16 var110 = scriptNumberArray[0];
-				displayAnimFrames(var110, true);
+			if (scriptExecuteFlag) {
+				int16 animId = scriptNumberArray[0];
+				displayAnimFrames(animId, true);
 			}
 			break;
 		case 0x18:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				bool found = false;
 				int16 scriptRandomItemId = getRandom(scriptNumberArray[1] - scriptNumberArray[0] + 1) + scriptNumberArray[0] - 1;
 				int16 counter;
@@ -408,7 +409,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x19:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				if (_largeMapFlag) {
 					_mapGameMap[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				} else {
@@ -418,7 +419,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x1A:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
 				if (tileId != -1) {
 					// Disable tile
@@ -428,7 +429,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x1B:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
 				if (tileId != -1) {
 					// Disable tile
@@ -440,20 +441,20 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x1C:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				_history[scriptNumberArray[0]] = 0xFF;
 			}
 			break;
 		case 0x1D:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				_history[scriptNumberArray[0]] = 0;
 			}
 			break;
 		case 0x1E:
 			// Dialog with condition { historyId, dialogId1, dialogId2 }
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
-			if (flag) {
+			if (scriptExecuteFlag) {
 				if (_history[scriptNumberArray[0]] == 0)
 					retVal = scriptNumberArray[2];
 				else
@@ -462,12 +463,12 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x1F:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
-			if (flag)
+			if (scriptExecuteFlag)
 				_unk2C8AA = scriptNumberArray[0];
 
 			break;
 		case 0x20:
-			if (flag) {
+			if (scriptExecuteFlag) {
 				handleWinSequence();
 				_system->quit();
 			}
@@ -476,14 +477,14 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		}
 	}
 
-	if (curLine.size() >= 0 && curLineNb < numbLines && var_F2 == 0)
+	if (curLine.size() >= 0 && curLineNb < numbLines && !noTextFlag)
 		displayStringAtTextPos(curLine);
 
-	if (var_EE != 0xFF) {
+	if (joiningNpcId != 0xFF) {
 		displayLowStatusScreen(true);
 		int16 teamSlot = handleCharacterJoining();
 		if (teamSlot > -1) {
-			_teamCharId[teamSlot] = var_EE;
+			_teamCharId[teamSlot] = joiningNpcId;
 		}
 		refreshTeamSize();
 	}


Commit: 878576311d4d918bc36f680d97f87fb50746ff48
    https://github.com/scummvm/scummvm/commit/878576311d4d918bc36f680d97f87fb50746ff48
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Change EFH_EFH_H_ to EFH_H based on sev's review. Fix a typo

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index dfffbc38f11..7e277b2b919 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -538,7 +538,7 @@ void EfhEngine::initMapMonsters() {
 
 void EfhEngine::loadMapArrays(int idx) {
 	debugC(6, kDebugEngine, "loadMapArrays %d", idx);
-	debug("TODO : rewrite the pre-loadign of data and loadMapArrays in order to avoid to lose info when changing map");
+	debug("TODO : rewrite the pre-loading of data and loadMapArrays in order to avoid to lose info when changing map");
 
 	uint8 *mapSpecialTilePtr = &_mapArr[idx][2];
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0eb8db566a6..34a4bd18194 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -19,8 +19,8 @@
  *
  */
 
-#ifndef EFH_EFH_H
-#define EFH_EFH_H
+#ifndef EFH_H
+#define EFH_H
 
 #include "engines/advancedDetector.h"
 


Commit: ba46f70a62b633ec6073f1b3ea40b19ef9ceffa2
    https://github.com/scummvm/scummvm/commit/ba46f70a62b633ec6073f1b3ea40b19ef9ceffa2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Change include order in EFH.H (sev's review)

Changed paths:
    engines/efh/efh.h


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 34a4bd18194..14d7df47ea1 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -22,13 +22,12 @@
 #ifndef EFH_H
 #define EFH_H
 
-#include "engines/advancedDetector.h"
-
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/events.h"
 #include "common/serializer.h"
 
+#include "engines/advancedDetector.h"
 #include "engines/engine.h"
 #include "graphics/surface.h"
 


Commit: cd888fec432e9d92bfbacfaa6117c3ea68894745
    https://github.com/scummvm/scummvm/commit/cd888fec432e9d92bfbacfaa6117c3ea68894745
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Fix bug in tryToggleEquipped()

Changed paths:
    engines/efh/menu.cpp


diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index c052aeb2a8b..df459bc0e59 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -893,12 +893,13 @@ void EfhEngine::tryToggleEquipped(int16 charId, int16 objectId, int16 windowId,
 		int16 curType = _items[itemId]._exclusiveType;
 		if (curType != 4) {
 			for (uint counter = 0; counter < 10; ++counter) {
-				if (_npcBuf[charId]._inventory[counter]._ref == 0x7FFF) {
+				int16 curItemId = _npcBuf[charId]._inventory[counter]._ref;
+				if (curItemId == 0x7FFF) {
 					warning("CHECKME : hack");
 					continue;
 				}
-				if (curType == _items[_npcBuf[charId]._inventory[counter]._ref]._exclusiveType)
-					unequipItem(charId, objectId, windowId, menuId, curMenuLine);
+				if (curType == _items[curItemId]._exclusiveType)
+					unequipItem(charId, counter, windowId, menuId, curMenuLine);
 			}
 		}
 


Commit: a976d28c1d3280e8fdcc910f7a75f587b33306cb
    https://github.com/scummvm/scummvm/commit/a976d28c1d3280e8fdcc910f7a75f587b33306cb
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Fix a bug in unequipItem(), fix a bug in displayString_3()

Changed paths:
    engines/efh/efh.h
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 14d7df47ea1..990da18be06 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -466,7 +466,7 @@ private:
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
 	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool refreshFl);
 	void displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayString_3(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void tryToggleEquipped(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index df459bc0e59..68b2f9ac8d7 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -485,8 +485,8 @@ void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 m
 	}
 }
 
-int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), animFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+int16 EfhEngine::displayString_3(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), delayFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
 
@@ -496,13 +496,16 @@ int16 EfhEngine::displayString_3(Common::String str, bool animFl, int16 charId,
 
 		if (counter == 0) {
 			script_parse(str, 28, 122, 105, 166, false);
-			displayFctFullScreen();
 		} else {
 			retVal = script_parse(str, 28, 122, 105, 166, true);
 		}
+		// The original is only calling displayFctFullScreen when counter = 0, but it's related to the screen buffers which aren't used in ScummVM implementation
+		// Calling it once fix the almost unreadable text displayed otherwise.
+		// Maybe a refactoring to remove those 0..1 loop would be useful at some point.
+		displayFctFullScreen();
 	}
 
-	if (animFl) {
+	if (delayFl) {
 		getLastCharAfterAnimCount(_guessAnimationAmount);
 		displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 	}
@@ -874,7 +877,7 @@ void EfhEngine::unequipItem(int16 charId, int16 objectId, int16 windowId, int16
 
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 
-	if (isItemCursed(itemId)) {
+	if (!isItemCursed(itemId)) {
 		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
 	} else {
 		// Original message. "Cursed item can't be unequipped" would make more sense, imho


Commit: d7730488695a8de46b4a9d7dc4d28321cf8af320
    https://github.com/scummvm/scummvm/commit/d7730488695a8de46b4a9d7dc4d28321cf8af320
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Fix several issues in handleStatusMenu() / Trade

Changed paths:
    engines/efh/menu.cpp


diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 68b2f9ac8d7..b699ec9f454 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -733,58 +733,61 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
 				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
-			} else if (hasObjectEquipped(charId, objectId)) {
+				break;
+			}
+
+			if (hasObjectEquipped(charId, objectId)) {
 				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
+			}
+			
+			if (validationFl) {
+				bool givenFl;
+				int16 destCharId;
+				do {
+					if (_teamCharId[2] != -1) {
+						displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
+						destCharId = selectOtherCharFromTeam();
+						var2 = false;
+					} else if (_teamCharId[1] == -1) {
+						destCharId = 0x1A;
+						var2 = false;
+					} else {
+						var2 = true;
+						if (_teamCharId[0] == charId)
+							destCharId = 1;
+						else
+							destCharId = 0;
+					}
 
-				if (validationFl) {
-					bool givenFl;
-					int16 destCharId;
-					do {
-						if (_teamCharId[2] != -1) {
-							displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
-							destCharId = selectOtherCharFromTeam();
-							var2 = false;
-						} else if (_teamCharId[1]) {
-							destCharId = 0x1A;
-							var2 = false;
-						} else {
-							var2 = true;
-							if (_teamCharId[0] == charId)
-								destCharId = 1;
-							else
-								destCharId = 0;
-						}
-
-						if (destCharId != 0x1A && destCharId != 0x1B) {
-							givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
-							if (!givenFl) {
-								displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
-								getLastCharAfterAnimCount(_guessAnimationAmount);
-							}
-						} else {
-							if (destCharId == 0x1A) {
-								displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
-								getLastCharAfterAnimCount(_guessAnimationAmount);
-								destCharId = 0x1B;
-							}
-							givenFl = false;
+					if (destCharId != 0x1A && destCharId != 0x1B) {
+						givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
+						if (!givenFl) {
+							displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
+							getLastCharAfterAnimCount(_guessAnimationAmount);
 						}
-					} while (!givenFl && !var2 && destCharId != 0x1B);
-
-					if (givenFl) {
-						removeObject(charId, objectId);
-						if (gameMode == 2) {
-							restoreAnimImageSetId();
-							_statusMenuActive = false;
-							return 0x7D00;
+					} else {
+						if (destCharId == 0x1A) {
+							displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
+							getLastCharAfterAnimCount(_guessAnimationAmount);
+							destCharId = 0x1B;
 						}
+						givenFl = false;
 					}
+				} while (!givenFl && !var2 && destCharId != 0x1B);
 
-					displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
+				if (givenFl) {
+					removeObject(charId, objectId);
+					if (gameMode == 2) {
+						restoreAnimImageSetId();
+						_statusMenuActive = false;
+						return 0x7D00;
+					}
 				}
+
+				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 			}
 			break;
 		case 4:


Commit: 5bc5534ca343164e13a86bd4324032474cc871c5
    https://github.com/scummvm/scummvm/commit/5bc5534ca343164e13a86bd4324032474cc871c5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Make menu code slightly more readable by using an enum

Changed paths:
    engines/efh/constants.h
    engines/efh/menu.cpp


diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index c08ade3e690..46b3e2ed6db 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -25,6 +25,19 @@
 #include "common/scummsys.h"
 
 namespace Efh {
+enum EfhMenuItems {
+	kEfhMenuEquip = 0,
+	kEfhMenuUse = 1,
+	kEfhMenuGive = 2,
+	kEfhMenuTrade = 3,
+	kEfhMenuDrop = 4,
+	kEfhMenuInfo = 5,
+	kEfhMenuPassive = 6,
+	kEfhMenuActive = 7,
+	kEfhMenuLeave = 8,
+	kEfhMenuInvalid = 9
+};
+
 struct Font {
 	uint8 _lines[8];
 };
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index b699ec9f454..56c487fdc39 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -241,15 +241,15 @@ void EfhEngine::prepareStatusRightWindowIndexes(int16 menuId, int16 charId) {
 	_menuItemCounter = 0;
 
 	switch (menuId) {
-	case 5:
+	case kEfhMenuInfo:
 		minId = 26;
 		maxId = 36;
 		break;
-	case 6:
+	case kEfhMenuPassive:
 		minId = 15;
 		maxId = 25;
 		break;
-	case 7:
+	case kEfhMenuActive:
 		minId = 0;
 		maxId = 14;
 		break;
@@ -419,40 +419,40 @@ void EfhEngine::displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16
 	displayCenteredString("(ESCape Aborts)", 144, 310, 175);
 	_textColor = 0x0E;
 	switch (menuId) {
-	case 0:
+	case kEfhMenuEquip:
 		displayCenteredString("Select Item to Equip", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
-	case 1:
+	case kEfhMenuUse:
 		displayCenteredString("Select Item to Use", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
-	case 2:
+	case kEfhMenuGive:
 		displayCenteredString("Select Item to Give", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
-	case 3:
+	case kEfhMenuTrade:
 		displayCenteredString("Select Item to Trade", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
-	case 4:
+	case kEfhMenuDrop:
 		displayCenteredString("Select Item to Drop", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
-	case 5:
+	case kEfhMenuInfo:
 		displayCenteredString("Character Information", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
-	case 6:
+	case kEfhMenuPassive:
 		displayCenteredString("Passive Skills", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
-	case 7:
+	case kEfhMenuActive:
 		displayCenteredString("Active Skills", 144, 310, 15);
 		displayCharacterInformationOrSkills(curMenuLine, npcId);
 		break;
-	case 8:
-	case 9:
+	case kEfhMenuLeave:
+	case kEfhMenuInvalid:
 		displayCenteredString("Character Summary", 144, 310, 15);
 		displayCharacterSummary(curMenuLine, npcId);
 		break;
@@ -516,11 +516,11 @@ int16 EfhEngine::displayString_3(Common::String str, bool delayFl, int16 charId,
 int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 	debug("handleStatusMenu %d %d", gameMode, charId);
 
-	int16 menuId = 9;
+	int16 menuId = kEfhMenuInvalid;
 	int16 selectedLine = -1;
 	int16 windowId = -1;
 	int16 curMenuLine = -1;
-	bool var10 = false;
+	bool selectionDoneFl = false;
 	bool var2 = false;
 
 	saveAnimImageSetId();
@@ -534,50 +534,50 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		if (windowId != -1)
 			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 		else
-			windowId = 0;
+			windowId = kEfhMenuEquip;
 
 		do {
 			Common::KeyCode var19 = handleAndMapInput(false);
 			if (_menuDepth == 0) {
 				switch (var19) {
 				case Common::KEYCODE_ESCAPE:
-					windowId = 8;
+					windowId = kEfhMenuLeave;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_a:
-					windowId = 7;
+					windowId = kEfhMenuActive;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_d:
-					windowId = 4;
+					windowId = kEfhMenuDrop;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_e:
-					windowId = 0;
+					windowId = kEfhMenuEquip;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_g:
-					windowId = 2;
+					windowId = kEfhMenuGive;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_i:
-					windowId = 5;
+					windowId = kEfhMenuInfo;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_l:
-					windowId = 8;
+					windowId = kEfhMenuLeave;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_p:
-					windowId = 6;
+					windowId = kEfhMenuPassive;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_t:
-					windowId = 3;
+					windowId = kEfhMenuTrade;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				case Common::KEYCODE_u:
-					windowId = 1;
+					windowId = kEfhMenuUse;
 					var19 = Common::KEYCODE_RETURN;
 					break;
 				// case 0xFB: Joystick button 2
@@ -601,8 +601,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				// case 0xFA: Joystick button 1
 				if (_menuDepth == 0) {
 					menuId = windowId;
-					if (menuId > 7)
-						var10 = true;
+					if (menuId >= kEfhMenuLeave)
+						selectionDoneFl = true;
 					else {
 						_menuDepth = 1;
 						curMenuLine = 0;
@@ -611,18 +611,18 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					if (_menuItemCounter == 0) {
 						_menuDepth = 0;
 						curMenuLine = -1;
-						menuId = 9;
+						menuId = kEfhMenuInvalid;
 						prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 					} else {
 						selectedLine = curMenuLine;
-						var10 = true;
+						selectionDoneFl = true;
 					}
 				}
 				break;
 			case Common::KEYCODE_ESCAPE:
 				_menuDepth = 0;
 				curMenuLine = -1;
-				menuId = 9;
+				menuId = kEfhMenuInvalid;
 				prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 				break;
 			case Common::KEYCODE_2:
@@ -634,8 +634,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			case Common::KEYCODE_KP6:
 				// Original checks joystick axis: case 0xCC, 0xCF
 				if (_menuDepth == 0) {
-					if (++windowId > 8)
-						windowId = 0;
+					if (++windowId > kEfhMenuLeave)
+						windowId = kEfhMenuEquip;
 				} else if (_menuDepth == 1) {
 					if (_menuItemCounter != 0) {
 						++curMenuLine;
@@ -653,8 +653,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			case Common::KEYCODE_KP8:
 				// Original checks joystick axis: case 0xC7, 0xCA
 				if (_menuDepth == 0) {
-					if (--windowId < 0)
-						windowId = 8;
+					if (--windowId < kEfhMenuEquip)
+						windowId = kEfhMenuLeave;
 				} else if (_menuDepth == 1) {
 					if (_menuItemCounter != 0) {
 						--curMenuLine;
@@ -669,14 +669,14 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 			prepareStatusMenu(windowId, menuId, curMenuLine, charId, true);
 
-		} while (!var10);
+		} while (!selectionDoneFl); // Loop until a menu entry is confirmed by the user by pressing the enter key 
 
 		bool validationFl = true;
 
 		int16 objectId;
 		int16 itemId;
 		switch (menuId) {
-		case 0:
+		case kEfhMenuEquip:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref; // CHECKME: Useless?
 			tryToggleEquipped(charId, objectId, windowId, menuId, curMenuLine);
@@ -686,7 +686,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				return 0x7D00;
 			}
 			break;
-		case 1:
+		case kEfhMenuUse:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (gameMode == 2) {
@@ -702,7 +702,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 
 			useObject(charId, objectId, windowId, menuId, curMenuLine, 2);
 			break;
-		case 2:
+		case kEfhMenuGive:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
@@ -728,7 +728,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 
 			break;
-		case 3:
+		case kEfhMenuTrade:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
@@ -790,7 +790,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 			}
 			break;
-		case 4:
+		case kEfhMenuDrop:
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
@@ -817,7 +817,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				}
 			}
 			break;
-		case 5:
+		case kEfhMenuInfo:
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
@@ -829,7 +829,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				}
 			}
 			break;
-		case 6: // Identical to case 5?
+		case kEfhMenuPassive:
+			// Identical to case 5?
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
@@ -841,7 +842,8 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				}
 			}
 			break;
-		case 7: // Identical to case 5?
+		case kEfhMenuActive:
+			// Identical to case 5?
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
@@ -857,15 +859,15 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			break;
 		}
 
-		if (menuId != 8) {
-			var10 = false;
+		if (menuId != kEfhMenuLeave) {
+			selectionDoneFl = false;
 			_menuDepth = 0;
-			menuId = 9;
+			menuId = kEfhMenuInvalid;
 			selectedLine = -1;
 			curMenuLine = -1;
 		}
 
-		if (menuId == 8) {
+		if (menuId == kEfhMenuLeave) {
 			restoreAnimImageSetId();
 			_statusMenuActive = false;
 			return 0x7FFF;


Commit: 751f2859ea6196052730ae6a604db9d607a64936
    https://github.com/scummvm/scummvm/commit/751f2859ea6196052730ae6a604db9d607a64936
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Fix a bug in giveItemTo()

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 7e277b2b919..be8cdee3fde 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -996,9 +996,9 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 fromCharId) {
 			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _items[objectId]._defense;
 			_npcBuf[charId]._inventory[newObjectId]._stat1 = _items[objectId]._uses;
 		} else {
-			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[fromCharId]._inventory[newObjectId]._ref;
-			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _npcBuf[fromCharId]._inventory[newObjectId]._curHitPoints;
-			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[fromCharId]._inventory[newObjectId].getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
+			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[fromCharId]._inventory[objectId]._ref;
+			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _npcBuf[fromCharId]._inventory[objectId]._curHitPoints;
+			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[fromCharId]._inventory[objectId].getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
 		}
 
 		return true;


Commit: dad84346eb4341d8f85535f813851db6d9f1b089
    https://github.com/scummvm/scummvm/commit/dad84346eb4341d8f85535f813851db6d9f1b089
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:45+01:00

Commit Message:
EFH: Validate handleStatusMenu, remove duplicate code

Changed paths:
    engines/efh/menu.cpp


diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 56c487fdc39..4290a021fee 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -514,7 +514,7 @@ int16 EfhEngine::displayString_3(Common::String str, bool delayFl, int16 charId,
 }
 
 int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
-	debug("handleStatusMenu %d %d", gameMode, charId);
+	debugC(3, kDebugEngine, "handleStatusMenu %d %d", gameMode, charId);
 
 	int16 menuId = kEfhMenuInvalid;
 	int16 selectedLine = -1;
@@ -718,8 +718,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						displayString_3("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
 					} else {
 						removeObject(charId, objectId);
-						int16 var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1);
-						if (var8 != 0) {
+						if (sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1)) {
 							_statusMenuActive = false;
 							return -1;
 						}
@@ -809,8 +808,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						return 0x7D00;
 					}
 
-					bool var8 = sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1);
-					if (var8) {
+					if (sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1)) {
 						_statusMenuActive = false;
 						return -1;
 					}
@@ -818,41 +816,14 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			}
 			break;
 		case kEfhMenuInfo:
-			objectId = _menuStatItemArr[selectedLine];
-			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
-			}
-			break;
 		case kEfhMenuPassive:
-			// Identical to case 5?
-			objectId = _menuStatItemArr[selectedLine];
-			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
-			}
-			break;
 		case kEfhMenuActive:
-			// Identical to case 5?
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else {
-				bool var8 = sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1);
-				if (var8) {
-					_statusMenuActive = false;
-					return -1;
-				}
+			} else if (sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1)) {
+				_statusMenuActive = false;
+				return -1;
 			}
 			break;
 		default:


Commit: f5246243828e4aa49af1639667a6eca4d73b2a58
    https://github.com/scummvm/scummvm/commit/f5246243828e4aa49af1639667a6eca4d73b2a58
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Rename displayString_3 to displayStringInSmallWindowWithBorder

Changed paths:
    engines/efh/efh.h
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 990da18be06..0466bcfaec0 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -466,7 +466,7 @@ private:
 	void displayStatusMenuActions(int16 menuId, int16 curMenuLine, int16 npcId);
 	void prepareStatusMenu(int16 windowId, int16 menuId, int16 curMenuLine, int16 charId, bool refreshFl);
 	void displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 displayString_3(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
+	int16 displayStringInSmallWindowWithBorder(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine);
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void tryToggleEquipped(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 4290a021fee..d25ae4f16d3 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -485,8 +485,8 @@ void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 m
 	}
 }
 
-int16 EfhEngine::displayString_3(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayString_3 %s %s %d %d %d %d", str.c_str(), delayFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+int16 EfhEngine::displayStringInSmallWindowWithBorder(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
+	debug("displayStringInSmallWindowWithBorder %s %s %d %d %d %d", str.c_str(), delayFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
 
@@ -706,16 +706,16 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 			} else if (hasObjectEquipped(charId, objectId)) {
-				displayString_3("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("Item is Equipped!  Give anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
 
 				if (validationFl) {
 					if (gameMode == 2) {
-						displayString_3("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
+						displayStringInSmallWindowWithBorder("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
 					} else {
 						removeObject(charId, objectId);
 						if (sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1)) {
@@ -731,12 +731,12 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 				break;
 			}
 
 			if (hasObjectEquipped(charId, objectId)) {
-				displayString_3("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("Item is Equipped!  Trade anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
@@ -747,7 +747,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				int16 destCharId;
 				do {
 					if (_teamCharId[2] != -1) {
-						displayString_3("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
+						displayStringInSmallWindowWithBorder("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
 						destCharId = selectOtherCharFromTeam();
 						var2 = false;
 					} else if (_teamCharId[1] == -1) {
@@ -764,12 +764,12 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 					if (destCharId != 0x1A && destCharId != 0x1B) {
 						givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
 						if (!givenFl) {
-							displayString_3("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
+							displayStringInSmallWindowWithBorder("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
 							getLastCharAfterAnimCount(_guessAnimationAmount);
 						}
 					} else {
 						if (destCharId == 0x1A) {
-							displayString_3("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
+							displayStringInSmallWindowWithBorder("No one to trade with!", false, charId, windowId, menuId, curMenuLine);
 							getLastCharAfterAnimCount(_guessAnimationAmount);
 							destCharId = 0x1B;
 						}
@@ -793,9 +793,9 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _menuStatItemArr[selectedLine];
 			itemId = _npcBuf[charId]._inventory[objectId]._ref;
 			if (hasObjectEquipped(charId, objectId) && isItemCursed(itemId)) {
-				displayString_3("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("The item is cursed!  IT IS EVIL!!!!!!!!", true, charId, windowId, menuId, curMenuLine);
 			} else if (hasObjectEquipped(charId, objectId)) {
-				displayString_3("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("Item Is Equipped!  Drop Anyway?", false, charId, windowId, menuId, curMenuLine);
 				if (!getValidationFromUser())
 					validationFl = false;
 				displayWindowAndStatusMenu(charId, windowId, menuId, curMenuLine);
@@ -820,7 +820,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 		case kEfhMenuActive:
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
-				displayString_3("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
 			} else if (sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1)) {
 				_statusMenuActive = false;
 				return -1;
@@ -857,7 +857,7 @@ void EfhEngine::unequipItem(int16 charId, int16 objectId, int16 windowId, int16
 		_npcBuf[charId]._inventory[objectId]._stat1 &= 0x7F;
 	} else {
 		// Original message. "Cursed item can't be unequipped" would make more sense, imho
-		displayString_3("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
+		displayStringInSmallWindowWithBorder("Cursed Item Already Equipped!", true, charId, windowId, menuId, curMenuLine);
 	}
 }
 
@@ -901,7 +901,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	switch (_items[itemId]._specialEffect - 1) {
 	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
 		if (argA == 2) {
-			displayString_3("The item emits a low droning hum...", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("The item emits a low droning hum...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 victims = 0;
 			_messageToBePrinted += "  The item emits a low droning hum...";
@@ -940,7 +940,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
 		if (argA == 2) {
-			displayString_3("The item grows very cold for a moment...", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("The item grows very cold for a moment...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The item emits a blue beam...";
 			int16 victim = 0;
@@ -981,7 +981,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 2:
 		if (argA == 2) {
-			displayString_3("A serene feeling passes through the air...", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("A serene feeling passes through the air...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
 			_unk2C8AA = 0;
@@ -991,7 +991,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 4: // "Unholy Sinwave", "Holy Water"
 		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
 			if (getRandom(100) < 50) {
@@ -1015,7 +1015,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
 		if (argA == 2) {
-			displayString_3("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			if (getRandom(100) < 50) {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
@@ -1036,7 +1036,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
 		if (argA == 2) {
-			displayString_3("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
 			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
@@ -1046,7 +1046,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 14: { // "Feathered Cap"
 		int16 varAA;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			varAA = selectOtherCharFromTeam();
 		} else {
 			varAA = teamMonsterId;
@@ -1055,7 +1055,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (varAA != 0x1B) {
 			buffer1 = "  The magic makes the user as quick and agile as a bird!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -1069,7 +1069,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 15: { // "Regal Crown"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
 			teamCharId = teamMonsterId;
@@ -1078,7 +1078,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (teamCharId != 0x1B) {
 			buffer1 = "  The magic makes the user invisible!";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
@@ -1099,7 +1099,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1108,7 +1108,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1116,7 +1116,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1134,7 +1134,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1143,7 +1143,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1151,7 +1151,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
 				if (argA == 2) {
-					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 					retVal = true;
@@ -1163,7 +1163,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	} break;
 	case 18:
 		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
@@ -1182,7 +1182,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 19: // "Junk"
 		buffer1 = "  * The item breaks!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 		}
@@ -1218,7 +1218,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 		buffer1 += "'";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1229,7 +1229,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 24: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
 			teamCharId = teamMonsterId;
@@ -1247,7 +1247,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1259,7 +1259,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 25: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
 			teamCharId = teamMonsterId;
@@ -1277,7 +1277,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
 
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1289,7 +1289,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 26: // "Black Sphere"
 		buffer1 = "The entire party collapses, dead!!!";
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1300,7 +1300,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 27: { // "Magic Pyramid", "Razor Blade"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
 			teamCharId = teamMonsterId;
@@ -1310,7 +1310,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
 			if (argA == 2) {
-				displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 				retVal = true;
@@ -1321,7 +1321,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	} break;
 	case 28: // "Bugle"
 		if (argA == 2) {
-			displayString_3("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
@@ -1340,7 +1340,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
 			teamCharId = teamMonsterId;
@@ -1359,7 +1359,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1370,7 +1370,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	case 30: {
 		int16 teamCharId;
 		if (argA == 2) {
-			displayString_3("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
 			teamCharId = teamMonsterId;
@@ -1389,7 +1389,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 
 		if (argA == 2) {
-			displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
 			retVal = true;
@@ -1421,7 +1421,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				buffer1 = "  * The item breaks!";
 				if (argA == 2) {
 					getLastCharAfterAnimCount(_guessAnimationAmount);
-					displayString_3(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
+					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
 				}


Commit: a5407440f47d8a3f7652c59faec9e74abce257e2
    https://github.com/scummvm/scummvm/commit/a5407440f47d8a3f7652c59faec9e74abce257e2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Validate one more function, renaming

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0466bcfaec0..898ae78ec38 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -154,7 +154,7 @@ struct NPCStruct {
 	uint8 field_6B;
 	uint8 field_6C;
 	uint8 field_6D;
-	uint8 _unkItemId;
+	uint8 _defaultDefenseItemId;
 	uint8 field_6F;
 	uint8 field_70;
 	uint8 field_71;
@@ -400,7 +400,7 @@ private:
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
-	bool hasAdequateDefense_2(int16 charId, uint8 attackType);
+	bool hasAdequateDefenseNPC(int16 charId, uint8 attackType);
 	void sub1BE9A(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 5f01a494b14..75394a3300d 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -203,7 +203,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 									++var62;
 
-									if (hasAdequateDefense_2(_teamCharId[var7E], _items[monsterWeaponItemId]._attackType))
+									if (hasAdequateDefenseNPC(_teamCharId[var7E], _items[monsterWeaponItemId]._attackType))
 										continue;
 
 									int16 var7C = getRandom(_items[monsterWeaponItemId]._damage);
@@ -1526,10 +1526,10 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	return _items[itemId]._field17_attackTypeDefense == attackType;
 }
 
-bool EfhEngine::hasAdequateDefense_2(int16 charId, uint8 attackType) {
-	debug("hasAdequateDefense_2 %d %d", charId, attackType);
+bool EfhEngine::hasAdequateDefenseNPC(int16 charId, uint8 attackType) {
+	debugC(3, kDebugFight, "hasAdequateDefenseNPC %d %d", charId, attackType);
 
-	int16 itemId = _npcBuf[charId]._unkItemId;
+	int16 itemId = _npcBuf[charId]._defaultDefenseItemId;
 
 	if (_items[itemId]._specialEffect == 0 && _items[itemId]._field17_attackTypeDefense == attackType)
 		return true;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index dfc475f313f..1c53d35736e 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -295,7 +295,7 @@ void EfhEngine::loadNPCS() {
 		_npcBuf[i].field_6B = f.readByte();
 		_npcBuf[i].field_6C = f.readByte();
 		_npcBuf[i].field_6D = f.readByte();
-		_npcBuf[i]._unkItemId = f.readByte();
+		_npcBuf[i]._defaultDefenseItemId = f.readByte();
 		_npcBuf[i].field_6F = f.readByte();
 		_npcBuf[i].field_70 = f.readByte();
 		_npcBuf[i].field_71 = f.readByte();
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index db1a4b2f746..7efea57cc86 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -114,7 +114,7 @@ void NPCStruct::init() {
 	field_6B = 0;
 	field_6C = 0;
 	field_6D = 0;
-	_unkItemId = 0;
+	_defaultDefenseItemId = 0;
 	field_6F = 0;
 	field_70 = 0;
 	field_71 = 0;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 00b9ea278f5..ed64a0c5a23 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -198,7 +198,7 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		s.syncAsByte(_npcBuf[i].field_6B);
 		s.syncAsByte(_npcBuf[i].field_6C);
 		s.syncAsByte(_npcBuf[i].field_6D);
-		s.syncAsByte(_npcBuf[i]._unkItemId);
+		s.syncAsByte(_npcBuf[i]._defaultDefenseItemId);
 		s.syncAsByte(_npcBuf[i].field_6F);
 		s.syncAsByte(_npcBuf[i].field_70);
 		s.syncAsByte(_npcBuf[i].field_71);


Commit: a2e496f783fb2b9db54074523d9ffcb2eff2587d
    https://github.com/scummvm/scummvm/commit/a2e496f783fb2b9db54074523d9ffcb2eff2587d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Add a new enum, validate some more functions, some renaming

Changed paths:
    engines/efh/constants.h
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 46b3e2ed6db..2cc2f3916a3 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -38,6 +38,16 @@ enum EfhMenuItems {
 	kEfhMenuInvalid = 9
 };
 
+enum EfhReactionType {
+	kEfhReactionReels = 0,
+	kEfhReactionCriesOut = 1,
+	kEfhReactionFalters = 2,
+	kEfhReactionWinces = 3,
+	kEfhReactionScreams = 4,
+	kEfhReactionChortles = 5,
+	kEfhReactionLaughs = 6
+};
+
 struct Font {
 	uint8 _lines[8];
 };
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 898ae78ec38..08faff8d3c7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -396,7 +396,7 @@ private:
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void addReactionText(int16 id);
 	void sub1C4CA(bool WhiteFl);
-	int16 sub1DEC8(int16 groupNumber);
+	int16 getWeakestMobster(int16 groupNumber);
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 75394a3300d..727169e5420 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -272,20 +272,20 @@ bool EfhEngine::handleFight(int16 monsterId) {
 									// handleFight - Add reaction text - start
 									if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
 										if (_npcBuf[_teamCharId[var7E]]._hitPoints - 5 <= originalDamage) {
-											addReactionText(0);
+											addReactionText(kEfhReactionReels);
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 8) {
-											addReactionText(1);
+											addReactionText(kEfhReactionCriesOut);
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 4) {
-											addReactionText(2);
+											addReactionText(kEfhReactionFalters);
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
-											addReactionText(3);
+											addReactionText(kEfhReactionWinces);
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
 											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
-											addReactionText(4);
+											addReactionText(kEfhReactionScreams);
 										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
-											addReactionText(5);
+											addReactionText(kEfhReactionChortles);
 										} else if (originalDamage == 0 && getRandom(100) < 35) {
-											addReactionText(6);
+											addReactionText(kEfhReactionLaughs);
 										}
 									}
 									// handleFight - Add reaction text - end
@@ -439,7 +439,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	int16 var54;
 	int16 teamMemberId;
 	if (_items[teamCharItemId]._range < 3) {
-		teamMemberId = sub1DEC8(monsterGroupNumber);
+		teamMemberId = getWeakestMobster(monsterGroupNumber);
 		var54 = teamMemberId + 1;
 	} else {
 		teamMemberId = 0;
@@ -551,20 +551,20 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add reaction text - Start
 						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
 							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] - 5 <= originalDamage) {
-								addReactionText(0);
+								addReactionText(kEfhReactionReels);
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 8) {
-								addReactionText(1);
+								addReactionText(kEfhReactionCriesOut);
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 4) {
-								addReactionText(2);
+								addReactionText(kEfhReactionFalters);
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 2) {
-								addReactionText(3);
+								addReactionText(kEfhReactionWinces);
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 3) {
 								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
-								addReactionText(4);
+								addReactionText(kEfhReactionScreams);
 							} else if (hitPointsBefore / 8 >= originalDamage) {
-								addReactionText(5);
+								addReactionText(kEfhReactionChortles);
 							} else if (originalDamage == 0 && getRandom(100) < 35) {
-								addReactionText(6);
+								addReactionText(kEfhReactionLaughs);
 							}
 						}
 						// Action A - Add reaction text - End
@@ -1210,12 +1210,12 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 }
 
 void EfhEngine::addReactionText(int16 id) {
-	debug("addReactionText %d", id);
+	debugC(3, kDebugFight, "addReactionText %d", id);
 
 	int16 rand3 = getRandom(3);
 
 	switch (id) {
-	case 0:
+	case kEfhReactionReels:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s reels from the blow!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1230,7 +1230,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 1:
+	case kEfhReactionCriesOut:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s cries out in agony!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1245,7 +1245,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 2:
+	case kEfhReactionFalters:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s is staggering!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1260,7 +1260,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 3:
+	case kEfhReactionWinces:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s winces from the pain!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1275,7 +1275,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 4:
+	case kEfhReactionScreams:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s screams!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1290,7 +1290,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 5:
+	case kEfhReactionChortles:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s chortles!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1305,7 +1305,7 @@ void EfhEngine::addReactionText(int16 id) {
 			break;
 		}
 		break;
-	case 6:
+	case kEfhReactionLaughs:
 		switch (rand3) {
 		case 1:
 			_messageToBePrinted += Common::String::format("  %s%s laughs at the feeble attack!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -1386,10 +1386,10 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 	}
 }
 
-int16 EfhEngine::sub1DEC8(int16 groupNumber) {
-	debug("sub1DEC8 %d", groupNumber);
+int16 EfhEngine::getWeakestMobster(int16 groupNumber) {
+	debugC(3, kDebugFight, "getWeakestMobster %d", groupNumber);
 
-	int16 var4 = -1;
+	int16 weakestMobsterId = -1;
 	int16 monsterId = _teamMonsterIdArray[groupNumber];
 
 	if (monsterId == -1)
@@ -1397,23 +1397,24 @@ int16 EfhEngine::sub1DEC8(int16 groupNumber) {
 
 	for (uint counter = 0; counter < 9; ++counter) {
 		if (isMonsterActive(groupNumber, counter)) {
-			var4 = counter;
+			weakestMobsterId = counter;
 			break;
 		}
 	}
 
-	for (int16 counter = var4 + 1; counter < 9; ++counter) {
+	for (int16 counter = weakestMobsterId + 1; counter < 9; ++counter) {
 		if (!isMonsterActive(groupNumber, counter))
 			continue;
 
-		if (_mapMonsters[monsterId]._hitPoints[var4] > _mapMonsters[monsterId]._hitPoints[counter])
-			var4 = counter;
+		if (_mapMonsters[monsterId]._hitPoints[weakestMobsterId] > _mapMonsters[monsterId]._hitPoints[counter])
+			weakestMobsterId = counter;
 	}
 
-	if (_mapMonsters[monsterId]._hitPoints[var4] <= 0)
+	// Useless check, as the
+	if (_mapMonsters[monsterId]._hitPoints[weakestMobsterId] <= 0)
 		return -1;
 
-	return var4;
+	return weakestMobsterId;
 }
 
 int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
@@ -1499,24 +1500,25 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 }
 
 bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
-	debug("checkSpecialItemsOnCurrentPlace %d", itemId);
+	debugC(3, kDebugFight, "checkSpecialItemsOnCurrentPlace %d", itemId);
 
+	bool retVal = true;
 	switch (_techDataArr[_techId][_techDataId_MapPosX * 64 + _techDataId_MapPosY]) {
 	case 1:
 		if ((itemId >= 0x58 && itemId <= 0x68) || (itemId >= 0x86 && itemId <= 0x89) || (itemId >= 0x74 && itemId <= 0x76) || itemId == 0x8C)
-			return false;
-		return true;
+			retVal = false;
 	case 2:
 		if ((itemId >= 0x61 && itemId <= 0x63) || (itemId >= 0x74 && itemId <= 0x76) || (itemId >= 0x86 && itemId <= 0x89) || itemId == 0x5B || itemId == 0x5E || itemId == 0x66 || itemId == 0x68 || itemId == 0x8C)
-			return false;
-		return true;
+			retVal = false;
 	default:
-		return true;
+		break;
 	}
+
+	return retVal;
 }
 
 bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
-	debug("hasAdequateDefense %d %d", monsterId, attackType);
+	debugC(3, kDebugFight, "hasAdequateDefense %d %d", monsterId, attackType);
 
 	int16 itemId = _mapMonsters[monsterId]._weaponItemId;
 


Commit: 0e6a5d9d0c750722010d899470fd399ec65a135d
    https://github.com/scummvm/scummvm/commit/0e6a5d9d0c750722010d899470fd399ec65a135d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Fix bug in characterSearchesMonsterCorpse()

Changed paths:
    engines/efh/fight.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 727169e5420..435d1f1e9e5 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1191,7 +1191,7 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 }
 
 bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
-	debug("characterSearchesMonsterCorpse %d %d", charId, monsterId);
+	debugC(3, kDebugFight, "characterSearchesMonsterCorpse %d %d", charId, monsterId);
 
 	int16 rndVal = getRandom(100);
 	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
@@ -1199,7 +1199,7 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 
 	rndVal = getRandom(5) - 1;
 	int16 itemId = kEncounters[_mapMonsters[monsterId]._monsterRef]._dropItemId[rndVal];
-	if (itemId == -1)
+	if (itemId == -1 || itemId == 0)
 		return false;
 
 	if (!giveItemTo(charId, itemId, 0xFF))


Commit: b8544bb762b43ad8ac5c2027fe51bdc8650a2a7d
    https://github.com/scummvm/scummvm/commit/b8544bb762b43ad8ac5c2027fe51bdc8650a2a7d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Fix a couple of issues in sub1C956, renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index be8cdee3fde..0ce8a10ee37 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -885,8 +885,8 @@ void EfhEngine::refreshTeamSize() {
 	debugC(6, kDebugEngine, "refreshTeamSize");
 
 	_teamSize = 0;
-	for (uint counter = 0; counter < 3; ++counter) {
-		if (_teamCharId[counter] != -1)
+	for (uint charId = 0; charId < 3; ++charId) {
+		if (_teamCharId[charId] != -1)
 			++_teamSize;
 	}
 }
@@ -894,8 +894,8 @@ void EfhEngine::refreshTeamSize() {
 bool EfhEngine::isNpcATeamMember(int16 id) {
 	debugC(6, kDebugEngine,"isNpcATeamMember %d", id);
 
-	for (int counter = 0; counter < _teamSize; ++counter) {
-		if (_teamCharId[counter] == id)
+	for (int charId = 0; charId < _teamSize; ++charId) {
+		if (_teamCharId[charId] == id)
 			return true;
 	}
 
@@ -1916,10 +1916,10 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 4:
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field11_NpcId) {
-					removeObject(_teamCharId[counter], charId);
+		for (int charId = 0; charId < _teamSize; ++charId) {
+			for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
+				if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
+					removeObject(_teamCharId[charId], inventoryId);
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
@@ -1937,9 +1937,9 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 6:
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			for (uint charId = 0; charId < 10; ++charId) {
-				if (_npcBuf[_teamCharId[counter]]._inventory[charId]._ref == _npcBuf[npcId].field11_NpcId) {
+		for (int charId = 0; charId < _teamSize; ++charId) {
+			for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
+				if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
@@ -1949,9 +1949,9 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 7:
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
-				removeCharacterFromTeam(counter);
+		for (int charId = 0; charId < _teamSize; ++charId) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
+				removeCharacterFromTeam(charId);
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
@@ -1960,11 +1960,11 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 8:
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
+		for (int charId = 0; charId < _teamSize; ++charId) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[npcId]._name;
-				_characterNamePt2 = _npcBuf[_teamCharId[counter]]._name;
+				_characterNamePt2 = _npcBuf[_teamCharId[charId]]._name;
 				Common::String buffer = Common::String::format("%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
 				for (uint i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
@@ -1978,7 +1978,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 				setTextColorRed();
 				Common::KeyCode input = mapInputCode(waitForKey());
 				if (input == Common::KEYCODE_y) {
-					removeCharacterFromTeam(counter);
+					removeCharacterFromTeam(charId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 				}
 				displayAnimFrames(0xFE, true);
@@ -1987,8 +1987,8 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		}
 		break;
 	case 9:
-		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[counter]) {
+		for (int charId = 0; charId < _teamSize; ++charId) {
+			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 435d1f1e9e5..1ccfd5a6690 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1040,30 +1040,30 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 }
 
 bool EfhEngine::sub1CB27() {
-	debug("sub1CB27");
+	debugC(3, kDebugFight, "sub1CB27");
+	warning("To be renamed: sub1CB27");
 
-	bool var4 = false;
-	for (int counter1 = 0; counter1 < _teamSize; ++counter1) {
-		_teamLastAction[counter1] = 0;
-		if (!isTeamMemberStatusNormal(counter1))
+	bool retVal = false;
+	for (int charId = 0; charId < _teamSize; ++charId) {
+		_teamLastAction[charId] = 0;
+		if (!isTeamMemberStatusNormal(charId))
 			continue;
 
-		var4 = true;
+		retVal = true;
 		do {
-			drawCombatScreen(_teamCharId[counter1], false, true);
-			Common::KeyCode var1 = handleAndMapInput(true);
-			switch (var1) {
+			drawCombatScreen(_teamCharId[charId], false, true);
+			switch (handleAndMapInput(true)) {
 			case Common::KEYCODE_a: // Attack
-				_teamLastAction[counter1] = 'A';
-				_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, true);
-				if (_teamNextAttack[counter1] == -1)
-					_teamLastAction[counter1] = 0;
+				_teamLastAction[charId] = 'A';
+				_teamNextAttack[charId] = sub1C956(_teamCharId[charId], 9, true);
+				if (_teamNextAttack[charId] == -1)
+					_teamLastAction[charId] = 0;
 				break;
 			case Common::KEYCODE_d: // Defend
-				_teamLastAction[counter1] = 'D';
+				_teamLastAction[charId] = 'D';
 				break;
 			case Common::KEYCODE_h: // Hide
-				_teamLastAction[counter1] = 'H';
+				_teamLastAction[charId] = 'H';
 				break;
 			case Common::KEYCODE_r: // Run
 				for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
@@ -1071,16 +1071,16 @@ bool EfhEngine::sub1CB27() {
 				}
 				return true;
 			case Common::KEYCODE_s: { // Status
-				int16 var8 = handleStatusMenu(2, _teamCharId[counter1]);
-				sub1CAB6(_teamCharId[counter1]);
+				int16 var8 = handleStatusMenu(2, _teamCharId[charId]);
+				sub1CAB6(_teamCharId[charId]);
 				if (var8 > 999) {
 					if (var8 == 0x7D00)
-						_teamLastAction[counter1] = 'S';
+						_teamLastAction[charId] = 'S';
 				} else {
-					_teamLastAction[counter1] = 'U';
-					_word31780[counter1] = var8;
-					int16 var6 = _npcBuf[_teamCharId[counter1]]._inventory[var8]._ref;
-					switch (var6 - 1) {
+					_teamLastAction[charId] = 'U';
+					_word31780[charId] = var8;
+					int16 invEffect = _items[_npcBuf[_teamCharId[charId]]._inventory[var8]._ref]._specialEffect;
+					switch (invEffect - 1) {
 					case 0:
 					case 1:
 					case 2:
@@ -1093,7 +1093,7 @@ bool EfhEngine::sub1CB27() {
 					case 10:
 					case 12:
 					case 13:
-						_teamNextAttack[counter1] = sub1C956(_teamCharId[counter1], 9, false);
+						_teamNextAttack[charId] = sub1C956(_teamCharId[charId], 9, false);
 						break;
 
 					case 9:
@@ -1108,13 +1108,13 @@ bool EfhEngine::sub1CB27() {
 					case 29:
 					case 30:
 						displayBoxWithText("Select Character:", 3, 1, false);
-						_teamNextAttack[counter1] = selectOtherCharFromTeam();
+						_teamNextAttack[charId] = selectOtherCharFromTeam();
 						break;
 
 					case 16:
 					case 17:
 					case 26:
-						_teamNextAttack[counter1] = 0xC8;
+						_teamNextAttack[charId] = 0xC8;
 						break;
 
 					case 19:
@@ -1123,6 +1123,8 @@ bool EfhEngine::sub1CB27() {
 					case 22:
 					case 23:
 					default:
+						_word31780[charId] = var8;
+						_teamNextAttack[charId] = -1;
 						break;
 					}
 				}
@@ -1131,15 +1133,15 @@ bool EfhEngine::sub1CB27() {
 			case Common::KEYCODE_t: // Terrain
 				redrawScreenForced();
 				getInputBlocking();
-				drawCombatScreen(_teamCharId[counter1], false, true);
+				drawCombatScreen(_teamCharId[charId], false, true);
 				break;
 			default:
 				break;
 			}
-		} while (_teamLastAction[counter1] == 0);
+		} while (_teamLastAction[charId] == 0);
 	}
 
-	return var4;
+	return retVal;
 }
 
 void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {


Commit: ac5da028ef6b2bf607e8efd75c21ec8019d7d0a0
    https://github.com/scummvm/scummvm/commit/ac5da028ef6b2bf607e8efd75c21ec8019d7d0a0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Renaming

Changed paths:
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 1ccfd5a6690..d58492b598c 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -158,9 +158,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					}
 				}
 			} else if (checkMonsterMovementType(monsterGroupIdOrMonsterId, true)) {
-				// handleFight - Loop on var86 - Start
-				for (uint var86 = 0; var86 < 9; ++var86) {
-					if (isMonsterActive(monsterGroupIdOrMonsterId, var86)) {
+				// handleFight - Loop on mobsterId - Start
+				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+					if (isMonsterActive(monsterGroupIdOrMonsterId, ctrMobsterId)) {
 						int16 monsterWeaponItemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._weaponItemId;
 						if (monsterWeaponItemId == 0xFF)
 							monsterWeaponItemId = 0x3F;
@@ -337,9 +337,9 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							}
 							// handleFight - Loop on var7E - End
 						}
-					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[var86] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
-						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86];
-						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[var86] <= 0) {
+					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
+						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId];
+						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId] <= 0) {
 							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
@@ -347,7 +347,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							else
 								_enemyNamePt1 = "";
 
-							switch (_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86]) {
+							switch (_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
 							case 1:
 								_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
@@ -358,12 +358,12 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 								break;
 							}
-							_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[var86] = 0;
+							_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId] = 0;
 							displayBoxWithText(_messageToBePrinted, 1, 2, true);
 						}
 					}
 				}
-				// handleFight - Loop on var86 - End
+				// handleFight - Loop on mobsterId - End
 			}
 		}
 
@@ -452,8 +452,8 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			if (_teamMonsterIdArray[groupId] == -1)
 				continue;
 
-			for (int16 mobsterCounter = teamMemberId; mobsterCounter < var54; ++mobsterCounter) {
-				if (isMonsterActive(groupId, mobsterCounter) && var6E) {
+			for (int16 ctrMobsterId = teamMemberId; ctrMobsterId < var54; ++ctrMobsterId) {
+				if (isMonsterActive(groupId, ctrMobsterId) && var6E) {
 					bool noticedFl;
 					if (!checkMonsterMovementType(groupId, true)) {
 						setMapMonsterAggressivenessAndMovementType(groupId, 9, true);
@@ -467,7 +467,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					int16 monsterId = _teamMonsterIdArray[groupId];
 					int16 characterPronoun = kEncounters[_mapMonsters[monsterId]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
-					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter];
+					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
 					int16 hitCount = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
@@ -500,7 +500,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						hitCount = 0;
 
 					if (hitCount > 0) {
-						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] -= originalDamage;
+						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
 						if (hitCount > 1) {
 							_attackBuffer = Common::String::format("%d times ", hitCount);
 						} else {
@@ -531,7 +531,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] <= 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -539,7 +539,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							}
 						} else {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] <= 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -549,16 +549,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check damages - End
 
 						// Action A - Add reaction text - Start
-						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] - 5 <= originalDamage) {
+						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
 								addReactionText(kEfhReactionReels);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 8) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
 								addReactionText(kEfhReactionCriesOut);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 4) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
 								addReactionText(kEfhReactionFalters);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 2) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
 								addReactionText(kEfhReactionWinces);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] < hitPointsBefore / 3) {
+							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
 								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
 								addReactionText(kEfhReactionScreams);
 							} else if (hitPointsBefore / 8 >= originalDamage) {
@@ -570,7 +570,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add reaction text - End
 
 						// Action A - Add armor absorb text - Start
-						if (var76 && hitCount && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
+						if (var76 && hitCount && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
 							if (damagePointsAbsorbed <= 1)
 								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							else
@@ -600,15 +600,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
+						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
 							if (getRandom(100) < 35) {
-								_teamMonsterEffects[groupId]._effect[mobsterCounter] = 1;
-								_teamMonsterEffects[groupId]._duration[mobsterCounter] = getRandom(10);
+								_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 1;
+								_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[mobsterCounter] > 0) {
-							_teamMonsterEffects[groupId]._effect[mobsterCounter] = 2;
-							_teamMonsterEffects[groupId]._duration[mobsterCounter] = getRandom(10);
+						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+							_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 2;
+							_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						// Action A - Check effect - End
@@ -706,10 +706,10 @@ bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
 
 void EfhEngine::resetTeamMonsterEffects() {
 	debugC(6, kDebugFight, "resetTeamMonsterEffects");
-	for (uint ctrMonsterId = 0; ctrMonsterId < 5; ++ctrMonsterId) {
-		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-			_teamMonsterEffects[ctrMonsterId]._effect[ctrEffectId] = 0;
-			_teamMonsterEffects[ctrMonsterId]._duration[ctrEffectId] = 0;
+	for (uint ctrGroupId = 0; ctrGroupId < 5; ++ctrGroupId) {
+		for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+			_teamMonsterEffects[ctrGroupId]._effect[ctrMobsterId] = 0;
+			_teamMonsterEffects[ctrGroupId]._duration[ctrMobsterId] = 0;
 		}
 	}
 }
@@ -1554,26 +1554,26 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	debug("sub1BE9A %d", monsterId);
 
 	// sub1BE9A - 1rst loop counter1_monsterId - Start
-	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		if (countMonsterGroupMembers(counter1))
+	for (uint ctrGroupId = 0; ctrGroupId < 5; ++ctrGroupId) {
+		if (countMonsterGroupMembers(ctrGroupId))
 			continue;
 
-		for (uint counter2 = 0; counter2 < 9; ++counter2) {
-			_mapMonsters[_teamMonsterIdArray[counter1]]._hitPoints[counter2] = 0;
-			_teamMonsterEffects[counter1]._effect[counter2] = 0;
-			_teamMonsterEffects[counter1]._duration[counter2] = 0;
+		for (uint ctrMobster = 0; ctrMobster < 9; ++ctrMobster) {
+			_mapMonsters[_teamMonsterIdArray[ctrGroupId]]._hitPoints[ctrMobster] = 0;
+			_teamMonsterEffects[ctrGroupId]._effect[ctrMobster] = 0;
+			_teamMonsterEffects[ctrGroupId]._duration[ctrMobster] = 0;
 		}
 
-		_teamMonsterIdArray[counter1] = -1;
+		_teamMonsterIdArray[ctrGroupId] = -1;
 
 		// CHECKME: counter1 is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
 		// if the purpose is compact the array, it should be handle differently
-		for (uint counter2 = counter1 + 1; counter2 < 5; ++counter2) {
-			for (uint var8 = 0; var8 < 9; ++var8) {
-				_teamMonsterEffects[counter1]._effect[var8] = _teamMonsterEffects[counter2]._effect[var8];
-				_teamMonsterEffects[counter1]._duration[var8] = _teamMonsterEffects[counter2]._duration[var8];
+		for (uint counter2 = ctrGroupId + 1; counter2 < 5; ++counter2) {
+			for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+				_teamMonsterEffects[ctrGroupId]._effect[ctrMobsterId] = _teamMonsterEffects[counter2]._effect[ctrMobsterId];
+				_teamMonsterEffects[ctrGroupId]._duration[ctrMobsterId] = _teamMonsterEffects[counter2]._duration[ctrMobsterId];
 			}
-			_teamMonsterIdArray[counter1] = _teamMonsterIdArray[counter2];
+			_teamMonsterIdArray[ctrGroupId] = _teamMonsterIdArray[counter2];
 		}
 	}
 	// sub1BE9A - 1rst loop counter1_monsterId - End
@@ -1620,8 +1620,8 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 						// The original at this point was doing a loop on counter1, which is not a good idea as
 						// it was resetting the counter1 to 9 whatever its value before the loop.
 						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
-						for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-							_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 0;
+						for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+							_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 0;
 						}
 
 						if (++teamMonsterId >= 5)
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 7efea57cc86..d34963244e6 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -145,9 +145,9 @@ uint8 MapMonster::getPronoun() {
 }
 
 void TeamMonsterEffect::init() {
-	for (int i = 0; i < 9; ++i) {
-		_effect[i] = 0;
-		_duration[i] = 0;
+	for (int ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+		_effect[ctrMobsterId] = 0;
+		_duration[ctrMobsterId] = 0;
 	}
 }
 
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index d25ae4f16d3..ba3c89ceea6 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -906,24 +906,24 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			int16 victims = 0;
 			_messageToBePrinted += "  The item emits a low droning hum...";
 			if (getRandom(100) < 50) {
-				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
+				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victims;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 1;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 1;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
 					}
 				}
 			} else {
 				int16 NumberOfTargets = getRandom(9);
-				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
 					if (NumberOfTargets == 0)
 						break;
 
-					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
+					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victims;
 						--NumberOfTargets;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 1;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 1;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
 					}
 				}
 			}
@@ -954,15 +954,15 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				}
 			} else {
 				int16 varAC = getRandom(9);
-				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
+				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
 					if (varAC == 0)
 						break;
 
-					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
+					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victim;
 						--varAC;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 2;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
+						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 2;
+						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
 					}
 				}
 			}


Commit: d6650f6ca30ba0cd265760e90655813b8a74f373
    https://github.com/scummvm/scummvm/commit/d6650f6ca30ba0cd265760e90655813b8a74f373
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Validate addNewOpponents(), some renaming

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 08faff8d3c7..b1995d98ba8 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -401,7 +401,7 @@ private:
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
 	bool hasAdequateDefense(int16 monsterId, uint8 attackType);
 	bool hasAdequateDefenseNPC(int16 charId, uint8 attackType);
-	void sub1BE9A(int16 monsterId);
+	void addNewOpponents(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 
 	// Files
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index d58492b598c..8f690a77ad3 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -368,7 +368,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		}
 
 		handleMapMonsterMoves();
-		sub1BE9A(monsterId);
+		addNewOpponents(monsterId);
 	}
 
 	resetTeamMonsterIdArray();
@@ -1550,10 +1550,10 @@ bool EfhEngine::hasAdequateDefenseNPC(int16 charId, uint8 attackType) {
 }
 
 // The parameter isn't used in the original
-void EfhEngine::sub1BE9A(int16 monsterId) {
-	debug("sub1BE9A %d", monsterId);
+void EfhEngine::addNewOpponents(int16 monsterId) {
+	debugC(3, kDebugFight, "addNewOpponents %d", monsterId);
 
-	// sub1BE9A - 1rst loop counter1_monsterId - Start
+	// addNewOpponents - 1rst loop counter1_monsterId - Start
 	for (uint ctrGroupId = 0; ctrGroupId < 5; ++ctrGroupId) {
 		if (countMonsterGroupMembers(ctrGroupId))
 			continue;
@@ -1566,7 +1566,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 
 		_teamMonsterIdArray[ctrGroupId] = -1;
 
-		// CHECKME: counter1 is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
+		// CHECKME: ctrGroupId is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
 		// if the purpose is compact the array, it should be handle differently
 		for (uint counter2 = ctrGroupId + 1; counter2 < 5; ++counter2) {
 			for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
@@ -1576,7 +1576,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 			_teamMonsterIdArray[ctrGroupId] = _teamMonsterIdArray[counter2];
 		}
 	}
-	// sub1BE9A - 1rst loop counter1_monsterId - End
+	// addNewOpponents - 1rst loop counter1_monsterId - End
 
 	int16 teamMonsterId = -1;
 	for (uint counter1 = 0; counter1 < 5; ++counter1) {
@@ -1587,7 +1587,7 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 	}
 
 	if (teamMonsterId != -1) {
-		// sub1BE9A - loop var2 - Start
+		// addNewOpponents - loop var2 - Start
 		for (int var2 = 1; var2 < 3; ++var2) {
 			if (teamMonsterId >= 5)
 				break;
@@ -1599,8 +1599,8 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
 						bool monsterActiveFound = false;
-						for (uint ctrSubId = 0; ctrSubId < 9; ++ctrSubId) {
-							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrSubId] > 0) {
+						for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrMobsterId] > 0) {
 								monsterActiveFound = true;
 								break;
 							}
@@ -1630,20 +1630,20 @@ void EfhEngine::sub1BE9A(int16 monsterId) {
 				}
 			}
 		}
-		// sub1BE9A - loop var2 - End
+		// addNewOpponents - loop var2 - End
 	}
 
 	if (teamMonsterId == -1 || teamMonsterId > 4)
 		return;
 
-	// sub1BE9A - last loop counter1_monsterId - Start
+	// addNewOpponents - last loop counter1_monsterId - Start
 	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
 		_teamMonsterIdArray[ctrTeamMonsterId] = -1;
 		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
 			_teamMonsterEffects[ctrTeamMonsterId]._effect[ctrEffectId] = (int16)0x8000;
 		}
 	}
-	// sub1BE9A - last loop counter1_monsterId - End
+	// addNewOpponents - last loop counter1_monsterId - End
 }
 
 int16 EfhEngine::getTeamMonsterAnimId() {


Commit: 90e16512d529398d8566f119854fc189627d47a4
    https://github.com/scummvm/scummvm/commit/90e16512d529398d8566f119854fc189627d47a4
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Fix CppCheck warnings, add some comments, validate loadPlacesFile()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/fight.cpp
    engines/efh/files.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0ce8a10ee37..119f8336795 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2029,10 +2029,10 @@ void EfhEngine::displayImp1Text(int16 textId) {
 
 	int16 charCounter = 0;
 	int16 stringIdx = 0;
-	bool textComplete = false;
-	bool maxReached = false;
 
 	if (textId <= 0xFE) {
+		bool textComplete = false;
+		bool maxReached = false;
 		// Clear temp text on the lower left part of the screen
 		if (_tempTextPtr) {
 			_tempTextPtr = nullptr;
@@ -2265,8 +2265,8 @@ void EfhEngine::computeInitiatives() {
 	debugC(6, kDebugEngine, "computeInitiatives");
 
 	for (int counter = 0; counter < 3; ++counter) {
-		if (_teamCharId[counter] != -1 && counter < _teamSize) {
-			_initiatives[counter]._id = counter + 1000;
+		if (counter < _teamSize && _teamCharId[counter] != -1) {
+			_initiatives[counter]._id = counter + 1000; // Magic value added to detect it's a member of the team
 			_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3]; // "Agility"
 		} else {
 			_initiatives[counter]._id = -1;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 8f690a77ad3..c3c404439f3 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -280,11 +280,12 @@ bool EfhEngine::handleFight(int16 monsterId) {
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
 											addReactionText(kEfhReactionWinces);
 										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
-											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
 											addReactionText(kEfhReactionScreams);
 										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
 											addReactionText(kEfhReactionChortles);
 										} else if (originalDamage == 0 && getRandom(100) < 35) {
+											// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
 											addReactionText(kEfhReactionLaughs);
 										}
 									}
@@ -559,11 +560,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
 								addReactionText(kEfhReactionWinces);
 							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
-								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it
+								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
 								addReactionText(kEfhReactionScreams);
 							} else if (hitPointsBefore / 8 >= originalDamage) {
 								addReactionText(kEfhReactionChortles);
 							} else if (originalDamage == 0 && getRandom(100) < 35) {
+								// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
 								addReactionText(kEfhReactionLaughs);
 							}
 						}
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 1c53d35736e..218c8208a14 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -220,7 +220,7 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 }
 
 void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
-	debug("loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
+	debugC(2, kDebugEngine, "loadPlacesFile %d %s", fullPlaceId, forceReloadFl ? "True" : "False");
 
 	if (fullPlaceId == 0xFF)
 		return;


Commit: 2ec85960ad891e1254aed7881226d217a0c5b32c
    https://github.com/scummvm/scummvm/commit/2ec85960ad891e1254aed7881226d217a0c5b32c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Validate more functions, renaming

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index b1995d98ba8..6b7ace5ca11 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -470,7 +470,7 @@ private:
 	int16 handleStatusMenu(int16 gameMode, int16 charId);
 	void unequipItem(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
 	void tryToggleEquipped(int16 charId, int16 objectId, int16 windowId, int16 menuId, int16 curMenuLine);
-	int16 useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA);
+	int16 useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 gameMode);
 
 	// Savegames
 	void synchronize(Common::Serializer &s);
@@ -603,7 +603,7 @@ private:
 	int16 _menuDepth;
 	int16 _menuItemCounter;
 	int16 _teamPctVisible[3];
-	int16 _word32482[3];
+	int16 _teamPctDodgeMiss[3];
 	int16 _teamNextAttack[3];
 	int16 _word31780[3];
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index c3c404439f3..274caafd58b 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -112,7 +112,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		displayAnimFrames(varInt, true);
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			_teamPctVisible[counter] = 100;
-			_word32482[counter] = 65;
+			_teamPctDodgeMiss[counter] = 65;
 		}
 
 		if (!sub1CB27()) {
@@ -190,7 +190,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 ennemyPronoun = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
 								int16 characterPronoun = _npcBuf[_teamCharId[var7E]].getPronoun();
 								varInt = _items[monsterWeaponItemId].field_13;
-								_word32482[var7E] += (varInt * 5);
+								_teamPctDodgeMiss[var7E] += (varInt * 5);
 								int16 var62 = 0;
 								int16 hitPoints = 0;
 								int16 originalDamage = 0;
@@ -198,7 +198,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[monsterWeaponItemId]._attacks;
 								for (int var84 = 0; var84 < var64; ++var84) {
 									// handleFight - Loop var84 on var64 (objectId) - Start
-									if (getRandom(100) > _word32482[var7E])
+									if (getRandom(100) > _teamPctDodgeMiss[var7E])
 										continue;
 
 									++var62;
@@ -627,9 +627,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
-	debug("handleFight_lastAction_D %d", teamCharId);
+	// Fight - Action 'D' - Defend
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+	debugC(3, kDebugFight, "handleFight_lastAction_D %d", teamCharId);
 
-	_word32482[teamCharId] -= 40;
+	_teamPctDodgeMiss[teamCharId] -= 40;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 
 	uint8 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
@@ -644,10 +647,10 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 }
 
 void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
-	debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
-
+	// Fight - Action 'H' - Hide
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
+	debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
 
 	_teamPctVisible[teamCharId] -= 50;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
@@ -663,11 +666,11 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 }
 
 bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
-	debug("handleFight_lastAction_U %d", teamCharId);
-
 	// Fight - Action 'U' - Use Item
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
+	debugC(3, kDebugFight, "handleFight_lastAction_U %d", teamCharId);
+
 	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	_nameBuffer = _items[itemId]._name;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index d34963244e6..99dfcca0681 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -252,7 +252,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_teamCharStatus[i]._status = 0;
 		_teamCharStatus[i]._duration = 0;
 		_teamPctVisible[i] = 0;
-		_word32482[i] = 0;
+		_teamPctDodgeMiss[i] = 0;
 		_teamNextAttack[i] = -1;
 		_word31780[i] = 0;
 		_teamLastAction[i] = 0;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index ba3c89ceea6..b1d9dcd7914 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -889,8 +889,8 @@ void EfhEngine::tryToggleEquipped(int16 charId, int16 objectId, int16 windowId,
 	}
 }
 
-int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 argA) {
-	debug("useObject %d %d %d %d %d %d", charId, objectId, teamMonsterId, menuId, curMenuLine, argA);
+int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 gameMode) {
+	debug("useObject %d %d %d %d %d %s", charId, objectId, teamMonsterId, menuId, curMenuLine, gameMode == 3 ? "Combat" : "Normal");
 
 	Common::String buffer1 = "";
 
@@ -900,7 +900,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	int16 itemId = _npcBuf[charId]._inventory[objectId]._ref;
 	switch (_items[itemId]._specialEffect - 1) {
 	case 0: // "Demonic Powers", "MindDomination", "Guilt Trip", "Sleep Grenade", "SleepGrenader"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("The item emits a low droning hum...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 victims = 0;
@@ -939,7 +939,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 1: // "Chilling Touch", "Guilt", "Petrify Rod", "Elmer's Gun"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("The item grows very cold for a moment...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The item emits a blue beam...";
@@ -980,7 +980,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 2:
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("A serene feeling passes through the air...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
@@ -990,7 +990,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 4: // "Unholy Sinwave", "Holy Water"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  A dark gray fiery whirlwind surrounds the poor victim...the power fades and death abounds!";
@@ -1014,7 +1014,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 5: // "Lucifer'sTouch", "Book of Death", "Holy Cross"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("A dark sense fills your soul...then fades!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			if (getRandom(100) < 50) {
@@ -1035,7 +1035,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 12: // "Terror Gaze", "Servitude Rod", "Despair Ankh", "ConfusionPrism", "Pipe of Peace", "Red Cape", "Peace Symbol", "Hell Badge"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
@@ -1044,31 +1044,31 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 		break;
 	case 14: { // "Feathered Cap"
-		int16 varAA;
-		if (argA == 2) {
+		int16 teamCharId;
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
-			varAA = selectOtherCharFromTeam();
+			teamCharId = selectOtherCharFromTeam();
 		} else {
-			varAA = teamMonsterId;
+			teamCharId = teamMonsterId;
 		}
 
-		if (varAA != 0x1B) {
+		if (teamCharId != 0x1B) { // Escape code, which means the user cancelled the selection
 			buffer1 = "  The magic makes the user as quick and agile as a bird!";
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
 			}
-			_word32482[varAA] -= 50;
-			if (_word32482[varAA] < 0)
-				_word32482[varAA] = 0;
+			_teamPctDodgeMiss[teamCharId] -= 50;
+			if (_teamPctDodgeMiss[teamCharId] < 0)
+				_teamPctDodgeMiss[teamCharId] = 0;
 		}
 
 		objectUsedFl = true;
 	} break;
 	case 15: { // "Regal Crown"
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
@@ -1077,7 +1077,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 
 		if (teamCharId != 0x1B) {
 			buffer1 = "  The magic makes the user invisible!";
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1098,7 +1098,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (_tileFact[tileFactId]._field0 == 0) {
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1107,7 +1107,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
-				if (argA == 2) {
+				if (gameMode == 2) {
 					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
@@ -1115,7 +1115,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				}
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
-				if (argA == 2) {
+				if (gameMode == 2) {
 					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
@@ -1133,7 +1133,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (_tileFact[tileFactId]._field0 == 0) {
 			totalPartyKill();
 			buffer1 = "The entire party vanishes in a flash... only to appear in stone !";
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1142,7 +1142,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			if (tileFactId == 0 || tileFactId == 0x48) {
 				buffer1 = "The entire party vanishes in a flash...but re-appears, as if nothing happened!";
-				if (argA == 2) {
+				if (gameMode == 2) {
 					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
@@ -1150,7 +1150,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				}
 			} else {
 				buffer1 = "The entire party vanishes in a flash...only to appear elsewhere!";
-				if (argA == 2) {
+				if (gameMode == 2) {
 					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
 					_messageToBePrinted += buffer1;
@@ -1162,7 +1162,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 	} break;
 	case 18:
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 teamCharId = teamMonsterId;
@@ -1181,7 +1181,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 19: // "Junk"
 		buffer1 = "  * The item breaks!";
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
@@ -1217,7 +1217,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			}
 		}
 		buffer1 += "'";
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
@@ -1228,7 +1228,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 24: {
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
@@ -1246,7 +1246,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			else
 				buffer1 = Common::String::format("%s increased 1 point!", kSkillArray[varAE]);
 
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1258,7 +1258,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	} break;
 	case 25: {
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use this item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else
@@ -1276,7 +1276,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			else
 				buffer1 = Common::String::format("%s lowered 1 point!", kSkillArray[varAE]);
 
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1288,7 +1288,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	} break;
 	case 26: // "Black Sphere"
 		buffer1 = "The entire party collapses, dead!!!";
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
@@ -1299,7 +1299,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 27: { // "Magic Pyramid", "Razor Blade"
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
@@ -1309,7 +1309,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (teamCharId != 0x1B) {
 			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
 			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
-			if (argA == 2) {
+			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
 				_messageToBePrinted += buffer1;
@@ -1320,7 +1320,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		objectUsedFl = true;
 	} break;
 	case 28: // "Bugle"
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("The item makes a loud noise!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			int16 teamCharId = teamMonsterId;
@@ -1339,7 +1339,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		break;
 	case 29: { // "Healing Spray", "Healing Elixir", "Curing Potion", "Magic Potion"
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
@@ -1358,7 +1358,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
 		}
 
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
@@ -1369,7 +1369,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 	} break;
 	case 30: {
 		int16 teamCharId;
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder("Who will use the item?", false, charId, teamMonsterId, menuId, curMenuLine);
 			teamCharId = selectOtherCharFromTeam();
 		} else {
@@ -1388,7 +1388,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
 		}
 
-		if (argA == 2) {
+		if (gameMode == 2) {
 			displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += buffer1;
@@ -1419,7 +1419,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			--usesLeft;
 			if (usesLeft <= 0) {
 				buffer1 = "  * The item breaks!";
-				if (argA == 2) {
+				if (gameMode == 2) {
 					getLastCharAfterAnimCount(_guessAnimationAmount);
 					displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 				} else {
@@ -1433,7 +1433,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			}
 		}
 
-		if (argA == 2) {
+		if (gameMode == 2) {
 			getLastCharAfterAnimCount(_guessAnimationAmount);
 			displayWindowAndStatusMenu(charId, teamMonsterId, menuId, curMenuLine);
 		}


Commit: 789917e1742e692384c99b06e33eb250bc10883a
    https://github.com/scummvm/scummvm/commit/789917e1742e692384c99b06e33eb250bc10883a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Fix issues in getDeathTypeDescription, renaming

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 6b7ace5ca11..4e0a067fd02 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -388,7 +388,7 @@ private:
 	void initFight(int16 monsterId);
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
-	void getDeathTypeDescription(int16 attackerId, int16 victimId);
+	void getDeathTypeDescription(int16 victimId, int16 attackerId);
 	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
 	bool sub1CB27();
 	void drawCombatScreen(int16 charId, bool whiteFl, bool drawFl);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 274caafd58b..ed7e58b7e76 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -736,16 +736,16 @@ bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 	return false;
 }
 
-void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
-	debug("getDeathTypeDescription %d %d", attackerId, victimId);
+void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
+	debugC(3, kDebugFight, "getDeathTypeDescription %d %d", victimId, attackerId);
 
 	uint8 pronoun;
 
-	if (attackerId > 999) {
-		int16 charId = _teamCharId[attackerId - 1000];
+	if (victimId >= 1000) { // Magic value for team members
+		int16 charId = _teamCharId[victimId - 1000];
 		pronoun = _npcBuf[charId].getPronoun();
 	} else {
-		int16 charId = _teamMonsterIdArray[attackerId];
+		int16 charId = _teamMonsterIdArray[victimId];
 		pronoun = _mapMonsters[charId].getPronoun();
 	}
 
@@ -755,27 +755,25 @@ void EfhEngine::getDeathTypeDescription(int16 attackerId, int16 victimId) {
 	int16 deathType;
 	if (getRandom(100) < 20) {
 		deathType = 0;
-	} else {
-		if (victimId >= 1000) {
-			int16 charId = _teamCharId[victimId - 1000];
-			if (charId == -1)
-				deathType = 0;
-			else {
-				int16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
-				if (exclusiveItemId == 0x7FFF)
-					deathType = 0;
-				else
-					deathType = _items[exclusiveItemId]._attackType + 1;
-			}
-		} else if (_teamMonsterIdArray[victimId] == -1)
+	} else if (attackerId >= 1000) {
+		int16 charId = _teamCharId[attackerId - 1000];
+		if (charId == -1)
 			deathType = 0;
 		else {
-			int16 itemId = _mapMonsters[_teamMonsterIdArray[victimId]]._weaponItemId;
-			deathType = _items[itemId]._attackType;
+			int16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
+			if (exclusiveItemId == 0x7FFF)
+				deathType = 0;
+			else
+				deathType = _items[exclusiveItemId]._attackType + 1;
 		}
+	} else if (_teamMonsterIdArray[attackerId] == -1)
+		deathType = 0;
+	else {
+		int16 itemId = _mapMonsters[_teamMonsterIdArray[attackerId]]._weaponItemId;
+		deathType = _items[itemId]._attackType + 1;
 	}
 
-	int16 rndDescrForDeathType = getRandom((3)) - 1;
+	int16 rndDescrForDeathType = getRandom((3)) - 1; // [0..2]
 	Common::String tmpStr = "DUDE IS TOAST!";
 	switch (deathType) {
 	case 0:


Commit: ddb0cc8dbe6d972d4745a8d0dc2965be1af181b0
    https://github.com/scummvm/scummvm/commit/ddb0cc8dbe6d972d4745a8d0dc2965be1af181b0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: rename determineTeamTarget(), fix issues in it

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 4e0a067fd02..e59f9890e00 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -389,7 +389,7 @@ private:
 	void resetTeamMonsterIdArray();
 	bool isTeamMemberStatusNormal(int16 id);
 	void getDeathTypeDescription(int16 victimId, int16 attackerId);
-	int16 sub1C956(int16 charId, int16 unkFied18Val, bool arg4);
+	int16 determineTeamTarget(int16 charId, int16 unkFied18Val, bool checkDistanceFl);
 	bool sub1CB27();
 	void drawCombatScreen(int16 charId, bool whiteFl, bool drawFl);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index ed7e58b7e76..bdcba0de6ff 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -983,31 +983,32 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 	_messageToBePrinted += tmpStr;
 }
 
-int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
-	debug("sub1C956 %d %d %d", charId, unkFied18Val, arg4);
+int16 EfhEngine::determineTeamTarget(int16 charId, int16 unkFied18Val, bool checkDistanceFl) {
+	debug("determineTeamTarget %d %d %d", charId, unkFied18Val, checkDistanceFl);
 
-	int16 varE = -1;
+	int16 retVal = -1;
 
 	int16 curItemId = getEquippedExclusiveType(charId, unkFied18Val, true);
-	int16 range = 0;
+	int16 rangeType = 0;
+	int16 realRange = 0;
 	if (curItemId != 0x7FFF)
-		range = _items[curItemId]._range;
+		rangeType = _items[curItemId]._range;
 
-	switch (range) {
+	switch (rangeType) {
 	case 3:
 	case 2:
-		++range;
+		++realRange;
 		// no break on purpose
 	case 1:
-		++range;
+		++realRange;
 		// no break on purpose
 	case 0:
-		++range;
+		++realRange;
 		break;
 	case 4:
 		return 100;
 	default:
-		return varE;
+		return retVal;
 	}
 
 	do {
@@ -1020,26 +1021,25 @@ int16 EfhEngine::sub1C956(int16 charId, int16 unkFied18Val, bool arg4) {
 				displayFctFullScreen();
 		}
 
-		if (_teamMonsterIdArray[1] == -1)
-			varE = 0;
-		else
-			varE = selectMonsterGroup();
-
-		if (!arg4) {
-			if (varE == 27) // Esc
-				varE = 0;
-		} else if (varE != 27) {
-			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[varE]);
-			if (monsterGroupDistance > range) {
-				varE = 27;
+		retVal = (_teamMonsterIdArray[1] == -1) ? 0 : selectMonsterGroup();
+
+		if (!checkDistanceFl) {
+			if (retVal == 27) // Esc
+				retVal = 0;
+		} else if (retVal != 27) {
+			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[retVal]);
+			if (monsterGroupDistance > realRange) {
+				retVal = 27;
+				displayBoxWithText("That Group Is Out Of Range!", 3, 1, false);
+				getLastCharAfterAnimCount(_guessAnimationAmount);
 			}
 		}
-	} while (varE == -1);
+	} while (retVal == -1);
 
-	if (varE == 27)
-		varE = -1;
+	if (retVal == 27)
+		retVal = -1;
 
-	return varE;
+	return retVal;
 }
 
 bool EfhEngine::sub1CB27() {
@@ -1058,7 +1058,7 @@ bool EfhEngine::sub1CB27() {
 			switch (handleAndMapInput(true)) {
 			case Common::KEYCODE_a: // Attack
 				_teamLastAction[charId] = 'A';
-				_teamNextAttack[charId] = sub1C956(_teamCharId[charId], 9, true);
+				_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, true);
 				if (_teamNextAttack[charId] == -1)
 					_teamLastAction[charId] = 0;
 				break;
@@ -1096,7 +1096,7 @@ bool EfhEngine::sub1CB27() {
 					case 10:
 					case 12:
 					case 13:
-						_teamNextAttack[charId] = sub1C956(_teamCharId[charId], 9, false);
+						_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, false);
 						break;
 
 					case 9:


Commit: e8fed6ff3bdddd981e2276583bb56c9f0e6e9cd9
    https://github.com/scummvm/scummvm/commit/e8fed6ff3bdddd981e2276583bb56c9f0e6e9cd9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Validate 4 more functions, fix a bug in chooseCharacterToReplace()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 119f8336795..2633022dfa2 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1008,13 +1008,13 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 fromCharId) {
 }
 
 int16 EfhEngine::chooseCharacterToReplace() {
-	debug("chooseCharacterToReplace");
+	debugC(3, kDebugEngine, "chooseCharacterToReplace");
 
 	Common::KeyCode maxVal = (Common::KeyCode)(Common::KEYCODE_0 + _teamSize);
 	Common::KeyCode input;
 	for (;;) {
 		input = waitForKey();
-		if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0 || (input > Common::KEYCODE_1 && input <= maxVal))
+		if (input == Common::KEYCODE_ESCAPE || input == Common::KEYCODE_0 || (input > Common::KEYCODE_1 && input < maxVal))
 			break;
 	}
 
@@ -1025,7 +1025,7 @@ int16 EfhEngine::chooseCharacterToReplace() {
 }
 
 int16 EfhEngine::handleCharacterJoining() {
-	debug("handleCharacterJoining");
+	debugC(3, kDebugEngine, "handleCharacterJoining");
 
 	for (uint counter = 0; counter < 3; ++counter) {
 		if (_teamCharId[counter] == -1) {
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index bdcba0de6ff..d5f7e7ddf1f 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -135,7 +135,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			int16 monsterGroupIdOrMonsterId = _initiatives[counter]._id;
 			if (monsterGroupIdOrMonsterId == -1)
 				continue;
-			if (monsterGroupIdOrMonsterId > 999) { // Team Member
+			if (monsterGroupIdOrMonsterId >= 1000) { // Magic number which determines if it's a Team Member
 				monsterGroupIdOrMonsterId -= 1000;
 				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
 					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
@@ -379,7 +379,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 }
 
 void EfhEngine::handleFight_checkEndEffect(int16 charId) {
-	debug("handleFight_checkEndEffect %d", charId);
+	debugC(3, kDebugFight, "handleFight_checkEndEffect %d", charId);
 
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -984,7 +984,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 }
 
 int16 EfhEngine::determineTeamTarget(int16 charId, int16 unkFied18Val, bool checkDistanceFl) {
-	debug("determineTeamTarget %d %d %d", charId, unkFied18Val, checkDistanceFl);
+	debugC(3, kDebugFight, "determineTeamTarget %d %d %d", charId, unkFied18Val, checkDistanceFl);
 
 	int16 retVal = -1;
 


Commit: b9424bd35d28ed9220cdc4def83607428bb6b699
    https://github.com/scummvm/scummvm/commit/b9424bd35d28ed9220cdc4def83607428bb6b699
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: Add safeguards in transitionMap() and setSpecialTechZone(), move selectMonsterGroup() to fight.cpp, validate some more functions and renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 2633022dfa2..5044ff8dd7d 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1102,7 +1102,7 @@ void EfhEngine::displayMiddleLeftTempText(uint8 *impArray, bool flag) {
 }
 
 void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
-	debug("transitionMap %d %d", centerX, centerY);
+	debugC(2, kDebugEngine, "transitionMap %d %d", centerX, centerY);
 
 	_drawHeroOnMapFl = false;
 	int16 minX = centerX - 11;
@@ -1117,7 +1117,9 @@ void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
 		for (uint counterY = 0; counterY <= 23; ++counterY) {
 			int16 curX = counterX + minX;
 			int16 curY = counterY + minY;
-			_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
+
+			if (curX < 64 && curY < 64)
+				_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
@@ -1126,7 +1128,9 @@ void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
 		for (uint counterY = 0; counterY <= 23; ++counterY) {
 			int16 curX = counterX + minX;
 			int16 curY = counterY + minY;
-			_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
+
+			if (curX < 64 && curY < 64)
+				_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
@@ -1135,25 +1139,25 @@ void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
 	_drawHeroOnMapFl = true;
 }
 
-void EfhEngine::sub2455E(int16 arg0, int16 arg2, int16 arg4) {
-	debug("sub2455E %d %d %d", arg0, arg2, arg4);
+void EfhEngine::setSpecialTechZone(int16 unkId, int16 centerX, int16 centerY) {
+	debugC(2, kDebugEngine, "setSpecialTechZone %d %d %d", unkId, centerX, centerY);
 
-	uint8 varD = kByte2C7D0[arg0];
-	int16 varC = arg2 - 11;
-	int16 varA = arg4 - 11;
+	if (unkId < 0 || unkId >= 60)
+		error("setSpecialTechZone - unexpected value for unkId: %d", unkId);
 
-	if (varC < 0)
-		varC = 0;
+	uint8 zoneValue = kByte2C7D0[unkId];
 
-	if (varA < 0)
-		varA = 0;
+	// Added a CLIP as a safeguard to avoid any value larger than 64
+	int16 minX = CLIP(centerX - 11, 0, 64);
+	int16 minY = CLIP(centerY - 11, 0, 64);
 
-	int16 var8 = varC + 23;
-	int16 var6 = varA + 23;
 
-	for (int16 var4 = varC; var4 <= var8; ++var4) {
-		for (int16 var2 = varA; var2 <= var6; ++var2) {
-			WRITE_LE_INT16(&_techDataArr[_techId][var2 + var4 * 64], varD);
+	int16 maxX = CLIP(minX + 23, 0, 64);
+	int16 maxY = CLIP(minY + 23,0, 64);
+
+	for (int16 counterX = minX; counterX <= maxX; ++counterX) {
+		for (int16 counterY = minY; counterY <= maxY; ++counterY) {
+			_techDataArr[_techId][counterY + counterX * 64] = zoneValue;
 		}
 	}
 }
@@ -2296,7 +2300,7 @@ void EfhEngine::computeInitiatives() {
 }
 
 void EfhEngine::redrawScreenForced() {
-	debug("redrawScreenForced");
+	debugC(3, kDebugEngine,"redrawScreenForced");
 
 	for (uint counter = 0; counter < 2; ++counter) {
 		drawScreen();
@@ -2305,34 +2309,6 @@ void EfhEngine::redrawScreenForced() {
 	}
 }
 
-int16 EfhEngine::selectMonsterGroup() {
-	debug("selectMonsterGroup");
-
-	int16 retVal = -1;
-
-	while (retVal == -1) {
-		Common::KeyCode input = handleAndMapInput(true);
-		switch (input) {
-		case Common::KEYCODE_ESCAPE:
-			retVal = 27;
-			break;
-		case Common::KEYCODE_a:
-		case Common::KEYCODE_b:
-		case Common::KEYCODE_c:
-		case Common::KEYCODE_d:
-		case Common::KEYCODE_e:
-			retVal = input - Common::KEYCODE_a;
-			if (_teamMonsterIdArray[retVal] == -1)
-				retVal = -1;
-			break;
-		default:
-			break;
-		}
-	}
-
-	return retVal;
-}
-
 void EfhEngine::sub1CAB6(int16 charId) {
 	debug("sub1CAB6 %d", charId);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e59f9890e00..d96cf981885 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -322,7 +322,7 @@ private:
 	void drawText(uint8 *impPtr, int16 posX, int16 posY, int16 maxX, int16 maxY, bool flag);
 	void displayMiddleLeftTempText(uint8 *impArray, bool flag);
 	void transitionMap(int16 centerX, int16 centerY);
-	void sub2455E(int16 arg0, int16 arg1, int16 arg2);
+	void setSpecialTechZone(int16 unkId, int16 arg1, int16 arg2);
 	int16 findMapSpecialTileIndex(int16 posX, int16 posY);
 	bool isPosOutOfMap(int16 mapPosX, int16 mapPosY);
 	void goSouth();
@@ -360,7 +360,6 @@ private:
 	int8 checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4);
 	void computeInitiatives();
 	void redrawScreenForced();
-	int16 selectMonsterGroup();
 	void sub1CAB6(int16 charId);
 	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1D8C2(int16 charId, int16 damage);
@@ -403,6 +402,7 @@ private:
 	bool hasAdequateDefenseNPC(int16 charId, uint8 attackType);
 	void addNewOpponents(int16 monsterId);
 	int16 getTeamMonsterAnimId();
+	int16 selectMonsterGroup();
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index d5f7e7ddf1f..6f72af04ad9 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1671,4 +1671,32 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 	return retVal;
 }
 
+int16 EfhEngine::selectMonsterGroup() {
+	debugC(3, kDebugFight, "selectMonsterGroup");
+
+	int16 retVal = -1;
+
+	while (retVal == -1) {
+		Common::KeyCode input = handleAndMapInput(true);
+		switch (input) {
+		case Common::KEYCODE_ESCAPE:
+			retVal = 27;
+			break;
+		case Common::KEYCODE_a:
+		case Common::KEYCODE_b:
+		case Common::KEYCODE_c:
+		case Common::KEYCODE_d:
+		case Common::KEYCODE_e:
+			retVal = input - Common::KEYCODE_a;
+			if (_teamMonsterIdArray[retVal] == -1)
+				retVal = -1;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return retVal;
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index ca57a000d01..dfcb27bf0e0 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -324,7 +324,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				_word2C87A = true;
 				loadPlacesFile(scriptNumberArray[0], false);
 				transitionMap(scriptNumberArray[1], scriptNumberArray[2]);
-				sub2455E(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
+				setSpecialTechZone(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
 				retVal = -1;
 			}
 			break;


Commit: adc85ef1859c400cb730707a6f63ee6991907224
    https://github.com/scummvm/scummvm/commit/adc85ef1859c400cb730707a6f63ee6991907224
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:46+01:00

Commit Message:
EFH: More validations and renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 5044ff8dd7d..f5e1e464b04 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2309,18 +2309,6 @@ void EfhEngine::redrawScreenForced() {
 	}
 }
 
-void EfhEngine::sub1CAB6(int16 charId) {
-	debug("sub1CAB6 %d", charId);
-
-	for (uint counter = 0; counter < 2; ++counter) {
-		drawGameScreenAndTempText(false);
-		displayLowStatusScreen(false);
-		drawCombatScreen(charId, false, false);
-		if (counter == 0)
-			displayFctFullScreen();
-	}
-}
-
 int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	debugC(9, kDebugEngine, "countMonsterGroupMembers %d", monsterGroup);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index d96cf981885..78780b31c5b 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -360,7 +360,6 @@ private:
 	int8 checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4);
 	void computeInitiatives();
 	void redrawScreenForced();
-	void sub1CAB6(int16 charId);
 	int16 countMonsterGroupMembers(int16 monsterGroup);
 	void sub1D8C2(int16 charId, int16 damage);
 	int16 getXPLevel(int32 xp);
@@ -403,6 +402,7 @@ private:
 	void addNewOpponents(int16 monsterId);
 	int16 getTeamMonsterAnimId();
 	int16 selectMonsterGroup();
+	void redrawCombatScreenWithTempText(int16 charId);
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
@@ -605,7 +605,7 @@ private:
 	int16 _teamPctVisible[3];
 	int16 _teamPctDodgeMiss[3];
 	int16 _teamNextAttack[3];
-	int16 _word31780[3];
+	int16 _teamLastInventoryUsed[3];
 
 	int16 _menuStatItemArr[15];
 	TeamMonsterEffect _teamMonsterEffects[5];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 6f72af04ad9..fe2addd77c9 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -671,7 +671,7 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	// It has been split for readability purposes.
 	debugC(3, kDebugFight, "handleFight_lastAction_U %d", teamCharId);
 
-	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_word31780[teamCharId]]._ref;
+	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_teamLastInventoryUsed[teamCharId]]._ref;
 	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	_nameBuffer = _items[itemId]._name;
 	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
@@ -681,7 +681,7 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 		_enemyNamePt1 = "";
 
 	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
-	bool retVal = useObject(_teamCharId[teamCharId], _word31780[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
+	bool retVal = useObject(_teamCharId[teamCharId], _teamLastInventoryUsed[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 
 	return retVal;
@@ -1074,15 +1074,15 @@ bool EfhEngine::sub1CB27() {
 				}
 				return true;
 			case Common::KEYCODE_s: { // Status
-				int16 var8 = handleStatusMenu(2, _teamCharId[charId]);
-				sub1CAB6(_teamCharId[charId]);
-				if (var8 > 999) {
-					if (var8 == 0x7D00)
+				int16 lastInvId = handleStatusMenu(2, _teamCharId[charId]);
+				redrawCombatScreenWithTempText(_teamCharId[charId]);
+				if (lastInvId >= 999) {
+					if (lastInvId == 0x7D00) // Result of Equip, Give and Drop in combat mode(2)
 						_teamLastAction[charId] = 'S';
 				} else {
 					_teamLastAction[charId] = 'U';
-					_word31780[charId] = var8;
-					int16 invEffect = _items[_npcBuf[_teamCharId[charId]]._inventory[var8]._ref]._specialEffect;
+					_teamLastInventoryUsed[charId] = lastInvId;
+					int16 invEffect = _items[_npcBuf[_teamCharId[charId]]._inventory[lastInvId]._ref]._specialEffect;
 					switch (invEffect - 1) {
 					case 0:
 					case 1:
@@ -1126,7 +1126,7 @@ bool EfhEngine::sub1CB27() {
 					case 22:
 					case 23:
 					default:
-						_word31780[charId] = var8;
+						_teamLastInventoryUsed[charId] = lastInvId;
 						_teamNextAttack[charId] = -1;
 						break;
 					}
@@ -1699,4 +1699,16 @@ int16 EfhEngine::selectMonsterGroup() {
 	return retVal;
 }
 
+void EfhEngine::redrawCombatScreenWithTempText(int16 charId) {
+	debugC(3, kDebugFight, "redrawCombatScreenWithTempText %d", charId);
+
+	for (uint counter = 0; counter < 2; ++counter) {
+		drawGameScreenAndTempText(false);
+		displayLowStatusScreen(false);
+		drawCombatScreen(charId, false, false);
+		if (counter == 0)
+			displayFctFullScreen();
+	}
+}
+
 } // End of namespace Efh
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 99dfcca0681..f17d8eb6711 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -254,7 +254,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		_teamPctVisible[i] = 0;
 		_teamPctDodgeMiss[i] = 0;
 		_teamNextAttack[i] = -1;
-		_word31780[i] = 0;
+		_teamLastInventoryUsed[i] = 0;
 		_teamLastAction[i] = 0;
 	}
 
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index b1d9dcd7914..0661e0e7f87 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -486,7 +486,7 @@ void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 m
 }
 
 int16 EfhEngine::displayStringInSmallWindowWithBorder(Common::String str, bool delayFl, int16 charId, int16 windowId, int16 menuId, int16 curMenuLine) {
-	debug("displayStringInSmallWindowWithBorder %s %s %d %d %d %d", str.c_str(), delayFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
+	debugC(3, kDebugEngine, "displayStringInSmallWindowWithBorder %s %s %d %d %d %d", str.c_str(), delayFl ? "True" : "False", charId, windowId, menuId, curMenuLine);
 
 	int16 retVal = 0;
 
@@ -500,7 +500,7 @@ int16 EfhEngine::displayStringInSmallWindowWithBorder(Common::String str, bool d
 			retVal = script_parse(str, 28, 122, 105, 166, true);
 		}
 		// The original is only calling displayFctFullScreen when counter = 0, but it's related to the screen buffers which aren't used in ScummVM implementation
-		// Calling it once fix the almost unreadable text displayed otherwise.
+		// Calling it once fixes the (almost) unreadable text displayed otherwise.
 		// Maybe a refactoring to remove those 0..1 loop would be useful at some point.
 		displayFctFullScreen();
 	}


Commit: ba52ee0cc7cc5e46a386e22769b354e01a907221
    https://github.com/scummvm/scummvm/commit/ba52ee0cc7cc5e46a386e22769b354e01a907221
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: rename handleDamageOnArmor() and getTeamAttackRoundPlans(), validate two functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index f5e1e464b04..8613b873f29 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2321,8 +2321,8 @@ int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	return result;
 }
 
-void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
-	debug("sub1D8C2 %d %d", charId, damage);
+void EfhEngine::handleDamageOnArmor(int16 charId, int16 damage) {
+	debugC(3, kDebugEngine, "handleDamageOnArmor %d %d", charId, damage);
 
 	int16 destroyCounter = 0;
 	int16 pronoun = _npcBuf[charId].getPronoun();
@@ -2347,12 +2347,12 @@ void EfhEngine::sub1D8C2(int16 charId, int16 damage) {
 			removeObject(charId, objectId);
 
 			if (destroyCounter == 0) {
-				destroyCounter = 1;
 				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[pronoun]) + buffer2;
 			} else {
-				++destroyCounter;
 				_messageToBePrinted += Common::String(", ") + buffer2;
 			}
+
+			++destroyCounter;
 		}
 
 		if (remainingDamage > 0)
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 78780b31c5b..2b148a37299 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -361,7 +361,7 @@ private:
 	void computeInitiatives();
 	void redrawScreenForced();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
-	void sub1D8C2(int16 charId, int16 damage);
+	void handleDamageOnArmor(int16 charId, int16 damage);
 	int16 getXPLevel(int32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
@@ -388,7 +388,7 @@ private:
 	bool isTeamMemberStatusNormal(int16 id);
 	void getDeathTypeDescription(int16 victimId, int16 attackerId);
 	int16 determineTeamTarget(int16 charId, int16 unkFied18Val, bool checkDistanceFl);
-	bool sub1CB27();
+	bool getTeamAttackRoundPlans();
 	void drawCombatScreen(int16 charId, bool whiteFl, bool drawFl);
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index fe2addd77c9..1c0c2110efa 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -115,7 +115,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			_teamPctDodgeMiss[counter] = 65;
 		}
 
-		if (!sub1CB27()) {
+		if (!getTeamAttackRoundPlans()) {
 			resetTeamMonsterIdArray();
 			_ongoingFightFl = false;
 			totalPartyKill();
@@ -299,7 +299,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 										varInt = (originalDamage + damagePointsAbsorbed) / 10;
-										sub1D8C2(_teamCharId[var7E], varInt);
+										handleDamageOnArmor(_teamCharId[var7E], varInt);
 									}
 									// handleFight - Check armor - end
 
@@ -1042,9 +1042,8 @@ int16 EfhEngine::determineTeamTarget(int16 charId, int16 unkFied18Val, bool chec
 	return retVal;
 }
 
-bool EfhEngine::sub1CB27() {
-	debugC(3, kDebugFight, "sub1CB27");
-	warning("To be renamed: sub1CB27");
+bool EfhEngine::getTeamAttackRoundPlans() {
+	debugC(3, kDebugFight, "getTeamAttackRoundPlans");
 
 	bool retVal = false;
 	for (int charId = 0; charId < _teamSize; ++charId) {


Commit: a0ae5cb427bfc0505e0e00cee7acd026c1523a5c
    https://github.com/scummvm/scummvm/commit/a0ae5cb427bfc0505e0e00cee7acd026c1523a5c
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Move handleDamageOnArmor to fight.cpp

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8613b873f29..49cca4b4189 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2321,58 +2321,6 @@ int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	return result;
 }
 
-void EfhEngine::handleDamageOnArmor(int16 charId, int16 damage) {
-	debugC(3, kDebugEngine, "handleDamageOnArmor %d %d", charId, damage);
-
-	int16 destroyCounter = 0;
-	int16 pronoun = _npcBuf[charId].getPronoun();
-
-	if (pronoun > 2) {
-		pronoun = 2;
-	}
-
-	int16 curDamage = CLIP<int16>(damage, 0, 50);
-
-	for (uint objectId = 0; objectId < 10; ++objectId) {
-		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || !_npcBuf[charId]._inventory[objectId].isEquipped() || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
-			continue;
-
-		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._curHitPoints;
-		// not in the original: this int16 is used to test if the result is negative. Otherwise _curHitPoints (uint8) turns it into a "large" positive value.
-		int16 newDurability = _npcBuf[charId]._inventory[objectId]._curHitPoints - curDamage;
-		_npcBuf[charId]._inventory[objectId]._curHitPoints = newDurability;
-
-		if (newDurability <= 0) {
-			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
-			removeObject(charId, objectId);
-
-			if (destroyCounter == 0) {
-				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[pronoun]) + buffer2;
-			} else {
-				_messageToBePrinted += Common::String(", ") + buffer2;
-			}
-
-			++destroyCounter;
-		}
-
-		if (remainingDamage > 0)
-			curDamage = remainingDamage;
-		// The original doesn't contain this Else clause. But logically, if the remainingDamage is less than 0, it doesn't make sense to keep damaging equipment with the previous damage.
-		// As it looks like an original bug, I just added the code to stop damaging equipped protections.
-		else
-			break;
-	}
-
-	if (destroyCounter == 0) {
-		_messageToBePrinted += "!";
-	} else if (destroyCounter > 1 || _messageToBePrinted.lastChar() == 's' || _messageToBePrinted.lastChar() == 'S') {
-		_messageToBePrinted += " are destroyed!";
-	} else {
-		_messageToBePrinted += " is destroyed!";
-	}
-}
-
-
 int16 EfhEngine::getXPLevel(int32 xp) {
 	debugC(6, kDebugEngine, "getXPLevel %ld", xp);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 2b148a37299..94137f0bd4c 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -361,7 +361,6 @@ private:
 	void computeInitiatives();
 	void redrawScreenForced();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
-	void handleDamageOnArmor(int16 charId, int16 damage);
 	int16 getXPLevel(int32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
@@ -403,6 +402,7 @@ private:
 	int16 getTeamMonsterAnimId();
 	int16 selectMonsterGroup();
 	void redrawCombatScreenWithTempText(int16 charId);
+	void handleDamageOnArmor(int16 charId, int16 damage);
 
 	// Files
 	int32 readFileToBuffer(Common::String &filename, uint8 *destBuffer);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 1c0c2110efa..e181e8a7901 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1710,4 +1710,55 @@ void EfhEngine::redrawCombatScreenWithTempText(int16 charId) {
 	}
 }
 
+void EfhEngine::handleDamageOnArmor(int16 charId, int16 damage) {
+	debugC(3, kDebugFight, "handleDamageOnArmor %d %d", charId, damage);
+
+	int16 destroyCounter = 0;
+	int16 pronoun = _npcBuf[charId].getPronoun();
+
+	if (pronoun > 2) {
+		pronoun = 2;
+	}
+
+	int16 curDamage = CLIP<int16>(damage, 0, 50);
+
+	for (uint objectId = 0; objectId < 10; ++objectId) {
+		if (_npcBuf[charId]._inventory[objectId]._ref == 0x7FFF || !_npcBuf[charId]._inventory[objectId].isEquipped() || _items[_npcBuf[charId]._inventory[objectId]._ref]._defense == 0)
+			continue;
+
+		int16 remainingDamage = curDamage - _npcBuf[charId]._inventory[objectId]._curHitPoints;
+		// not in the original: this int16 is used to test if the result is negative. Otherwise _curHitPoints (uint8) turns it into a "large" positive value.
+		int16 newDurability = _npcBuf[charId]._inventory[objectId]._curHitPoints - curDamage;
+		_npcBuf[charId]._inventory[objectId]._curHitPoints = newDurability;
+
+		if (newDurability <= 0) {
+			Common::String buffer2 = _items[_npcBuf[charId]._inventory[objectId]._ref]._name;
+			removeObject(charId, objectId);
+
+			if (destroyCounter == 0) {
+				_messageToBePrinted += Common::String::format(", but %s ", kPossessive[pronoun]) + buffer2;
+			} else {
+				_messageToBePrinted += Common::String(", ") + buffer2;
+			}
+
+			++destroyCounter;
+		}
+
+		if (remainingDamage > 0)
+			curDamage = remainingDamage;
+		// The original doesn't contain this Else clause. But logically, if the remainingDamage is less than 0, it doesn't make sense to keep damaging equipment with the previous damage.
+		// As it looks like an original bug, I just added the code to stop damaging equipped protections.
+		else
+			break;
+	}
+
+	if (destroyCounter == 0) {
+		_messageToBePrinted += "!";
+	} else if (destroyCounter > 1 || _messageToBePrinted.lastChar() == 's' || _messageToBePrinted.lastChar() == 'S') {
+		_messageToBePrinted += " are destroyed!";
+	} else {
+		_messageToBePrinted += " is destroyed!";
+	}
+}
+
 } // End of namespace Efh


Commit: 6e402815eff89e5b429f7e8d6fa375c27955be91
    https://github.com/scummvm/scummvm/commit/6e402815eff89e5b429f7e8d6fa375c27955be91
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Validate 3 more functions

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 49cca4b4189..e0b3f312f38 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2381,7 +2381,7 @@ bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 }
 
 int16 EfhEngine::getTileFactId(int16 mapPosX, int16 mapPosY) {
-	debug("getTileFactId %d-%d", mapPosX, mapPosY);
+	debugC(3, kDebugEngine, "getTileFactId %d-%d", mapPosX, mapPosY);
 
 	int16 curTileInfo = getMapTileInfo(mapPosX, mapPosY);
 	int16 imageSetId = _currentTileBankImageSetId[curTileInfo / 72] * 72;
@@ -2391,13 +2391,13 @@ int16 EfhEngine::getTileFactId(int16 mapPosX, int16 mapPosY) {
 }
 
 void EfhEngine::setCharacterObjectToBroken(int16 charId, int16 objectId) {
-	debug("setCharacterObjectToBroken %d %d", charId, objectId);
+	debugC(3, kDebugEngine, "setCharacterObjectToBroken %d %d", charId, objectId);
 
 	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
 }
 
 int16 EfhEngine::selectOtherCharFromTeam() {
-	debug("selectOtherCharFromTeam");
+	debugC(3, kDebugEngine, "selectOtherCharFromTeam");
 
 	Common::KeyCode maxVal = (Common::KeyCode) (Common::KEYCODE_0 + _teamSize);
 	Common::KeyCode input = Common::KEYCODE_INVALID;


Commit: 8f7bf6b26529861a124b1d43d4ed9f1b2a2b835e
    https://github.com/scummvm/scummvm/commit/8f7bf6b26529861a124b1d43d4ed9f1b2a2b835e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: rewrite the pre-loading of "map" files, related refactoring

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e0b3f312f38..73ff6b5e8a7 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -506,13 +506,13 @@ void EfhEngine::initMapMonsters() {
 	debugC(3, kDebugEngine, "initMapMonsters");
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-		if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
+		if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
 			continue;
 
 		for (uint counter = 0; counter < 9; ++counter)
-			_mapMonsters[monsterId]._hitPoints[counter] = 0;
+			_mapMonsters[_techId][monsterId]._hitPoints[counter] = 0;
 
-		uint8 groupSize = _mapMonsters[monsterId]._groupSize;
+		uint8 groupSize = _mapMonsters[_techId][monsterId]._groupSize;
 		if (groupSize == 0)
 			groupSize = getRandom(10) - 1;
 
@@ -521,60 +521,23 @@ void EfhEngine::initMapMonsters() {
 		
 		for (uint counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
-			uint16 pictureRef = kEncounters[_mapMonsters[monsterId]._monsterRef]._pictureRef;
+			uint16 pictureRef = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._pictureRef;
 
 			if (rand100 <= 25) {
 				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef - delta;
+				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef - delta;
 			} else if (rand100 <= 75) {
-				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef;
+				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef;
 			} else {
 				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[monsterId]._hitPoints[counter] = pictureRef + delta;
+				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef + delta;
 			}
 		}
 	}
 }
 
 void EfhEngine::loadMapArrays(int idx) {
-	debugC(6, kDebugEngine, "loadMapArrays %d", idx);
-	debug("TODO : rewrite the pre-loading of data and loadMapArrays in order to avoid to lose info when changing map");
-
-	uint8 *mapSpecialTilePtr = &_mapArr[idx][2];
-
-	for (int i = 0; i < 100; ++i) {
-		_mapSpecialTile[i]._placeId = mapSpecialTilePtr[9 * i];
-		_mapSpecialTile[i]._posX = mapSpecialTilePtr[9 * i + 1];
-		_mapSpecialTile[i]._posY = mapSpecialTilePtr[9 * i + 2];
-		_mapSpecialTile[i]._field3 = mapSpecialTilePtr[9 * i + 3];
-		_mapSpecialTile[i]._triggerId = mapSpecialTilePtr[9 * i + 4];
-		_mapSpecialTile[i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
-		_mapSpecialTile[i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
-	}
-
-	uint8 *mapMonstersPtr = &_mapArr[idx][902];
-
-	for (int i = 0; i < 64; ++i) {
-		_mapMonsters[i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
-		_mapMonsters[i]._npcId = mapMonstersPtr[29 * i + 1];
-		_mapMonsters[i]._fullPlaceId = mapMonstersPtr[29 * i + 2];
-		_mapMonsters[i]._posX = mapMonstersPtr[29 * i + 3];
-		_mapMonsters[i]._posY = mapMonstersPtr[29 * i + 4];
-		_mapMonsters[i]._weaponItemId = mapMonstersPtr[29 * i + 5];
-		_mapMonsters[i]._maxDamageAbsorption = mapMonstersPtr[29 * i + 6];
-		_mapMonsters[i]._monsterRef = mapMonstersPtr[29 * i + 7];
-		_mapMonsters[i]._additionalInfo = mapMonstersPtr[29 * i + 8];
-		_mapMonsters[i]._talkTextId = mapMonstersPtr[29 * i + 9];
-		_mapMonsters[i]._groupSize = mapMonstersPtr[29 * i + 10];
-		for (int j = 0; j < 9; ++j)
-			_mapMonsters[i]._hitPoints[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
-	}
-
-	uint8 *mapPtr = &_mapArr[idx][2758];
-	for (int i = 0; i < 64; ++i) {
-		for (int j = 0; j < 64; ++j)
-			_mapGameMap[i][j] = *mapPtr++;
-	}
+	// No longer required as everything is in memory. 
 }
 
 void EfhEngine::saveAnimImageSetId() {
@@ -703,7 +666,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 		int16 drawPosX = 128;
 		for (int16 counterX = minX; counterX <= maxX; ++counterX) {
 			if (largeMapFl) {
-				int16 curTile = _mapGameMap[counterX][counterY];
+				int16 curTile = _mapGameMaps[_techId][counterX][counterY];
 				displayRawDataAtPos(_imageSetSubFilesArray[curTile], drawPosX, drawPosY);
 			} else {
 				int16 curTile = _curPlace[counterX][counterY];
@@ -723,26 +686,26 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 
 	if (drawMonstersFl) {
 		for (uint var16 = 0; var16 < 64; ++var16) {
-			if ((_largeMapFlag && _mapMonsters[var16]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[var16]._fullPlaceId == _fullPlaceId)){
+			if ((_largeMapFlag && _mapMonsters[_techId][var16]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[_techId][var16]._fullPlaceId == _fullPlaceId)){
 				bool var4 = false;
-				int16 posX = _mapMonsters[var16]._posX;
-				int16 posY = _mapMonsters[var16]._posY;
+				int16 posX = _mapMonsters[_techId][var16]._posX;
+				int16 posY = _mapMonsters[_techId][var16]._posY;
 
 				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
 					continue;
 
 				for (uint counterY = 0; counterY < 9 && !var4; ++counterY) {
-					if (_mapMonsters[var16]._hitPoints[counterY] > 0)
+					if (_mapMonsters[_techId][var16]._hitPoints[counterY] > 0)
 						var4 = true;
 				}
 
 				if (!var4)
 					continue;
 
-				int16 var6 = 148 + kEncounters[_mapMonsters[var16]._monsterRef]._animId;
-				int16 var1 = _mapMonsters[var16]._possessivePronounSHL6 & 0x3F;
+				int16 var6 = 148 + kEncounters[_mapMonsters[_techId][var16]._monsterRef]._animId;
+				int16 var1 = _mapMonsters[_techId][var16]._possessivePronounSHL6 & 0x3F;
 
-				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[var16]._npcId))
+				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[_techId][var16]._npcId))
 					continue;
 
 				int16 drawPosX = 128 + (posX - minX) * 16;
@@ -1119,7 +1082,7 @@ void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
 			int16 curY = counterY + minY;
 
 			if (curX < 64 && curY < 64)
-				_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
+				_mapGameMaps[_techId][curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
@@ -1130,7 +1093,7 @@ void EfhEngine::transitionMap(int16 centerX, int16 centerY) {
 			int16 curY = counterY + minY;
 
 			if (curX < 64 && curY < 64)
-				_mapGameMap[curX][curY] = _curPlace[counterX][counterY];
+				_mapGameMaps[_techId][curX][curY] = _curPlace[counterX][counterY];
 		}
 		drawScreen();
 	}
@@ -1168,7 +1131,7 @@ int16 EfhEngine::findMapSpecialTileIndex(int16 posX, int16 posY) {
 	uint16 searchPlaceId = _largeMapFlag ? 0xFE : _fullPlaceId;
 	
 	for (uint counter = 0; counter < 100; ++counter) {
-		if (_mapSpecialTile[counter]._posX == posX && _mapSpecialTile[counter]._posY == posY && _mapSpecialTile[counter]._placeId == searchPlaceId)
+		if (_mapSpecialTiles[_techId][counter]._posX == posX && _mapSpecialTiles[_techId][counter]._posY == posY && _mapSpecialTiles[_techId][counter]._placeId == searchPlaceId)
 			return counter;
 	}
 
@@ -1371,13 +1334,13 @@ void EfhEngine::computeMapAnimation() {
 				continue;
 
 			if (_largeMapFlag) {
-				uint8 curTile = _mapGameMap[counterX][counterY];
+				uint8 curTile = _mapGameMaps[_techId][counterX][counterY];
 				if (curTile >= 1 && curTile <= 0xF) {
 					if (getRandom(100) < 50)
-						_mapGameMap[counterX][counterY] += 0xC5;
+						_mapGameMaps[_techId][counterX][counterY] += 0xC5;
 				} else if (curTile >= 0xC6 && curTile <= 0xD5) {
 					if (getRandom(100) < 50)
-						_mapGameMap[counterX][counterY] -= 0xC5;
+						_mapGameMaps[_techId][counterX][counterY] -= 0xC5;
 				}
 			} else {
 				uint8 curTile = _curPlace[counterX][counterY];
@@ -1414,10 +1377,10 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 	debugC(3, kDebugEngine,"checkMonsterMoveCollisionAndTileTexture %d", monsterId);
 
 	int16 maxSize = _largeMapFlag ? 63 : 23;
-	if (_mapMonsters[monsterId]._posX < 0 || _mapMonsters[monsterId]._posY < 0 || _mapMonsters[monsterId]._posX > maxSize || _mapMonsters[monsterId]._posY > maxSize)
+	if (_mapMonsters[_techId][monsterId]._posX < 0 || _mapMonsters[_techId][monsterId]._posY < 0 || _mapMonsters[_techId][monsterId]._posX > maxSize || _mapMonsters[_techId][monsterId]._posY > maxSize)
 		return 0;
 
-	if (_mapMonsters[monsterId]._posX == _mapPosX && _mapMonsters[monsterId]._posY == _mapPosY)
+	if (_mapMonsters[_techId][monsterId]._posX == _mapPosX && _mapMonsters[_techId][monsterId]._posY == _mapPosY)
 		return 0;
 
 	for (int counter = 0; counter < 64; ++counter) {
@@ -1427,43 +1390,43 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 		if (!checkMapMonsterAvailability(counter))
 			continue;
 
-		if (_mapMonsters[monsterId]._fullPlaceId == _mapMonsters[counter]._fullPlaceId
-		 && _mapMonsters[monsterId]._posX == _mapMonsters[counter]._posX
-		 && _mapMonsters[monsterId]._posY == _mapMonsters[counter]._posY)
+		if (_mapMonsters[_techId][monsterId]._fullPlaceId == _mapMonsters[_techId][counter]._fullPlaceId
+		 && _mapMonsters[_techId][monsterId]._posX == _mapMonsters[_techId][counter]._posX
+		 && _mapMonsters[_techId][monsterId]._posY == _mapMonsters[_techId][counter]._posY)
 			return 0;
 	}
 
-	return checkTileStatus(_mapMonsters[monsterId]._posX, _mapMonsters[monsterId]._posY, false);
+	return checkTileStatus(_mapMonsters[_techId][monsterId]._posX, _mapMonsters[_techId][monsterId]._posY, false);
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 	debugC(6, kDebugEngine, "moveMonsterAwayFromTeam %d", monsterId);
 
-	if (_mapMonsters[monsterId]._posX < _mapPosX) {
-		--_mapMonsters[monsterId]._posX;
-		if (_mapMonsters[monsterId]._posY < _mapPosY)
-			--_mapMonsters[monsterId]._posY;
-		else if (_mapMonsters[monsterId]._posY > _mapPosY)
-			++_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posX < _mapPosX) {
+		--_mapMonsters[_techId][monsterId]._posX;
+		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+			--_mapMonsters[_techId][monsterId]._posY;
+		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+			++_mapMonsters[_techId][monsterId]._posY;
 
 		return true;
 	}
 
-	if (_mapMonsters[monsterId]._posX > _mapPosX) {
-		++_mapMonsters[monsterId]._posX;
-		if (_mapMonsters[monsterId]._posY < _mapPosY)
-			--_mapMonsters[monsterId]._posY;
-		else if (_mapMonsters[monsterId]._posY > _mapPosY)
-			++_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posX > _mapPosX) {
+		++_mapMonsters[_techId][monsterId]._posX;
+		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+			--_mapMonsters[_techId][monsterId]._posY;
+		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+			++_mapMonsters[_techId][monsterId]._posY;
 
 		return true;
 	}
 
 	// Original checks for posX equality, which is the only possible option at this point => skipped
-	if (_mapMonsters[monsterId]._posY < _mapPosY)
-		--_mapMonsters[monsterId]._posY;
-	else if (_mapMonsters[monsterId]._posY > _mapPosY)
-		++_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+		--_mapMonsters[_techId][monsterId]._posY;
+	else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+		++_mapMonsters[_techId][monsterId]._posY;
 	else
 		return false;
 
@@ -1473,31 +1436,31 @@ bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 	debugC(6, kDebugEngine, "moveMonsterTowardsTeam %d", monsterId);
 
-	if (_mapMonsters[monsterId]._posX < _mapPosX) {
-		++_mapMonsters[monsterId]._posX;
-		if (_mapMonsters[monsterId]._posY < _mapPosY)
-			++_mapMonsters[monsterId]._posY;
-		else if (_mapMonsters[monsterId]._posY > _mapPosY)
-			--_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posX < _mapPosX) {
+		++_mapMonsters[_techId][monsterId]._posX;
+		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+			++_mapMonsters[_techId][monsterId]._posY;
+		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+			--_mapMonsters[_techId][monsterId]._posY;
 
 		return true;
 	}
 
-	if (_mapMonsters[monsterId]._posX > _mapPosX) {
-		--_mapMonsters[monsterId]._posX;
-		if (_mapMonsters[monsterId]._posY < _mapPosY)
-			++_mapMonsters[monsterId]._posY;
-		else if (_mapMonsters[monsterId]._posY > _mapPosY)
-			--_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posX > _mapPosX) {
+		--_mapMonsters[_techId][monsterId]._posX;
+		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+			++_mapMonsters[_techId][monsterId]._posY;
+		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+			--_mapMonsters[_techId][monsterId]._posY;
 
 		return true;
 	}
 
 	// Original checks for posX equality, which is the only possible option at this point => skipped
-	if (_mapMonsters[monsterId]._posY < _mapPosY)
-		++_mapMonsters[monsterId]._posY;
-	else if (_mapMonsters[monsterId]._posY > _mapPosY)
-		--_mapMonsters[monsterId]._posY;
+	if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
+		++_mapMonsters[_techId][monsterId]._posY;
+	else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
+		--_mapMonsters[_techId][monsterId]._posY;
 	else
 		return false;
 
@@ -1511,39 +1474,39 @@ bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 
 	switch (direction - 1) {
 	case 0:
-		--_mapMonsters[monsterId]._posY;
+		--_mapMonsters[_techId][monsterId]._posY;
 		retVal = true;
 		break;
 	case 1:
-		--_mapMonsters[monsterId]._posY;
-		++_mapMonsters[monsterId]._posX;
+		--_mapMonsters[_techId][monsterId]._posY;
+		++_mapMonsters[_techId][monsterId]._posX;
 		retVal = true;
 		break;
 	case 2:
-		++_mapMonsters[monsterId]._posX;
+		++_mapMonsters[_techId][monsterId]._posX;
 		retVal = true;
 		break;
 	case 3:
-		++_mapMonsters[monsterId]._posX;
-		++_mapMonsters[monsterId]._posY;
+		++_mapMonsters[_techId][monsterId]._posX;
+		++_mapMonsters[_techId][monsterId]._posY;
 		retVal = true;
 		break;
 	case 4:
-		++_mapMonsters[monsterId]._posY;
+		++_mapMonsters[_techId][monsterId]._posY;
 		retVal = true;
 		break;
 	case 5:
-		++_mapMonsters[monsterId]._posY;
-		--_mapMonsters[monsterId]._posX;
+		++_mapMonsters[_techId][monsterId]._posY;
+		--_mapMonsters[_techId][monsterId]._posX;
 		retVal = true;
 		break;
 	case 6:
-		--_mapMonsters[monsterId]._posX;
+		--_mapMonsters[_techId][monsterId]._posX;
 		retVal = true;
 		break;
 	case 7:
-		--_mapMonsters[monsterId]._posX;
-		--_mapMonsters[monsterId]._posY;
+		--_mapMonsters[_techId][monsterId]._posX;
+		--_mapMonsters[_techId][monsterId]._posY;
 		retVal = true;
 		break;
 	default:
@@ -1572,8 +1535,8 @@ bool EfhEngine::moveMonsterGroupRandom(int16 monsterId) {
 int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
 	debugC(2, kDebugEngine, "computeMonsterGroupDistance %d", monsterId);
 
-	int16 monsterPosX = _mapMonsters[monsterId]._posX;
-	int16 monsterPosY = _mapMonsters[monsterId]._posY;
+	int16 monsterPosX = _mapMonsters[_techId][monsterId]._posX;
+	int16 monsterPosY = _mapMonsters[_techId][monsterId]._posY;
 
 	int16 deltaX = monsterPosX - _mapPosX;
 	int16 deltaY = monsterPosY - _mapPosY;
@@ -1600,10 +1563,10 @@ bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	if (teamFlag)
 		monsterId = _teamMonsterIdArray[id];
 
-	if ((_mapMonsters[monsterId]._additionalInfo & 0xF) >= 8)
+	if ((_mapMonsters[_techId][monsterId]._additionalInfo & 0xF) >= 8)
 		return true;
 
-	if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._additionalInfo & 0x80) != 0)
+	if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80) != 0)
 		return true;
 
 	return false;
@@ -1616,7 +1579,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 		return true;
 
 	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[monsterId]._weaponItemId))
+		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[_techId][monsterId]._weaponItemId))
 			return false;
 	}
 
@@ -1626,10 +1589,10 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkIfMonsterOnSameLargeMapPlace %d", monsterId);
 
-	if (_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == 0xFE)
+	if (_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE)
 		return true;
 
-	if (!_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == _fullPlaceId)
+	if (!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId)
 		return true;
 
 	return false;
@@ -1638,7 +1601,7 @@ bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 bool EfhEngine::checkMonsterWeaponRange(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMonsterWeaponRange %d", monsterId);
 
-	return checkWeaponRange(monsterId, _mapMonsters[monsterId]._weaponItemId);
+	return checkWeaponRange(monsterId, _mapMonsters[_techId][monsterId]._weaponItemId);
 }
 
 void EfhEngine::handleMapMonsterMoves() {
@@ -1662,8 +1625,8 @@ void EfhEngine::handleMapMonsterMoves() {
 		if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 			continue;
 
-		int16 previousPosX = _mapMonsters[monsterId]._posX;
-		int16 previousPosY = _mapMonsters[monsterId]._posY;
+		int16 previousPosX = _mapMonsters[_techId][monsterId]._posX;
+		int16 previousPosY = _mapMonsters[_techId][monsterId]._posY;
 
 		if (previousPosX < minDisplayedMapX || previousPosX > maxDisplayedMapX || previousPosY < minDisplayedMapY || previousPosY > maxDisplayedMapY)
 			continue;
@@ -1671,12 +1634,12 @@ void EfhEngine::handleMapMonsterMoves() {
 		bool monsterMovedFl = false;
 		int16 lastRangeCheck = 0;
 
-		int8 monsterMoveType = _mapMonsters[monsterId]._additionalInfo & 0xF; // 0000 1111
+		int8 monsterMoveType = _mapMonsters[_techId][monsterId]._additionalInfo & 0xF; // 0000 1111
 
-		if (_unk2C8AA != 0 && (_mapMonsters[monsterId]._additionalInfo & 0x80)) // 1000 0000
+		if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80)) // 1000 0000
 			monsterMoveType = 9;
 
-		int16 randomModPct = _mapMonsters[monsterId]._additionalInfo & 0x70; // 0111 0000
+		int16 randomModPct = _mapMonsters[_techId][monsterId]._additionalInfo & 0x70; // 0111 0000
 		randomModPct >>= 4; // Max 7 (0111)
 
 		int16 retryCounter = randomModPct;
@@ -1788,13 +1751,13 @@ void EfhEngine::handleMapMonsterMoves() {
 					int8 checkMoveFl = checkMonsterMoveCollisionAndTileTexture(monsterId);
 
 					if (checkMoveFl == 0) { // Blocked
-						_mapMonsters[monsterId]._posX = previousPosX;
-						_mapMonsters[monsterId]._posY = previousPosY;
+						_mapMonsters[_techId][monsterId]._posX = previousPosX;
+						_mapMonsters[_techId][monsterId]._posY = previousPosY;
 						monsterMovedFl = false;
 						--retryCounter;
 					} else if (checkMoveFl == 2) { // Wall
-						_mapMonsters[monsterId]._posX = previousPosX;
-						_mapMonsters[monsterId]._posY = previousPosY;
+						_mapMonsters[_techId][monsterId]._posX = previousPosX;
+						_mapMonsters[_techId][monsterId]._posY = previousPosY;
 					}
 				}
 
@@ -1815,11 +1778,11 @@ void EfhEngine::handleMapMonsterMoves() {
 bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMapMonsterAvailability %d", monsterId);
 
-	if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
+	if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
 		return false;
 
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[monsterId]._hitPoints[counter] > 0)
+		if (_mapMonsters[_techId][monsterId]._hitPoints[counter] > 0)
 			return true;
 	}
 
@@ -1829,7 +1792,7 @@ bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
 void EfhEngine::displayMonsterAnim(int16 monsterId) {
 	debugC(6, kDebugEngine, "displayMonsterAnim %d", monsterId);
 
-	int16 animId = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
+	int16 animId = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._animId;
 	displayAnimFrames(animId, true);
 }
 
@@ -1841,7 +1804,7 @@ int16 EfhEngine::countAliveMonsters(int16 id) {
 	int16 count = 0;
 
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[id]._hitPoints[counter] > 0)
+		if (_mapMonsters[_techId][id]._hitPoints[counter] > 0)
 			++count;
 	}
 
@@ -1860,7 +1823,7 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	debugC(6, kDebugEngine, "handleTalk %d %d %d", monsterId, arg2, itemId);
 
-	if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
+	if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
 		return false;
 
 	if (countAliveMonsters(monsterId) < 1)
@@ -1872,20 +1835,20 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	if (!checkMonsterGroupDistance1OrLess(monsterId))
 		return false;
 
-	if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F) {
-		if (_mapMonsters[monsterId]._talkTextId == 0xFF || arg2 != 5) {
+	if ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F) {
+		if (_mapMonsters[_techId][monsterId]._talkTextId == 0xFF || arg2 != 5) {
 			return false;
 		}
 		displayMonsterAnim(monsterId);
-		displayImp1Text(_mapMonsters[monsterId]._talkTextId);
+		displayImp1Text(_mapMonsters[_techId][monsterId]._talkTextId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	}
 
-	if (isNpcATeamMember(_mapMonsters[monsterId]._npcId))
+	if (isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId))
 		return false;
 
-	int16 npcId = _mapMonsters[monsterId]._npcId;
+	int16 npcId = _mapMonsters[_techId][monsterId]._npcId;
 	switch (_npcBuf[npcId].field_10 - 0xEE) {
 	case 0:
 		if (arg2 == 4 && _npcBuf[npcId].field11_NpcId == itemId) {
@@ -2154,35 +2117,35 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (arg8 == 0) {
-		if (_mapSpecialTile[tileId]._field3 == 0xFF) {
-			displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+		if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFF) {
+			displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 			return true;
 		}
 
-		if (_mapSpecialTile[tileId]._field3 == 0xFE) {
+		if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFE) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
-				if (_teamCharId[counter] == _mapSpecialTile[tileId]._triggerId) {
-					displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+				if (_teamCharId[counter] == _mapSpecialTiles[_techId][tileId]._triggerId) {
+					displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 					return true;
 				}
 			}
-		} else if (_mapSpecialTile[tileId]._field3 == 0xFD) {
+		} else if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFD) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTile[tileId]._triggerId) {
-						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
+						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		// original makes a useless check on (_mapSpecialTile[tileId]._field3 > 0x7F)
-		} else if (_mapSpecialTile[tileId]._field3 <= 0x77) {
-			int16 var6 = _mapSpecialTile[tileId]._field3;
+		} else if (_mapSpecialTiles[_techId][tileId]._field3 <= 0x77) {
+			int16 var6 = _mapSpecialTiles[_techId][tileId]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
@@ -2191,26 +2154,26 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
 					warning("sub22293 - _activeScore[%d]", var6);
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTile[tileId]._triggerId) {
-						displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
+						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		}
-	} else if ((_mapSpecialTile[tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTile[tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTile[tileId]._field3 == 0xFB && arg8 == 3)) {
-		if (_mapSpecialTile[tileId]._triggerId == itemId) {
-			displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+	} else if ((_mapSpecialTiles[_techId][tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTiles[_techId][tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTiles[_techId][tileId]._field3 == 0xFB && arg8 == 3)) {
+		if (_mapSpecialTiles[_techId][tileId]._triggerId == itemId) {
+			displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 			return true;
 		}
 	} else if (arg8 == 4) {
-		int16 var6 = _mapSpecialTile[tileId]._field3;
+		int16 var6 = _mapSpecialTiles[_techId][tileId]._field3;
 		if (var6 >= 0x78 && var6 <= 0xEF) {
 			var6 -= 0x78;
 			warning("sub22293 - _activeScore[%d]", var6);
 			// The 2 checks on var6 are useless, as [0x78..0xEF] - 0x78 => [0x00..0x77]
-			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTile[tileId]._triggerId <= _npcBuf[charId]._activeScore[itemId]) {
-				displayImp1Text(_mapSpecialTile[tileId]._field5_textId);
+			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTiles[_techId][tileId]._triggerId <= _npcBuf[charId]._activeScore[itemId]) {
+				displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 				return true;
 			}
 		}
@@ -2222,10 +2185,10 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 	}
 
 	// CHECKME: there's suspiciously no check on tileId
-	if ((arg8 == 4 && _mapSpecialTile[tileId]._field3 < 0xFA) || arg8 != 4) {
-		if (_mapSpecialTile[tileId]._field7_textId > 0xFE)
+	if ((arg8 == 4 && _mapSpecialTiles[_techId][tileId]._field3 < 0xFA) || arg8 != 4) {
+		if (_mapSpecialTiles[_techId][tileId]._field7_textId > 0xFE)
 			return false;
-		displayImp1Text(_mapSpecialTile[tileId]._field7_textId);
+		displayImp1Text(_mapSpecialTiles[_techId][tileId]._field7_textId);
 		return true;
 	}
 
@@ -2250,7 +2213,7 @@ int8 EfhEngine::checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4) {
 	if (_tileFact[tileFactId]._tileId != 0xFF && !_dbgForceMonsterBlock) {
 		if ((arg4) || (!arg4 && tileFactId != 128 && tileFactId != 121)) {
 			if (_largeMapFlag) {
-				_mapGameMap[mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
+				_mapGameMaps[_techId][mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
 			} else {
 				_curPlace[mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
 			}
@@ -2284,7 +2247,7 @@ void EfhEngine::computeInitiatives() {
 			_initiatives[counter + 3]._initiative = -1;
 		} else {
 			_initiatives[counter + 3]._id = counter;
-			_initiatives[counter + 3]._initiative = _mapMonsters[_teamMonsterIdArray[counter]]._npcId + getRandom(20);
+			_initiatives[counter + 3]._initiative = _mapMonsters[_techId][_teamMonsterIdArray[counter]]._npcId + getRandom(20);
 		}
 	}
 
@@ -2368,14 +2331,14 @@ void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask,
 	}
 
 	mask &= 0x0F;
-	_mapMonsters[monsterId]._additionalInfo &= 0xF0;
-	_mapMonsters[monsterId]._additionalInfo |= mask;
+	_mapMonsters[_techId][monsterId]._additionalInfo &= 0xF0;
+	_mapMonsters[_techId][monsterId]._additionalInfo |= mask;
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	debugC(5, kDebugEngine, "isMonsterActive %d %d", groupId, id);
 
-	if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
+	if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
 		return true;
 	return false;
 }
@@ -2420,15 +2383,15 @@ bool EfhEngine::checkMonsterCollision() {
 		if (!checkMapMonsterAvailability(monsterId))
 			continue;
 
-		if (!(_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == 0xFE)
-		 && !(!_largeMapFlag && _mapMonsters[monsterId]._fullPlaceId == _fullPlaceId))
+		if (!(_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE)
+		 && !(!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId))
 			continue;
 
-		if ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
-		 && ((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[monsterId]._npcId)))
+		if ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
+		 && ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId)))
 			continue;
 
-		if (_mapMonsters[monsterId]._posX != _mapPosX || _mapMonsters[monsterId]._posY != _mapPosY)
+		if (_mapMonsters[_techId][monsterId]._posX != _mapPosX || _mapMonsters[_techId][monsterId]._posY != _mapPosY)
 			continue;
 
 		_mapPosX = _oldMapPosX;
@@ -2439,7 +2402,7 @@ bool EfhEngine::checkMonsterCollision() {
 
 		int16 mobsterCount = 0;
 		for (uint mobsterCounter = 0; mobsterCounter < 9; ++mobsterCounter) {
-			if (_mapMonsters[monsterId]._hitPoints[mobsterCounter])
+			if (_mapMonsters[_techId][monsterId]._hitPoints[mobsterCounter])
 				++mobsterCount;
 		}
 
@@ -2448,18 +2411,18 @@ bool EfhEngine::checkMonsterCollision() {
 		do {
 			for (uint displayCounter = 0; displayCounter < 2; ++displayCounter) {
 				Common::String dest;
-				switch (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) {
+				switch (_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) {
 				case 0x3E:
 					buffer = "(NOT DEFINED)";
 					dest = "(NOT DEFINED)";
 					break;
 				case 0x3F:
 					// Special character name
-					dest = _npcBuf[_mapMonsters[monsterId]._npcId]._name;
+					dest = _npcBuf[_mapMonsters[_techId][monsterId]._npcId]._name;
 					buffer = Common::String("with ") + dest;
 					break;
 				default:
-					dest = kEncounters[_mapMonsters[monsterId]._monsterRef]._name;
+					dest = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._name;
 					if (mobsterCount > 1)
 						dest += "s";
 
@@ -2544,8 +2507,10 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 
 	_currentTileBankImageSetId[bankId] = setId;
 
-	if (bankId == 0 || bankId == 1)
-		_mapBitmapRefArr[_techId][bankId] = setId;
+	if (bankId == 0)
+		_mapBitmapRefArr[_techId]._setId1 = setId;
+	else if (bankId == 1)
+		_mapBitmapRefArr[_techId]._setId2 = setId;
 
 	int16 ptrIndex = bankId * 72;
 	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _hiResImageBuf);
@@ -2628,7 +2593,7 @@ uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	debugC(3, kDebugEngine, "getMapTileInfo %d-%d", mapPosX, mapPosY);
 
 	if (_largeMapFlag)
-		return _mapGameMap[mapPosX][mapPosY];
+		return _mapGameMaps[_techId][mapPosX][mapPosY];
 
 	return _curPlace[mapPosX][mapPosY];
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 94137f0bd4c..8d4f84b1e08 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -177,6 +177,7 @@ struct NPCStruct {
 
 	void init();
 	uint8 getPronoun();
+	void synchronize(Common::Serializer &s);
 };
 
 struct FontDescr {
@@ -537,10 +538,16 @@ private:
 	Common::String _attackBuffer;
 	Common::String _messageToBePrinted;
 
-	uint8 *_mapBitmapRefArr[19];
-	MapSpecialTileStruct _mapSpecialTile[100];
-	MapMonster _mapMonsters[64];
-	uint8 _mapGameMap[64][64];
+	struct BitmapRef {
+		int8 _setId1;
+		int8 _setId2;
+	};
+
+	BitmapRef _mapBitmapRefArr[19];
+	
+	MapSpecialTileStruct _mapSpecialTiles[19][100];
+	MapMonster _mapMonsters[19][64];
+	uint8 _mapGameMaps[19][64][64];
 
 	uint8 _defaultBoxColor;
 	FontDescr _fontDescr;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index e181e8a7901..e094730ac1e 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -37,10 +37,10 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 			break;
 
 		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if (_mapMonsters[monsterId]._fullPlaceId == 0xFF)
+			if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
 				continue;
 
-			if (((_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[monsterId]._npcId)) && (_mapMonsters[monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+			if (((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId)) && (_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
 				continue;
 
 			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
@@ -48,7 +48,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 
 			bool found = false;
 			for (uint subId = 0; subId < 9; ++subId) {
-				if (_mapMonsters[monsterId]._hitPoints[subId] > 0) {
+				if (_mapMonsters[_techId][monsterId]._hitPoints[subId] > 0) {
 					found = true;
 					break;
 				}
@@ -161,7 +161,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 				// handleFight - Loop on mobsterId - Start
 				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
 					if (isMonsterActive(monsterGroupIdOrMonsterId, ctrMobsterId)) {
-						int16 monsterWeaponItemId = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._weaponItemId;
+						int16 monsterWeaponItemId = _mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._weaponItemId;
 						if (monsterWeaponItemId == 0xFF)
 							monsterWeaponItemId = 0x3F;
 						int16 teamMemberId = -1;
@@ -187,7 +187,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
 								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
-								int16 ennemyPronoun = kEncounters[_mapMonsters[varInt]._monsterRef]._nameArticle;
+								int16 ennemyPronoun = kEncounters[_mapMonsters[_techId][varInt]._monsterRef]._nameArticle;
 								int16 characterPronoun = _npcBuf[_teamCharId[var7E]].getPronoun();
 								varInt = _items[monsterWeaponItemId].field_13;
 								_teamPctDodgeMiss[var7E] += (varInt * 5);
@@ -195,7 +195,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								int16 hitPoints = 0;
 								int16 originalDamage = 0;
 								int16 damagePointsAbsorbed = 0;
-								int16 var64 = _mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[monsterWeaponItemId]._attacks;
+								int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[monsterWeaponItemId]._attacks;
 								for (int var84 = 0; var84 < var64; ++var84) {
 									// handleFight - Loop var84 on var64 (objectId) - Start
 									if (getRandom(100) > _teamPctDodgeMiss[var7E])
@@ -245,7 +245,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 								else
 									_enemyNamePt1 = "";
 
-								_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
+								_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
 								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
 								_nameBuffer = _items[monsterWeaponItemId]._name;
 								if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
@@ -338,11 +338,11 @@ bool EfhEngine::handleFight(int16 monsterId) {
 							}
 							// handleFight - Loop on var7E - End
 						}
-					} else if (_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
+					} else if (_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
 						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId];
 						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId] <= 0) {
-							_enemyNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-							int16 var70 = kEncounters[_mapMonsters[_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
+							_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
+							int16 var70 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
 							if (var70 == 2)
 								_enemyNamePt1 = "The ";
 							else
@@ -463,12 +463,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					} else
 						noticedFl = false;
 
-					int16 var76 = getRandom(_mapMonsters[_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
+					int16 var76 = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
 					int16 ennemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
 					int16 monsterId = _teamMonsterIdArray[groupId];
-					int16 characterPronoun = kEncounters[_mapMonsters[monsterId]._monsterRef]._nameArticle;
+					int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
 					int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
-					int16 hitPointsBefore = _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
+					int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
 					int16 hitCount = 0;
 					int16 originalDamage = 0;
 					int16 damagePointsAbsorbed = 0;
@@ -501,7 +501,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						hitCount = 0;
 
 					if (hitCount > 0) {
-						_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
+						_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
 						if (hitCount > 1) {
 							_attackBuffer = Common::String::format("%d times ", hitCount);
 						} else {
@@ -521,7 +521,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						_enemyNamePt1 = "";
 					}
 
-					_characterNamePt2 = kEncounters[_mapMonsters[_teamMonsterIdArray[groupId]]._monsterRef]._name;
+					_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
 					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 					_nameBuffer = _items[teamCharItemId]._name;
 					if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
@@ -532,7 +532,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 						} else if (hitPoints == 1) {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -540,7 +540,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 							}
 						} else {
 							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 								getDeathTypeDescription(groupId, teamCharId + 1000);
 								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 							} else {
@@ -550,16 +550,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check damages - End
 
 						// Action A - Add reaction text - Start
-						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-							if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
+						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
 								addReactionText(kEfhReactionReels);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
+							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
 								addReactionText(kEfhReactionCriesOut);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
+							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
 								addReactionText(kEfhReactionFalters);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
+							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
 								addReactionText(kEfhReactionWinces);
-							} else if (_mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
+							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
 								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
 								addReactionText(kEfhReactionScreams);
 							} else if (hitPointsBefore / 8 >= originalDamage) {
@@ -572,7 +572,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Add reaction text - End
 
 						// Action A - Add armor absorb text - Start
-						if (var76 && hitCount && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+						if (var76 && hitCount && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
 							if (damagePointsAbsorbed <= 1)
 								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							else
@@ -602,13 +602,13 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						// Action A - Check item durability - End
 
 						// Action A - Check effect - Start
-						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
 							if (getRandom(100) < 35) {
 								_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 1;
 								_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
 								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 							}
-						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
 							_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 2;
 							_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
@@ -746,7 +746,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 		pronoun = _npcBuf[charId].getPronoun();
 	} else {
 		int16 charId = _teamMonsterIdArray[victimId];
-		pronoun = _mapMonsters[charId].getPronoun();
+		pronoun = _mapMonsters[_techId][charId].getPronoun();
 	}
 
 	if (pronoun > 2)
@@ -769,7 +769,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 	} else if (_teamMonsterIdArray[attackerId] == -1)
 		deathType = 0;
 	else {
-		int16 itemId = _mapMonsters[_teamMonsterIdArray[attackerId]]._weaponItemId;
+		int16 itemId = _mapMonsters[_techId][_teamMonsterIdArray[attackerId]]._weaponItemId;
 		deathType = _items[itemId]._attackType + 1;
 	}
 
@@ -1170,7 +1170,7 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 	debugC(3, kDebugFight, "getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
 
 	int16 oldXpLevel = getXPLevel(_npcBuf[charId]._xp);
-	_npcBuf[charId]._xp += kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven;
+	_npcBuf[charId]._xp += kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._xpGiven;
 
 	if (getXPLevel(_npcBuf[charId]._xp) > oldXpLevel) {
 		generateSound(15);
@@ -1189,7 +1189,7 @@ void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Commo
 		_npcBuf[charId]._infoScore[4] += getRandom(3) - 1;
 	}
 
-	_messageToBePrinted += Common::String::format("  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[monsterId]._monsterRef]._xpGiven);
+	_messageToBePrinted += Common::String::format("  %s%s gains %d experience", namePt1.c_str(), namePt2.c_str(), kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._xpGiven);
 	if (!characterSearchesMonsterCorpse(charId, monsterId))
 		_messageToBePrinted += "!";
 }
@@ -1198,11 +1198,11 @@ bool EfhEngine::characterSearchesMonsterCorpse(int16 charId, int16 monsterId) {
 	debugC(3, kDebugFight, "characterSearchesMonsterCorpse %d %d", charId, monsterId);
 
 	int16 rndVal = getRandom(100);
-	if (kEncounters[_mapMonsters[monsterId]._monsterRef]._dropOccurrencePct < rndVal)
+	if (kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._dropOccurrencePct < rndVal)
 		return false;
 
 	rndVal = getRandom(5) - 1;
-	int16 itemId = kEncounters[_mapMonsters[monsterId]._monsterRef]._dropItemId[rndVal];
+	int16 itemId = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._dropItemId[rndVal];
 	if (itemId == -1 || itemId == 0)
 		return false;
 
@@ -1348,16 +1348,16 @@ void EfhEngine::sub1C4CA(bool whiteFl) {
 		Common::String buffer = Common::String::format("%c)", 'A' + counter);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
-		int16 var1 = _mapMonsters[_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
+		int16 var1 = _mapMonsters[_techId][_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
 		if (var1 <= 0x3D) {
-			buffer = Common::String::format("%d %s", mobsterCount, kEncounters[_mapMonsters[_teamMonsterIdArray[counter]]._monsterRef]._name);
+			buffer = Common::String::format("%d %s", mobsterCount, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[counter]]._monsterRef]._name);
 			displayStringAtTextPos(buffer);
 			if (mobsterCount > 1)
 				displayStringAtTextPos("s");
 		} else if (var1 == 0x3E) {
 			displayStringAtTextPos("(NOT DEFINED)");
 		} else if (var1 == 0x3F) {
-			Common::String stringToDisplay = _npcBuf[_mapMonsters[_teamMonsterIdArray[counter]]._npcId]._name;
+			Common::String stringToDisplay = _npcBuf[_mapMonsters[_techId][_teamMonsterIdArray[counter]]._npcId]._name;
 			displayStringAtTextPos(stringToDisplay);
 		}
 
@@ -1410,12 +1410,12 @@ int16 EfhEngine::getWeakestMobster(int16 groupNumber) {
 		if (!isMonsterActive(groupNumber, counter))
 			continue;
 
-		if (_mapMonsters[monsterId]._hitPoints[weakestMobsterId] > _mapMonsters[monsterId]._hitPoints[counter])
+		if (_mapMonsters[_techId][monsterId]._hitPoints[weakestMobsterId] > _mapMonsters[_techId][monsterId]._hitPoints[counter])
 			weakestMobsterId = counter;
 	}
 
 	// Useless check, as the
-	if (_mapMonsters[monsterId]._hitPoints[weakestMobsterId] <= 0)
+	if (_mapMonsters[_techId][monsterId]._hitPoints[weakestMobsterId] <= 0)
 		return -1;
 
 	return weakestMobsterId;
@@ -1524,7 +1524,7 @@ bool EfhEngine::checkSpecialItemsOnCurrentPlace(int16 itemId) {
 bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	debugC(3, kDebugFight, "hasAdequateDefense %d %d", monsterId, attackType);
 
-	int16 itemId = _mapMonsters[monsterId]._weaponItemId;
+	int16 itemId = _mapMonsters[_techId][monsterId]._weaponItemId;
 
 	if (_items[itemId]._specialEffect != 0)
 		return false;
@@ -1561,7 +1561,7 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 			continue;
 
 		for (uint ctrMobster = 0; ctrMobster < 9; ++ctrMobster) {
-			_mapMonsters[_teamMonsterIdArray[ctrGroupId]]._hitPoints[ctrMobster] = 0;
+			_mapMonsters[_techId][_teamMonsterIdArray[ctrGroupId]]._hitPoints[ctrMobster] = 0;
 			_teamMonsterEffects[ctrGroupId]._effect[ctrMobster] = 0;
 			_teamMonsterEffects[ctrGroupId]._duration[ctrMobster] = 0;
 		}
@@ -1595,14 +1595,14 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 				break;
 
 			for (uint ctrMapMonsterId = 0; ctrMapMonsterId < 64; ++ctrMapMonsterId) {
-				if (_mapMonsters[ctrMapMonsterId]._fullPlaceId == 0xFF)
+				if (_mapMonsters[_techId][ctrMapMonsterId]._fullPlaceId == 0xFF)
 					continue;
 
-				if (((_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[ctrMapMonsterId]._npcId)) || (_mapMonsters[ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
+				if (((_mapMonsters[_techId][ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) == 0x3F && !isNpcATeamMember(_mapMonsters[_techId][ctrMapMonsterId]._npcId)) || (_mapMonsters[_techId][ctrMapMonsterId]._possessivePronounSHL6 & 0x3F) <= 0x3D) {
 					if (checkIfMonsterOnSameLargeMapPlace(ctrMapMonsterId)) {
 						bool monsterActiveFound = false;
 						for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-							if (_mapMonsters[ctrMapMonsterId]._hitPoints[ctrMobsterId] > 0) {
+							if (_mapMonsters[_techId][ctrMapMonsterId]._hitPoints[ctrMobsterId] > 0) {
 								monsterActiveFound = true;
 								break;
 							}
@@ -1660,12 +1660,12 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 		if (!checkMonsterMovementType(monsterId, false))
 			continue;
 
-		retVal = kEncounters[_mapMonsters[monsterId]._monsterRef]._animId;
+		retVal = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._animId;
 		break;
 	}
 
 	if (retVal == 0xFF)
-		retVal = kEncounters[_mapMonsters[_teamMonsterIdArray[0]]._monsterRef]._animId;
+		retVal = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[0]]._monsterRef]._animId;
 
 	return retVal;
 }
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 218c8208a14..9940cde059a 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -211,8 +211,8 @@ void EfhEngine::loadTechMapImp(int16 fileId) {
 	// The purpose is to properly load the misc map data in arrays in order to use them without being a pain afterwards
 	loadMapArrays(_techId);
 
-	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId][0] + 1);
-	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId][1] + 1);
+	loadImageSetToTileBank(1, _mapBitmapRefArr[_techId]._setId1 + 1);
+	loadImageSetToTileBank(2, _mapBitmapRefArr[_techId]._setId2 + 1);
 
 	initMapMonsters();
 	readImpFile(_techId, true);
@@ -323,16 +323,54 @@ void EfhEngine::loadNPCS() {
  * This is required in order to implement a clean savegame feature
  */
 void EfhEngine::preLoadMaps() {
-	for (int i = 0; i < 19; ++i) {
-		Common::String fileName = Common::String::format("tech.%d", i);
+	for (int idx = 0; idx < 19; ++idx) {
+		Common::String fileName = Common::String::format("tech.%d", idx);
 		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _techDataArr[i]);
+		uncompressBuffer(_hiResImageBuf, _techDataArr[idx]);
 
-		fileName = Common::String::format("map.%d", i);
+		fileName = Common::String::format("map.%d", idx);
 		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _mapArr[i]);
+		uncompressBuffer(_hiResImageBuf, _mapArr[idx]);
+
+		_mapBitmapRefArr[idx]._setId1 = _mapArr[idx][0];
+		_mapBitmapRefArr[idx]._setId2 = _mapArr[idx][1];
+
+		uint8 *mapSpecialTilePtr = &_mapArr[idx][2];
+
+		for (int i = 0; i < 100; ++i) {
+			_mapSpecialTiles[idx][i]._placeId = mapSpecialTilePtr[9 * i];
+			_mapSpecialTiles[idx][i]._posX = mapSpecialTilePtr[9 * i + 1];
+			_mapSpecialTiles[idx][i]._posY = mapSpecialTilePtr[9 * i + 2];
+			_mapSpecialTiles[idx][i]._field3 = mapSpecialTilePtr[9 * i + 3];
+			_mapSpecialTiles[idx][i]._triggerId = mapSpecialTilePtr[9 * i + 4];
+			_mapSpecialTiles[idx][i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
+			_mapSpecialTiles[idx][i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
+		}
+
+		uint8 *mapMonstersPtr = &_mapArr[idx][902];
+		for (int i = 0; i < 64; ++i) {
+			_mapMonsters[idx][i]._possessivePronounSHL6 = mapMonstersPtr[29 * i];
+			_mapMonsters[idx][i]._npcId = mapMonstersPtr[29 * i + 1];
+			_mapMonsters[idx][i]._fullPlaceId = mapMonstersPtr[29 * i + 2];
+			_mapMonsters[idx][i]._posX = mapMonstersPtr[29 * i + 3];
+			_mapMonsters[idx][i]._posY = mapMonstersPtr[29 * i + 4];
+			_mapMonsters[idx][i]._weaponItemId = mapMonstersPtr[29 * i + 5];
+			_mapMonsters[idx][i]._maxDamageAbsorption = mapMonstersPtr[29 * i + 6];
+			_mapMonsters[idx][i]._monsterRef = mapMonstersPtr[29 * i + 7];
+			_mapMonsters[idx][i]._additionalInfo = mapMonstersPtr[29 * i + 8];
+			_mapMonsters[idx][i]._talkTextId = mapMonstersPtr[29 * i + 9];
+			_mapMonsters[idx][i]._groupSize = mapMonstersPtr[29 * i + 10];
+			for (int j = 0; j < 9; ++j)
+				_mapMonsters[idx][i]._hitPoints[j] = READ_LE_INT16(&mapMonstersPtr[29 * i + 11 + j * 2]);
+		}
+
+		uint8 *mapPtr = &_mapArr[idx][2758];
+		for (int i = 0; i < 64; ++i) {
+			for (int j = 0; j < 64; ++j)
+				_mapGameMaps[idx][i][j] = *mapPtr++;
+		}
+		
 
-		_mapBitmapRefArr[i] = &_mapArr[i][0];
 	}
 }
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index f17d8eb6711..95ddff0a770 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -140,6 +140,63 @@ uint8 NPCStruct::getPronoun() {
 	return _possessivePronounSHL6 >> 6;
 }
 
+void NPCStruct::synchronize(Common::Serializer &s) {
+	for (int idx = 0; idx < 11; ++idx)
+		s.syncAsByte(_name[idx]);
+
+	s.syncAsByte(fieldB_textId);
+	s.syncAsByte(field_C);
+	s.syncAsByte(field_D);
+	s.syncAsByte(fieldE_textId);
+	s.syncAsByte(field_F);
+	s.syncAsByte(field_10);
+	s.syncAsByte(field11_NpcId);
+	s.syncAsSint16LE(field12_textId);
+	s.syncAsSint16LE(field14_textId);
+	s.syncAsSint32LE(_xp);
+	for (int idx = 0; idx < 15; ++idx)
+		s.syncAsByte(_activeScore[idx]);
+
+	for (int idx = 0; idx < 11; ++idx)
+		s.syncAsByte(_passiveScore[idx]);
+
+	for (int idx = 0; idx < 11; ++idx)
+		s.syncAsByte(_infoScore[idx]);
+
+	s.syncAsByte(field_3F);
+	s.syncAsByte(field_40);
+	for (int idx = 0; idx < 10; ++idx) {
+		s.syncAsSint16LE(_inventory[idx]._ref);
+		s.syncAsByte(_inventory[idx]._stat1);
+		s.syncAsByte(_inventory[idx]._curHitPoints);
+	}
+	s.syncAsByte(_possessivePronounSHL6);
+	s.syncAsByte(_speed);
+	s.syncAsByte(field_6B);
+	s.syncAsByte(field_6C);
+	s.syncAsByte(field_6D);
+	s.syncAsByte(_defaultDefenseItemId);
+	s.syncAsByte(field_6F);
+	s.syncAsByte(field_70);
+	s.syncAsByte(field_71);
+	s.syncAsByte(field_72);
+	s.syncAsByte(field_73);
+	s.syncAsSint16LE(_hitPoints);
+	s.syncAsSint16LE(_maxHP);
+	s.syncAsByte(field_78);
+	s.syncAsSint16LE(field_79);
+	s.syncAsSint16LE(field_7B);
+	s.syncAsByte(field_7D);
+	s.syncAsByte(field_7E);
+	s.syncAsByte(field_7F);
+	s.syncAsByte(field_80);
+	s.syncAsByte(field_81);
+	s.syncAsByte(field_82);
+	s.syncAsByte(field_83);
+	s.syncAsByte(field_84);
+	s.syncAsByte(field_85);
+}
+
 uint8 MapMonster::getPronoun() {
 	return _possessivePronounSHL6 >> 6;
 }
@@ -182,8 +239,10 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_videoMode = 0;
 	_graphicsStruct = nullptr;
 
-	for (int i = 0; i < 19; ++i)
-		_mapBitmapRefArr[i] = nullptr;
+	for (int i = 0; i < 19; ++i) {
+		_mapBitmapRefArr[i]._setId1 = 0;
+		_mapBitmapRefArr[i]._setId2 = 0;
+	}
 
 	_defaultBoxColor = 0;
 
@@ -229,7 +288,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 
 	for (int i = 0; i < 100; ++i) {
 		_imp1PtrArray[i] = nullptr;
-		_mapSpecialTile[i].init();
+		_mapSpecialTiles[_techId][i].init();
 	}
 
 	for (int i = 0; i < 432; ++i)
@@ -320,9 +379,9 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	for (int i = 0; i < 19; ++i) {
 		memset(_techDataArr[i], 0, ARRAYSIZE(_techDataArr[i]));
 		memset(_mapArr[i], 0, ARRAYSIZE(_mapArr[i]));
+		memset(_mapMonsters[i], 0, ARRAYSIZE(_mapMonsters[i]));
+		memset(_mapGameMaps[i], 0, ARRAYSIZE(_mapGameMaps[i]));
 	}
-	memset(_mapMonsters, 0, ARRAYSIZE(_mapMonsters));
-	memset(_mapGameMap, 0, ARRAYSIZE(_mapGameMap));
 	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
 	_regenCounter = 0;
 
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 0661e0e7f87..bfe6368794a 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -929,9 +929,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			}
 			// The original was duplicating this code in each branch of the previous random check.
 			if (victims > 1) {
-				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 		}
@@ -969,9 +969,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 			// </CHECKME>
@@ -997,14 +997,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
-						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+						_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 					}
 				}
 			} else {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
 						if (getRandom(100) < 50) {
-							_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+							_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 						}
 						break;
 					}
@@ -1020,13 +1020,13 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (getRandom(100) < 50) {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
 				for (uint counter = 0; counter < 9; ++counter) {
-					_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+					_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 				}
 			} else {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
-						_mapMonsters[_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+						_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
 					}
 				}
 			}
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index ed64a0c5a23..c832e470250 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -151,11 +151,37 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 		for (int j = 0; j < size; ++j)
 			s.syncAsByte(_techDataArr[i][j]);
 
+		s.syncAsByte(_mapBitmapRefArr[i]._setId1);
+		s.syncAsByte(_mapBitmapRefArr[i]._setId2);
+		for (int idx = 0; idx < 100; ++idx) {
+			s.syncAsByte(_mapSpecialTiles[i][idx]._placeId);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._posX);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._posY);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._field3);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._triggerId);
+			s.syncAsUint16LE(_mapSpecialTiles[i][idx]._field5_textId);
+			s.syncAsUint16LE(_mapSpecialTiles[i][idx]._field7_textId);
+		}
+
+		for (int idx = 0; idx < 64; ++idx) {
+			s.syncAsByte(_mapMonsters[i][idx]._possessivePronounSHL6);
+			s.syncAsByte(_mapMonsters[i][idx]._npcId);
+			s.syncAsByte(_mapMonsters[i][idx]._fullPlaceId);
+			s.syncAsByte(_mapMonsters[i][idx]._posX);
+			s.syncAsByte(_mapMonsters[i][idx]._posY);
+			s.syncAsByte(_mapMonsters[i][idx]._weaponItemId);
+			s.syncAsByte(_mapMonsters[i][idx]._maxDamageAbsorption);
+			s.syncAsByte(_mapMonsters[i][idx]._monsterRef);
+			s.syncAsByte(_mapMonsters[i][idx]._additionalInfo);
+			s.syncAsByte(_mapMonsters[i][idx]._talkTextId);
+			s.syncAsByte(_mapMonsters[i][idx]._groupSize);
+			for (int j = 0; j < 9; ++j)
+				s.syncAsSint16LE(_mapMonsters[i][idx]._hitPoints[j]);
+		}
+		
 		size = ARRAYSIZE(_mapArr[i]);
-		for (int j = 0; j < size; ++j)
+		for (int j = 2758; j < size; ++j)
 			s.syncAsByte(_mapArr[i][j]);
-
-		_mapBitmapRefArr[i] = &_mapArr[i][0];
 	}
 
 	// Dialog flags
@@ -164,62 +190,9 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 
 	// NPCs
 	for (int i = 0; i < 99; ++i) {
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._name[idx]);
-
-		s.syncAsByte(_npcBuf[i].fieldB_textId);
-		s.syncAsByte(_npcBuf[i].field_C);
-		s.syncAsByte(_npcBuf[i].field_D);
-		s.syncAsByte(_npcBuf[i].fieldE_textId);
-		s.syncAsByte(_npcBuf[i].field_F);
-		s.syncAsByte(_npcBuf[i].field_10);
-		s.syncAsByte(_npcBuf[i].field11_NpcId);
-		s.syncAsSint16LE(_npcBuf[i].field12_textId);
-		s.syncAsSint16LE(_npcBuf[i].field14_textId);
-		s.syncAsSint32LE(_npcBuf[i]._xp);
-		for (int idx = 0; idx < 15; ++idx)
-			s.syncAsByte(_npcBuf[i]._activeScore[idx]);
-
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._passiveScore[idx]);
-
-		for (int idx = 0; idx < 11; ++idx)
-			s.syncAsByte(_npcBuf[i]._infoScore[idx]);
-
-		s.syncAsByte(_npcBuf[i].field_3F);
-		s.syncAsByte(_npcBuf[i].field_40);
-		for (int idx = 0; idx < 10; ++idx) {
-			s.syncAsSint16LE(_npcBuf[i]._inventory[idx]._ref);
-			s.syncAsByte(_npcBuf[i]._inventory[idx]._stat1);
-			s.syncAsByte(_npcBuf[i]._inventory[idx]._curHitPoints);
-		}
-		s.syncAsByte(_npcBuf[i]._possessivePronounSHL6);
-		s.syncAsByte(_npcBuf[i]._speed);
-		s.syncAsByte(_npcBuf[i].field_6B);
-		s.syncAsByte(_npcBuf[i].field_6C);
-		s.syncAsByte(_npcBuf[i].field_6D);
-		s.syncAsByte(_npcBuf[i]._defaultDefenseItemId);
-		s.syncAsByte(_npcBuf[i].field_6F);
-		s.syncAsByte(_npcBuf[i].field_70);
-		s.syncAsByte(_npcBuf[i].field_71);
-		s.syncAsByte(_npcBuf[i].field_72);
-		s.syncAsByte(_npcBuf[i].field_73);
-		s.syncAsSint16LE(_npcBuf[i]._hitPoints);
-		s.syncAsSint16LE(_npcBuf[i]._maxHP);
-		s.syncAsByte(_npcBuf[i].field_78);
-		s.syncAsSint16LE(_npcBuf[i].field_79);
-		s.syncAsSint16LE(_npcBuf[i].field_7B);
-		s.syncAsByte(_npcBuf[i].field_7D);
-		s.syncAsByte(_npcBuf[i].field_7E);
-		s.syncAsByte(_npcBuf[i].field_7F);
-		s.syncAsByte(_npcBuf[i].field_80);
-		s.syncAsByte(_npcBuf[i].field_81);
-		s.syncAsByte(_npcBuf[i].field_82);
-		s.syncAsByte(_npcBuf[i].field_83);
-		s.syncAsByte(_npcBuf[i].field_84);
-		s.syncAsByte(_npcBuf[i].field_85);
+		_npcBuf[i].synchronize(s);
 	}
-
+		
 	s.syncAsByte(_saveAuthorized);
 }
 
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index dfcb27bf0e0..2eb19348c93 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -315,7 +315,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (scriptExecuteFlag) {
 				int16 tileId = findMapSpecialTileIndex(_mapPosX, _mapPosY);
 				if (tileId != -1)
-					_mapSpecialTile[tileId]._posX = 0xFF;
+					_mapSpecialTiles[_techId][tileId]._posX = 0xFF;
 			}
 			break;
 		case 0x13:
@@ -402,7 +402,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				int16 tileId = findMapSpecialTileIndex(_mapPosX, _mapPosY);
 				if (tileId != -1) {
 					// Disable special tile
-					_mapSpecialTile[tileId]._posX = 0xFF;
+					_mapSpecialTiles[_techId][tileId]._posX = 0xFF;
 				}
 				_redrawNeededFl = true;
 			}
@@ -411,7 +411,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (scriptExecuteFlag) {
 				if (_largeMapFlag) {
-					_mapGameMap[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
+					_mapGameMaps[_techId][scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				} else {
 					_curPlace[scriptNumberArray[0]][scriptNumberArray[1]] = scriptNumberArray[2] & 0xFF;
 				}
@@ -423,7 +423,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
 				if (tileId != -1) {
 					// Disable tile
-					_mapSpecialTile[tileId]._posX = 0xFF;
+					_mapSpecialTiles[_techId][tileId]._posX = 0xFF;
 				}
 			}
 			break;
@@ -433,10 +433,10 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				int16 tileId = findMapSpecialTileIndex(scriptNumberArray[0], scriptNumberArray[1]);
 				if (tileId != -1) {
 					// Disable tile
-					_mapSpecialTile[tileId]._posX = 0xFF;
+					_mapSpecialTiles[_techId][tileId]._posX = 0xFF;
 				}
-				_mapSpecialTile[scriptNumberArray[2]]._posX = scriptNumberArray[0];
-				_mapSpecialTile[scriptNumberArray[2]]._posY = scriptNumberArray[1];
+				_mapSpecialTiles[_techId][scriptNumberArray[2]]._posX = scriptNumberArray[0];
+				_mapSpecialTiles[_techId][scriptNumberArray[2]]._posY = scriptNumberArray[1];
 			}
 			break;
 		case 0x1C:


Commit: 7b1e1c7362e750fa5b4d386ca0c70de34e188904
    https://github.com/scummvm/scummvm/commit/7b1e1c7362e750fa5b4d386ca0c70de34e188904
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Fix missing bit in savegames

Changed paths:
    engines/efh/savegames.cpp


diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index c832e470250..6e43acc9d79 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -179,9 +179,10 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 				s.syncAsSint16LE(_mapMonsters[i][idx]._hitPoints[j]);
 		}
 		
-		size = ARRAYSIZE(_mapArr[i]);
-		for (int j = 2758; j < size; ++j)
-			s.syncAsByte(_mapArr[i][j]);
+		for (int x = 0; x < 64; ++x) {
+			for (int y = 0; y < 64; ++y)
+				s.syncAsByte(_mapGameMaps[i][x][y]);
+		}
 	}
 
 	// Dialog flags


Commit: f997af97023e8e0b1848e375a8c5918743909523
    https://github.com/scummvm/scummvm/commit/f997af97023e8e0b1848e375a8c5918743909523
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Fix (hopefully) several Clang warnings

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 73ff6b5e8a7..21c36107146 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2284,10 +2284,10 @@ int16 EfhEngine::countMonsterGroupMembers(int16 monsterGroup) {
 	return result;
 }
 
-int16 EfhEngine::getXPLevel(int32 xp) {
-	debugC(6, kDebugEngine, "getXPLevel %ld", xp);
+uint16 EfhEngine::getXPLevel(uint32 xp) {
+	debugC(6, kDebugEngine, "getXPLevel %u", xp);
 
-	int16 level = 0;
+	uint16 level = 0;
 	int16 nextLevelXP = 1500;
 
 	int32 wrkXp = xp;
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 8d4f84b1e08..a927afaeda7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -362,7 +362,7 @@ private:
 	void computeInitiatives();
 	void redrawScreenForced();
 	int16 countMonsterGroupMembers(int16 monsterGroup);
-	int16 getXPLevel(int32 xp);
+	uint16 getXPLevel(uint32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
 	void setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask, bool groupFl);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index e094730ac1e..726b80d503b 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1169,7 +1169,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {
 void EfhEngine::getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId) {
 	debugC(3, kDebugFight, "getXPAndSearchCorpse %d %s%s %d", charId, namePt1.c_str(), namePt2.c_str(), monsterId);
 
-	int16 oldXpLevel = getXPLevel(_npcBuf[charId]._xp);
+	uint16 oldXpLevel = getXPLevel(_npcBuf[charId]._xp);
 	_npcBuf[charId]._xp += kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._xpGiven;
 
 	if (getXPLevel(_npcBuf[charId]._xp) > oldXpLevel) {
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index bfe6368794a..194ae4f5607 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -284,7 +284,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	buffer1 = Common::String::format("Level: %d", getXPLevel(_npcBuf[npcId]._xp));
 	setTextPos(146, 36);
 	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("XP: %lu", _npcBuf[npcId]._xp);
+	buffer1 = Common::String::format("XP: %u", _npcBuf[npcId]._xp);
 	setTextPos(227, 36);
 	displayStringAtTextPos(buffer1);
 	buffer1 = Common::String::format("Speed: %d", _npcBuf[npcId]._speed);


Commit: e501c8a8c85b951d508433334728b2f4397133c2
    https://github.com/scummvm/scummvm/commit/e501c8a8c85b951d508433334728b2f4397133c2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Remove saveEfhGame, directly call the appropriate dialog

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 21c36107146..19ebf33846d 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -173,15 +173,13 @@ Common::Error EfhEngine::run() {
 			if (input == Common::KEYCODE_y) {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
-				saveEfhGame();
-				clearBottomTextZone_2(0);
-				displayLowStatusScreen(true);
+				saveGameDialog();
 			} else {
 				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
 				getInput(2);
-				clearBottomTextZone_2(0);
-				displayLowStatusScreen(true);
 			}
+			clearBottomTextZone_2(0);
+			displayLowStatusScreen(true);
 
 			}
 			break;
@@ -196,16 +194,13 @@ Common::Error EfhEngine::run() {
 			if (input == Common::KEYCODE_y) {
 				displayMenuAnswerString("-> Yes <-", 24, 296, 169);
 				getInput(2);
-//				loadEfhGame();
-				saveEfhGame();
-				clearBottomTextZone_2(0);
-				displayLowStatusScreen(true);
+				loadGameDialog();
 			} else {
 				displayMenuAnswerString("-> No!!! <-", 24, 296, 169);
 				getInput(2);
-				clearBottomTextZone_2(0);
-				displayLowStatusScreen(true);
 			}
+			clearBottomTextZone_2(0);
+			displayLowStatusScreen(true);
 
 		} break;
 		default:
@@ -291,7 +286,7 @@ void EfhEngine::songDelay(int delay) {
 }
 
 void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
-	debug("playNote %d %ld", frequencyIndex, totalDelay);
+	debug("playNote %d %d", frequencyIndex, totalDelay);
 }
 
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
@@ -2584,11 +2579,6 @@ void EfhEngine::loadEfhGame() {
 	loadPlacesFile(_fullPlaceId, true);
 }
 
-void EfhEngine::saveEfhGame() {
-	warning("STUB - saveEfhGame");
-	openMainMenuDialog();
-}
-
 uint8 EfhEngine::getMapTileInfo(int16 mapPosX, int16 mapPosY) {
 	debugC(3, kDebugEngine, "getMapTileInfo %d-%d", mapPosX, mapPosY);
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a927afaeda7..16c6624689f 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -300,7 +300,6 @@ private:
 	void restoreAnimImageSetId();
 	void checkProtection();
 	void loadEfhGame();
-	void saveEfhGame();
 	void copyCurrentPlaceToBuffer(int16 id);
 	uint8 getMapTileInfo(int16 mapPosX, int16 mapPosY);
 	void writeTechAndMapFiles();
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 194ae4f5607..9fefb458b09 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -126,11 +126,10 @@ bool EfhEngine::handleDeathMenu() {
 		Common::KeyCode input = waitForKey();
 		switch (input) {
 		case Common::KEYCODE_l:
-			// SaveEfhGame opens the GUI save/load screen. It's not possible to save at this point (_saveAuthorizd is false).
 			// If the user actually loads a savegame, it'll get _saveAuthorized from the savegame (always true) and will set 'found' to true.
 			// If 'found' remains false, it means the user cancelled the loading and still needs to take a decision
 			// Original is calling loadEfhGame() because there's only one savegame, so it's not ambiguous
-			saveEfhGame();
+			loadGameDialog();
 			found = _saveAuthorized;
 			break;
 		case Common::KEYCODE_q:


Commit: 0b9d9b1446a5306831e5f66c5b83a6b8432d618d
    https://github.com/scummvm/scummvm/commit/0b9d9b1446a5306831e5f66c5b83a6b8432d618d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Rename displayEncounterInfo()

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 16c6624689f..ff002c889be 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -392,7 +392,7 @@ private:
 	void getXPAndSearchCorpse(int16 charId, Common::String namePt1, Common::String namePt2, int16 monsterId);
 	bool characterSearchesMonsterCorpse(int16 charId, int16 monsterId);
 	void addReactionText(int16 id);
-	void sub1C4CA(bool WhiteFl);
+	void displayEncounterInfo(bool WhiteFl);
 	int16 getWeakestMobster(int16 groupNumber);
 	int16 getCharacterScore(int16 charId, int16 itemId);
 	bool checkSpecialItemsOnCurrentPlace(int16 itemId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 726b80d503b..9f2acd720b0 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1156,7 +1156,7 @@ void EfhEngine::drawCombatScreen(int16 charId, bool whiteFl, bool drawFl) {
 			drawColoredRect(200, 112, 278, 132, 0);
 			displayCenteredString("'T' for Terrain", 128, 303, 117);
 			displayBoxWithText("", 1, 0, false);
-			sub1C4CA(whiteFl);
+			displayEncounterInfo(whiteFl);
 			displayCombatMenu(charId);
 			displayLowStatusScreen(false);
 		}
@@ -1329,8 +1329,8 @@ void EfhEngine::addReactionText(int16 id) {
 	}
 }
 
-void EfhEngine::sub1C4CA(bool whiteFl) {
-	debugC(5, kDebugFight, "sub1C4CA %s", whiteFl ? "True" : "False");
+void EfhEngine::displayEncounterInfo(bool whiteFl) {
+	debugC(5, kDebugFight, "displayEncounterInfo %s", whiteFl ? "True" : "False");
 
 	int16 textPosY = 20;
 	for (uint counter = 0; counter < 5; ++counter) {


Commit: 03746ad3227f09d054d78fa16e6e160a1eea8801
    https://github.com/scummvm/scummvm/commit/03746ad3227f09d054d78fa16e6e160a1eea8801
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: some renaming in handleFight_lastAction_A, invert some if statement to reduce code depth

Changed paths:
    engines/efh/fight.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 9f2acd720b0..8842f7dfd74 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -425,203 +425,206 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	int16 teamCharItemId = getEquippedExclusiveType(_teamCharId[teamCharId], 9, true);
 	if (teamCharItemId == 0x7FFF)
 		teamCharItemId = 0x3F;
-	int16 monsterGroupNumber = _teamNextAttack[teamCharId];
-	if (monsterGroupNumber == 0x64)
-		monsterGroupNumber = 0;
+	int16 minMonsterGroupId = _teamNextAttack[teamCharId];
+	if (minMonsterGroupId == 0x64)
+		minMonsterGroupId = 0;
 
-	if (monsterGroupNumber == -1)
+	if (minMonsterGroupId == -1)
 		return;
-	int16 var58;
+	
+	int16 maxMonsterGroupId;
 	if (_items[teamCharItemId]._range == 4)
-		var58 = 5;
+		maxMonsterGroupId = 5;
 	else
-		var58 = monsterGroupNumber + 1;
+		maxMonsterGroupId = minMonsterGroupId + 1;
 
-	int16 var54;
-	int16 teamMemberId;
+	int16 minTeamMemberId;
+	int16 maxTeamMemberId;
 	if (_items[teamCharItemId]._range < 3) {
-		teamMemberId = getWeakestMobster(monsterGroupNumber);
-		var54 = teamMemberId + 1;
+		minTeamMemberId = getWeakestMobster(minMonsterGroupId);
+		maxTeamMemberId = minTeamMemberId + 1;
 	} else {
-		teamMemberId = 0;
-		var54 = 9;
+		minTeamMemberId = 0;
+		maxTeamMemberId = 9;
 	}
 
-	if (teamMemberId != -1) {
-		bool var6E = true;
-		for (int16 groupId = monsterGroupNumber; groupId < var58; ++groupId) {
-			if (_teamMonsterIdArray[groupId] == -1)
-				continue;
+	if (minTeamMemberId == -1)
+		return;
 
-			for (int16 ctrMobsterId = teamMemberId; ctrMobsterId < var54; ++ctrMobsterId) {
-				if (isMonsterActive(groupId, ctrMobsterId) && var6E) {
-					bool noticedFl;
-					if (!checkMonsterMovementType(groupId, true)) {
-						setMapMonsterAggressivenessAndMovementType(groupId, 9, true);
-						_unk2C8AA += 500;
-						noticedFl = true;
-					} else
-						noticedFl = false;
-
-					int16 var76 = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
-					int16 ennemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
-					int16 monsterId = _teamMonsterIdArray[groupId];
-					int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
-					int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
-					int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
-					int16 hitCount = 0;
-					int16 originalDamage = 0;
-					int16 damagePointsAbsorbed = 0;
-					int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
-
-					// Action A - Loop var84 - Start
-					for (int var84 = 0; var84 < attackSpeed; ++var84) {
-						if (getRandom(100) < charScore) {
-							++hitCount;
-							if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
-								int16 var7C = getRandom(_items[teamCharItemId]._damage);
-								int16 varInt = var7C - var76;
-								if (varInt > 0) {
-									originalDamage += varInt;
-									damagePointsAbsorbed += var76;
-								} else {
-									damagePointsAbsorbed += var7C;
-								}
-							}
+	bool var6E = true;
+	for (int16 groupId = minMonsterGroupId; groupId < maxMonsterGroupId; ++groupId) {
+		if (_teamMonsterIdArray[groupId] == -1)
+			continue;
+
+		for (int16 ctrMobsterId = minTeamMemberId; ctrMobsterId < maxTeamMemberId; ++ctrMobsterId) {
+			if (!isMonsterActive(groupId, ctrMobsterId) || !var6E)
+				return;
+
+			bool noticedFl;
+			if (!checkMonsterMovementType(groupId, true)) {
+				setMapMonsterAggressivenessAndMovementType(groupId, 9, true);
+				_unk2C8AA += 500;
+				noticedFl = true;
+			} else
+				noticedFl = false;
+
+			int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
+			int16 ennemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+			int16 monsterId = _teamMonsterIdArray[groupId];
+			int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
+			int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
+			int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
+			int16 hitCount = 0;
+			int16 originalDamage = 0;
+			int16 damagePointsAbsorbed = 0;
+			int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
+
+			// Action A - Loop var84 - Start
+			for (int var84 = 0; var84 < attackSpeed; ++var84) {
+				if (getRandom(100) < charScore) {
+					++hitCount;
+					if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
+						int16 var7C = getRandom(_items[teamCharItemId]._damage);
+						int16 varInt = var7C - randomDamageAbsorbed;
+						if (varInt > 0) {
+							originalDamage += varInt;
+							damagePointsAbsorbed += randomDamageAbsorbed;
+						} else {
+							damagePointsAbsorbed += var7C;
 						}
 					}
-					// Action A - Loop var84 - End
+				}
+			}
+			// Action A - Loop var84 - End
 
-					if (originalDamage < 0)
-						originalDamage = 0;
+			if (originalDamage < 0)
+				originalDamage = 0;
 
-					int16 hitPoints = originalDamage + damagePointsAbsorbed;
+			int16 hitPoints = originalDamage + damagePointsAbsorbed;
 
-					if (!checkSpecialItemsOnCurrentPlace(teamCharItemId))
-						hitCount = 0;
+			if (!checkSpecialItemsOnCurrentPlace(teamCharItemId))
+				hitCount = 0;
 
-					if (hitCount > 0) {
-						_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
-						if (hitCount > 1) {
-							_attackBuffer = Common::String::format("%d times ", hitCount);
-						} else {
-							_attackBuffer = "";
-						}
-					}
-					int16 verbId = (3 * _items[teamCharItemId]._attackType + 1) + getRandom(3) - 1;
-					if (characterPronoun == 2) {
-						_characterNamePt1 = "The ";
+			if (hitCount > 0) {
+				_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
+				if (hitCount > 1) {
+					_attackBuffer = Common::String::format("%d times ", hitCount);
+				} else {
+					_attackBuffer = "";
+				}
+			}
+			int16 verbId = (3 * _items[teamCharItemId]._attackType + 1) + getRandom(3) - 1;
+			if (characterPronoun == 2) {
+				_characterNamePt1 = "The ";
+			} else {
+				_characterNamePt1 = "";
+			}
+
+			if (ennemyPronoun == 2) {
+				_enemyNamePt1 = "The ";
+			} else {
+				_enemyNamePt1 = "";
+			}
+
+			_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+			_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+			_nameBuffer = _items[teamCharItemId]._name;
+			if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
+				// Action A - Check damages - Start
+				if (hitCount == 0) {
+					_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+				} else if (hitPoints <= 0) {
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+				} else if (hitPoints == 1) {
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+						getDeathTypeDescription(groupId, teamCharId + 1000);
+						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 					} else {
-						_characterNamePt1 = "";
+						_messageToBePrinted += "!";
 					}
-
-					if (ennemyPronoun == 2) {
-						_enemyNamePt1 = "The ";
+				} else {
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
+					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+						getDeathTypeDescription(groupId, teamCharId + 1000);
+						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 					} else {
-						_enemyNamePt1 = "";
+						_messageToBePrinted += "!";
 					}
-
-					_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
-					_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-					_nameBuffer = _items[teamCharItemId]._name;
-					if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
-						// Action A - Check damages - Start
-						if (hitCount == 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-						} else if (hitPoints <= 0) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-						} else if (hitPoints == 1) {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
-								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
-							} else {
-								_messageToBePrinted += "!";
-							}
-						} else {
-							_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
-							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
-								getDeathTypeDescription(groupId, teamCharId + 1000);
-								getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
-							} else {
-								_messageToBePrinted += "!";
-							}
-						}
-						// Action A - Check damages - End
-
-						// Action A - Add reaction text - Start
-						if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-							if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
-								addReactionText(kEfhReactionReels);
-							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
-								addReactionText(kEfhReactionCriesOut);
-							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
-								addReactionText(kEfhReactionFalters);
-							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
-								addReactionText(kEfhReactionWinces);
-							} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
-								// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
-								addReactionText(kEfhReactionScreams);
-							} else if (hitPointsBefore / 8 >= originalDamage) {
-								addReactionText(kEfhReactionChortles);
-							} else if (originalDamage == 0 && getRandom(100) < 35) {
-								// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
-								addReactionText(kEfhReactionLaughs);
-							}
-						}
-						// Action A - Add reaction text - End
-
-						// Action A - Add armor absorb text - Start
-						if (var76 && hitCount && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-							if (damagePointsAbsorbed <= 1)
-								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-							else
-								_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
-						}
-						// Action A - Add armor absorb text - End
-
-						if (noticedFl)
-							_messageToBePrinted += Common::String("  Your actions do not go un-noticed...");
-
-						// Action A - Check item durability - Start
-						int16 npcId = _teamCharId[teamCharId];
-
-						// get equipped inventory slot with exclusiveType == 9
-						uint16 exclusiveInventoryId = getEquippedExclusiveType(npcId, 9, false);
-						if (exclusiveInventoryId != 0x7FFF && _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft() != 0x7F) {
-							int16 usesLeft = _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft();
-							--usesLeft;
-							if (usesLeft <= 0) {
-								_messageToBePrinted += Common::String::format("  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
-								setCharacterObjectToBroken(npcId, exclusiveInventoryId);
-								var6E = false;
-							} else {
-								_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 = (_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 & 80) + usesLeft;
-							}
-						}
-						// Action A - Check item durability - End
-
-						// Action A - Check effect - Start
-						if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-							if (getRandom(100) < 35) {
-								_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 1;
-								_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
-								_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-							}
-						} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-							_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 2;
-							_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
-							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-						}
-						// Action A - Check effect - End
+				}
+				// Action A - Check damages - End
+
+				// Action A - Add reaction text - Start
+				if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
+						addReactionText(kEfhReactionReels);
+					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
+						addReactionText(kEfhReactionCriesOut);
+					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
+						addReactionText(kEfhReactionFalters);
+					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
+						addReactionText(kEfhReactionWinces);
+					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
+						// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
+						addReactionText(kEfhReactionScreams);
+					} else if (hitPointsBefore / 8 >= originalDamage) {
+						addReactionText(kEfhReactionChortles);
+					} else if (originalDamage == 0 && getRandom(100) < 35) {
+						// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
+						addReactionText(kEfhReactionLaughs);
+					}
+				}
+				// Action A - Add reaction text - End
+
+				// Action A - Add armor absorb text - Start
+				if (randomDamageAbsorbed && hitCount && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+					if (damagePointsAbsorbed <= 1)
+						_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+					else
+						_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
+				}
+				// Action A - Add armor absorb text - End
+
+				if (noticedFl)
+					_messageToBePrinted += Common::String("  Your actions do not go un-noticed...");
+
+				// Action A - Check item durability - Start
+				int16 npcId = _teamCharId[teamCharId];
+
+				// get equipped inventory slot with exclusiveType == 9
+				uint16 exclusiveInventoryId = getEquippedExclusiveType(npcId, 9, false);
+				if (exclusiveInventoryId != 0x7FFF && _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft() != 0x7F) {
+					int16 usesLeft = _npcBuf[npcId]._inventory[exclusiveInventoryId].getUsesLeft();
+					--usesLeft;
+					if (usesLeft <= 0) {
+						_messageToBePrinted += Common::String::format("  * %s%s's %s breaks!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), _nameBuffer.c_str());
+						setCharacterObjectToBroken(npcId, exclusiveInventoryId);
+						var6E = false;
 					} else {
-						_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+						_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 = (_npcBuf[npcId]._inventory[exclusiveInventoryId]._stat1 & 80) + usesLeft;
 					}
-
-					genericGenerateSound(_items[teamCharItemId]._attackType, hitCount);
-					displayBoxWithText(_messageToBePrinted, 1, 2, true);
 				}
+				// Action A - Check item durability - End
+
+				// Action A - Check effect - Start
+				if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+					if (getRandom(100) < 35) {
+						_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 1;
+						_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
+						_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+					}
+				} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+					_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 2;
+					_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
+					_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+				}
+				// Action A - Check effect - End
+			} else {
+				_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
 			}
+
+			genericGenerateSound(_items[teamCharItemId]._attackType, hitCount);
+			displayBoxWithText(_messageToBePrinted, 1, 2, true);
 		}
 	}
 }


Commit: a95b4960e049df3bb5ea4314c20023da4350294e
    https://github.com/scummvm/scummvm/commit/a95b4960e049df3bb5ea4314c20023da4350294e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Split handleFight_MobstersAttack out of handleFight()

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index ff002c889be..03e91a7c516 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -378,6 +378,7 @@ private:
 	void handleFight_lastAction_D(int16 teamCharId);
 	void handleFight_lastAction_H(int16 teamCharId);
 	bool handleFight_lastAction_U(int16 teamCharId);
+	void handleFight_MobstersAttack(int groupId);
 	bool isTPK();
 	bool isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId);
 	void createOpponentList(int16 monsterTeamId);
@@ -620,7 +621,6 @@ private:
 	int16 _regenCounter;
 };
 
-
 } // End of namespace Efh
 
 #endif
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 8842f7dfd74..e3fe6a93aae 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -108,8 +108,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			return true;
 		}
 
-		int16 varInt = getTeamMonsterAnimId();
-		displayAnimFrames(varInt, true);
+		displayAnimFrames(getTeamMonsterAnimId(), true);
 		for (int counter = 0; counter < _teamSize; ++counter) {
 			_teamPctVisible[counter] = 100;
 			_teamPctDodgeMiss[counter] = 65;
@@ -158,213 +157,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 					}
 				}
 			} else if (checkMonsterMovementType(monsterGroupIdOrMonsterId, true)) {
-				// handleFight - Loop on mobsterId - Start
-				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-					if (isMonsterActive(monsterGroupIdOrMonsterId, ctrMobsterId)) {
-						int16 monsterWeaponItemId = _mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._weaponItemId;
-						if (monsterWeaponItemId == 0xFF)
-							monsterWeaponItemId = 0x3F;
-						int16 teamMemberId = -1;
-						int16 var54;
-						if (_items[monsterWeaponItemId]._range < 3) {
-							for (uint var84 = 0; var84 < 10; ++var84) {
-								teamMemberId = getRandom(_teamSize) - 1;
-								if (checkWeaponRange(_teamMonsterIdArray[monsterGroupIdOrMonsterId], monsterWeaponItemId) && isTeamMemberStatusNormal(teamMemberId) && getRandom(100) < _teamPctVisible[teamMemberId]) {
-									break;
-								}
-								teamMemberId = -1;
-							}
-							var54 = teamMemberId + 1;
-						} else {
-							teamMemberId = 0;
-							var54 = _teamSize;
-						}
-						if (teamMemberId != -1) {
-							// handleFight - Loop on var7E - Start
-							for (int16 var7E = teamMemberId; var7E < var54; ++var7E) {
-								if (_teamCharId[var7E] == -1 || !isTeamMemberStatusNormal(var7E))
-									continue;
-
-								int16 var76 = getRandom(getEquipmentDefense(_teamCharId[var7E], false));
-								varInt = _teamMonsterIdArray[monsterGroupIdOrMonsterId];
-								int16 ennemyPronoun = kEncounters[_mapMonsters[_techId][varInt]._monsterRef]._nameArticle;
-								int16 characterPronoun = _npcBuf[_teamCharId[var7E]].getPronoun();
-								varInt = _items[monsterWeaponItemId].field_13;
-								_teamPctDodgeMiss[var7E] += (varInt * 5);
-								int16 var62 = 0;
-								int16 hitPoints = 0;
-								int16 originalDamage = 0;
-								int16 damagePointsAbsorbed = 0;
-								int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._npcId * _items[monsterWeaponItemId]._attacks;
-								for (int var84 = 0; var84 < var64; ++var84) {
-									// handleFight - Loop var84 on var64 (objectId) - Start
-									if (getRandom(100) > _teamPctDodgeMiss[var7E])
-										continue;
-
-									++var62;
-
-									if (hasAdequateDefenseNPC(_teamCharId[var7E], _items[monsterWeaponItemId]._attackType))
-										continue;
-
-									int16 var7C = getRandom(_items[monsterWeaponItemId]._damage);
-									varInt = var7C - var76;
-
-									if (varInt > 0) {
-										damagePointsAbsorbed += var76;
-										originalDamage += varInt;
-									} else {
-										damagePointsAbsorbed += var7C;
-									}
-									// handleFight - Loop var84 on var64 (objectId) - End
-								}
-
-								if (originalDamage < 0)
-									originalDamage = 0;
-
-								hitPoints = originalDamage + damagePointsAbsorbed;
-								if (!checkSpecialItemsOnCurrentPlace(monsterWeaponItemId))
-									var62 = 0;
-
-								if (var62 > 0) {
-									_npcBuf[_teamCharId[var7E]]._hitPoints -= originalDamage;
-									if (var62 > 1)
-										_attackBuffer = Common::String::format("%d times ", var62);
-									else
-										_attackBuffer = "";
-								}
-
-								int16 var68 = _items[monsterWeaponItemId]._attackType + 1;
-								int16 var6A = getRandom(3);
-								if (characterPronoun == 2)
-									_characterNamePt1 = "The ";
-								else
-									_characterNamePt1 = "";
-
-								if (ennemyPronoun == 2)
-									_enemyNamePt1 = "The ";
-								else
-									_enemyNamePt1 = "";
-
-								_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-								_characterNamePt2 = _npcBuf[_teamCharId[var7E]]._name;
-								_nameBuffer = _items[monsterWeaponItemId]._name;
-								if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
-									// handleFight - check damages - Start
-									if (var62 == 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-									} else if (hitPoints <= 0) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-									} else if (hitPoints == 1) {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
-											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
-										else
-											_messageToBePrinted += "!";
-									} else {
-										_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints <= 0)
-											getDeathTypeDescription(var7E + 1000, monsterGroupIdOrMonsterId);
-										else
-											_messageToBePrinted += "!";
-									}
-									// handleFight - check damages - End
-
-									// handleFight - Add reaction text - start
-									if (var62 != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
-										if (_npcBuf[_teamCharId[var7E]]._hitPoints - 5 <= originalDamage) {
-											addReactionText(kEfhReactionReels);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 8) {
-											addReactionText(kEfhReactionCriesOut);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 4) {
-											addReactionText(kEfhReactionFalters);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 2) {
-											addReactionText(kEfhReactionWinces);
-										} else if (_npcBuf[_teamCharId[var7E]]._hitPoints < _npcBuf[_teamCharId[var7E]]._maxHP / 3) {
-											// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
-											addReactionText(kEfhReactionScreams);
-										} else if (_npcBuf[_teamCharId[var7E]]._maxHP / 8 >= originalDamage) {
-											addReactionText(kEfhReactionChortles);
-										} else if (originalDamage == 0 && getRandom(100) < 35) {
-											// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
-											addReactionText(kEfhReactionLaughs);
-										}
-									}
-									// handleFight - Add reaction text - end
-
-									// handleFight - Check armor - start
-									if (var76 != 0 && var62 != 0 && _npcBuf[_teamCharId[var7E]]._hitPoints > 0) {
-										if (damagePointsAbsorbed <= 1)
-											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-										else
-											_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
-
-										varInt = (originalDamage + damagePointsAbsorbed) / 10;
-										handleDamageOnArmor(_teamCharId[var7E], varInt);
-									}
-									// handleFight - Check armor - end
-
-									// handleFight - Check effect - start
-									switch (_items[monsterWeaponItemId]._specialEffect) {
-									case 1:
-										if (getRandom(100) < 20) {
-											_teamCharStatus[var7E]._status = 1;
-											_teamCharStatus[var7E]._duration = getRandom(10);
-											_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-										}
-										break;
-									case 2:
-										if (getRandom(100) < 20) {
-											_teamCharStatus[var7E]._status = 2;
-											_teamCharStatus[var7E]._duration = getRandom(10);
-											_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-										}
-										break;
-									case 5:
-									case 6:
-										if (getRandom(100) < 20) {
-											_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-											_npcBuf[_teamCharId[var7E]]._hitPoints = 0;
-										}
-										break;
-									default:
-										break;
-									}
-									// handleFight - Check effect - end
-								} else {
-									_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
-								}
-								genericGenerateSound(_items[monsterWeaponItemId]._attackType, var62);
-								displayBoxWithText(_messageToBePrinted, 1, 2, true);
-							}
-							// handleFight - Loop on var7E - End
-						}
-					} else if (_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
-						--_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId];
-						if (_teamMonsterEffects[monsterGroupIdOrMonsterId]._duration[ctrMobsterId] <= 0) {
-							_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._name;
-							int16 var70 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[monsterGroupIdOrMonsterId]]._monsterRef]._nameArticle;
-							if (var70 == 2)
-								_enemyNamePt1 = "The ";
-							else
-								_enemyNamePt1 = "";
-
-							switch (_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId]) {
-							case 1:
-								_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							case 2:
-								_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							default:
-								_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
-								break;
-							}
-							_teamMonsterEffects[monsterGroupIdOrMonsterId]._effect[ctrMobsterId] = 0;
-							displayBoxWithText(_messageToBePrinted, 1, 2, true);
-						}
-					}
-				}
-				// handleFight - Loop on mobsterId - End
+				handleFight_MobstersAttack(monsterGroupIdOrMonsterId);
 			}
 		}
 
@@ -690,6 +483,218 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	return retVal;
 }
 
+void EfhEngine::handleFight_MobstersAttack(int groupId) {
+	// In the original, this function is part of handleFight.
+	// It has been split for readability purposes.
+	debug("handleFight_MobstersAttack %d", groupId);
+	
+	// handleFight - Loop on mobsterId - Start
+	for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
+		if (isMonsterActive(groupId, ctrMobsterId)) {
+			int16 monsterWeaponItemId = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._weaponItemId;
+			if (monsterWeaponItemId == 0xFF)
+				monsterWeaponItemId = 0x3F;
+			int16 minTeamMemberId = -1;
+			int16 maxTeamMemberId;
+			if (_items[monsterWeaponItemId]._range < 3) {
+				for (uint attackTry = 0; attackTry < 10; ++attackTry) {
+					minTeamMemberId = getRandom(_teamSize) - 1;
+					if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamPctVisible[minTeamMemberId]) {
+						break;
+					}
+					minTeamMemberId = -1;
+				}
+				maxTeamMemberId = minTeamMemberId + 1;
+			} else {
+				minTeamMemberId = 0;
+				maxTeamMemberId = _teamSize;
+			}
+
+			if (minTeamMemberId == -1)
+				continue;
+
+			// handleFight - Loop on var7E - Start
+			for (int16 targetId = minTeamMemberId; targetId < maxTeamMemberId; ++targetId) {
+				if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
+					continue;
+
+				int16 randomeDefense = getRandom(getEquipmentDefense(_teamCharId[targetId], false));
+				int16 ennemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
+				int16 characterPronoun = _npcBuf[_teamCharId[targetId]].getPronoun();
+				_teamPctDodgeMiss[targetId] += (_items[monsterWeaponItemId].field_13 * 5);
+				int16 hitCount = 0;
+				int16 originalDamage = 0;
+				int16 damagePointsAbsorbed = 0;
+				int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._npcId * _items[monsterWeaponItemId]._attacks;
+				for (int var84 = 0; var84 < var64; ++var84) {
+					// handleFight - Loop var84 on var64 (objectId) - Start
+					if (getRandom(100) > _teamPctDodgeMiss[targetId])
+						continue;
+
+					++hitCount;
+
+					if (hasAdequateDefenseNPC(_teamCharId[targetId], _items[monsterWeaponItemId]._attackType))
+						continue;
+
+					int16 var7C = getRandom(_items[monsterWeaponItemId]._damage);
+					int varInt = var7C - randomeDefense;
+
+					if (varInt > 0) {
+						damagePointsAbsorbed += randomeDefense;
+						originalDamage += varInt;
+					} else {
+						damagePointsAbsorbed += var7C;
+					}
+					// handleFight - Loop var84 on var64 (objectId) - End
+				}
+
+				if (originalDamage < 0)
+					originalDamage = 0;
+
+				int16 hitPoints = originalDamage + damagePointsAbsorbed;
+				if (!checkSpecialItemsOnCurrentPlace(monsterWeaponItemId))
+					hitCount = 0;
+
+				if (hitCount > 0) {
+					_npcBuf[_teamCharId[targetId]]._hitPoints -= originalDamage;
+					if (hitCount > 1)
+						_attackBuffer = Common::String::format("%d times ", hitCount);
+					else
+						_attackBuffer = "";
+				}
+
+				int16 var68 = _items[monsterWeaponItemId]._attackType + 1;
+				int16 var6A = getRandom(3);
+				if (characterPronoun == 2)
+					_characterNamePt1 = "The ";
+				else
+					_characterNamePt1 = "";
+
+				if (ennemyPronoun == 2)
+					_enemyNamePt1 = "The ";
+				else
+					_enemyNamePt1 = "";
+
+				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+				_characterNamePt2 = _npcBuf[_teamCharId[targetId]]._name;
+				_nameBuffer = _items[monsterWeaponItemId]._name;
+				if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
+					// handleFight - check damages - Start
+					if (hitCount == 0) {
+						_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					} else if (hitPoints <= 0) {
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					} else if (hitPoints == 1) {
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
+							getDeathTypeDescription(targetId + 1000, groupId);
+						else
+							_messageToBePrinted += "!";
+					} else {
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
+						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
+							getDeathTypeDescription(targetId + 1000, groupId);
+						else
+							_messageToBePrinted += "!";
+					}
+					// handleFight - check damages - End
+
+					// handleFight - Add reaction text - start
+					if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
+						if (_npcBuf[_teamCharId[targetId]]._hitPoints - 5 <= originalDamage) {
+							addReactionText(kEfhReactionReels);
+						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 8) {
+							addReactionText(kEfhReactionCriesOut);
+						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 4) {
+							addReactionText(kEfhReactionFalters);
+						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 2) {
+							addReactionText(kEfhReactionWinces);
+						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 3) {
+							// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
+							addReactionText(kEfhReactionScreams);
+						} else if (_npcBuf[_teamCharId[targetId]]._maxHP / 8 >= originalDamage) {
+							addReactionText(kEfhReactionChortles);
+						} else if (originalDamage == 0 && getRandom(100) < 35) {
+							// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
+							addReactionText(kEfhReactionLaughs);
+						}
+					}
+					// handleFight - Add reaction text - end
+
+					// handleFight - Check armor - start
+					if (randomeDefense != 0 && hitCount != 0 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
+						if (damagePointsAbsorbed <= 1)
+							_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+						else
+							_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
+
+						int armorDamage = (originalDamage + damagePointsAbsorbed) / 10;
+						handleDamageOnArmor(_teamCharId[targetId], armorDamage);
+					}
+					// handleFight - Check armor - end
+
+					// handleFight - Check effect - start
+					switch (_items[monsterWeaponItemId]._specialEffect) {
+					case 1:
+						if (getRandom(100) < 20) {
+							_teamCharStatus[targetId]._status = 1;
+							_teamCharStatus[targetId]._duration = getRandom(10);
+							_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+						}
+						break;
+					case 2:
+						if (getRandom(100) < 20) {
+							_teamCharStatus[targetId]._status = 2;
+							_teamCharStatus[targetId]._duration = getRandom(10);
+							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+						}
+						break;
+					case 5:
+					case 6:
+						if (getRandom(100) < 20) {
+							_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
+							_npcBuf[_teamCharId[targetId]]._hitPoints = 0;
+						}
+						break;
+					default:
+						break;
+					}
+					// handleFight - Check effect - end
+				} else {
+					_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+				}
+				genericGenerateSound(_items[monsterWeaponItemId]._attackType, hitCount);
+				displayBoxWithText(_messageToBePrinted, 1, 2, true);
+			}
+			// handleFight - Loop on var7E - End
+		} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[groupId]._effect[ctrMobsterId] > 0) {
+			--_teamMonsterEffects[groupId]._duration[ctrMobsterId];
+			if (_teamMonsterEffects[groupId]._duration[ctrMobsterId] <= 0) {
+				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+				if (kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle == 2)
+					_enemyNamePt1 = "The ";
+				else
+					_enemyNamePt1 = "";
+
+				switch (_teamMonsterEffects[groupId]._effect[ctrMobsterId]) {
+				case 1:
+					_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+					break;
+				case 2:
+					_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+					break;
+				default:
+					_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
+					break;
+				}
+				_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 0;
+				displayBoxWithText(_messageToBePrinted, 1, 2, true);
+			}
+		}
+	}
+	// handleFight - Loop on mobsterId - End
+}
+
 bool EfhEngine::isTPK() {
 	debugC(6, kDebugFight, "isTPK");
 


Commit: 6179bb75adbd56cd637b3653d64b29ea32d5ac80
    https://github.com/scummvm/scummvm/commit/6179bb75adbd56cd637b3653d64b29ea32d5ac80
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Rename last SUB function

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 19ebf33846d..0379bad9209 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2103,8 +2103,8 @@ void EfhEngine::displayImp1Text(int16 textId) {
 	displayAnimFrames(0xFE, true);
 }
 
-bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
-	debugC(3, kDebugEngine, "sub22293 %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
+bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId) {
+	debugC(3, kDebugEngine, "handleInteractionText %d-%d %d %d %d %d", mapPosX, mapPosY, charId, itemId, arg8, imageSetId);
 
 	int16 tileId = findMapSpecialTileIndex(mapPosX, mapPosY);
 
@@ -2148,7 +2148,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 				for (uint var2 = 0; var2 < 39; ++var2) {
 					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
-					warning("sub22293 - _activeScore[%d]", var6);
+					warning("handleInteractionText - _activeScore[%d]", var6);
 					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
@@ -2165,7 +2165,7 @@ bool EfhEngine::sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemI
 		int16 var6 = _mapSpecialTiles[_techId][tileId]._field3;
 		if (var6 >= 0x78 && var6 <= 0xEF) {
 			var6 -= 0x78;
-			warning("sub22293 - _activeScore[%d]", var6);
+			warning("handleInteractionText - _activeScore[%d]", var6);
 			// The 2 checks on var6 are useless, as [0x78..0xEF] - 0x78 => [0x00..0x77]
 			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTiles[_techId][tileId]._triggerId <= _npcBuf[charId]._activeScore[itemId]) {
 				displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
@@ -2198,7 +2198,7 @@ int8 EfhEngine::checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4) {
 	tileFactId += curTileInfo % 72;
 
 	if (arg4) {
-		sub22293(mapPosX, mapPosY, -1, 0x7FFF, 0, tileFactId);
+		handleInteractionText(mapPosX, mapPosY, -1, 0x7FFF, 0, tileFactId);
 	}
 
 	if (_word2C880) {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 03e91a7c516..2fd42f5d930 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -356,7 +356,7 @@ private:
 	bool handleTalk(int16 monsterId, int16 arg2, int16 itemId);
 	void startTalkMenu(int16 monsterId);
 	void displayImp1Text(int16 textId);
-	bool sub22293(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
+	bool handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId, int16 itemId, int16 arg8, int16 imageSetId);
 	int8 checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4);
 	void computeInitiatives();
 	void redrawScreenForced();
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 9fefb458b09..c7bcc2cd675 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -694,7 +694,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				return objectId;
 			}
 
-			if (sub22293(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
+			if (handleInteractionText(_mapPosX, _mapPosY, charId, itemId, 2, -1)) {
 				_statusMenuActive = false;
 				return -1;
 			}
@@ -717,7 +717,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						displayStringInSmallWindowWithBorder("Not a Combat Option !", true, charId, windowId, menuId, curMenuLine);
 					} else {
 						removeObject(charId, objectId);
-						if (sub22293(_mapPosX, _mapPosY, charId, itemId, 3, -1)) {
+						if (handleInteractionText(_mapPosX, _mapPosY, charId, itemId, 3, -1)) {
 							_statusMenuActive = false;
 							return -1;
 						}
@@ -807,7 +807,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 						return 0x7D00;
 					}
 
-					if (sub22293(_mapPosX, _mapPosY, charId, itemId, 1, -1)) {
+					if (handleInteractionText(_mapPosX, _mapPosY, charId, itemId, 1, -1)) {
 						_statusMenuActive = false;
 						return -1;
 					}
@@ -820,7 +820,7 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 			objectId = _menuStatItemArr[selectedLine];
 			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder("Not a Combat Option!", true, charId, windowId, menuId, curMenuLine);
-			} else if (sub22293(_mapPosX, _mapPosY, charId, objectId, 4, -1)) {
+			} else if (handleInteractionText(_mapPosX, _mapPosY, charId, objectId, 4, -1)) {
 				_statusMenuActive = false;
 				return -1;
 			}


Commit: 04f3b5ff724c9cb3f443edfdff21fd01aab4eb9b
    https://github.com/scummvm/scummvm/commit/04f3b5ff724c9cb3f443edfdff21fd01aab4eb9b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: Some work on song parsing

Changed paths:
    engines/efh/constants.h
    engines/efh/efh.cpp


diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index 2cc2f3916a3..a0ba37c442a 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -62,7 +62,7 @@ struct Encounter {
 	uint8 _nameArticle;
 };
 
-#define kDefaultNoteDuration 616;
+#define kDefaultNoteDuration 616
 
 extern const uint8 kFontWidthArray[96];
 extern const uint8 kFontExtraLinesArray[96];
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 0379bad9209..a86bc992d63 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -271,17 +271,10 @@ void EfhEngine::initialize() {
 void EfhEngine::songDelay(int delay) {
 	debug("songDelay %ld", delay);
 
-	int remainingDelay = delay * kDefaultNoteDuration;
-	Common::KeyCode input = Common::KEYCODE_INVALID;
-	Common::Event event;
-	while (input == Common::KEYCODE_INVALID && remainingDelay > 0 && !shouldQuit()) {
-		_system->delayMillis(20);
-		remainingDelay -= 20;
-
-		_system->getEventManager()->pollEvent(event);
-		if (event.type == Common::EVENT_KEYUP) {
-			input = event.kbd.keycode;
-		}
+	int remainingDelay = delay;
+	while (remainingDelay > 0 && !shouldQuit()) {
+		remainingDelay -= 10;
+		_system->delayMillis(10);
 	}
 }
 
@@ -292,41 +285,46 @@ void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	debug("playSong");
 
-	return Common::KEYCODE_INVALID;
-	
 	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
-	int32 totalDelay = 0;
+	int totalDelay = 0;
 
+	int8 stopFl;
 	uint8 varC = *buffer++;
-	int8 stopFl = *buffer & 0x3F;
-	while (stopFl != 0) {
-		int32 delay = stopFl * varC * 0x2200 / 1000;
-		if (*buffer > 0x7F)
-			delay /= 2;
-		if (*buffer & 0x40)
-			delay = (delay * 2) / 3;
-		int8 frequencyIndex = *++buffer & 0xF;
-		++buffer;
-
-		if (frequencyIndex > 0x7F)
-			totalDelay += delay;
-		else if (frequencyIndex == 0)
-			songDelay(delay);
-		else {
-			playNote(frequencyIndex, totalDelay + delay);
-			totalDelay = 0;
+	Common::Event event;
+	do {
+		stopFl = *buffer & 0x3F;
+		if (stopFl != 0) {
+			int delay = stopFl * varC * 0x2200 / 1000;
+
+			if (*buffer > 0x7F)
+				delay /= 2;
+
+			if (*buffer & 0x40)
+				delay = (delay * 2) / 3;
+
+			++buffer;
+			uint8 frequencyIndex = *buffer;
+			++buffer;
+
+			if (frequencyIndex > 0x7F)
+				totalDelay += delay;
+			else if (frequencyIndex == 0)
+				songDelay(delay);
+			else {
+				playNote(frequencyIndex, totalDelay + delay);
+				totalDelay = 0;
+			}
 		}
 
 		songDelay(10);
-		Common::Event event;
 		_system->getEventManager()->pollEvent(event);
 		if (event.type == Common::EVENT_KEYUP) {
 			inputChar = event.kbd.keycode;
+			// Hack, sometimes there's a ghost event after the 2nd note
+			if (inputChar == Common::KEYCODE_ESCAPE || inputChar == Common::KEYCODE_RETURN)
+				stopFl = 0;
 		}
-
-		if (inputChar != Common::KEYCODE_INVALID)
-			stopFl = 0;
-	}
+	} while (stopFl != 0);
 	
 	return inputChar;
 }


Commit: 577fbde5ba1a0513e43f7c722af0b00111fbdae0
    https://github.com/scummvm/scummvm/commit/577fbde5ba1a0513e43f7c722af0b00111fbdae0
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:47+01:00

Commit Message:
EFH: ... Music implementation! 0_o

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a86bc992d63..f6b5ef1b471 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -280,11 +280,18 @@ void EfhEngine::songDelay(int delay) {
 
 void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
 	debug("playNote %d %d", frequencyIndex, totalDelay);
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DD / kSoundFrequency [frequencyIndex], -1);
+	songDelay(totalDelay);
+	_speakerStream->stop();
 }
 
 Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 	debug("playSong");
 
+	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+							_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
 	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
 	int totalDelay = 0;
 
@@ -326,6 +333,10 @@ Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
 		}
 	} while (stopFl != 0);
 	
+	_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
+	_speakerStream = nullptr;
+
 	return inputChar;
 }
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 2fd42f5d930..7e8034d81cd 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -22,6 +22,8 @@
 #ifndef EFH_H
 #define EFH_H
 
+#include "audio/softsynth/pcspk.h"
+#include "audio/mixer.h"
 #include "common/file.h"
 #include "common/rect.h"
 #include "common/events.h"
@@ -619,6 +621,9 @@ private:
 	InitiativeStruct _initiatives[8];
 
 	int16 _regenCounter;
+
+	Audio::PCSpeaker *_speakerStream;
+	Audio::SoundHandle _speakerHandle;
 };
 
 } // End of namespace Efh


Commit: af35f1c3bd69844aef471a5884fa53c7ff63c09a
    https://github.com/scummvm/scummvm/commit/af35f1c3bd69844aef471a5884fa53c7ff63c09a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Sync volume settings, add a purge of keyboard events to stop exiting the splash screen accidentally

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index f6b5ef1b471..e21ac4423a0 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -54,12 +54,6 @@ EfhEngine::~EfhEngine() {
 	delete _vgaGraphicsStruct2;
 }
 
-void EfhEngine::syncSoundSettings() {
-	Engine::syncSoundSettings();
-
-	warning("TODO: _sound->syncVolume();");
-}
-
 Common::Error EfhEngine::run() {
 	debug("run");
 
@@ -70,11 +64,13 @@ Common::Error EfhEngine::run() {
 	_mainSurface->create(320, 200, Graphics::PixelFormat::createFormatCLUT8());
 
 	initPalette();
-/*
+
 	// Setup mixer
 	syncSoundSettings();
-	_soundHandler->init();
-*/
+
+	// Sometimes a ghost key event stops the intro, so we ass a short delay and purge the keyboard events
+	_system->delayMillis(100);
+	_system->getEventManager()->purgeKeyboardEvents();
 
 	initEngine();
 	drawGameScreenAndTempText(true);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 7e8034d81cd..42acf582905 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -256,8 +256,6 @@ public:
 
 	const ADGameDescription *_gameDescription;
 
-	void syncSoundSettings() override;
-
 	// metaengine.cpp
 	void initGame(const ADGameDescription *gd);
 	uint32 getFeatures() const;


Commit: a25e1b09c96785de70c3e47b9ddb3f7b03bf1cc5
    https://github.com/scummvm/scummvm/commit/a25e1b09c96785de70c3e47b9ddb3f7b03bf1cc5
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Improve delay length in title music

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index e21ac4423a0..d14c0582eae 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -199,6 +199,16 @@ Common::Error EfhEngine::run() {
 			displayLowStatusScreen(true);
 
 		} break;
+		// debug cases to test sound
+		case Common::KEYCODE_1:
+			generateSound(13);
+			break;
+		case Common::KEYCODE_2:
+			generateSound(14);
+			break;
+		case Common::KEYCODE_3:
+			generateSound(15);
+			break;
 		default:
 			if (retVal != Common::KEYCODE_INVALID)
 				warning("Main Loop: Unhandled input %d", retVal);
@@ -267,10 +277,10 @@ void EfhEngine::initialize() {
 void EfhEngine::songDelay(int delay) {
 	debug("songDelay %ld", delay);
 
-	int remainingDelay = delay;
+	int remainingDelay = delay / 2;
 	while (remainingDelay > 0 && !shouldQuit()) {
-		remainingDelay -= 10;
-		_system->delayMillis(10);
+		remainingDelay -= 3;
+		_system->delayMillis(3);
 	}
 }
 


Commit: f52852512e4122ee707088dc35e1dcbd94fb171e
    https://github.com/scummvm/scummvm/commit/f52852512e4122ee707088dc35e1dcbd94fb171e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Implementation of generateSound2 (based on assembly, no idea about how it should sound like on real hardware)

Changed paths:
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/sound.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 42acf582905..f731e100a28 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -483,7 +483,7 @@ private:
 
 	// Sound
 	void generateSound1(int arg0, int arg2, int duration);
-	void generateSound2(int startFreq, int endFreq, int arg4);
+	void generateSound2(int startFreq, int endFreq, int speed);
 	void generateSound3();
 	void generateSound4(int arg0);
 	void generateSound5(int arg0);
@@ -504,6 +504,7 @@ private:
 	Common::KeyCode getInputBlocking();
 	void setNumLock();
 	bool getValidationFromUser();
+	uint32 ROR(uint32 val, uint8 shiftVal);
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index e3fe6a93aae..c15910b8e14 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -525,6 +525,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				int16 hitCount = 0;
 				int16 originalDamage = 0;
 				int16 damagePointsAbsorbed = 0;
+
 				int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._npcId * _items[monsterWeaponItemId]._attacks;
 				for (int var84 = 0; var84 < var64; ++var84) {
 					// handleFight - Loop var84 on var64 (objectId) - Start
diff --git a/engines/efh/sound.cpp b/engines/efh/sound.cpp
index 8da1fa70078..7f66d586163 100644
--- a/engines/efh/sound.cpp
+++ b/engines/efh/sound.cpp
@@ -25,12 +25,68 @@ namespace Efh {
 
 void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
 	warning("STUB: generateSound1 %d %d %d", arg0, arg2, duration);
+
+	if (arg0 < 19)
+		arg0 = 19;
+
+	if (arg2 < 19)
+		arg2 = 19;
+
+	uint32 var2 = 0;
+	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+					   _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DE / arg2, -1);
+	songDelay(10);
+	_speakerStream->stop();
+
+	for (int i = 0; i < duration; ++i) {
+		var2 = ROR(var2 + 0x9248, 3);
+		uint32 val = var2 * (arg2 - arg0);
+		
+		
+	}
+	
+
+	_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
+	_speakerStream = nullptr;
 }
 
-void EfhEngine::generateSound2(int startFreq, int endFreq, int arg4) {
-	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, arg4);
+void EfhEngine::generateSound2(int startFreq, int endFreq, int speed) {
+	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, speed);
+
+	if (startFreq < 19)
+		startFreq = 19;
+
+	if (endFreq < 19)
+		endFreq = 19;
+
+	int delta;
+	if (startFreq > endFreq)
+		delta = -5;
+	else
+		delta = 5;
+
+	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+					   _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+	int curFreq = startFreq;
+
+	do {
+		_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, curFreq, -1);
+		songDelay(speed / 10);
+		_speakerStream->stop();
+		curFreq += delta;
+	} while (curFreq < endFreq && !shouldQuit());
+	
+
+	_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
+	_speakerStream = nullptr;
 
-	// Arg4 doesn't seem to be used.
 }
 
 void EfhEngine::generateSound3() {
@@ -46,6 +102,8 @@ void EfhEngine::generateSound5(int arg0) {
 }
 
 void EfhEngine::generateSound(int16 soundType) {
+	warning("generateSound %d", soundType);
+
 	switch (soundType) {
 	case 5:
 		generateSound3();
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index 78a01fe96d1..e10b99c5462 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -295,4 +295,8 @@ bool EfhEngine::getValidationFromUser() {
 	return false;
 }
 
+uint32 EfhEngine::ROR(uint32 val, uint8 shiftVal) {
+	return val >> shiftVal | val << (32 - shiftVal);
+}
+
 } // End of namespace Efh


Commit: 16cc90a9731758bd2c03ec17f407447437632d66
    https://github.com/scummvm/scummvm/commit/16cc90a9731758bd2c03ec17f407447437632d66
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Implement generateSound3

Changed paths:
    engines/efh/efh.cpp
    engines/efh/sound.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d14c0582eae..ce8c3a7e601 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -209,6 +209,9 @@ Common::Error EfhEngine::run() {
 		case Common::KEYCODE_3:
 			generateSound(15);
 			break;
+		case Common::KEYCODE_4:
+			generateSound(5);
+			break;
 		default:
 			if (retVal != Common::KEYCODE_INVALID)
 				warning("Main Loop: Unhandled input %d", retVal);
@@ -286,7 +289,7 @@ void EfhEngine::songDelay(int delay) {
 
 void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
 	debug("playNote %d %d", frequencyIndex, totalDelay);
-	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DD / kSoundFrequency [frequencyIndex], -1);
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DD / kSoundFrequency[frequencyIndex], -1);
 	songDelay(totalDelay);
 	_speakerStream->stop();
 }
diff --git a/engines/efh/sound.cpp b/engines/efh/sound.cpp
index 7f66d586163..1d9da78d281 100644
--- a/engines/efh/sound.cpp
+++ b/engines/efh/sound.cpp
@@ -55,7 +55,7 @@ void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
 }
 
 void EfhEngine::generateSound2(int startFreq, int endFreq, int speed) {
-	warning("STUB: generateSound2 %d %d %d", startFreq, endFreq, speed);
+	debugC(3, kDebugEngine, "generateSound2 %d %d %d", startFreq, endFreq, speed);
 
 	if (startFreq < 19)
 		startFreq = 19;
@@ -64,6 +64,7 @@ void EfhEngine::generateSound2(int startFreq, int endFreq, int speed) {
 		endFreq = 19;
 
 	int delta;
+	// The original is using -/+1 but it takes ages even with speed / 10, so I switched to -/+5
 	if (startFreq > endFreq)
 		delta = -5;
 	else
@@ -77,6 +78,8 @@ void EfhEngine::generateSound2(int startFreq, int endFreq, int speed) {
 
 	do {
 		_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, curFreq, -1);
+		// The original is just looping, making the sound improperly timed as the length of a loop is directly related to the speed of the CPU
+		// Dividing by 10 is just a guess based on how it sounds. I suspect it may be still too much
 		songDelay(speed / 10);
 		_speakerStream->stop();
 		curFreq += delta;
@@ -90,7 +93,19 @@ void EfhEngine::generateSound2(int startFreq, int endFreq, int speed) {
 }
 
 void EfhEngine::generateSound3() {
-	warning("STUB: generateSound3");
+	debugC(3, kDebugEngine, "generateSound3");
+	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+					   _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 88, -1);
+	// The original makes me think the delay is so short it's not possible to hear. So that delay is guessed (and short)
+	songDelay(30);
+	_speakerStream->stop();
+
+	_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
+	_speakerStream = nullptr;
 }
 
 void EfhEngine::generateSound4(int arg0) {


Commit: 6fa1582bfae0901b652572ac110d79f2de786f7e
    https://github.com/scummvm/scummvm/commit/6fa1582bfae0901b652572ac110d79f2de786f7e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Add the last sound generation functions

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/sound.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index ce8c3a7e601..dcf184e4a33 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -212,6 +212,12 @@ Common::Error EfhEngine::run() {
 		case Common::KEYCODE_4:
 			generateSound(5);
 			break;
+		case Common::KEYCODE_5:
+			generateSound(10);
+			break;
+		case Common::KEYCODE_6:
+			generateSound1(20, 888, 3000);
+			break;
 		default:
 			if (retVal != Common::KEYCODE_INVALID)
 				warning("Main Loop: Unhandled input %d", retVal);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index f731e100a28..a27c739ca93 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -482,11 +482,11 @@ private:
 	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool scriptExecuteFlag);
 
 	// Sound
-	void generateSound1(int arg0, int arg2, int duration);
+	void generateSound1(int lowFreq, int highFreq, int duration);
 	void generateSound2(int startFreq, int endFreq, int speed);
 	void generateSound3();
-	void generateSound4(int arg0);
-	void generateSound5(int arg0);
+	void generateSound4(int repeat);
+	void generateSound5(int repeat);
 	void generateSound(int16 soundType);
 	void genericGenerateSound(int16 soundType, int16 repeatCount);
 
diff --git a/engines/efh/sound.cpp b/engines/efh/sound.cpp
index 1d9da78d281..17b32332f98 100644
--- a/engines/efh/sound.cpp
+++ b/engines/efh/sound.cpp
@@ -23,29 +23,34 @@
 
 namespace Efh {
 
-void EfhEngine::generateSound1(int arg0, int arg2, int duration) {
-	warning("STUB: generateSound1 %d %d %d", arg0, arg2, duration);
+void EfhEngine::generateSound1(int lowFreq, int highFreq, int duration) {
+	debugC(3, kDebugEngine, "generateSound1 %d %d %d - suspicious code", lowFreq, highFreq, duration);
 
-	if (arg0 < 19)
-		arg0 = 19;
+	if (lowFreq < 19)
+		lowFreq = 19;
 
-	if (arg2 < 19)
-		arg2 = 19;
+	if (highFreq < 19)
+		highFreq = 19;
+
+	uint16 var2 = 0;
+	duration /= 20;
 
-	uint32 var2 = 0;
 	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
 	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
 					   _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
 
-	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DE / arg2, -1);
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, highFreq, -1);
 	songDelay(10);
-	_speakerStream->stop();
+	_speakerStream->stop();		
+
 
 	for (int i = 0; i < duration; ++i) {
 		var2 = ROR(var2 + 0x9248, 3);
-		uint32 val = var2 * (arg2 - arg0);
-		
+		int val = (var2 * (highFreq - lowFreq)) >> 16;
 		
+		_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, lowFreq + val, -1);
+		songDelay(10);
+		_speakerStream->stop();		
 	}
 	
 
@@ -108,16 +113,22 @@ void EfhEngine::generateSound3() {
 	_speakerStream = nullptr;
 }
 
-void EfhEngine::generateSound4(int arg0) {
-	warning("STUB: generateSound4 %d", arg0);
+void EfhEngine::generateSound4(int repeat) {
+	debugC(3, kDebugEngine, "generateSound4 %d", repeat);
+	for (int i = 0; i < repeat; ++i)
+		//It looks identical, so I'm reusing generateSound1
+		generateSound1(256, 4096, 10);
 }
 
-void EfhEngine::generateSound5(int arg0) {
-	warning("STUB: generateSound5 %d", arg0);
+void EfhEngine::generateSound5(int repeat) {
+	debugC(3, kDebugEngine, "generateSound5 %d", repeat);
+	for (int i = 0; i < repeat; ++i)
+		//It looks identical, so I'm reusing generateSound2
+		generateSound2(256, 4096, 10);
 }
 
 void EfhEngine::generateSound(int16 soundType) {
-	warning("generateSound %d", soundType);
+	debugC(3, kDebugEngine, "generateSound %d", soundType);
 
 	switch (soundType) {
 	case 5:
@@ -146,12 +157,14 @@ void EfhEngine::generateSound(int16 soundType) {
 		generateSound4(1);
 		break;
 	default:
-		// Not implemented because not used by the engine
+		debug("generateSound %d - Not implemented because not used by the engine", soundType);
 		break;
 	}
 }
 
 void EfhEngine::genericGenerateSound(int16 soundType, int16 repeatCount) {
+	debugC(3, kDebugEngine, "genericGenerateSound %d %d", soundType, repeatCount);
+
 	if (repeatCount <= 0)
 		return;
 


Commit: 90ceabd3fcb92cd559b67b38ad24670bd1d50b79
    https://github.com/scummvm/scummvm/commit/90ceabd3fcb92cd559b67b38ad24670bd1d50b79
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Delete _mainSurface on exit

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index dcf184e4a33..d6a65901b00 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -48,6 +48,9 @@ int8 InvObject::getUsesLeft() {
 }
 
 EfhEngine::~EfhEngine() {
+	_mainSurface->free();
+	delete _mainSurface;
+	
 	delete _rnd;
 	delete _graphicsStruct;
 	delete _vgaGraphicsStruct1;


Commit: 6c027c0373ee267c7c89735343c3b639df12de35
    https://github.com/scummvm/scummvm/commit/6c027c0373ee267c7c89735343c3b639df12de35
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Some renaming

Changed paths:
    engines/efh/fight.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index c15910b8e14..5efc40a152d 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -272,23 +272,23 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			int16 damagePointsAbsorbed = 0;
 			int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
 
-			// Action A - Loop var84 - Start
-			for (int var84 = 0; var84 < attackSpeed; ++var84) {
+			// Action A - Loop attackCounter - Start
+			for (int attackCounter = 0; attackCounter < attackSpeed; ++attackCounter) {
 				if (getRandom(100) < charScore) {
 					++hitCount;
 					if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
-						int16 var7C = getRandom(_items[teamCharItemId]._damage);
-						int16 varInt = var7C - randomDamageAbsorbed;
-						if (varInt > 0) {
-							originalDamage += varInt;
+						int16 randomDamage = getRandom(_items[teamCharItemId]._damage);
+						int16 residualDamage = randomDamage - randomDamageAbsorbed;
+						if (residualDamage > 0) {
+							originalDamage += residualDamage;
 							damagePointsAbsorbed += randomDamageAbsorbed;
 						} else {
-							damagePointsAbsorbed += var7C;
+							damagePointsAbsorbed += randomDamage;
 						}
 					}
 				}
 			}
-			// Action A - Loop var84 - End
+			// Action A - Loop attackCounter - End
 
 			if (originalDamage < 0)
 				originalDamage = 0;
@@ -513,7 +513,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 			if (minTeamMemberId == -1)
 				continue;
 
-			// handleFight - Loop on var7E - Start
+			// handleFight - Loop on targetId - Start
 			for (int16 targetId = minTeamMemberId; targetId < maxTeamMemberId; ++targetId) {
 				if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
 					continue;
@@ -667,7 +667,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				genericGenerateSound(_items[monsterWeaponItemId]._attackType, hitCount);
 				displayBoxWithText(_messageToBePrinted, 1, 2, true);
 			}
-			// handleFight - Loop on var7E - End
+			// handleFight - Loop on targetId - End
 		} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[groupId]._effect[ctrMobsterId] > 0) {
 			--_teamMonsterEffects[groupId]._duration[ctrMobsterId];
 			if (_teamMonsterEffects[groupId]._duration[ctrMobsterId] <= 0) {
@@ -1598,8 +1598,8 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 	}
 
 	if (teamMonsterId != -1) {
-		// addNewOpponents - loop var2 - Start
-		for (int var2 = 1; var2 < 3; ++var2) {
+		// addNewOpponents - loop distCtr - Start
+		for (int distCtr = 1; distCtr < 3; ++distCtr) {
 			if (teamMonsterId >= 5)
 				break;
 
@@ -1620,7 +1620,7 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 						if (!monsterActiveFound)
 							continue;
 
-						if (computeMonsterGroupDistance(ctrMapMonsterId) > var2)
+						if (computeMonsterGroupDistance(ctrMapMonsterId) > distCtr)
 							continue;
 
 						if (isMonsterAlreadyFighting(ctrMapMonsterId, teamMonsterId))
@@ -1641,7 +1641,7 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 				}
 			}
 		}
-		// addNewOpponents - loop var2 - End
+		// addNewOpponents - loop distCtr - End
 	}
 
 	if (teamMonsterId == -1 || teamMonsterId > 4)


Commit: a33db72da44d9a1576ad8871d17a0654ff6ed353
    https://github.com/scummvm/scummvm/commit/a33db72da44d9a1576ad8871d17a0654ff6ed353
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Move songDelay, playNote and PlaySong to sound.sound.cpp

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/sound.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d6a65901b00..c4909c73f4c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -286,78 +286,6 @@ void EfhEngine::initialize() {
 	_shouldQuit = false;
 }
 
-void EfhEngine::songDelay(int delay) {
-	debug("songDelay %ld", delay);
-
-	int remainingDelay = delay / 2;
-	while (remainingDelay > 0 && !shouldQuit()) {
-		remainingDelay -= 3;
-		_system->delayMillis(3);
-	}
-}
-
-void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
-	debug("playNote %d %d", frequencyIndex, totalDelay);
-	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DD / kSoundFrequency[frequencyIndex], -1);
-	songDelay(totalDelay);
-	_speakerStream->stop();
-}
-
-Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
-	debug("playSong");
-
-	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
-							_speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
-
-	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
-	int totalDelay = 0;
-
-	int8 stopFl;
-	uint8 varC = *buffer++;
-	Common::Event event;
-	do {
-		stopFl = *buffer & 0x3F;
-		if (stopFl != 0) {
-			int delay = stopFl * varC * 0x2200 / 1000;
-
-			if (*buffer > 0x7F)
-				delay /= 2;
-
-			if (*buffer & 0x40)
-				delay = (delay * 2) / 3;
-
-			++buffer;
-			uint8 frequencyIndex = *buffer;
-			++buffer;
-
-			if (frequencyIndex > 0x7F)
-				totalDelay += delay;
-			else if (frequencyIndex == 0)
-				songDelay(delay);
-			else {
-				playNote(frequencyIndex, totalDelay + delay);
-				totalDelay = 0;
-			}
-		}
-
-		songDelay(10);
-		_system->getEventManager()->pollEvent(event);
-		if (event.type == Common::EVENT_KEYUP) {
-			inputChar = event.kbd.keycode;
-			// Hack, sometimes there's a ghost event after the 2nd note
-			if (inputChar == Common::KEYCODE_ESCAPE || inputChar == Common::KEYCODE_RETURN)
-				stopFl = 0;
-		}
-	} while (stopFl != 0);
-	
-	_mixer->stopHandle(_speakerHandle);
-	delete _speakerStream;
-	_speakerStream = nullptr;
-
-	return inputChar;
-}
-
 void EfhEngine::playIntro() {
 	debugC(6, kDebugEngine, "playIntro");
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a27c739ca93..0a7329e1aa4 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -285,9 +285,6 @@ private:
 	bool _saveAuthorized;
 
 	void initialize();
-	void songDelay(int delay);
-	void playNote(int frequencyIndex, int totalDelay);
-	Common::KeyCode playSong(uint8 *buffer);
 	void playIntro();
 	void initEngine();
 	void initMapMonsters();
@@ -482,6 +479,9 @@ private:
 	int16 script_parse(Common::String str, int16 posX, int16 posY, int16 maxX, int16 maxY, bool scriptExecuteFlag);
 
 	// Sound
+	void songDelay(int delay);
+	void playNote(int frequencyIndex, int totalDelay);
+	Common::KeyCode playSong(uint8 *buffer);
 	void generateSound1(int lowFreq, int highFreq, int duration);
 	void generateSound2(int startFreq, int endFreq, int speed);
 	void generateSound3();
diff --git a/engines/efh/sound.cpp b/engines/efh/sound.cpp
index 17b32332f98..e0b0181cabe 100644
--- a/engines/efh/sound.cpp
+++ b/engines/efh/sound.cpp
@@ -23,6 +23,78 @@
 
 namespace Efh {
 
+void EfhEngine::songDelay(int delay) {
+	debugC(3, kDebugEngine, "songDelay %ld", delay);
+
+	int remainingDelay = delay / 2;
+	while (remainingDelay > 0 && !shouldQuit()) {
+		remainingDelay -= 3;
+		_system->delayMillis(3);
+	}
+}
+
+void EfhEngine::playNote(int frequencyIndex, int totalDelay) {
+	debugC(3, kDebugEngine, "playNote %d %d", frequencyIndex, totalDelay);
+	_speakerStream->play(Audio::PCSpeaker::kWaveFormSquare, 0x1234DD / kSoundFrequency[frequencyIndex], -1);
+	songDelay(totalDelay);
+	_speakerStream->stop();
+}
+
+Common::KeyCode EfhEngine::playSong(uint8 *buffer) {
+	debugC(3, kDebugEngine, "playSong");
+
+	_speakerStream = new Audio::PCSpeaker(_mixer->getOutputRate());
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_speakerHandle,
+					   _speakerStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true);
+
+	Common::KeyCode inputChar = Common::KEYCODE_INVALID;
+	int totalDelay = 0;
+
+	int8 stopFl;
+	uint8 varC = *buffer++;
+	Common::Event event;
+	do {
+		stopFl = *buffer & 0x3F;
+		if (stopFl != 0) {
+			int delay = stopFl * varC * 0x2200 / 1000;
+
+			if (*buffer > 0x7F)
+				delay /= 2;
+
+			if (*buffer & 0x40)
+				delay = (delay * 2) / 3;
+
+			++buffer;
+			uint8 frequencyIndex = *buffer;
+			++buffer;
+
+			if (frequencyIndex > 0x7F)
+				totalDelay += delay;
+			else if (frequencyIndex == 0)
+				songDelay(delay);
+			else {
+				playNote(frequencyIndex, totalDelay + delay);
+				totalDelay = 0;
+			}
+		}
+
+		songDelay(10);
+		_system->getEventManager()->pollEvent(event);
+		if (event.type == Common::EVENT_KEYUP) {
+			inputChar = event.kbd.keycode;
+			// Hack, sometimes there's a ghost event after the 2nd note
+			if (inputChar == Common::KEYCODE_ESCAPE || inputChar == Common::KEYCODE_RETURN)
+				stopFl = 0;
+		}
+	} while (stopFl != 0);
+
+	_mixer->stopHandle(_speakerHandle);
+	delete _speakerStream;
+	_speakerStream = nullptr;
+
+	return inputChar;
+}
+
 void EfhEngine::generateSound1(int lowFreq, int highFreq, int duration) {
 	debugC(3, kDebugEngine, "generateSound1 %d %d %d - suspicious code", lowFreq, highFreq, duration);
 


Commit: 207bbbbbbfe8fd47d9e79843b172cf767400c845
    https://github.com/scummvm/scummvm/commit/207bbbbbbfe8fd47d9e79843b172cf767400c845
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Turn some debug into debugC()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/fight.cpp
    engines/efh/menu.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c4909c73f4c..976b04831eb 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -58,8 +58,6 @@ EfhEngine::~EfhEngine() {
 }
 
 Common::Error EfhEngine::run() {
-	debug("run");
-
 	initialize();
 	initGraphics(320, 200);
 
@@ -2480,7 +2478,7 @@ void EfhEngine::checkProtection() {
 }
 
 void EfhEngine::loadEfhGame() {
-	debug("loadEfhGame");
+	debugC(2, kDebugEngine, "loadEfhGame");
 
 	// The original used a loop to check for the presence of the savegame on the current floppy.
 	// When the savegame wasn't found, it was displaying a screen asking for Disk 1 and was setting a flag used
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 5efc40a152d..2ff065801bc 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -78,7 +78,7 @@ void EfhEngine::initFight(int16 monsterId) {
 }
 
 bool EfhEngine::handleFight(int16 monsterId) {
-	debug("handleFight %d", monsterId);
+	debugC(3, kDebugFight, "handleFight %d", monsterId);
 
 	_ongoingFightFl = true;
 
@@ -210,7 +210,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 }
 
 void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
-	debug("handleFight_lastAction_A %d", teamCharId);
+	debugC(3, kDebugFight, "handleFight_lastAction_A %d", teamCharId);
 
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
@@ -486,7 +486,7 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 void EfhEngine::handleFight_MobstersAttack(int groupId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
-	debug("handleFight_MobstersAttack %d", groupId);
+	debugC(3, kDebugFight, "handleFight_MobstersAttack %d", groupId);
 	
 	// handleFight - Loop on mobsterId - Start
 	for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index c7bcc2cd675..afb9593bb75 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -889,7 +889,7 @@ void EfhEngine::tryToggleEquipped(int16 charId, int16 objectId, int16 windowId,
 }
 
 int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, int16 menuId, int16 curMenuLine, int16 gameMode) {
-	debug("useObject %d %d %d %d %d %s", charId, objectId, teamMonsterId, menuId, curMenuLine, gameMode == 3 ? "Combat" : "Normal");
+	debugC(3, kDebugEngine, "useObject %d %d %d %d %d %s", charId, objectId, teamMonsterId, menuId, curMenuLine, gameMode == 3 ? "Combat" : "Normal");
 
 	Common::String buffer1 = "";
 
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 2eb19348c93..298e960cf05 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -55,7 +55,7 @@ uint8 *EfhEngine::script_getNumber(uint8 *srcBuffer, int16 *retBuf) {
 }
 
 int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 posY, int16 maxX, int16 maxY, bool scriptExecuteFlag) {
-	debug("script_parse stringBuffer %d-%d %d-%d %s", posX, posY, maxX, maxY, scriptExecuteFlag ? "True" : "False");
+	debugC(3, kDebugScript, "script_parse stringBuffer %d-%d %d-%d %s", posX, posY, maxX, maxY, scriptExecuteFlag ? "True" : "False");
 	debugC(6, kDebugScript, "%s", stringBuffer.c_str());
 
 	bool doneFlag = false;


Commit: 0ee97e0a6568b2503423355fd8e0a3b929cf0c83
    https://github.com/scummvm/scummvm/commit/0ee97e0a6568b2503423355fd8e0a3b929cf0c83
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Use hex values for palette definition

Changed paths:
    engines/efh/graphics.cpp


diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 7d73ea35cf9..2ac0736e1b4 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -28,22 +28,22 @@ namespace Efh {
 void EfhEngine::initPalette() {
 	// Strangerke - values from a tool I wrote in 2008. I can't remember if it's guess work or not.
 	static const uint8 pal[3 * 16] = {
-		0, 0, 0,
-		0, 0, 170,
-		0, 170, 0,
-		0, 170, 170,
-		170, 0, 0,
-		170, 0, 170,
-		170, 85, 0,
-		170, 170, 170,
-		85, 85, 85,
-		85, 85, 255,
-		1, 1, 1, // Color 0xA is for transparency
-		85, 255, 255,
-		255, 85, 85,
-		255, 85, 255,
-		255, 255, 85,
-		255, 255, 255
+		0x00, 0x00, 0x00,
+		0x00, 0x00, 0xAA,
+		0x00, 0xAA, 0x00,
+		0x00, 0xAA, 0xAA,
+		0xAA, 0x00, 0x00,
+		0xAA, 0x00, 0xAA,
+		0xAA, 0x55, 0x00,
+		0xAA, 0xAA, 0xAA,
+		0x55, 0x55, 0x55,
+		0x55, 0x55, 0xFF,
+		0x01, 0x01, 0x01, // Color 0xA is for transparency
+		0x55, 0xFF, 0xFF,
+		0xFF, 0x55, 0x55,
+		0xFF, 0x55, 0xFF,
+		0xFF, 0xFF, 0x55,
+		0xFF, 0xFF, 0xFF
 	};
 
 	debugC(1, kDebugGraphics, "initPalette");


Commit: b62431dd4dea54dec694afe62f08bef73708c3c7
    https://github.com/scummvm/scummvm/commit/b62431dd4dea54dec694afe62f08bef73708c3c7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Fix fileorder in makefile

Changed paths:
    engines/efh/module.mk


diff --git a/engines/efh/module.mk b/engines/efh/module.mk
index a81d60c278d..d8e9fc59b09 100644
--- a/engines/efh/module.mk
+++ b/engines/efh/module.mk
@@ -8,11 +8,11 @@ MODULE_OBJS = \
 	graphics.o \
 	init.o \
 	menu.o \
+	metaengine.o \
 	savegames.o \
 	script.o \
 	sound.o \
-	utils.o \
-	metaengine.o
+	utils.o
 
 MODULE_DIRS += \
 	engines/efh


Commit: cdd3004c29611dc205231c5a90879e7e836fcdf9
    https://github.com/scummvm/scummvm/commit/cdd3004c29611dc205231c5a90879e7e836fcdf9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Make use of dump-scripts command instead of defines

Changed paths:
    engines/efh/files.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 9940cde059a..d1350447048 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "efh/efh.h"
 
 namespace Efh {
@@ -88,18 +89,16 @@ void EfhEngine::rImageFile(Common::String filename, uint8 *targetBuffer, uint8 *
 	debugC(1, kDebugUtils, "rImageFile %s", filename.c_str());
 	readFileToBuffer(filename, packedBuffer);
 
-#ifndef debug
-	uncompressBuffer(packedBuffer, targetBuffer);
-#else
 	uint32 size = uncompressBuffer(packedBuffer, targetBuffer);
-	// dump a decompressed image file
-	Common::DumpFile dump;
-	dump.open(filename + ".dump");
-	dump.write(targetBuffer, size);
-	dump.flush();
-	dump.close();
-	// End of dump
-#endif
+	if (ConfMan.getBool("dump_scripts")) {
+		// dump a decompressed image file
+		Common::DumpFile dump;
+		dump.open(filename + ".dump");
+		dump.write(targetBuffer, size);
+		dump.flush();
+		dump.close();
+		// End of dump
+	}
 
 	// TODO: Refactoring: once uncompressed, the container contains for each image its width, its height, and raw data (4 Bpp)
 	// => Write a class to handle that more properly
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index e10b99c5462..ed4a9ceceb3 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include "common/config-manager.h"
 #include "common/system.h"
 #include "common/random.h"
 #include "efh/efh.h"
@@ -60,19 +61,19 @@ void EfhEngine::decryptImpFile(bool techMapFl) {
 			++curPtr;
 	} while (*curPtr != 0x60 && counter <= target);
 
-#ifdef debug
-// Dump the decompressed IMP file
-	Common::DumpFile dump;
-	if (!techMapFl) {
-		dump.open("imp2_unc.dump");
-		dump.write(_imp2, curPtr - _imp2);
-	} else {
-		dump.open("imp1_unc.dump");
-		dump.write(_imp1, curPtr - _imp1);
+	if (ConfMan.getBool("dump_scripts")) {
+		// Dump the decompressed IMP file
+		Common::DumpFile dump;
+		if (!techMapFl) {
+			dump.open("imp2_unc.dump");
+			dump.write(_imp2, curPtr - _imp2);
+		} else {
+			dump.open("imp1_unc.dump");
+			dump.write(_imp1, curPtr - _imp1);
+		}
+		dump.flush();
+		dump.close();
 	}
-	dump.flush();
-	dump.close();
-#endif
 }
 
 void EfhEngine::loadImageSet(int16 imageSetId, uint8 *buffer, uint8 **subFilesArray, uint8 *destBuffer) {


Commit: 956913fbbe0ca32c8d4577680a6c5a1db85eb276
    https://github.com/scummvm/scummvm/commit/956913fbbe0ca32c8d4577680a6c5a1db85eb276
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Add brackets for look consistency

Changed paths:
    engines/efh/fight.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 2ff065801bc..7dfdcf7ea1c 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -775,9 +775,9 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 			else
 				deathType = _items[exclusiveItemId]._attackType + 1;
 		}
-	} else if (_teamMonsterIdArray[attackerId] == -1)
+	} else if (_teamMonsterIdArray[attackerId] == -1) {
 		deathType = 0;
-	else {
+	} else {
 		int16 itemId = _mapMonsters[_techId][_teamMonsterIdArray[attackerId]]._weaponItemId;
 		deathType = _items[itemId]._attackType + 1;
 	}


Commit: f41c0e85ed0ffc20a76231a8cc972d387c27ae8b
    https://github.com/scummvm/scummvm/commit/f41c0e85ed0ffc20a76231a8cc972d387c27ae8b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:48+01:00

Commit Message:
EFH: Add code to dump decoded maps

Changed paths:
    engines/efh/files.cpp


diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index d1350447048..dc8303c9d06 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -322,6 +322,11 @@ void EfhEngine::loadNPCS() {
  * This is required in order to implement a clean savegame feature
  */
 void EfhEngine::preLoadMaps() {
+	Common::DumpFile dump;
+	if (ConfMan.getBool("dump_scripts")) {
+		dump.open("efhMaps.dump");
+	}
+
 	for (int idx = 0; idx < 19; ++idx) {
 		Common::String fileName = Common::String::format("tech.%d", idx);
 		readFileToBuffer(fileName, _hiResImageBuf);
@@ -344,6 +349,14 @@ void EfhEngine::preLoadMaps() {
 			_mapSpecialTiles[idx][i]._triggerId = mapSpecialTilePtr[9 * i + 4];
 			_mapSpecialTiles[idx][i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
 			_mapSpecialTiles[idx][i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
+
+			if (ConfMan.getBool("dump_scripts") && _mapSpecialTiles[idx][i]._placeId != 0xFF) {
+				// dump a decoded version of the maps
+				Common::String buffer = Common::String::format("[%d][%d] _ placeId: 0x%02X _pos: %d, %d _field3: 0x%02X (%d), triggerId: %d, _field5/7: %d %d\n"
+					, idx, i, _mapSpecialTiles[idx][i]._placeId, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._field3
+					, _mapSpecialTiles[idx][i]._field3, _mapSpecialTiles[idx][i]._triggerId, _mapSpecialTiles[idx][i]._field5_textId, _mapSpecialTiles[idx][i]._field7_textId);
+				dump.write(buffer.c_str(), buffer.size());
+			}
 		}
 
 		uint8 *mapMonstersPtr = &_mapArr[idx][902];
@@ -368,8 +381,11 @@ void EfhEngine::preLoadMaps() {
 			for (int j = 0; j < 64; ++j)
 				_mapGameMaps[idx][i][j] = *mapPtr++;
 		}
-		
+	}
 
+	if (ConfMan.getBool("dump_scripts")) {
+		dump.flush();
+		dump.close();
 	}
 }
 


Commit: de2f2390ee4d3f4630bd93fcb905bafbb3b60bc2
    https://github.com/scummvm/scummvm/commit/de2f2390ee4d3f4630bd93fcb905bafbb3b60bc2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Introduce getArticle(), some renaming

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/utils.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 976b04831eb..4558268a7cf 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2093,16 +2093,16 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 			}
 		// original makes a useless check on (_mapSpecialTile[tileId]._field3 > 0x7F)
 		} else if (_mapSpecialTiles[_techId][tileId]._field3 <= 0x77) {
-			int16 var6 = _mapSpecialTiles[_techId][tileId]._field3;
+			int16 scoreId = _mapSpecialTiles[_techId][tileId]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamCharId[counter] == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 39; ++var2) {
-					// CHECKME : the whole loop doesn't make much sense as it's using var6 instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
+					// CHECKME : the whole loop doesn't make much sense as it's using scoreId instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
-					warning("handleInteractionText - _activeScore[%d]", var6);
-					if (_npcBuf[_teamCharId[counter]]._activeScore[var6] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
+					warning("handleInteractionText - _activeScore[%d]", scoreId);
+					if (_npcBuf[_teamCharId[counter]]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0a7329e1aa4..f13f1358aaf 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -505,6 +505,7 @@ private:
 	void setNumLock();
 	bool getValidationFromUser();
 	uint32 ROR(uint32 val, uint8 shiftVal);
+	Common::String getArticle(int pronoun);
 
 	uint8 _videoMode;
 	uint8 _bufferCharBM[128];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 7dfdcf7ea1c..6dd3e4a02d9 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -183,12 +183,8 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
 	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
-	if (_npcBuf[_teamCharId[charId]].getPronoun() == 2) {
-		_enemyNamePt1 = "The ";
-	} else {
-		_enemyNamePt1 = "";
-	}
-
+	_enemyNamePt1 = getArticle(_npcBuf[_teamCharId[charId]].getPronoun());
+	
 	// End of effect message depends on the type of effect
 	switch (_teamCharStatus[charId]._status) {
 	case 1:
@@ -262,7 +258,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				noticedFl = false;
 
 			int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
-			int16 ennemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+			int16 enemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
 			int16 monsterId = _teamMonsterIdArray[groupId];
 			int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
 			int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
@@ -307,29 +303,22 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				}
 			}
 			int16 verbId = (3 * _items[teamCharItemId]._attackType + 1) + getRandom(3) - 1;
-			if (characterPronoun == 2) {
-				_characterNamePt1 = "The ";
-			} else {
-				_characterNamePt1 = "";
-			}
-
-			if (ennemyPronoun == 2) {
-				_enemyNamePt1 = "The ";
-			} else {
-				_enemyNamePt1 = "";
-			}
 
+			_characterNamePt1 = getArticle(characterPronoun);
 			_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+
+			_enemyNamePt1 = getArticle(enemyPronoun);
 			_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+
 			_nameBuffer = _items[teamCharItemId]._name;
 			if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
 				// Action A - Check damages - Start
 				if (hitCount == 0) {
-					_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 				} else if (hitPoints <= 0) {
-					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 				} else if (hitPoints == 1) {
-					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
 						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -337,7 +326,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 						_messageToBePrinted += "!";
 					}
 				} else {
-					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
+					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
 					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
 						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
@@ -413,7 +402,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				}
 				// Action A - Check effect - End
 			} else {
-				_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+				_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 			}
 
 			genericGenerateSound(_items[teamCharItemId]._attackType, hitCount);
@@ -429,14 +418,10 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	debugC(3, kDebugFight, "handleFight_lastAction_D %d", teamCharId);
 
 	_teamPctDodgeMiss[teamCharId] -= 40;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 
 	uint8 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
-
-	if (pronoun == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
+	_enemyNamePt1 = getArticle(pronoun);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -449,13 +434,10 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
 
 	_teamPctVisible[teamCharId] -= 50;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
-	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
 
-	if (pronoun == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
+	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+	_enemyNamePt1 = getArticle(pronoun);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -468,13 +450,11 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	debugC(3, kDebugFight, "handleFight_lastAction_U %d", teamCharId);
 
 	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_teamLastInventoryUsed[teamCharId]]._ref;
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 	_nameBuffer = _items[itemId]._name;
+
 	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
-	if (pronoun == 2)
-		_enemyNamePt1 = "The ";
-	else
-		_enemyNamePt1 = "";
+	_enemyNamePt1 = getArticle(pronoun);
+	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
 	bool retVal = useObject(_teamCharId[teamCharId], _teamLastInventoryUsed[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
@@ -518,9 +498,11 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
 					continue;
 
-				int16 randomeDefense = getRandom(getEquipmentDefense(_teamCharId[targetId], false));
-				int16 ennemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
+				int16 randomDefense = getRandom(getEquipmentDefense(_teamCharId[targetId], false));
+
+				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
 				int16 characterPronoun = _npcBuf[_teamCharId[targetId]].getPronoun();
+
 				_teamPctDodgeMiss[targetId] += (_items[monsterWeaponItemId].field_13 * 5);
 				int16 hitCount = 0;
 				int16 originalDamage = 0;
@@ -537,14 +519,14 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					if (hasAdequateDefenseNPC(_teamCharId[targetId], _items[monsterWeaponItemId]._attackType))
 						continue;
 
-					int16 var7C = getRandom(_items[monsterWeaponItemId]._damage);
-					int varInt = var7C - randomeDefense;
+					int16 baseDamage = getRandom(_items[monsterWeaponItemId]._damage);
+					int deltaDamage = baseDamage - randomDefense;
 
-					if (varInt > 0) {
-						damagePointsAbsorbed += randomeDefense;
-						originalDamage += varInt;
+					if (deltaDamage > 0) {
+						damagePointsAbsorbed += randomDefense;
+						originalDamage += deltaDamage;
 					} else {
-						damagePointsAbsorbed += var7C;
+						damagePointsAbsorbed += baseDamage;
 					}
 					// handleFight - Loop var84 on var64 (objectId) - End
 				}
@@ -566,33 +548,28 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 
 				int16 var68 = _items[monsterWeaponItemId]._attackType + 1;
 				int16 var6A = getRandom(3);
-				if (characterPronoun == 2)
-					_characterNamePt1 = "The ";
-				else
-					_characterNamePt1 = "";
-
-				if (ennemyPronoun == 2)
-					_enemyNamePt1 = "The ";
-				else
-					_enemyNamePt1 = "";
 
+				_enemyNamePt1 = getArticle(enemyPronoun);
 				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+
+				_characterNamePt1 = getArticle(characterPronoun);
 				_characterNamePt2 = _npcBuf[_teamCharId[targetId]]._name;
+
 				_nameBuffer = _items[monsterWeaponItemId]._name;
 				if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
 					// handleFight - check damages - Start
 					if (hitCount == 0) {
-						_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+						_messageToBePrinted = Common::String::format("%s%s %s at %s%s with %s %s, but misses!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 					} else if (hitPoints <= 0) {
-						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 					} else if (hitPoints == 1) {
-						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
 							getDeathTypeDescription(targetId + 1000, groupId);
 						else
 							_messageToBePrinted += "!";
 					} else {
-						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str(), hitPoints);
+						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
 						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
 							getDeathTypeDescription(targetId + 1000, groupId);
 						else
@@ -623,7 +600,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					// handleFight - Add reaction text - end
 
 					// handleFight - Check armor - start
-					if (randomeDefense != 0 && hitCount != 0 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
+					if (randomDefense != 0 && hitCount != 0 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
 						if (damagePointsAbsorbed <= 1)
 							_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						else
@@ -662,7 +639,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					}
 					// handleFight - Check effect - end
 				} else {
-					_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[ennemyPronoun], _nameBuffer.c_str());
+					_messageToBePrinted = Common::String::format("%s%s tries to use %s %s, but it doesn't work!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 				}
 				genericGenerateSound(_items[monsterWeaponItemId]._attackType, hitCount);
 				displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -671,11 +648,8 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 		} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[groupId]._effect[ctrMobsterId] > 0) {
 			--_teamMonsterEffects[groupId]._duration[ctrMobsterId];
 			if (_teamMonsterEffects[groupId]._duration[ctrMobsterId] <= 0) {
+				_enemyNamePt1 = getArticle(kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle);
 				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
-				if (kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle == 2)
-					_enemyNamePt1 = "The ";
-				else
-					_enemyNamePt1 = "";
 
 				switch (_teamMonsterEffects[groupId]._effect[ctrMobsterId]) {
 				case 1:
diff --git a/engines/efh/utils.cpp b/engines/efh/utils.cpp
index ed4a9ceceb3..6eba099c0bf 100644
--- a/engines/efh/utils.cpp
+++ b/engines/efh/utils.cpp
@@ -300,4 +300,10 @@ uint32 EfhEngine::ROR(uint32 val, uint8 shiftVal) {
 	return val >> shiftVal | val << (32 - shiftVal);
 }
 
+Common::String EfhEngine::getArticle(int pronoun) {
+	if (pronoun == 2)
+		return "The ";
+
+	return "";
+}
 } // End of namespace Efh


Commit: e20186c0bc0b5d5f7f4512de894663f617fa5c3d
    https://github.com/scummvm/scummvm/commit/e20186c0bc0b5d5f7f4512de894663f617fa5c3d
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Some renaming in drawMap

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 4558268a7cf..359d04aafd7 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -633,27 +633,27 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 	}
 
 	if (drawMonstersFl) {
-		for (uint var16 = 0; var16 < 64; ++var16) {
-			if ((_largeMapFlag && _mapMonsters[_techId][var16]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[_techId][var16]._fullPlaceId == _fullPlaceId)){
+		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
+			if ((_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId)) {
 				bool var4 = false;
-				int16 posX = _mapMonsters[_techId][var16]._posX;
-				int16 posY = _mapMonsters[_techId][var16]._posY;
+				int16 posX = _mapMonsters[_techId][monsterId]._posX;
+				int16 posY = _mapMonsters[_techId][monsterId]._posY;
 
 				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
 					continue;
 
 				for (uint counterY = 0; counterY < 9 && !var4; ++counterY) {
-					if (_mapMonsters[_techId][var16]._hitPoints[counterY] > 0)
+					if (_mapMonsters[_techId][monsterId]._hitPoints[counterY] > 0)
 						var4 = true;
 				}
 
 				if (!var4)
 					continue;
 
-				int16 var6 = 148 + kEncounters[_mapMonsters[_techId][var16]._monsterRef]._animId;
-				int16 var1 = _mapMonsters[_techId][var16]._possessivePronounSHL6 & 0x3F;
+				int16 var6 = 148 + kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._animId;
+				int16 var1 = _mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F;
 
-				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[_techId][var16]._npcId))
+				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId))
 					continue;
 
 				int16 drawPosX = 128 + (posX - minX) * 16;


Commit: 21ea9c9729354fc69dcb06ddd9f0adb3048303b8
    https://github.com/scummvm/scummvm/commit/21ea9c9729354fc69dcb06ddd9f0adb3048303b8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Start making code less verbose, remove a useless parameter to getEquipmentDefense()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 359d04aafd7..9919838b938 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -454,13 +454,14 @@ void EfhEngine::initMapMonsters() {
 	debugC(3, kDebugEngine, "initMapMonsters");
 
 	for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-		if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
+		MapMonster *curMons = &_mapMonsters[_techId][monsterId];
+		if (curMons->_fullPlaceId == 0xFF)
 			continue;
 
 		for (uint counter = 0; counter < 9; ++counter)
-			_mapMonsters[_techId][monsterId]._hitPoints[counter] = 0;
+			curMons->_hitPoints[counter] = 0;
 
-		uint8 groupSize = _mapMonsters[_techId][monsterId]._groupSize;
+		uint8 groupSize = curMons->_groupSize;
 		if (groupSize == 0)
 			groupSize = getRandom(10) - 1;
 
@@ -469,17 +470,15 @@ void EfhEngine::initMapMonsters() {
 		
 		for (uint counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
-			uint16 pictureRef = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._pictureRef;
-
-			if (rand100 <= 25) {
-				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef - delta;
-			} else if (rand100 <= 75) {
-				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef;
-			} else {
-				uint16 delta = getRandom(pictureRef / 2);
-				_mapMonsters[_techId][monsterId]._hitPoints[counter] = pictureRef + delta;
-			}
+			uint16 pictureRef = kEncounters[curMons->_monsterRef]._pictureRef;
+			uint16 delta = getRandom(pictureRef / 2);
+
+			if (rand100 <= 25)
+				curMons->_hitPoints[counter] = pictureRef - delta;
+			else if (rand100 <= 75)
+				curMons->_hitPoints[counter] = pictureRef;
+			else
+				curMons->_hitPoints[counter] = pictureRef + delta;
 		}
 	}
 }
@@ -495,33 +494,27 @@ void EfhEngine::saveAnimImageSetId() {
 	_animImageSetId = 0xFF;
 }
 
-int16 EfhEngine::getEquipmentDefense(int16 charId, bool flag) {
-	debugC(2, kDebugGraphics, "getEquipmentDefense %d %s", charId, flag ? "True" : "False");
-	// TODO: flag is always false, remove it when refactoring
+int16 EfhEngine::getEquipmentDefense(int16 charId) {
+	debugC(2, kDebugGraphics, "getEquipmentDefense %d %s", charId);
 
 	int16 altDef = 0;
-	int16 totalDef = 0;
+
 	for (int i = 0; i < 10; ++i) {
-		if (_npcBuf[charId]._inventory[i]._ref == 0x7FFF)
-			continue;
+		InvObject *curInvObj = &_npcBuf[charId]._inventory[i];
 
-		if (!_npcBuf[charId]._inventory[i].isEquipped())
+		if (curInvObj->_ref == 0x7FFF || !curInvObj->isEquipped())
 			continue;
 
-		int16 curDef = _npcBuf[charId]._inventory[i]._curHitPoints;
+		int16 curDef = curInvObj->_curHitPoints;
 		if (curDef == 0xFF)
-			curDef = _items[_npcBuf[charId]._inventory[i]._ref]._defense;
+			curDef = _items[curInvObj->_ref]._defense;
 
 		if (curDef <= 0)
 			continue;
 
-		totalDef += curDef;
 		altDef += (curDef / 8) + 1;
 	}
 
-	if (flag)
-		return totalDef;
-
 	return altDef;
 }
 
@@ -529,10 +522,12 @@ uint16 EfhEngine::getEquippedExclusiveType(int16 charId, int16 exclusiveType, bo
 	debugC(2, kDebugEngine, "getEquippedExclusiveType %d %d %s", charId, exclusiveType, flag ? "True" : "False");
 
 	for (int i = 0; i < 10; ++i) {
-		if (!_npcBuf[charId]._inventory[i].isEquipped())
+		InvObject *curInvObj = &_npcBuf[charId]._inventory[i];
+
+		if (!curInvObj->isEquipped())
 			continue;
 
-		int16 curItemId = _npcBuf[charId]._inventory[i]._ref;
+		int16 curItemId = curInvObj->_ref;
 
 		if (_items[curItemId]._exclusiveType != exclusiveType)
 			continue;
@@ -634,31 +629,31 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 
 	if (drawMonstersFl) {
 		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if ((_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE) || (!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId)) {
-				bool var4 = false;
-				int16 posX = _mapMonsters[_techId][monsterId]._posX;
-				int16 posY = _mapMonsters[_techId][monsterId]._posY;
+			MapMonster *curMapMons = &_mapMonsters[_techId][monsterId];
+			if ((_largeMapFlag && curMapMons->_fullPlaceId == 0xFE) || (!_largeMapFlag && curMapMons->_fullPlaceId == _fullPlaceId)) {
+				int16 posX = curMapMons->_posX;
+				int16 posY = curMapMons->_posY;
 
 				if (posX < minX || posX > maxX || posY < minY || posY > maxY)
 					continue;
 
-				for (uint counterY = 0; counterY < 9 && !var4; ++counterY) {
-					if (_mapMonsters[_techId][monsterId]._hitPoints[counterY] > 0)
-						var4 = true;
+				bool groupAliveFl = false;
+				for (uint counterY = 0; counterY < 9 && !groupAliveFl; ++counterY) {
+					if (curMapMons->_hitPoints[counterY] > 0)
+						groupAliveFl = true;
 				}
 
-				if (!var4)
+				if (!groupAliveFl)
 					continue;
 
-				int16 var6 = 148 + kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._animId;
-				int16 var1 = _mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F;
+				int16 imageSetIdx = 148 + kEncounters[curMapMons->_monsterRef]._animId;
 
-				if (var1 == 0x3F && isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId))
+				if ((curMapMons->_possessivePronounSHL6 & 0x3F) == 0x3F && isNpcATeamMember(curMapMons->_npcId))
 					continue;
 
 				int16 drawPosX = 128 + (posX - minX) * 16;
 				drawPosY = 8 + (posY - minY) * 16;
-				displayRawDataAtPos(_imageSetSubFilesArray[var6], drawPosX, drawPosY);
+				displayRawDataAtPos(_imageSetSubFilesArray[imageSetIdx], drawPosX, drawPosY);
 			}
 		}
 	}
@@ -713,7 +708,7 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 				Common::String buffer = _npcBuf[charId]._name;
 				setTextPos(16, textPosY);
 				displayStringAtTextPos(buffer);
-				buffer = Common::String::format("%d", getEquipmentDefense(charId, false));
+				buffer = Common::String::format("%d", getEquipmentDefense(charId));
 				displayCenteredString(buffer, 104, 128, textPosY);
 				buffer = Common::String::format("%d", _npcBuf[charId]._hitPoints);
 				displayCenteredString(buffer, 144, 176, textPosY);
@@ -757,9 +752,11 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 
 void EfhEngine::removeObject(int16 charId, int16 objectId) {
 	debugC(6, kDebugEngine, "removeObject %d %d", charId, objectId);
-	_npcBuf[charId]._inventory[objectId]._ref = 0x7FFF;
-	_npcBuf[charId]._inventory[objectId]._stat1 = 0;
-	_npcBuf[charId]._inventory[objectId]._curHitPoints = 0;
+
+	InvObject *curInvObj = &_npcBuf[charId]._inventory[objectId];
+	curInvObj->_ref = 0x7FFF;
+	curInvObj->_stat1 = 0;
+	curInvObj->_curHitPoints = 0;
 }
 
 void EfhEngine::totalPartyKill() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index f13f1358aaf..e332834dfc3 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -290,7 +290,7 @@ private:
 	void initMapMonsters();
 	void loadMapArrays(int idx);
 	void saveAnimImageSetId();
-	int16 getEquipmentDefense(int16 charId, bool flag);
+	int16 getEquipmentDefense(int16 charId);
 	uint16 getEquippedExclusiveType(int16 charId, int16 exclusiveType, bool flag);
 	void displayLowStatusScreen(bool flag);
 	void loadImageSetToTileBank(int16 tileBankId, int16 imageSetId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 6dd3e4a02d9..ac857855a7d 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -498,7 +498,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
 					continue;
 
-				int16 randomDefense = getRandom(getEquipmentDefense(_teamCharId[targetId], false));
+				int16 randomDefense = getRandom(getEquipmentDefense(_teamCharId[targetId]));
 
 				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
 				int16 characterPronoun = _npcBuf[_teamCharId[targetId]].getPronoun();
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index afb9593bb75..72a30f8db66 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -289,7 +289,7 @@ void EfhEngine::displayCharacterSummary(int16 curMenuLine, int16 npcId) {
 	buffer1 = Common::String::format("Speed: %d", _npcBuf[npcId]._speed);
 	setTextPos(146, 45);
 	displayStringAtTextPos(buffer1);
-	buffer1 = Common::String::format("Defense: %d", getEquipmentDefense(npcId, false));
+	buffer1 = Common::String::format("Defense: %d", getEquipmentDefense(npcId));
 	setTextPos(146, 54);
 	displayStringAtTextPos(buffer1);
 	buffer1 = Common::String::format("Hit Points: %d", _npcBuf[npcId]._hitPoints);


Commit: 116e15b3559920c07fde96ef1762184afb7ca375
    https://github.com/scummvm/scummvm/commit/116e15b3559920c07fde96ef1762184afb7ca375
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Add code to keep track of character 2 status (and related duration) when character 1 leaves

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 9919838b938..83d82b52a13 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -784,6 +784,10 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	for (int var4 = teamMemberId; var4 < 2; ++var4) {
 		_teamCharId[var4] = _teamCharId[var4 + 1];
 		_teamCharId[var4 + 1] = -1;
+
+		// The original isn't doing that, resulting in losing its altered status and remaining duration
+		_teamCharStatus[var4]._status = _teamCharStatus[var4 + 1]._status;
+		_teamCharStatus[var4]._duration = _teamCharStatus[var4 + 1]._duration;
 	}
 
 	refreshTeamSize();


Commit: bd88a709f290e5b505023b9f0aa8591e808d4ba2
    https://github.com/scummvm/scummvm/commit/bd88a709f290e5b505023b9f0aa8591e808d4ba2
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Remove an unused buffer, rename another one

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/files.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 83d82b52a13..6417406190e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -292,7 +292,7 @@ void EfhEngine::playIntro() {
 	displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
 
 	// Load animations on previous picture with GF
-	loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
+	loadImageSet(63, _circleImageBuf, _circleImageSubFileArray, _decompBuf);
 	readImpFile(100, false);
 	Common::KeyCode lastInput = getLastCharAfterAnimCount(8);
 	if (lastInput == Common::KEYCODE_ESCAPE)
@@ -388,7 +388,7 @@ void EfhEngine::initEngine() {
 	saveAnimImageSetId();
 
 	// Load Title Screen, skip if loading a savegame from launcher
-	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
+	loadImageSet(11, _circleImageBuf, _circleImageSubFileArray, _decompBuf);
 	if (_loadSaveSlot == -1) {
 		displayFctFullScreen();
 		displayRawDataAtPos(_circleImageSubFileArray[0], 0, 0);
@@ -420,7 +420,7 @@ void EfhEngine::initEngine() {
 	loadNPCS();
 
 	// Load picture room with girlfriend
-	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
+	loadImageSet(62, _circleImageBuf, _circleImageSubFileArray, _decompBuf);
 	fileName = "titlsong";
 	readFileToBuffer(fileName, _titleSong);
 	setDefaultNoteDuration();
@@ -430,7 +430,7 @@ void EfhEngine::initEngine() {
 		playIntro();
 	}
 
-	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _hiResImageBuf);
+	loadImageSet(6, _circleImageBuf, _circleImageSubFileArray, _decompBuf);
 	readImpFile(99, false);
 	_introDoneFl = true;
 	restoreAnimImageSetId();
@@ -783,11 +783,13 @@ void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 
 	for (int var4 = teamMemberId; var4 < 2; ++var4) {
 		_teamCharId[var4] = _teamCharId[var4 + 1];
-		_teamCharId[var4 + 1] = -1;
 
 		// The original isn't doing that, resulting in losing its altered status and remaining duration
 		_teamCharStatus[var4]._status = _teamCharStatus[var4 + 1]._status;
 		_teamCharStatus[var4]._duration = _teamCharStatus[var4 + 1]._duration;
+		//
+
+		_teamCharId[var4 + 1] = -1;
 	}
 
 	refreshTeamSize();
@@ -2462,7 +2464,7 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 		_mapBitmapRefArr[_techId]._setId2 = setId;
 
 	int16 ptrIndex = bankId * 72;
-	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _hiResImageBuf);
+	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _decompBuf);
 }
 
 void EfhEngine::restoreAnimImageSetId() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index e332834dfc3..a39559da8d2 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -516,8 +516,7 @@ private:
 	uint8 _tileBank[3][12000];
 	uint8 _circleImageBuf[40100];
 	uint8 _portraitBuf[25000];
-	uint8 _hiResImageBuf[40100];
-	uint8 _loResImageBuf[40100];
+	uint8 _decompBuf[40100];
 	uint8 _menuBuf[12500];
 	uint8 _windowWithBorderBuf[1500];
 	uint8 _mapArr[19][7000];
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index dc8303c9d06..909e41be2cf 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -169,7 +169,7 @@ void EfhEngine::loadNewPortrait() {
 	findMapFile(_techId);
 	_currentAnimImageSetId = 200 + _unkRelatedToAnimImageSetId;
 	int imageSetId = _unkRelatedToAnimImageSetId + 13;
-	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
+	loadImageSet(imageSetId, _portraitBuf, _portraitSubFilesArray, _decompBuf);
 }
 
 void EfhEngine::loadAnimImageSet() {
@@ -184,7 +184,7 @@ void EfhEngine::loadAnimImageSet() {
 	_currentAnimImageSetId = _animImageSetId;
 
 	int16 animSetId = _animImageSetId + 17;
-	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, _hiResImageBuf);
+	loadImageSet(animSetId, _portraitBuf, _portraitSubFilesArray, _decompBuf);
 }
 
 void EfhEngine::loadHistory() {
@@ -232,8 +232,8 @@ void EfhEngine::loadPlacesFile(uint16 fullPlaceId, bool forceReloadFl) {
 	if (_fullPlaceId < minPlace || _fullPlaceId > maxPlace || forceReloadFl) {
 		_lastMainPlaceId = _fullPlaceId / 20;
 		Common::String fileName = Common::String::format("places.%d", _lastMainPlaceId);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _places);
+		readFileToBuffer(fileName, _decompBuf);
+		uncompressBuffer(_decompBuf, _places);
 	}
 	copyCurrentPlaceToBuffer(_fullPlaceId % 20);
 }
@@ -329,12 +329,12 @@ void EfhEngine::preLoadMaps() {
 
 	for (int idx = 0; idx < 19; ++idx) {
 		Common::String fileName = Common::String::format("tech.%d", idx);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _techDataArr[idx]);
+		readFileToBuffer(fileName, _decompBuf);
+		uncompressBuffer(_decompBuf, _techDataArr[idx]);
 
 		fileName = Common::String::format("map.%d", idx);
-		readFileToBuffer(fileName, _hiResImageBuf);
-		uncompressBuffer(_hiResImageBuf, _mapArr[idx]);
+		readFileToBuffer(fileName, _decompBuf);
+		uncompressBuffer(_decompBuf, _mapArr[idx]);
 
 		_mapBitmapRefArr[idx]._setId1 = _mapArr[idx][0];
 		_mapBitmapRefArr[idx]._setId2 = _mapArr[idx][1];
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 95ddff0a770..39ce01765ca 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -361,8 +361,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		memset(_tileBank[i], 0, ARRAYSIZE(_tileBank[i]));
 	memset(_circleImageBuf, 0, ARRAYSIZE(_circleImageBuf));
 	memset(_portraitBuf, 0, ARRAYSIZE(_portraitBuf));
-	memset(_hiResImageBuf, 0, ARRAYSIZE(_hiResImageBuf));
-	memset(_loResImageBuf, 0, ARRAYSIZE(_loResImageBuf));
+	memset(_decompBuf, 0, ARRAYSIZE(_decompBuf));
 	memset(_menuBuf, 0, ARRAYSIZE(_menuBuf));
 	memset(_windowWithBorderBuf, 0, ARRAYSIZE(_windowWithBorderBuf));
 	memset(_places, 0, ARRAYSIZE(_places));
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 72a30f8db66..fbad82bb13f 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -476,7 +476,7 @@ void EfhEngine::displayWindowAndStatusMenu(int16 charId, int16 windowId, int16 m
 	debugC(6, kDebugEngine, "displayWindowAndStatusMenu %d %d %d %d", charId, windowId, menuId, curMenuLine);
 
 	for (int counter = 0; counter < 2; ++counter) {
-		displayWindow(_menuBuf, 0, 0, _hiResImageBuf);
+		displayWindow(_menuBuf, 0, 0, _decompBuf);
 		prepareStatusMenu(windowId, menuId, curMenuLine, charId, false);
 
 		if (counter == 0)
@@ -491,7 +491,7 @@ int16 EfhEngine::displayStringInSmallWindowWithBorder(Common::String str, bool d
 
 	for (uint counter = 0; counter < 2; ++counter) {
 		prepareStatusMenu(windowId, menuId, curMenuLine, charId, false);
-		displayWindow(_windowWithBorderBuf, 19, 113, _hiResImageBuf);
+		displayWindow(_windowWithBorderBuf, 19, 113, _decompBuf);
 
 		if (counter == 0) {
 			script_parse(str, 28, 122, 105, 166, false);


Commit: cb467912a60c4a7ed43036cf5313f76ed3214f3e
    https://github.com/scummvm/scummvm/commit/cb467912a60c4a7ed43036cf5313f76ed3214f3e
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: More code simplification

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 6417406190e..456d939fe3c 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -902,17 +902,19 @@ bool EfhEngine::giveItemTo(int16 charId, int16 objectId, int16 fromCharId) {
 	debugC(3, kDebugEngine, "giveItemTo %d %d %d", charId, objectId, fromCharId);
 
 	for (uint newObjectId = 0; newObjectId < 10; ++newObjectId) {
-		if (_npcBuf[charId]._inventory[newObjectId]._ref != 0x7FFF)
+		InvObject *newInvObj = &_npcBuf[charId]._inventory[newObjectId];
+		if (newInvObj->_ref != 0x7FFF)
 			continue;
 
 		if (fromCharId == 0xFF) {
-			_npcBuf[charId]._inventory[newObjectId]._ref = objectId;
-			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _items[objectId]._defense;
-			_npcBuf[charId]._inventory[newObjectId]._stat1 = _items[objectId]._uses;
+			newInvObj->_ref = objectId;
+			newInvObj->_curHitPoints = _items[objectId]._defense;
+			newInvObj->_stat1 = _items[objectId]._uses;
 		} else {
-			_npcBuf[charId]._inventory[newObjectId]._ref = _npcBuf[fromCharId]._inventory[objectId]._ref;
-			_npcBuf[charId]._inventory[newObjectId]._curHitPoints = _npcBuf[fromCharId]._inventory[objectId]._curHitPoints;
-			_npcBuf[charId]._inventory[newObjectId]._stat1 = _npcBuf[fromCharId]._inventory[objectId].getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
+			InvObject *fromInvObj = &_npcBuf[fromCharId]._inventory[objectId];
+			newInvObj->_ref = fromInvObj->_ref;
+			newInvObj->_curHitPoints = fromInvObj->_curHitPoints;
+			newInvObj->_stat1 = fromInvObj->getUsesLeft(); // not equipped as the upper bit isn't set (0x80)
 		}
 
 		return true;
@@ -1082,7 +1084,8 @@ int16 EfhEngine::findMapSpecialTileIndex(int16 posX, int16 posY) {
 	uint16 searchPlaceId = _largeMapFlag ? 0xFE : _fullPlaceId;
 	
 	for (uint counter = 0; counter < 100; ++counter) {
-		if (_mapSpecialTiles[_techId][counter]._posX == posX && _mapSpecialTiles[_techId][counter]._posY == posY && _mapSpecialTiles[_techId][counter]._placeId == searchPlaceId)
+		MapSpecialTileStruct *curTile = &_mapSpecialTiles[_techId][counter];
+		if (curTile->_posX == posX && curTile->_posY == posY && curTile->_placeId == searchPlaceId)
 			return counter;
 	}
 
@@ -1106,13 +1109,10 @@ bool EfhEngine::isPosOutOfMap(int16 mapPosX, int16 mapPosY) {
 void EfhEngine::goSouth() {
 	debugC(6,kDebugEngine, "goSouth");
 
-	if (_largeMapFlag) {
-		if (++_mapPosY > 63)
-			_mapPosY = 63;
-	} else {
-		if (++_mapPosY > 23)
-			_mapPosY = 23;
-	}
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+
+	if (++_mapPosY > maxMapBlocks)
+		_mapPosY = maxMapBlocks;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;
@@ -1135,13 +1135,10 @@ void EfhEngine::goNorth() {
 void EfhEngine::goEast() {
 	debugC(6, kDebugEngine, "goEast");
 
-	if (_largeMapFlag) {
-		if (++_mapPosX > 63)
-			_mapPosX = 63;
-	} else {
-		if (++_mapPosX > 23)
-			_mapPosX = 23;
-	}
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+
+	if (++_mapPosX > maxMapBlocks)
+		_mapPosX = maxMapBlocks;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;
@@ -1184,17 +1181,13 @@ void EfhEngine::goNorthEast() {
 void EfhEngine::goSouthEast() {
 	debugC(6, kDebugEngine, "goSouthEast");
 
-	if (_largeMapFlag) {
-		if (++_mapPosX > 63)
-			_mapPosX = 63;
-	} else if (++_mapPosX > 23)
-		_mapPosX = 23;
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
 
-	if (_largeMapFlag) {
-		if (++_mapPosY > 63)
-			_mapPosY = 63;
-	} else if (++_mapPosY > 23)
-		_mapPosY = 23;
+	if (++_mapPosX > maxMapBlocks)
+		_mapPosX = maxMapBlocks;
+
+	if (++_mapPosY > maxMapBlocks)
+		_mapPosY = maxMapBlocks;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;
@@ -1223,11 +1216,10 @@ void EfhEngine::goSouthWest() {
 	if (--_mapPosX < 0)
 		_mapPosX = 0;
 
-	if (_largeMapFlag) {
-		if (++_mapPosY > 63)
-			_mapPosY = 63;
-	} else if (++_mapPosY > 23)
-		_mapPosY = 23;
+	int16 maxMapBlocks = _largeMapFlag ? 63 : 23;
+
+	if (++_mapPosY > maxMapBlocks)
+		_mapPosY = maxMapBlocks;
 
 	if (isPosOutOfMap(_mapPosX, _mapPosY)) {
 		_mapPosX = _oldMapPosX;


Commit: 2a48a8f6c653623c5fa76fd7482f6db24d71d01b
    https://github.com/scummvm/scummvm/commit/2a48a8f6c653623c5fa76fd7482f6db24d71d01b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Fix issue in regen

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 456d939fe3c..c59a3569578 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1246,8 +1246,8 @@ void EfhEngine::handleNewRoundEffects() {
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
 		NPCStruct *curNpc = &_npcBuf[_teamCharId[counter]];
-		if (curNpc->_hitPoints < curNpc->_maxHP)
-			++curNpc->_hitPoints = curNpc->_maxHP;
+		if (++curNpc->_hitPoints > curNpc->_maxHP)
+			curNpc->_hitPoints = curNpc->_maxHP;
 	}
 	_regenCounter = 0;
 }


Commit: e5cd8dc6ef8c37442b64cb4a82612bf7d85bcddd
    https://github.com/scummvm/scummvm/commit/e5cd8dc6ef8c37442b64cb4a82612bf7d85bcddd
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Add comment in checkMonsterMovementType, refactor computeMapAnimation and more code simplification

Changed paths:
    engines/efh/efh.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index c59a3569578..8cba17a5020 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1276,25 +1276,13 @@ void EfhEngine::computeMapAnimation() {
 			if (_currentTileBankImageSetId[0] != 0)
 				continue;
 
-			if (_largeMapFlag) {
-				uint8 curTile = _mapGameMaps[_techId][counterX][counterY];
-				if (curTile >= 1 && curTile <= 0xF) {
-					if (getRandom(100) < 50)
-						_mapGameMaps[_techId][counterX][counterY] += 0xC5;
-				} else if (curTile >= 0xC6 && curTile <= 0xD5) {
-					if (getRandom(100) < 50)
-						_mapGameMaps[_techId][counterX][counterY] -= 0xC5;
-				}
-			} else {
-				uint8 curTile = _curPlace[counterX][counterY];
-				if (curTile >= 1 && curTile <= 0xF) {
-					if (getRandom(100) < 50)
-						_curPlace[counterX][counterY] += 0xC5;
-				} else if (curTile >= 0xC6 && curTile <= 0xD5) {
-					if (getRandom(100) < 50)
-						_curPlace[counterX][counterY] -= 0xC5;
-				}
-			}
+			uint8 *curTile = _largeMapFlag ? &_mapGameMaps[_techId][counterX][counterY] : &_curPlace[counterX][counterY];
+
+			if (*curTile >= 1 && *curTile <= 0xF && getRandom(100) < 50)
+				*curTile += 0xC5;
+			else if (*curTile >= 0xC6 && *curTile <= 0xD5 && getRandom(100) < 50)
+				*curTile -= 0xC5;
+
 		}
 	}
 }
@@ -1320,10 +1308,11 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 	debugC(3, kDebugEngine,"checkMonsterMoveCollisionAndTileTexture %d", monsterId);
 
 	int16 maxSize = _largeMapFlag ? 63 : 23;
-	if (_mapMonsters[_techId][monsterId]._posX < 0 || _mapMonsters[_techId][monsterId]._posY < 0 || _mapMonsters[_techId][monsterId]._posX > maxSize || _mapMonsters[_techId][monsterId]._posY > maxSize)
+	MapMonster *curMapMonster = &_mapMonsters[_techId][monsterId];
+	if (curMapMonster->_posX < 0 || curMapMonster->_posY < 0 || curMapMonster->_posX > maxSize || curMapMonster->_posY > maxSize)
 		return 0;
 
-	if (_mapMonsters[_techId][monsterId]._posX == _mapPosX && _mapMonsters[_techId][monsterId]._posY == _mapPosY)
+	if (curMapMonster->_posX == _mapPosX && curMapMonster->_posY == _mapPosY)
 		return 0;
 
 	for (int counter = 0; counter < 64; ++counter) {
@@ -1333,43 +1322,43 @@ int8 EfhEngine::checkMonsterMoveCollisionAndTileTexture(int16 monsterId) {
 		if (!checkMapMonsterAvailability(counter))
 			continue;
 
-		if (_mapMonsters[_techId][monsterId]._fullPlaceId == _mapMonsters[_techId][counter]._fullPlaceId
-		 && _mapMonsters[_techId][monsterId]._posX == _mapMonsters[_techId][counter]._posX
-		 && _mapMonsters[_techId][monsterId]._posY == _mapMonsters[_techId][counter]._posY)
+		MapMonster *compMapMonster = &_mapMonsters[_techId][counter];
+		if (curMapMonster->_fullPlaceId == compMapMonster->_fullPlaceId && curMapMonster->_posX == compMapMonster->_posX && curMapMonster->_posY == compMapMonster->_posY)
 			return 0;
 	}
 
-	return checkTileStatus(_mapMonsters[_techId][monsterId]._posX, _mapMonsters[_techId][monsterId]._posY, false);
+	return checkTileStatus(curMapMonster->_posX, curMapMonster->_posY, false);
 }
 
 bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 	debugC(6, kDebugEngine, "moveMonsterAwayFromTeam %d", monsterId);
 
-	if (_mapMonsters[_techId][monsterId]._posX < _mapPosX) {
-		--_mapMonsters[_techId][monsterId]._posX;
-		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-			--_mapMonsters[_techId][monsterId]._posY;
-		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-			++_mapMonsters[_techId][monsterId]._posY;
+	MapMonster *curMapMonster = &_mapMonsters[_techId][monsterId];
+	if (curMapMonster->_posX < _mapPosX) {
+		--curMapMonster->_posX;
+		if (curMapMonster->_posY < _mapPosY)
+			--curMapMonster->_posY;
+		else if (curMapMonster->_posY > _mapPosY)
+			++curMapMonster->_posY;
 
 		return true;
 	}
 
-	if (_mapMonsters[_techId][monsterId]._posX > _mapPosX) {
-		++_mapMonsters[_techId][monsterId]._posX;
-		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-			--_mapMonsters[_techId][monsterId]._posY;
-		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-			++_mapMonsters[_techId][monsterId]._posY;
+	if (curMapMonster->_posX > _mapPosX) {
+		++curMapMonster->_posX;
+		if (curMapMonster->_posY < _mapPosY)
+			--curMapMonster->_posY;
+		else if (curMapMonster->_posY > _mapPosY)
+			++curMapMonster->_posY;
 
 		return true;
 	}
 
 	// Original checks for posX equality, which is the only possible option at this point => skipped
-	if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-		--_mapMonsters[_techId][monsterId]._posY;
-	else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-		++_mapMonsters[_techId][monsterId]._posY;
+	if (curMapMonster->_posY < _mapPosY)
+		--curMapMonster->_posY;
+	else if (curMapMonster->_posY > _mapPosY)
+		++curMapMonster->_posY;
 	else
 		return false;
 
@@ -1379,31 +1368,32 @@ bool EfhEngine::moveMonsterAwayFromTeam(int16 monsterId) {
 bool EfhEngine::moveMonsterTowardsTeam(int16 monsterId) {
 	debugC(6, kDebugEngine, "moveMonsterTowardsTeam %d", monsterId);
 
-	if (_mapMonsters[_techId][monsterId]._posX < _mapPosX) {
-		++_mapMonsters[_techId][monsterId]._posX;
-		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-			++_mapMonsters[_techId][monsterId]._posY;
-		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-			--_mapMonsters[_techId][monsterId]._posY;
+	MapMonster *curMapMonster = &_mapMonsters[_techId][monsterId];
+	if (curMapMonster->_posX < _mapPosX) {
+		++curMapMonster->_posX;
+		if (curMapMonster->_posY < _mapPosY)
+			++curMapMonster->_posY;
+		else if (curMapMonster->_posY > _mapPosY)
+			--curMapMonster->_posY;
 
 		return true;
 	}
 
-	if (_mapMonsters[_techId][monsterId]._posX > _mapPosX) {
-		--_mapMonsters[_techId][monsterId]._posX;
-		if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-			++_mapMonsters[_techId][monsterId]._posY;
-		else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-			--_mapMonsters[_techId][monsterId]._posY;
+	if (curMapMonster->_posX > _mapPosX) {
+		--curMapMonster->_posX;
+		if (curMapMonster->_posY < _mapPosY)
+			++curMapMonster->_posY;
+		else if (curMapMonster->_posY > _mapPosY)
+			--curMapMonster->_posY;
 
 		return true;
 	}
 
 	// Original checks for posX equality, which is the only possible option at this point => skipped
-	if (_mapMonsters[_techId][monsterId]._posY < _mapPosY)
-		++_mapMonsters[_techId][monsterId]._posY;
-	else if (_mapMonsters[_techId][monsterId]._posY > _mapPosY)
-		--_mapMonsters[_techId][monsterId]._posY;
+	if (curMapMonster->_posY < _mapPosY)
+		++curMapMonster->_posY;
+	else if (curMapMonster->_posY > _mapPosY)
+		--curMapMonster->_posY;
 	else
 		return false;
 
@@ -1414,42 +1404,43 @@ bool EfhEngine::moveMonsterGroupOther(int16 monsterId, int16 direction) {
 	debugC(6, kDebugEngine, "moveMonsterGroupOther %d %d", monsterId, direction);
 
 	bool retVal;
+	MapMonster *curMapMonster = &_mapMonsters[_techId][monsterId];
 
 	switch (direction - 1) {
 	case 0:
-		--_mapMonsters[_techId][monsterId]._posY;
+		--curMapMonster->_posY;
 		retVal = true;
 		break;
 	case 1:
-		--_mapMonsters[_techId][monsterId]._posY;
-		++_mapMonsters[_techId][monsterId]._posX;
+		--curMapMonster->_posY;
+		++curMapMonster->_posX;
 		retVal = true;
 		break;
 	case 2:
-		++_mapMonsters[_techId][monsterId]._posX;
+		++curMapMonster->_posX;
 		retVal = true;
 		break;
 	case 3:
-		++_mapMonsters[_techId][monsterId]._posX;
-		++_mapMonsters[_techId][monsterId]._posY;
+		++curMapMonster->_posX;
+		++curMapMonster->_posY;
 		retVal = true;
 		break;
 	case 4:
-		++_mapMonsters[_techId][monsterId]._posY;
+		++curMapMonster->_posY;
 		retVal = true;
 		break;
 	case 5:
-		++_mapMonsters[_techId][monsterId]._posY;
-		--_mapMonsters[_techId][monsterId]._posX;
+		++curMapMonster->_posY;
+		--curMapMonster->_posX;
 		retVal = true;
 		break;
 	case 6:
-		--_mapMonsters[_techId][monsterId]._posX;
+		--curMapMonster->_posX;
 		retVal = true;
 		break;
 	case 7:
-		--_mapMonsters[_techId][monsterId]._posX;
-		--_mapMonsters[_techId][monsterId]._posY;
+		--curMapMonster->_posX;
+		--curMapMonster->_posY;
 		retVal = true;
 		break;
 	default:
@@ -1506,7 +1497,7 @@ bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	if (teamFlag)
 		monsterId = _teamMonsterIdArray[id];
 
-	if ((_mapMonsters[_techId][monsterId]._additionalInfo & 0xF) >= 8)
+	if ((_mapMonsters[_techId][monsterId]._additionalInfo & 0xF) >= 8) // Check hostility
 		return true;
 
 	if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80) != 0)
@@ -1580,7 +1571,7 @@ void EfhEngine::handleMapMonsterMoves() {
 		int8 monsterMoveType = _mapMonsters[_techId][monsterId]._additionalInfo & 0xF; // 0000 1111
 
 		if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80)) // 1000 0000
-			monsterMoveType = 9;
+			monsterMoveType = 9; // Hostility + Move type 1
 
 		int16 randomModPct = _mapMonsters[_techId][monsterId]._additionalInfo & 0x70; // 0111 0000
 		randomModPct >>= 4; // Max 7 (0111)


Commit: 103b590d07e82dd841f0ea54d92cab0fba402655
    https://github.com/scummvm/scummvm/commit/103b590d07e82dd841f0ea54d92cab0fba402655
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Remove useless parameter from setMapMonsterAggressivenessAndMovementType(), simplify more code

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 8cba17a5020..fee4e53ed38 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1469,8 +1469,9 @@ bool EfhEngine::moveMonsterGroupRandom(int16 monsterId) {
 int16 EfhEngine::computeMonsterGroupDistance(int16 monsterId) {
 	debugC(2, kDebugEngine, "computeMonsterGroupDistance %d", monsterId);
 
-	int16 monsterPosX = _mapMonsters[_techId][monsterId]._posX;
-	int16 monsterPosY = _mapMonsters[_techId][monsterId]._posY;
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+	int16 monsterPosX = curMapMonst->_posX;
+	int16 monsterPosY = curMapMonst->_posY;
 
 	int16 deltaX = monsterPosX - _mapPosX;
 	int16 deltaY = monsterPosY - _mapPosY;
@@ -1493,14 +1494,13 @@ bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
 bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	debugC(6, kDebugEngine, "checkMonsterMovementType %d %s", id, teamFlag ? "True" : "False");
 
-	int16 monsterId = id;
-	if (teamFlag)
-		monsterId = _teamMonsterIdArray[id];
+	int16 monsterId = teamFlag ? _teamMonsterIdArray[id] : id;
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
 
-	if ((_mapMonsters[_techId][monsterId]._additionalInfo & 0xF) >= 8) // Check hostility
+	if ((curMapMonst->_additionalInfo & 0xF) >= 8) // Check hostility
 		return true;
 
-	if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80) != 0)
+	if (_unk2C8AA != 0 && (curMapMonst->_additionalInfo & 0x80) != 0)
 		return true;
 
 	return false;
@@ -1523,10 +1523,11 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 bool EfhEngine::checkIfMonsterOnSameLargeMapPlace(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkIfMonsterOnSameLargeMapPlace %d", monsterId);
 
-	if (_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE)
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+	if (_largeMapFlag && curMapMonst->_fullPlaceId == 0xFE)
 		return true;
 
-	if (!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId)
+	if (!_largeMapFlag && curMapMonst->_fullPlaceId == _fullPlaceId)
 		return true;
 
 	return false;
@@ -1559,8 +1560,9 @@ void EfhEngine::handleMapMonsterMoves() {
 		if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
 			continue;
 
-		int16 previousPosX = _mapMonsters[_techId][monsterId]._posX;
-		int16 previousPosY = _mapMonsters[_techId][monsterId]._posY;
+		MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+		int16 previousPosX = curMapMonst->_posX;
+		int16 previousPosY = curMapMonst->_posY;
 
 		if (previousPosX < minDisplayedMapX || previousPosX > maxDisplayedMapX || previousPosY < minDisplayedMapY || previousPosY > maxDisplayedMapY)
 			continue;
@@ -1568,12 +1570,12 @@ void EfhEngine::handleMapMonsterMoves() {
 		bool monsterMovedFl = false;
 		int16 lastRangeCheck = 0;
 
-		int8 monsterMoveType = _mapMonsters[_techId][monsterId]._additionalInfo & 0xF; // 0000 1111
+		int8 monsterMoveType = curMapMonst->_additionalInfo & 0xF; // 0000 1111
 
-		if (_unk2C8AA != 0 && (_mapMonsters[_techId][monsterId]._additionalInfo & 0x80)) // 1000 0000
+		if (_unk2C8AA != 0 && (curMapMonst->_additionalInfo & 0x80)) // 1000 0000
 			monsterMoveType = 9; // Hostility + Move type 1
 
-		int16 randomModPct = _mapMonsters[_techId][monsterId]._additionalInfo & 0x70; // 0111 0000
+		int16 randomModPct = curMapMonst->_additionalInfo & 0x70; // 0111 0000
 		randomModPct >>= 4; // Max 7 (0111)
 
 		int16 retryCounter = randomModPct;
@@ -1675,23 +1677,21 @@ void EfhEngine::handleMapMonsterMoves() {
 
 			for (;;) {
 				if (!monsterMovedFl) {
-					if (lastRangeCheck == 0) {
-						monsterMovedFl = true;
-					} else {
+					if (lastRangeCheck != 0)
 						attackMonsterId = monsterId;
-						monsterMovedFl = true;
-					}
+
+					monsterMovedFl = true;
 				} else {
 					int8 checkMoveFl = checkMonsterMoveCollisionAndTileTexture(monsterId);
 
 					if (checkMoveFl == 0) { // Blocked
-						_mapMonsters[_techId][monsterId]._posX = previousPosX;
-						_mapMonsters[_techId][monsterId]._posY = previousPosY;
+						curMapMonst->_posX = previousPosX;
+						curMapMonst->_posY = previousPosY;
 						monsterMovedFl = false;
 						--retryCounter;
 					} else if (checkMoveFl == 2) { // Wall
-						_mapMonsters[_techId][monsterId]._posX = previousPosX;
-						_mapMonsters[_techId][monsterId]._posY = previousPosY;
+						curMapMonst->_posX = previousPosX;
+						curMapMonst->_posY = previousPosY;
 					}
 				}
 
@@ -1712,11 +1712,13 @@ void EfhEngine::handleMapMonsterMoves() {
 bool EfhEngine::checkMapMonsterAvailability(int16 monsterId) {
 	debugC(6, kDebugEngine, "checkMapMonsterAvailability %d", monsterId);
 
-	if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+
+	if (curMapMonst->_fullPlaceId == 0xFF)
 		return false;
 
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[_techId][monsterId]._hitPoints[counter] > 0)
+		if (curMapMonst->_hitPoints[counter] > 0)
 			return true;
 	}
 
@@ -1735,10 +1737,11 @@ void EfhEngine::displayMonsterAnim(int16 monsterId) {
 int16 EfhEngine::countAliveMonsters(int16 id) {
 	debugC(6, kDebugEngine, "countAliveMonsters %d", id);
 
-	int16 count = 0;
+	MapMonster *curMapMonst = &_mapMonsters[_techId][id];
 
+	int16 count = 0;
 	for (uint counter = 0; counter < 9; ++counter) {
-		if (_mapMonsters[_techId][id]._hitPoints[counter] > 0)
+		if (curMapMonst->_hitPoints[counter] > 0)
 			++count;
 	}
 
@@ -1757,7 +1760,8 @@ bool EfhEngine::checkMonsterGroupDistance1OrLess(int16 monsterId) {
 bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	debugC(6, kDebugEngine, "handleTalk %d %d %d", monsterId, arg2, itemId);
 
-	if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+	if (curMapMonst->_fullPlaceId == 0xFF)
 		return false;
 
 	if (countAliveMonsters(monsterId) < 1)
@@ -1769,20 +1773,20 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	if (!checkMonsterGroupDistance1OrLess(monsterId))
 		return false;
 
-	if ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F) {
-		if (_mapMonsters[_techId][monsterId]._talkTextId == 0xFF || arg2 != 5) {
+	if ((curMapMonst->_possessivePronounSHL6 & 0x3F) != 0x3F) {
+		if (curMapMonst->_talkTextId == 0xFF || arg2 != 5) {
 			return false;
 		}
 		displayMonsterAnim(monsterId);
-		displayImp1Text(_mapMonsters[_techId][monsterId]._talkTextId);
+		displayImp1Text(curMapMonst->_talkTextId);
 		displayAnimFrames(0xFE, true);
 		return true;
 	}
 
-	if (isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId))
+	if (isNpcATeamMember(curMapMonst->_npcId))
 		return false;
 
-	int16 npcId = _mapMonsters[_techId][monsterId]._npcId;
+	int16 npcId = curMapMonst->_npcId;
 	switch (_npcBuf[npcId].field_10 - 0xEE) {
 	case 0:
 		if (arg2 == 4 && _npcBuf[npcId].field11_NpcId == itemId) {
@@ -2254,19 +2258,15 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 }
 
 
-void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask, bool groupFl) {
-	debugC(2, kDebugEngine, "setMapMonsterAggressivenessAndMovementType %d 0x%X %s", id, mask, groupFl ? "True" : "False");
+void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask) {
+	debugC(2, kDebugEngine, "setMapMonsterAggressivenessAndMovementType %d 0x%X", id, mask);
 
-	int16 monsterId;
-	if (groupFl) { // groupFl is always True
-		monsterId = _teamMonsterIdArray[id];
-	} else {
-		monsterId = id;
-	}
+	int16 monsterId = _teamMonsterIdArray[id];
+	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
 
 	mask &= 0x0F;
-	_mapMonsters[_techId][monsterId]._additionalInfo &= 0xF0;
-	_mapMonsters[_techId][monsterId]._additionalInfo |= mask;
+	curMapMonst->_additionalInfo &= 0xF0;
+	curMapMonst->_additionalInfo |= mask;
 }
 
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
@@ -2317,15 +2317,15 @@ bool EfhEngine::checkMonsterCollision() {
 		if (!checkMapMonsterAvailability(monsterId))
 			continue;
 
-		if (!(_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == 0xFE)
-		 && !(!_largeMapFlag && _mapMonsters[_techId][monsterId]._fullPlaceId == _fullPlaceId))
+		MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+	
+		if (!(_largeMapFlag && curMapMonst->_fullPlaceId == 0xFE) && !(!_largeMapFlag && curMapMonst->_fullPlaceId == _fullPlaceId))
 			continue;
 
-		if ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D
-		 && ((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId)))
+		if ((curMapMonst->_possessivePronounSHL6 & 0x3F) > 0x3D && ((curMapMonst->_possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(curMapMonst->_npcId)))
 			continue;
 
-		if (_mapMonsters[_techId][monsterId]._posX != _mapPosX || _mapMonsters[_techId][monsterId]._posY != _mapPosY)
+		if (curMapMonst->_posX != _mapPosX || curMapMonst->_posY != _mapPosY)
 			continue;
 
 		_mapPosX = _oldMapPosX;
@@ -2336,7 +2336,7 @@ bool EfhEngine::checkMonsterCollision() {
 
 		int16 mobsterCount = 0;
 		for (uint mobsterCounter = 0; mobsterCounter < 9; ++mobsterCounter) {
-			if (_mapMonsters[_techId][monsterId]._hitPoints[mobsterCounter])
+			if (curMapMonst->_hitPoints[mobsterCounter])
 				++mobsterCount;
 		}
 
@@ -2345,18 +2345,18 @@ bool EfhEngine::checkMonsterCollision() {
 		do {
 			for (uint displayCounter = 0; displayCounter < 2; ++displayCounter) {
 				Common::String dest;
-				switch (_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) {
+				switch (curMapMonst->_possessivePronounSHL6 & 0x3F) {
 				case 0x3E:
 					buffer = "(NOT DEFINED)";
 					dest = "(NOT DEFINED)";
 					break;
 				case 0x3F:
 					// Special character name
-					dest = _npcBuf[_mapMonsters[_techId][monsterId]._npcId]._name;
+					dest = _npcBuf[curMapMonst->_npcId]._name;
 					buffer = Common::String("with ") + dest;
 					break;
 				default:
-					dest = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._name;
+					dest = kEncounters[curMapMonst->_monsterRef]._name;
 					if (mobsterCount > 1)
 						dest += "s";
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index a39559da8d2..5d0aa3aca5a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -361,7 +361,7 @@ private:
 	uint16 getXPLevel(uint32 xp);
 	bool isItemCursed(int16 itemId);
 	bool hasObjectEquipped(int16 charId, int16 objectId);
-	void setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask, bool groupFl);
+	void setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask);
 	bool isMonsterActive(int16 groupId, int16 id);
 	int16 getTileFactId(int16 mapPosX, int16 mapPosY);
 	void setCharacterObjectToBroken(int16 charId, int16 objectId);
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index ac857855a7d..1647a7c640a 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -251,7 +251,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 			bool noticedFl;
 			if (!checkMonsterMovementType(groupId, true)) {
-				setMapMonsterAggressivenessAndMovementType(groupId, 9, true);
+				setMapMonsterAggressivenessAndMovementType(groupId, 9);
 				_unk2C8AA += 500;
 				noticedFl = true;
 			} else
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index fbad82bb13f..eefdfc6aeef 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1038,7 +1038,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			displayStringInSmallWindowWithBorder("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense, true);
+			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense);
 		}
 		objectUsedFl = true;
 		break;


Commit: c6f3e50a28ce9ea4c83b6319c01103be6406034b
    https://github.com/scummvm/scummvm/commit/c6f3e50a28ce9ea4c83b6319c01103be6406034b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Rename 3 previously unknown variables

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index fee4e53ed38..a8db6b39956 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -265,8 +265,8 @@ Common::Error EfhEngine::run() {
 			}
 		}
 
-		if (_unk2C8AA > 0)
-			--_unk2C8AA;
+		if (_alertDelay > 0)
+			--_alertDelay;
 
 		if (isTPK()) {
 			if (handleDeathMenu())
@@ -1258,7 +1258,7 @@ void EfhEngine::resetGame() {
 	_oldMapPosX = _mapPosX = 31;
 	_oldMapPosY = _mapPosY = 31;
 	_unkRelatedToAnimImageSetId = 0;
-	_unk2C8AA = 0;
+	_alertDelay = 0;
 }
 
 void EfhEngine::computeMapAnimation() {
@@ -1500,7 +1500,7 @@ bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	if ((curMapMonst->_additionalInfo & 0xF) >= 8) // Check hostility
 		return true;
 
-	if (_unk2C8AA != 0 && (curMapMonst->_additionalInfo & 0x80) != 0)
+	if (_alertDelay != 0 && (curMapMonst->_additionalInfo & 0x80) != 0)
 		return true;
 
 	return false;
@@ -1572,7 +1572,7 @@ void EfhEngine::handleMapMonsterMoves() {
 
 		int8 monsterMoveType = curMapMonst->_additionalInfo & 0xF; // 0000 1111
 
-		if (_unk2C8AA != 0 && (curMapMonst->_additionalInfo & 0x80)) // 1000 0000
+		if (_alertDelay != 0 && (curMapMonst->_additionalInfo & 0x80)) // 1000 0000
 			monsterMoveType = 9; // Hostility + Move type 1
 
 		int16 randomModPct = curMapMonst->_additionalInfo & 0x70; // 0111 0000
@@ -2005,7 +2005,7 @@ void EfhEngine::displayImp1Text(int16 textId) {
 					if (firstChar == 0x5E || firstChar == 0) {
 						if (firstChar == 0x5E) {
 							nextTextId = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
-							_word2C87A = false;
+							_textBoxDisabledByScriptFl = false;
 						}
 					} else {
 						for (uint counter = 0; counter < 2; ++counter) {
@@ -2144,8 +2144,8 @@ int8 EfhEngine::checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4) {
 		handleInteractionText(mapPosX, mapPosY, -1, 0x7FFF, 0, tileFactId);
 	}
 
-	if (_word2C880) {
-		_word2C880 = false;
+	if (_checkTileDisabledByScriptFl) {
+		_checkTileDisabledByScriptFl = false;
 		return -1;
 	}
 	if (_tileFact[tileFactId]._tileId != 0xFF && !_dbgForceMonsterBlock) {
@@ -2494,7 +2494,7 @@ void EfhEngine::loadEfhGame() {
 
 	_teamSize = f.readSint16LE();
 
-	_unk2C8AA = f.readSint16LE();
+	_alertDelay = f.readSint16LE();
 
 	_word2C872 = f.readSint16LE();
 
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 5d0aa3aca5a..f5b5a340f04 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -583,15 +583,15 @@ private:
 
 	int16 _teamMonsterIdArray[5];
 	CharStatus _teamCharStatus[3];
-	int16 _unk2C8AA;
+	int16 _alertDelay;
 	int16 _teamLastAction[3];
 	int16 _teamSize;
 	int16 _word2C872;
-	bool _word2C880;
+	bool _checkTileDisabledByScriptFl;
 	bool _redrawNeededFl;
 	bool _drawHeroOnMapFl;
 	bool _drawMonstersOnMapFl;
-	bool _word2C87A;
+	bool _textBoxDisabledByScriptFl;
 
 	int16 _imageSetSubFilesIdx;
 	int16 _oldImageSetSubFilesIdx;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 1647a7c640a..9df8db83cdc 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -37,10 +37,11 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 			break;
 
 		for (uint monsterId = 0; monsterId < 64; ++monsterId) {
-			if (_mapMonsters[_techId][monsterId]._fullPlaceId == 0xFF)
+			MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
+			if (curMapMonst->_fullPlaceId == 0xFF)
 				continue;
 
-			if (((_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(_mapMonsters[_techId][monsterId]._npcId)) && (_mapMonsters[_techId][monsterId]._possessivePronounSHL6 & 0x3F) > 0x3D)
+			if (((curMapMonst->_possessivePronounSHL6 & 0x3F) != 0x3F || isNpcATeamMember(curMapMonst->_npcId)) && (curMapMonst->_possessivePronounSHL6 & 0x3F) > 0x3D)
 				continue;
 
 			if (!checkIfMonsterOnSameLargeMapPlace(monsterId))
@@ -48,7 +49,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 
 			bool found = false;
 			for (uint subId = 0; subId < 9; ++subId) {
-				if (_mapMonsters[_techId][monsterId]._hitPoints[subId] > 0) {
+				if (curMapMonst->_hitPoints[subId] > 0) {
 					found = true;
 					break;
 				}
@@ -252,7 +253,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			bool noticedFl;
 			if (!checkMonsterMovementType(groupId, true)) {
 				setMapMonsterAggressivenessAndMovementType(groupId, 9);
-				_unk2C8AA += 500;
+				_alertDelay += 500;
 				noticedFl = true;
 			} else
 				noticedFl = false;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 39ce01765ca..51c2c31d7c5 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -303,7 +303,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_fullPlaceId = 0xFF;
 	_guessAnimationAmount = 9;
 	_largeMapFlag = 0xFFFF;
-	_unk2C8AA = 0;
+	_alertDelay = 0;
 	_teamCharId[0] = 0;
 	_teamCharId[1] = _teamCharId[2] = -1;
 
@@ -337,11 +337,11 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_lastMainPlaceId = 0;
 	_tempTextDelay = 0;
 	_tempTextPtr = nullptr;
-	_word2C880 = false;
+	_checkTileDisabledByScriptFl = false;
 	_redrawNeededFl = false;
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
-	_word2C87A = false;
+	_textBoxDisabledByScriptFl = false;
 	_dbgForceMonsterBlock = false;
 	_ongoingFightFl = false;
 	_statusMenuActive = false;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index eefdfc6aeef..38a570a51db 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -70,8 +70,8 @@ int16 EfhEngine::displayBoxWithText(Common::String str, int16 menuType, int16 di
 
 	if (displayOption != 0) {
 		displayFctFullScreen();
-		if (_word2C87A)
-			_word2C87A = false;
+		if (_textBoxDisabledByScriptFl)
+			_textBoxDisabledByScriptFl = false;
 		else {
 			drawColoredRect(minX, minY, maxX, maxY, 0);
 			if (!str.empty())
@@ -983,7 +983,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			displayStringInSmallWindowWithBorder("A serene feeling passes through the air...", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The combat pauses...as there is a moment of forgiveness...";
-			_unk2C8AA = 0;
+			_alertDelay = 0;
 		}
 
 		objectUsedFl = true;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 6e43acc9d79..46fb5b5c681 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -138,7 +138,7 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 	}
 
 	s.syncAsSint16LE(_teamSize);
-	s.syncAsSint16LE(_unk2C8AA);
+	s.syncAsSint16LE(_alertDelay);
 	s.syncAsSint16LE(_word2C872);
 	s.syncAsSint16LE(_imageSetSubFilesIdx);
 	s.syncAsSint16LE(_mapPosX);
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 298e960cf05..164050d4b94 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -132,7 +132,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				_oldMapPosX = _mapPosX = scriptNumberArray[1];
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadPlacesFile(scriptNumberArray[0], false);
-				_word2C880 = true;
+				_checkTileDisabledByScriptFl = true;
 				_redrawNeededFl = true;
 			}
 			break;
@@ -142,7 +142,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				_largeMapFlag = true;
 				_oldMapPosX = _mapPosX = _techDataId_MapPosX;
 				_oldMapPosY = _mapPosY = _techDataId_MapPosY;
-				_word2C880 = true;
+				_checkTileDisabledByScriptFl = true;
 				_redrawNeededFl = true;
 			}
 			break;
@@ -155,7 +155,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				_oldMapPosY = _mapPosY = scriptNumberArray[2];
 				loadTechMapImp(scriptNumberArray[0]);
 				_largeMapFlag = true;
-				_word2C880 = true;
+				_checkTileDisabledByScriptFl = true;
 				_redrawNeededFl = true;
 				doneFlag = true;
 			}
@@ -168,7 +168,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 
 				_mapPosX = getRandom(rangeX) + scriptNumberArray[0] - 1;
 				_mapPosY = getRandom(rangeY) + scriptNumberArray[1] - 1;
-				_word2C880 = true;
+				_checkTileDisabledByScriptFl = true;
 				_redrawNeededFl = true;
 			}
 			break;
@@ -177,7 +177,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (scriptExecuteFlag) {
 				_mapPosX = scriptNumberArray[0];
 				_mapPosY = scriptNumberArray[1];
-				_word2C880 = true;
+				_checkTileDisabledByScriptFl = true;
 				_redrawNeededFl = true;
 			}
 			break;
@@ -308,7 +308,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			break;
 		case 0x11:
 			if (scriptExecuteFlag)
-				_unk2C8AA = 0;
+				_alertDelay = 0;
 			break;
 		case 0x12:
 			// Disable special tile
@@ -321,7 +321,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x13:
 			buffer = script_readNumberArray(buffer, 3, scriptNumberArray);
 			if (scriptExecuteFlag && _largeMapFlag) {
-				_word2C87A = true;
+				_textBoxDisabledByScriptFl = true;
 				loadPlacesFile(scriptNumberArray[0], false);
 				transitionMap(scriptNumberArray[1], scriptNumberArray[2]);
 				setSpecialTechZone(scriptNumberArray[0], scriptNumberArray[1], scriptNumberArray[2]);
@@ -464,7 +464,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x1F:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (scriptExecuteFlag)
-				_unk2C8AA = scriptNumberArray[0];
+				_alertDelay = scriptNumberArray[0];
 
 			break;
 		case 0x20:


Commit: 4e8c31e90ead7336fb09218093207fa3bfc29dc9
    https://github.com/scummvm/scummvm/commit/4e8c31e90ead7336fb09218093207fa3bfc29dc9
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Remove unused original debug code, start grouping team and teamMonster variables

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/init.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index a8db6b39956..76cfc876aeb 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -227,7 +227,7 @@ Common::Error EfhEngine::run() {
 
 		if ((_mapPosX != _oldMapPosX || _mapPosY != _oldMapPosY) && !_shouldQuit) {
 			bool collisionFl = checkMonsterCollision();
-			if (_dbgForceMonsterBlock || collisionFl) {
+			if (collisionFl) {
 				_oldMapPosX = _mapPosX;
 				_oldMapPosY = _mapPosY;
 				_oldImageSetSubFilesIdx = _imageSetSubFilesIdx;
@@ -2148,13 +2148,13 @@ int8 EfhEngine::checkTileStatus(int16 mapPosX, int16 mapPosY, bool arg4) {
 		_checkTileDisabledByScriptFl = false;
 		return -1;
 	}
-	if (_tileFact[tileFactId]._tileId != 0xFF && !_dbgForceMonsterBlock) {
+
+	if (_tileFact[tileFactId]._tileId != 0xFF) {
 		if ((arg4) || (!arg4 && tileFactId != 128 && tileFactId != 121)) {
-			if (_largeMapFlag) {
+			if (_largeMapFlag)
 				_mapGameMaps[_techId][mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
-			} else {
+			else
 				_curPlace[mapPosX][mapPosY] = _tileFact[tileFactId]._tileId;
-			}
 
 			_redrawNeededFl = true;
 			if (_tileFact[tileFactId]._field0 == 0)
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index f5b5a340f04..c55d3f2b52a 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -573,7 +573,6 @@ private:
 	uint16 _fullPlaceId;
 	int16 _guessAnimationAmount;
 	uint16 _largeMapFlag; // CHECKME: bool?
-	int16 _teamCharId[3];
 	int16 _textPosX;
 	int16 _textPosY;
 
@@ -581,10 +580,7 @@ private:
 	bool _engineInitPending;
 	bool _protectionPassed;
 
-	int16 _teamMonsterIdArray[5];
-	CharStatus _teamCharStatus[3];
 	int16 _alertDelay;
-	int16 _teamLastAction[3];
 	int16 _teamSize;
 	int16 _word2C872;
 	bool _checkTileDisabledByScriptFl;
@@ -603,20 +599,24 @@ private:
 
 	uint16 _tempTextDelay;
 	uint8 *_tempTextPtr;
-	// TODO: Remove those useless debug flags
-	bool _dbgForceMonsterBlock; // Original debug flag? Always false.
 
 	bool _ongoingFightFl;
 	bool _statusMenuActive;
+	int16 _menuStatItemArr[15];
 	int16 _menuDepth;
 	int16 _menuItemCounter;
+
+	int16 _teamCharId[3];
+	CharStatus _teamCharStatus[3];
 	int16 _teamPctVisible[3];
 	int16 _teamPctDodgeMiss[3];
 	int16 _teamNextAttack[3];
 	int16 _teamLastInventoryUsed[3];
+	int16 _teamLastAction[3];
 
-	int16 _menuStatItemArr[15];
+	int16 _teamMonsterIdArray[5];
 	TeamMonsterEffect _teamMonsterEffects[5];
+
 	InitiativeStruct _initiatives[8];
 
 	int16 _regenCounter;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 51c2c31d7c5..3caf788835b 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -342,7 +342,6 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_drawHeroOnMapFl = true;
 	_drawMonstersOnMapFl = true;
 	_textBoxDisabledByScriptFl = false;
-	_dbgForceMonsterBlock = false;
 	_ongoingFightFl = false;
 	_statusMenuActive = false;
 	_menuDepth = 0;


Commit: 598a669091a74146592bce1eb2d11a56e666a57b
    https://github.com/scummvm/scummvm/commit/598a669091a74146592bce1eb2d11a56e666a57b
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Refactor TeamChar

Changed paths:
    engines/efh/constants.h
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp
    engines/efh/script.cpp


diff --git a/engines/efh/constants.h b/engines/efh/constants.h
index a0ba37c442a..1a28145f493 100644
--- a/engines/efh/constants.h
+++ b/engines/efh/constants.h
@@ -48,6 +48,12 @@ enum EfhReactionType {
 	kEfhReactionLaughs = 6
 };
 
+enum EfhStatusType {
+	kEfhStatusNormal = 0,
+	kEfhStatusSleeping = 1,
+	kEfhStatusFrozen = 2
+};
+
 struct Font {
 	uint8 _lines[8];
 };
diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 76cfc876aeb..942f657378b 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -136,24 +136,24 @@ Common::Error EfhEngine::run() {
 			_imageSetSubFilesIdx = 147;
 			break;
 		case Common::KEYCODE_F1:
-			if (_teamCharId[0] != -1) {
-				handleStatusMenu(1, _teamCharId[0]);
+			if (_teamChar[0]._id != -1) {
+				handleStatusMenu(1, _teamChar[0]._id);
 				_tempTextPtr = nullptr;
 				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
 			}
 			break;
 		case Common::KEYCODE_F2:
-			if (_teamCharId[1] != -1) {
-				handleStatusMenu(1, _teamCharId[1]);
+			if (_teamChar[1]._id != -1) {
+				handleStatusMenu(1, _teamChar[1]._id);
 				_tempTextPtr = nullptr;
 				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
 			}
 			break;
 		case Common::KEYCODE_F3:
-			if (_teamCharId[2] != -1) {
-				handleStatusMenu(1, _teamCharId[2]);
+			if (_teamChar[2]._id != -1) {
+				handleStatusMenu(1, _teamChar[2]._id);
 				_tempTextPtr = nullptr;
 				drawGameScreenAndTempText(true);
 				_redrawNeededFl = true;
@@ -701,9 +701,9 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 			setTextColorRed();
 
 			for (int i = 0; i < 3; ++i) {
-				if (_teamCharId[i] == -1)
+				if (_teamChar[i]._id == -1)
 					continue;
-				int16 charId = _teamCharId[i];
+				int16 charId = _teamChar[i]._id;
 				int16 textPosY = 161 + 9 * i;
 				Common::String buffer = _npcBuf[charId]._name;
 				setTextPos(16, textPosY);
@@ -720,8 +720,8 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 					continue;
 				}
 
-				switch (_teamCharStatus[i]._status) {
-				case 0: {
+				switch (_teamChar[i]._status._type) {
+				case kEfhStatusNormal: {
 					uint16 exclusiveItemId = getEquippedExclusiveType(charId, 9, true);
 					if (exclusiveItemId == 0x7FFF)
 						_nameBuffer = "(NONE)";
@@ -729,10 +729,10 @@ void EfhEngine::displayLowStatusScreen(bool flag) {
 						_nameBuffer = _items[exclusiveItemId]._name;
 					}
 					break;
-				case 1:
+				case kEfhStatusSleeping:
 					_nameBuffer = "* ASLEEP *";
 					break;
-				case 2:
+				case kEfhStatusFrozen:
 					_nameBuffer = "* FROZEN *";
 					break;
 				default:
@@ -763,7 +763,7 @@ void EfhEngine::totalPartyKill() {
 	debugC(6, kDebugEngine, "totalPartyKill");
 
 	for (uint counter = 0; counter < 3; ++counter) {
-		if (_teamCharId[counter] != -1)
+		if (_teamChar[counter]._id != -1)
 			_npcBuf[counter]._hitPoints = 0;
 	}
 }
@@ -771,25 +771,25 @@ void EfhEngine::totalPartyKill() {
 void EfhEngine::removeCharacterFromTeam(int16 teamMemberId) {
 	debugC(6, kDebugEngine, "removeCharacterFromTeam %d", teamMemberId);
 
-	int16 charId = _teamCharId[teamMemberId];
+	int16 charId = _teamChar[teamMemberId]._id;
 	_npcBuf[charId].field12_textId = _npcBuf[charId].fieldB_textId;
 	_npcBuf[charId].field14_textId = _npcBuf[charId].fieldE_textId;
 	_npcBuf[charId].field_10 = _npcBuf[charId].field_C;
 	_npcBuf[charId].field11_NpcId = _npcBuf[charId].field_D;
 
-	_teamCharId[teamMemberId] = -1;
-	_teamCharStatus[teamMemberId]._status = 0;
-	_teamCharStatus[teamMemberId]._duration = 0;
+	_teamChar[teamMemberId]._id = -1;
+	_teamChar[teamMemberId]._status._type = kEfhStatusNormal;
+	_teamChar[teamMemberId]._status._duration = 0;
 
 	for (int var4 = teamMemberId; var4 < 2; ++var4) {
-		_teamCharId[var4] = _teamCharId[var4 + 1];
+		_teamChar[var4]._id = _teamChar[var4 + 1]._id;
 
 		// The original isn't doing that, resulting in losing its altered status and remaining duration
-		_teamCharStatus[var4]._status = _teamCharStatus[var4 + 1]._status;
-		_teamCharStatus[var4]._duration = _teamCharStatus[var4 + 1]._duration;
+		_teamChar[var4]._status._type = _teamChar[var4 + 1]._status._type;
+		_teamChar[var4]._status._duration = _teamChar[var4 + 1]._status._duration;
 		//
 
-		_teamCharId[var4 + 1] = -1;
+		_teamChar[var4 + 1]._id = -1;
 	}
 
 	refreshTeamSize();
@@ -800,7 +800,7 @@ void EfhEngine::refreshTeamSize() {
 
 	_teamSize = 0;
 	for (uint charId = 0; charId < 3; ++charId) {
-		if (_teamCharId[charId] != -1)
+		if (_teamChar[charId]._id != -1)
 			++_teamSize;
 	}
 }
@@ -809,7 +809,7 @@ bool EfhEngine::isNpcATeamMember(int16 id) {
 	debugC(6, kDebugEngine,"isNpcATeamMember %d", id);
 
 	for (int charId = 0; charId < _teamSize; ++charId) {
-		if (_teamCharId[charId] == id)
+		if (_teamChar[charId]._id == id)
 			return true;
 	}
 
@@ -944,7 +944,7 @@ int16 EfhEngine::handleCharacterJoining() {
 	debugC(3, kDebugEngine, "handleCharacterJoining");
 
 	for (uint counter = 0; counter < 3; ++counter) {
-		if (_teamCharId[counter] == -1) {
+		if (_teamChar[counter]._id == -1) {
 			return counter;
 		}
 	}
@@ -1231,12 +1231,12 @@ void EfhEngine::handleNewRoundEffects() {
 	debugC(6, kDebugEngine, "handleNewRoundEffects");
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
-		CharStatus *curStatus = &_teamCharStatus[counter];
-		if (curStatus->_status == 0) // normal
+		CharStatus *curStatus = &_teamChar[counter]._status;
+		if (curStatus->_type == kEfhStatusNormal)
 			continue;
 
 		if (--curStatus->_duration <= 0) {
-			curStatus->_status = 0;
+			curStatus->_type = kEfhStatusNormal;
 			curStatus->_duration = 0;
 		}
 	}
@@ -1245,7 +1245,7 @@ void EfhEngine::handleNewRoundEffects() {
 		return;
 
 	for (int counter = 0; counter < _teamSize; ++counter) {
-		NPCStruct *curNpc = &_npcBuf[_teamCharId[counter]];
+		NPCStruct *curNpc = &_npcBuf[_teamChar[counter]._id];
 		if (++curNpc->_hitPoints > curNpc->_maxHP)
 			curNpc->_hitPoints = curNpc->_maxHP;
 	}
@@ -1823,8 +1823,8 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	case 4:
 		for (int charId = 0; charId < _teamSize; ++charId) {
 			for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
-				if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
-					removeObject(_teamCharId[charId], inventoryId);
+				if (_npcBuf[_teamChar[charId]._id]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
+					removeObject(_teamChar[charId]._id, inventoryId);
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
@@ -1844,7 +1844,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 	case 6:
 		for (int charId = 0; charId < _teamSize; ++charId) {
 			for (uint inventoryId = 0; inventoryId < 10; ++inventoryId) {
-				if (_npcBuf[_teamCharId[charId]]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
+				if (_npcBuf[_teamChar[charId]._id]._inventory[inventoryId]._ref == _npcBuf[npcId].field11_NpcId) {
 					displayMonsterAnim(monsterId);
 					displayImp1Text(_npcBuf[npcId].field14_textId);
 					displayAnimFrames(0xFE, true);
@@ -1855,7 +1855,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 7:
 		for (int charId = 0; charId < _teamSize; ++charId) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
 				removeCharacterFromTeam(charId);
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
@@ -1866,10 +1866,10 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 8:
 		for (int charId = 0; charId < _teamSize; ++charId) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
 				displayMonsterAnim(monsterId);
 				_enemyNamePt2 = _npcBuf[npcId]._name;
-				_characterNamePt2 = _npcBuf[_teamCharId[charId]]._name;
+				_characterNamePt2 = _npcBuf[_teamChar[charId]._id]._name;
 				Common::String buffer = Common::String::format("%s asks that %s leave your party.", _enemyNamePt2.c_str(), _characterNamePt2.c_str());
 				for (uint i = 0; i < 2; ++i) {
 					clearBottomTextZone(0);
@@ -1893,7 +1893,7 @@ bool EfhEngine::handleTalk(int16 monsterId, int16 arg2, int16 itemId) {
 		break;
 	case 9:
 		for (int charId = 0; charId < _teamSize; ++charId) {
-			if (_npcBuf[npcId].field11_NpcId == _teamCharId[charId]) {
+			if (_npcBuf[npcId].field11_NpcId == _teamChar[charId]._id) {
 				displayMonsterAnim(monsterId);
 				displayImp1Text(_npcBuf[npcId].field14_textId);
 				displayAnimFrames(0xFE, true);
@@ -2062,20 +2062,20 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 
 		if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFE) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
-				if (_teamCharId[counter] == -1)
+				if (_teamChar[counter]._id == -1)
 					continue;
-				if (_teamCharId[counter] == _mapSpecialTiles[_techId][tileId]._triggerId) {
+				if (_teamChar[counter]._id == _mapSpecialTiles[_techId][tileId]._triggerId) {
 					displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 					return true;
 				}
 			}
 		} else if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFD) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
-				if (_teamCharId[counter] == -1)
+				if (_teamChar[counter]._id == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamCharId[counter]]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
+					if (_npcBuf[_teamChar[counter]._id]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
@@ -2085,14 +2085,14 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 		} else if (_mapSpecialTiles[_techId][tileId]._field3 <= 0x77) {
 			int16 scoreId = _mapSpecialTiles[_techId][tileId]._field3;
 			for (int counter = 0; counter < _teamSize; ++counter) {
-				if (_teamCharId[counter] == -1)
+				if (_teamChar[counter]._id == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 39; ++var2) {
 					// CHECKME : the whole loop doesn't make much sense as it's using scoreId instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
 					warning("handleInteractionText - _activeScore[%d]", scoreId);
-					if (_npcBuf[_teamCharId[counter]]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
+					if (_npcBuf[_teamChar[counter]._id]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
@@ -2170,9 +2170,9 @@ void EfhEngine::computeInitiatives() {
 	debugC(6, kDebugEngine, "computeInitiatives");
 
 	for (int counter = 0; counter < 3; ++counter) {
-		if (counter < _teamSize && _teamCharId[counter] != -1) {
+		if (counter < _teamSize && _teamChar[counter]._id != -1) {
 			_initiatives[counter]._id = counter + 1000; // Magic value added to detect it's a member of the team
-			_initiatives[counter]._initiative = _npcBuf[_teamCharId[counter]]._infoScore[3]; // "Agility"
+			_initiatives[counter]._initiative = _npcBuf[_teamChar[counter]._id]._infoScore[3]; // "Agility"
 		} else {
 			_initiatives[counter]._id = -1;
 			_initiatives[counter]._initiative = -1;
@@ -2406,7 +2406,7 @@ bool EfhEngine::checkMonsterCollision() {
 				endLoop = true;
 				break;
 			case Common::KEYCODE_s: // Status
-				handleStatusMenu(1, _teamCharId[0]);
+				handleStatusMenu(1, _teamChar[0]._id);
 				endLoop = true;
 				_tempTextPtr = nullptr;
 				drawGameScreenAndTempText(true);
@@ -2483,13 +2483,13 @@ void EfhEngine::loadEfhGame() {
 	_fullPlaceId = f.readUint16LE();
 	_guessAnimationAmount = f.readSint16LE();
 	_largeMapFlag = f.readUint16LE();
-	_teamCharId[0] = f.readSint16LE();
-	_teamCharId[1] = f.readSint16LE();
-	_teamCharId[2] = f.readSint16LE();
+	_teamChar[0]._id = f.readSint16LE();
+	_teamChar[1]._id = f.readSint16LE();
+	_teamChar[2]._id = f.readSint16LE();
 
 	for (int i = 0; i < 3; ++i) {
-		_teamCharStatus[i]._status = f.readSint16LE();
-		_teamCharStatus[i]._duration = f.readSint16LE();
+		_teamChar[i]._status._type = f.readSint16LE();
+		_teamChar[i]._status._duration = f.readSint16LE();
 	}
 
 	_teamSize = f.readSint16LE();
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index c55d3f2b52a..9b7676a8a7c 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -203,7 +203,7 @@ struct BufferBM {
 };
 
 struct CharStatus {
-	int16 _status;
+	int16 _type;
 	int16 _duration;
 };
 
@@ -245,6 +245,16 @@ struct TileFactStruct {
 	void init();
 };
 
+struct TeamChar {
+	int16 _id;
+	CharStatus _status;
+	int16 _pctVisible;
+	int16 _pctDodgeMiss;
+	int16 _nextAttack;
+	int16 _lastInventoryUsed;
+	int16 _lastAction;
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const ADGameDescription *gd);
@@ -606,13 +616,7 @@ private:
 	int16 _menuDepth;
 	int16 _menuItemCounter;
 
-	int16 _teamCharId[3];
-	CharStatus _teamCharStatus[3];
-	int16 _teamPctVisible[3];
-	int16 _teamPctDodgeMiss[3];
-	int16 _teamNextAttack[3];
-	int16 _teamLastInventoryUsed[3];
-	int16 _teamLastAction[3];
+	TeamChar _teamChar[3];
 
 	int16 _teamMonsterIdArray[5];
 	TeamMonsterEffect _teamMonsterEffects[5];
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index 9df8db83cdc..d5ebd27c055 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -111,8 +111,8 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 		displayAnimFrames(getTeamMonsterAnimId(), true);
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			_teamPctVisible[counter] = 100;
-			_teamPctDodgeMiss[counter] = 65;
+			_teamChar[counter]._pctVisible = 100;
+			_teamChar[counter]._pctDodgeMiss = 65;
 		}
 
 		if (!getTeamAttackRoundPlans()) {
@@ -124,7 +124,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 		}
 
 		for (int counter = 0; counter < _teamSize; ++counter) {
-			if (_teamLastAction[counter] == 0x52) // 'R'
+			if (_teamChar[counter]._lastAction == 0x52) // 'R'
 				mainLoopCond = true;
 		}
 
@@ -140,7 +140,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 				if (!isTeamMemberStatusNormal(monsterGroupIdOrMonsterId)) {
 					handleFight_checkEndEffect(monsterGroupIdOrMonsterId);
 				} else {
-					switch (_teamLastAction[monsterGroupIdOrMonsterId]) {
+					switch (_teamChar[monsterGroupIdOrMonsterId]._lastAction) {
 					case 0x41: // 'A'ttack
 						handleFight_lastAction_A(monsterGroupIdOrMonsterId);
 						break;
@@ -177,21 +177,21 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
-	if (_teamCharStatus[charId]._status == 0)
+	if (_teamChar[charId]._status._type == kEfhStatusNormal)
 		return;
-	if (--_teamCharStatus[charId]._duration != 0)
+	if (--_teamChar[charId]._status._duration > 0)
 		return;
 
 	// At this point : The status is different to 0 (normal) and the effect duration is finally 0 (end of effect)
-	_enemyNamePt2 = _npcBuf[_teamCharId[charId]]._name;
-	_enemyNamePt1 = getArticle(_npcBuf[_teamCharId[charId]].getPronoun());
+	_enemyNamePt2 = _npcBuf[_teamChar[charId]._id]._name;
+	_enemyNamePt1 = getArticle(_npcBuf[_teamChar[charId]._id].getPronoun());
 	
 	// End of effect message depends on the type of effect
-	switch (_teamCharStatus[charId]._status) {
-	case 1:
+	switch (_teamChar[charId]._status._type) {
+	case kEfhStatusSleeping:
 		_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
-	case 2:
+	case kEfhStatusFrozen:
 		_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 		break;
 	default:
@@ -200,7 +200,7 @@ void EfhEngine::handleFight_checkEndEffect(int16 charId) {
 	}
 
 	// The character status is back to normal
-	_teamCharStatus[charId]._status = 0;
+	_teamChar[charId]._status._type = kEfhStatusNormal;
 
 	// Finally, display the message
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -212,10 +212,10 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 	// In the original, this function is part of handleFight.
 	// It has been split for readability purposes.
 
-	int16 teamCharItemId = getEquippedExclusiveType(_teamCharId[teamCharId], 9, true);
+	int16 teamCharItemId = getEquippedExclusiveType(_teamChar[teamCharId]._id, 9, true);
 	if (teamCharItemId == 0x7FFF)
 		teamCharItemId = 0x3F;
-	int16 minMonsterGroupId = _teamNextAttack[teamCharId];
+	int16 minMonsterGroupId = _teamChar[teamCharId]._nextAttack;
 	if (minMonsterGroupId == 0x64)
 		minMonsterGroupId = 0;
 
@@ -259,15 +259,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				noticedFl = false;
 
 			int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
-			int16 enemyPronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+			int16 enemyPronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
 			int16 monsterId = _teamMonsterIdArray[groupId];
 			int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
-			int16 charScore = getCharacterScore(_teamCharId[teamCharId], teamCharItemId);
+			int16 charScore = getCharacterScore(_teamChar[teamCharId]._id, teamCharItemId);
 			int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
 			int16 hitCount = 0;
 			int16 originalDamage = 0;
 			int16 damagePointsAbsorbed = 0;
-			int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamCharId[teamCharId]]._speed;
+			int16 attackSpeed = _items[teamCharItemId]._attacks * _npcBuf[_teamChar[teamCharId]._id]._speed;
 
 			// Action A - Loop attackCounter - Start
 			for (int attackCounter = 0; attackCounter < attackSpeed; ++attackCounter) {
@@ -309,7 +309,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
 
 			_enemyNamePt1 = getArticle(enemyPronoun);
-			_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+			_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
 
 			_nameBuffer = _items[teamCharItemId]._name;
 			if (checkSpecialItemsOnCurrentPlace(teamCharItemId)) {
@@ -322,7 +322,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
-						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 					} else {
 						_messageToBePrinted += "!";
 					}
@@ -330,7 +330,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
 					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
-						getXPAndSearchCorpse(_teamCharId[teamCharId], _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
 					} else {
 						_messageToBePrinted += "!";
 					}
@@ -372,7 +372,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					_messageToBePrinted += Common::String("  Your actions do not go un-noticed...");
 
 				// Action A - Check item durability - Start
-				int16 npcId = _teamCharId[teamCharId];
+				int16 npcId = _teamChar[teamCharId]._id;
 
 				// get equipped inventory slot with exclusiveType == 9
 				uint16 exclusiveInventoryId = getEquippedExclusiveType(npcId, 9, false);
@@ -418,11 +418,11 @@ void EfhEngine::handleFight_lastAction_D(int16 teamCharId) {
 	// It has been split for readability purposes.
 	debugC(3, kDebugFight, "handleFight_lastAction_D %d", teamCharId);
 
-	_teamPctDodgeMiss[teamCharId] -= 40;
+	_teamChar[teamCharId]._pctDodgeMiss -= 40;
 
-	uint8 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+	uint8 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
 	_enemyNamePt1 = getArticle(pronoun);
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s prepares to defend %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -434,11 +434,11 @@ void EfhEngine::handleFight_lastAction_H(int16 teamCharId) {
 	// It has been split for readability purposes.
 	debugC(3, kDebugFight, "handleFight_lastAction_H %d", teamCharId);
 
-	_teamPctVisible[teamCharId] -= 50;
+	_teamChar[teamCharId]._pctVisible -= 50;
 
-	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+	int16 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
 	_enemyNamePt1 = getArticle(pronoun);
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s attempts to hide %sself!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPersonal[pronoun]);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
@@ -450,15 +450,15 @@ bool EfhEngine::handleFight_lastAction_U(int16 teamCharId) {
 	// It has been split for readability purposes.
 	debugC(3, kDebugFight, "handleFight_lastAction_U %d", teamCharId);
 
-	int16 itemId = _npcBuf[_teamCharId[teamCharId]]._inventory[_teamLastInventoryUsed[teamCharId]]._ref;
+	int16 itemId = _npcBuf[_teamChar[teamCharId]._id]._inventory[_teamChar[teamCharId]._lastInventoryUsed]._ref;
 	_nameBuffer = _items[itemId]._name;
 
-	int16 pronoun = _npcBuf[_teamCharId[teamCharId]].getPronoun();
+	int16 pronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
 	_enemyNamePt1 = getArticle(pronoun);
-	_enemyNamePt2 = _npcBuf[_teamCharId[teamCharId]]._name;
+	_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
 
 	_messageToBePrinted = Common::String::format("%s%s uses %s %s!  ", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kPossessive[pronoun], _nameBuffer.c_str());
-	bool retVal = useObject(_teamCharId[teamCharId], _teamLastInventoryUsed[teamCharId], _teamNextAttack[teamCharId], teamCharId, 0, 3);
+	bool retVal = useObject(_teamChar[teamCharId]._id, _teamChar[teamCharId]._lastInventoryUsed, _teamChar[teamCharId]._nextAttack, teamCharId, 0, 3);
 	displayBoxWithText(_messageToBePrinted, 1, 2, true);
 
 	return retVal;
@@ -480,7 +480,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 			if (_items[monsterWeaponItemId]._range < 3) {
 				for (uint attackTry = 0; attackTry < 10; ++attackTry) {
 					minTeamMemberId = getRandom(_teamSize) - 1;
-					if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamPctVisible[minTeamMemberId]) {
+					if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamChar[minTeamMemberId]._pctVisible) {
 						break;
 					}
 					minTeamMemberId = -1;
@@ -496,15 +496,15 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 
 			// handleFight - Loop on targetId - Start
 			for (int16 targetId = minTeamMemberId; targetId < maxTeamMemberId; ++targetId) {
-				if (_teamCharId[targetId] == -1 || !isTeamMemberStatusNormal(targetId))
+				if (_teamChar[targetId]._id == -1 || !isTeamMemberStatusNormal(targetId))
 					continue;
 
-				int16 randomDefense = getRandom(getEquipmentDefense(_teamCharId[targetId]));
+				int16 randomDefense = getRandom(getEquipmentDefense(_teamChar[targetId]._id));
 
 				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
-				int16 characterPronoun = _npcBuf[_teamCharId[targetId]].getPronoun();
+				int16 characterPronoun = _npcBuf[_teamChar[targetId]._id].getPronoun();
 
-				_teamPctDodgeMiss[targetId] += (_items[monsterWeaponItemId].field_13 * 5);
+				_teamChar[targetId]._pctDodgeMiss += (_items[monsterWeaponItemId].field_13 * 5);
 				int16 hitCount = 0;
 				int16 originalDamage = 0;
 				int16 damagePointsAbsorbed = 0;
@@ -512,12 +512,12 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._npcId * _items[monsterWeaponItemId]._attacks;
 				for (int var84 = 0; var84 < var64; ++var84) {
 					// handleFight - Loop var84 on var64 (objectId) - Start
-					if (getRandom(100) > _teamPctDodgeMiss[targetId])
+					if (getRandom(100) > _teamChar[targetId]._pctDodgeMiss)
 						continue;
 
 					++hitCount;
 
-					if (hasAdequateDefenseNPC(_teamCharId[targetId], _items[monsterWeaponItemId]._attackType))
+					if (hasAdequateDefenseNPC(_teamChar[targetId]._id, _items[monsterWeaponItemId]._attackType))
 						continue;
 
 					int16 baseDamage = getRandom(_items[monsterWeaponItemId]._damage);
@@ -540,7 +540,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					hitCount = 0;
 
 				if (hitCount > 0) {
-					_npcBuf[_teamCharId[targetId]]._hitPoints -= originalDamage;
+					_npcBuf[_teamChar[targetId]._id]._hitPoints -= originalDamage;
 					if (hitCount > 1)
 						_attackBuffer = Common::String::format("%d times ", hitCount);
 					else
@@ -554,7 +554,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
 
 				_characterNamePt1 = getArticle(characterPronoun);
-				_characterNamePt2 = _npcBuf[_teamCharId[targetId]]._name;
+				_characterNamePt2 = _npcBuf[_teamChar[targetId]._id]._name;
 
 				_nameBuffer = _items[monsterWeaponItemId]._name;
 				if (checkSpecialItemsOnCurrentPlace(monsterWeaponItemId)) {
@@ -565,13 +565,13 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 					} else if (hitPoints == 1) {
 						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
-						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
+						if (_npcBuf[_teamChar[targetId]._id]._hitPoints <= 0)
 							getDeathTypeDescription(targetId + 1000, groupId);
 						else
 							_messageToBePrinted += "!";
 					} else {
 						_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[var68 * 3 + var6A], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
-						if (_npcBuf[_teamCharId[targetId]]._hitPoints <= 0)
+						if (_npcBuf[_teamChar[targetId]._id]._hitPoints <= 0)
 							getDeathTypeDescription(targetId + 1000, groupId);
 						else
 							_messageToBePrinted += "!";
@@ -579,19 +579,19 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					// handleFight - check damages - End
 
 					// handleFight - Add reaction text - start
-					if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
-						if (_npcBuf[_teamCharId[targetId]]._hitPoints - 5 <= originalDamage) {
+					if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _npcBuf[_teamChar[targetId]._id]._hitPoints > 0) {
+						if (_npcBuf[_teamChar[targetId]._id]._hitPoints - 5 <= originalDamage) {
 							addReactionText(kEfhReactionReels);
-						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 8) {
+						} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 8) {
 							addReactionText(kEfhReactionCriesOut);
-						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 4) {
+						} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 4) {
 							addReactionText(kEfhReactionFalters);
-						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 2) {
+						} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 2) {
 							addReactionText(kEfhReactionWinces);
-						} else if (_npcBuf[_teamCharId[targetId]]._hitPoints < _npcBuf[_teamCharId[targetId]]._maxHP / 3) {
+						} else if (_npcBuf[_teamChar[targetId]._id]._hitPoints < _npcBuf[_teamChar[targetId]._id]._maxHP / 3) {
 							// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
 							addReactionText(kEfhReactionScreams);
-						} else if (_npcBuf[_teamCharId[targetId]]._maxHP / 8 >= originalDamage) {
+						} else if (_npcBuf[_teamChar[targetId]._id]._maxHP / 8 >= originalDamage) {
 							addReactionText(kEfhReactionChortles);
 						} else if (originalDamage == 0 && getRandom(100) < 35) {
 							// CHECKME: "originalDamage == 0" is always false as it's checked beforehand. Looks like another original bug
@@ -601,14 +601,14 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					// handleFight - Add reaction text - end
 
 					// handleFight - Check armor - start
-					if (randomDefense != 0 && hitCount != 0 && _npcBuf[_teamCharId[targetId]]._hitPoints > 0) {
+					if (randomDefense != 0 && hitCount != 0 && _npcBuf[_teamChar[targetId]._id]._hitPoints > 0) {
 						if (damagePointsAbsorbed <= 1)
 							_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						else
 							_messageToBePrinted += Common::String::format("  %s%s's armor absorbs %d points!", _characterNamePt1.c_str(), _characterNamePt2.c_str(), damagePointsAbsorbed);
 
 						int armorDamage = (originalDamage + damagePointsAbsorbed) / 10;
-						handleDamageOnArmor(_teamCharId[targetId], armorDamage);
+						handleDamageOnArmor(_teamChar[targetId]._id, armorDamage);
 					}
 					// handleFight - Check armor - end
 
@@ -616,15 +616,15 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					switch (_items[monsterWeaponItemId]._specialEffect) {
 					case 1:
 						if (getRandom(100) < 20) {
-							_teamCharStatus[targetId]._status = 1;
-							_teamCharStatus[targetId]._duration = getRandom(10);
+							_teamChar[targetId]._status._type = kEfhStatusSleeping;
+							_teamChar[targetId]._status._duration = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						break;
 					case 2:
 						if (getRandom(100) < 20) {
-							_teamCharStatus[targetId]._status = 2;
-							_teamCharStatus[targetId]._duration = getRandom(10);
+							_teamChar[targetId]._status._type = kEfhStatusFrozen;
+							_teamChar[targetId]._status._duration = getRandom(10);
 							_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 						}
 						break;
@@ -632,7 +632,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 					case 6:
 						if (getRandom(100) < 20) {
 							_messageToBePrinted += Common::String::format("  %s%s's life energy is gone!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
-							_npcBuf[_teamCharId[targetId]]._hitPoints = 0;
+							_npcBuf[_teamChar[targetId]._id]._hitPoints = 0;
 						}
 						break;
 					default:
@@ -676,7 +676,7 @@ bool EfhEngine::isTPK() {
 
 	int16 zeroedChar = 0;
 	for (int counter = 0; counter < _teamSize; ++counter) {
-		if (_npcBuf[_teamCharId[counter]]._hitPoints <= 0)
+		if (_npcBuf[_teamChar[counter]._id]._hitPoints <= 0)
 			++zeroedChar;
 	}
 
@@ -714,7 +714,7 @@ void EfhEngine::resetTeamMonsterIdArray() {
 bool EfhEngine::isTeamMemberStatusNormal(int16 teamMemberId) {
 	debugC(6, kDebugFight, "isTeamMemberStatusNormal %d", teamMemberId);
 
-	if (_npcBuf[_teamCharId[teamMemberId]]._hitPoints > 0 && _teamCharStatus[teamMemberId]._status == 0)
+	if (_npcBuf[_teamChar[teamMemberId]._id]._hitPoints > 0 && _teamChar[teamMemberId]._status._type == kEfhStatusNormal)
 		return true;
 
 	return false;
@@ -726,7 +726,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 	uint8 pronoun;
 
 	if (victimId >= 1000) { // Magic value for team members
-		int16 charId = _teamCharId[victimId - 1000];
+		int16 charId = _teamChar[victimId - 1000]._id;
 		pronoun = _npcBuf[charId].getPronoun();
 	} else {
 		int16 charId = _teamMonsterIdArray[victimId];
@@ -740,7 +740,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 	if (getRandom(100) < 20) {
 		deathType = 0;
 	} else if (attackerId >= 1000) {
-		int16 charId = _teamCharId[attackerId - 1000];
+		int16 charId = _teamChar[attackerId - 1000]._id;
 		if (charId == -1)
 			deathType = 0;
 		else {
@@ -1031,41 +1031,41 @@ bool EfhEngine::getTeamAttackRoundPlans() {
 
 	bool retVal = false;
 	for (int charId = 0; charId < _teamSize; ++charId) {
-		_teamLastAction[charId] = 0;
+		_teamChar[charId]._lastAction = 0;
 		if (!isTeamMemberStatusNormal(charId))
 			continue;
 
 		retVal = true;
 		do {
-			drawCombatScreen(_teamCharId[charId], false, true);
+			drawCombatScreen(_teamChar[charId]._id, false, true);
 			switch (handleAndMapInput(true)) {
 			case Common::KEYCODE_a: // Attack
-				_teamLastAction[charId] = 'A';
-				_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, true);
-				if (_teamNextAttack[charId] == -1)
-					_teamLastAction[charId] = 0;
+				_teamChar[charId]._lastAction = 'A';
+				_teamChar[charId]._nextAttack = determineTeamTarget(_teamChar[charId]._id, 9, true);
+				if (_teamChar[charId]._nextAttack == -1)
+					_teamChar[charId]._lastAction = 0;
 				break;
 			case Common::KEYCODE_d: // Defend
-				_teamLastAction[charId] = 'D';
+				_teamChar[charId]._lastAction = 'D';
 				break;
 			case Common::KEYCODE_h: // Hide
-				_teamLastAction[charId] = 'H';
+				_teamChar[charId]._lastAction = 'H';
 				break;
 			case Common::KEYCODE_r: // Run
 				for (int counter2 = 0; counter2 < _teamSize; ++counter2) {
-					_teamLastAction[counter2] = 'R';
+					_teamChar[counter2]._lastAction = 'R';
 				}
 				return true;
 			case Common::KEYCODE_s: { // Status
-				int16 lastInvId = handleStatusMenu(2, _teamCharId[charId]);
-				redrawCombatScreenWithTempText(_teamCharId[charId]);
+				int16 lastInvId = handleStatusMenu(2, _teamChar[charId]._id);
+				redrawCombatScreenWithTempText(_teamChar[charId]._id);
 				if (lastInvId >= 999) {
 					if (lastInvId == 0x7D00) // Result of Equip, Give and Drop in combat mode(2)
-						_teamLastAction[charId] = 'S';
+						_teamChar[charId]._lastAction = 'S';
 				} else {
-					_teamLastAction[charId] = 'U';
-					_teamLastInventoryUsed[charId] = lastInvId;
-					int16 invEffect = _items[_npcBuf[_teamCharId[charId]]._inventory[lastInvId]._ref]._specialEffect;
+					_teamChar[charId]._lastAction = 'U';
+					_teamChar[charId]._lastInventoryUsed = lastInvId;
+					int16 invEffect = _items[_npcBuf[_teamChar[charId]._id]._inventory[lastInvId]._ref]._specialEffect;
 					switch (invEffect - 1) {
 					case 0:
 					case 1:
@@ -1079,7 +1079,7 @@ bool EfhEngine::getTeamAttackRoundPlans() {
 					case 10:
 					case 12:
 					case 13:
-						_teamNextAttack[charId] = determineTeamTarget(_teamCharId[charId], 9, false);
+						_teamChar[charId]._nextAttack = determineTeamTarget(_teamChar[charId]._id, 9, false);
 						break;
 
 					case 9:
@@ -1094,13 +1094,13 @@ bool EfhEngine::getTeamAttackRoundPlans() {
 					case 29:
 					case 30:
 						displayBoxWithText("Select Character:", 3, 1, false);
-						_teamNextAttack[charId] = selectOtherCharFromTeam();
+						_teamChar[charId]._nextAttack = selectOtherCharFromTeam();
 						break;
 
 					case 16:
 					case 17:
 					case 26:
-						_teamNextAttack[charId] = 0xC8;
+						_teamChar[charId]._nextAttack = 0xC8;
 						break;
 
 					case 19:
@@ -1109,8 +1109,8 @@ bool EfhEngine::getTeamAttackRoundPlans() {
 					case 22:
 					case 23:
 					default:
-						_teamLastInventoryUsed[charId] = lastInvId;
-						_teamNextAttack[charId] = -1;
+						_teamChar[charId]._lastInventoryUsed = lastInvId;
+						_teamChar[charId]._nextAttack = -1;
 						break;
 					}
 				}
@@ -1119,12 +1119,12 @@ bool EfhEngine::getTeamAttackRoundPlans() {
 			case Common::KEYCODE_t: // Terrain
 				redrawScreenForced();
 				getInputBlocking();
-				drawCombatScreen(_teamCharId[charId], false, true);
+				drawCombatScreen(_teamChar[charId]._id, false, true);
 				break;
 			default:
 				break;
 			}
-		} while (_teamLastAction[charId] == 0);
+		} while (_teamChar[charId]._lastAction == 0);
 	}
 
 	return retVal;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 3caf788835b..59b2ff80cfc 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -304,17 +304,17 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_guessAnimationAmount = 9;
 	_largeMapFlag = 0xFFFF;
 	_alertDelay = 0;
-	_teamCharId[0] = 0;
-	_teamCharId[1] = _teamCharId[2] = -1;
+	_teamChar[0]._id = 0;
+	_teamChar[1]._id = _teamChar[2]._id = -1;
 
 	for (int i = 0; i < 3; ++i) {
-		_teamCharStatus[i]._status = 0;
-		_teamCharStatus[i]._duration = 0;
-		_teamPctVisible[i] = 0;
-		_teamPctDodgeMiss[i] = 0;
-		_teamNextAttack[i] = -1;
-		_teamLastInventoryUsed[i] = 0;
-		_teamLastAction[i] = 0;
+		_teamChar[i]._status._type = kEfhStatusNormal;
+		_teamChar[i]._status._duration = 0;
+		_teamChar[i]._pctVisible = 0;
+		_teamChar[i]._pctDodgeMiss = 0;
+		_teamChar[i]._nextAttack = -1;
+		_teamChar[i]._lastInventoryUsed = 0;
+		_teamChar[i]._lastAction = 0;
 	}
 
 	for (int i = 0; i < 5; ++i) {
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 38a570a51db..79722cbcb14 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -745,23 +745,23 @@ int16 EfhEngine::handleStatusMenu(int16 gameMode, int16 charId) {
 				bool givenFl;
 				int16 destCharId;
 				do {
-					if (_teamCharId[2] != -1) {
+					if (_teamChar[2]._id != -1) {
 						displayStringInSmallWindowWithBorder("Who will you give the item to?", false, charId, windowId, menuId, curMenuLine);
 						destCharId = selectOtherCharFromTeam();
 						var2 = false;
-					} else if (_teamCharId[1] == -1) {
+					} else if (_teamChar[1]._id == -1) {
 						destCharId = 0x1A;
 						var2 = false;
 					} else {
 						var2 = true;
-						if (_teamCharId[0] == charId)
+						if (_teamChar[0]._id == charId)
 							destCharId = 1;
 						else
 							destCharId = 0;
 					}
 
 					if (destCharId != 0x1A && destCharId != 0x1B) {
-						givenFl = giveItemTo(_teamCharId[destCharId], objectId, charId);
+						givenFl = giveItemTo(_teamChar[destCharId]._id, objectId, charId);
 						if (!givenFl) {
 							displayStringInSmallWindowWithBorder("That character cannot carry anymore!", false, charId, windowId, menuId, curMenuLine);
 							getLastCharAfterAnimCount(_guessAnimationAmount);
@@ -1058,9 +1058,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			} else {
 				_messageToBePrinted += buffer1;
 			}
-			_teamPctDodgeMiss[teamCharId] -= 50;
-			if (_teamPctDodgeMiss[teamCharId] < 0)
-				_teamPctDodgeMiss[teamCharId] = 0;
+			_teamChar[teamCharId]._pctDodgeMiss -= 50;
+			if (_teamChar[teamCharId]._pctDodgeMiss < 0)
+				_teamChar[teamCharId]._pctDodgeMiss = 0;
 		}
 
 		objectUsedFl = true;
@@ -1082,9 +1082,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				_messageToBePrinted += buffer1;
 			}
 
-			_teamPctVisible[teamCharId] -= 50;
-			if (_teamPctVisible[teamCharId] < 0)
-				_teamPctVisible[teamCharId] = 0;
+			_teamChar[teamCharId]._pctVisible -= 50;
+			if (_teamChar[teamCharId]._pctVisible < 0)
+				_teamChar[teamCharId]._pctVisible = 0;
 		}
 
 		objectUsedFl = true;
@@ -1166,10 +1166,10 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
-				if (_teamCharStatus[teamCharId]._status == 2) { // frozen
+				if (_teamChar[teamCharId]._status._type == kEfhStatusFrozen) { // frozen
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
-					_teamCharStatus[teamCharId]._status = 0;
-					_teamCharStatus[teamCharId]._duration = 0;
+					_teamChar[teamCharId]._status._type = kEfhStatusNormal;
+					_teamChar[teamCharId]._status._duration = 0;
 				} else {
 					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
 				}
@@ -1236,9 +1236,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
 			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
-			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] += effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20) {
-				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 20;
+			_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] += effectPoints;
+			if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20) {
+				_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] = 20;
 			}
 			if (effectPoints > 1)
 				buffer1 = Common::String::format("%s increased %d points!", kSkillArray[varAE], effectPoints);
@@ -1266,9 +1266,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		if (teamCharId != 0x1B) {
 			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
 			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
-			_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] -= effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] > 20 || _npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] < 0) {
-				_npcBuf[_teamCharId[teamCharId]]._activeScore[varAE] = 1;
+			_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] -= effectPoints;
+			if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20 || _npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] < 0) {
+				_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] = 1;
 			}
 			if (effectPoints > 1)
 				buffer1 = Common::String::format("%s lowered %d points!", kSkillArray[varAE], effectPoints);
@@ -1306,8 +1306,8 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 
 		if (teamCharId != 0x1B) {
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
-			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamCharId[teamCharId]]._name);
+			_npcBuf[_teamChar[teamCharId]._id]._hitPoints = 0;
+			buffer1 = Common::String::format("%s collapses, dead!!!", _npcBuf[_teamChar[teamCharId]._id]._name);
 			if (gameMode == 2) {
 				displayStringInSmallWindowWithBorder(buffer1, false, charId, teamMonsterId, menuId, curMenuLine);
 			} else {
@@ -1324,10 +1324,10 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
-				if (_teamCharStatus[teamCharId]._status == 0) {
+				if (_teamChar[teamCharId]._status._type == kEfhStatusNormal) { // BUG (likely) 
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
-					_teamCharStatus[teamCharId]._status = 0;
-					_teamCharStatus[teamCharId]._duration = 0;
+					_teamChar[teamCharId]._status._type = kEfhStatusNormal;
+					_teamChar[teamCharId]._status._duration = 0;
 				} else {
 					_messageToBePrinted += "  The item makes a loud noise, but has no effect!";
 				}
@@ -1347,14 +1347,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 
 		if (teamCharId != 0x1B) {
 			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints += effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints > _npcBuf[_teamCharId[teamCharId]]._maxHP)
-				_npcBuf[_teamCharId[teamCharId]]._hitPoints = _npcBuf[_teamCharId[teamCharId]]._maxHP;
+			_npcBuf[_teamChar[teamCharId]._id]._hitPoints += effectPoints;
+			if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints > _npcBuf[_teamChar[teamCharId]._id]._maxHP)
+				_npcBuf[_teamChar[teamCharId]._id]._hitPoints = _npcBuf[_teamChar[teamCharId]._id]._maxHP;
 
 			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
+				buffer1 = Common::String::format("%s is healed %d points!", _npcBuf[_teamChar[teamCharId]._id]._name, effectPoints);
 			else
-				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
+				buffer1 = Common::String::format("%s is healed 1 point!", _npcBuf[_teamChar[teamCharId]._id]._name);
 		}
 
 		if (gameMode == 2) {
@@ -1377,14 +1377,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 
 		if (teamCharId != 0x1B) {
 			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
-			_npcBuf[_teamCharId[teamCharId]]._hitPoints -= effectPoints;
-			if (_npcBuf[_teamCharId[teamCharId]]._hitPoints < 0)
-				_npcBuf[_teamCharId[teamCharId]]._hitPoints = 0;
+			_npcBuf[_teamChar[teamCharId]._id]._hitPoints -= effectPoints;
+			if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints < 0)
+				_npcBuf[_teamChar[teamCharId]._id]._hitPoints = 0;
 
 			if (effectPoints > 1)
-				buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamCharId[teamCharId]]._name, effectPoints);
+				buffer1 = Common::String::format("%s is harmed for %d points!", _npcBuf[_teamChar[teamCharId]._id]._name, effectPoints);
 			else
-				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamCharId[teamCharId]]._name);
+				buffer1 = Common::String::format("%s is harmed for 1 point!", _npcBuf[_teamChar[teamCharId]._id]._name);
 		}
 
 		if (gameMode == 2) {
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index 46fb5b5c681..b0045e64a8b 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -128,13 +128,13 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 	s.syncAsUint16LE(_fullPlaceId);
 	s.syncAsSint16LE(_guessAnimationAmount);
 	s.syncAsUint16LE(_largeMapFlag);
-	s.syncAsSint16LE(_teamCharId[0]);
-	s.syncAsSint16LE(_teamCharId[1]);
-	s.syncAsSint16LE(_teamCharId[2]);
+	s.syncAsSint16LE(_teamChar[0]._id);
+	s.syncAsSint16LE(_teamChar[1]._id);
+	s.syncAsSint16LE(_teamChar[2]._id);
 
 	for (int i = 0; i < 3; ++i) {
-		s.syncAsSint16LE(_teamCharStatus[i]._status);
-		s.syncAsSint16LE(_teamCharStatus[i]._duration);
+		s.syncAsSint16LE(_teamChar[i]._status._type);
+		s.syncAsSint16LE(_teamChar[i]._status._duration);
 	}
 
 	s.syncAsSint16LE(_teamSize);
diff --git a/engines/efh/script.cpp b/engines/efh/script.cpp
index 164050d4b94..02710da2989 100644
--- a/engines/efh/script.cpp
+++ b/engines/efh/script.cpp
@@ -184,7 +184,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x05:
 			buffer = script_readNumberArray(buffer, 4, scriptNumberArray);
 			if (scriptExecuteFlag) {
-				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				int16 npcId = _teamChar[scriptNumberArray[0]]._id;
 				if (npcId != -1) {
 					int16 scoreId = scriptNumberArray[1];
 					_npcBuf[npcId]._activeScore[scoreId] += scriptNumberArray[2] & 0xFF;
@@ -195,7 +195,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x06:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (scriptExecuteFlag) {
-				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				int16 npcId = _teamChar[scriptNumberArray[0]]._id;
 				if (npcId != -1) {
 					int16 scoreId = scriptNumberArray[1];
 					_npcBuf[npcId]._activeScore[scoreId] = scriptNumberArray[2] & 0xFF;
@@ -210,13 +210,13 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x08:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (scriptExecuteFlag && scriptNumberArray[0] != -1) {
-				_npcBuf[_teamCharId[scriptNumberArray[0]]]._hitPoints = 0;
+				_npcBuf[_teamChar[scriptNumberArray[0]]._id]._hitPoints = 0;
 			}
 			break;
 		case 0x09:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (scriptExecuteFlag) {
-				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				int16 npcId = _teamChar[scriptNumberArray[0]]._id;
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints += getRandom(scriptNumberArray[1]);
 					if (_npcBuf[npcId]._hitPoints > _npcBuf[npcId]._maxHP)
@@ -227,7 +227,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0A:
 			buffer = script_readNumberArray(buffer, 1, scriptNumberArray);
 			if (scriptExecuteFlag) {
-				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				int16 npcId = _teamChar[scriptNumberArray[0]]._id;
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints = _npcBuf[npcId]._maxHP;
 				}
@@ -236,7 +236,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		case 0x0B:
 			buffer = script_readNumberArray(buffer, 2, scriptNumberArray);
 			if (scriptExecuteFlag) {
-				int16 npcId = _teamCharId[scriptNumberArray[0]];
+				int16 npcId = _teamChar[scriptNumberArray[0]]._id;
 				if (npcId != -1) {
 					_npcBuf[npcId]._hitPoints -= getRandom(scriptNumberArray[1]);
 					if (_npcBuf[npcId]._hitPoints < 0)
@@ -251,8 +251,8 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
 					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
-							removeObject(_teamCharId[counter], objectId);
+						if (_npcBuf[_teamChar[counter]._id]._inventory[objectId]._ref == scriptItemId) {
+							removeObject(_teamChar[counter]._id, objectId);
 							found = true;
 							break;
 						}
@@ -266,7 +266,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 			if (scriptExecuteFlag) {
 				int16 scriptObjectId = scriptNumberArray[0];
 				for (int counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], scriptObjectId, 0xFF))
+					if (giveItemTo(_teamChar[counter]._id, scriptObjectId, 0xFF))
 						break;
 				}
 			}
@@ -278,7 +278,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				bool found = false;
 				for (int counter = 0; counter < _teamSize && !found; ++counter) {
 					for (uint objectId = 0; objectId < 10; ++objectId) {
-						if (_npcBuf[_teamCharId[counter]]._inventory[objectId]._ref == scriptItemId) {
+						if (_npcBuf[_teamChar[counter]._id]._inventory[objectId]._ref == scriptItemId) {
 							found = true;
 							break;
 						}
@@ -354,7 +354,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				// TODO: This "if" is useless, it's doing just the same loop and if statement. Consider removing it.
 				if (isNpcATeamMember(scriptNpcId)) {
 					for (uint counter = 0; counter < 3; ++counter) {
-						if (_teamCharId[counter] == scriptNpcId) {
+						if (_teamChar[counter]._id == scriptNpcId) {
 							removeCharacterFromTeam(counter);
 							break;
 						}
@@ -376,7 +376,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 				int16 scriptRandomItemId = getRandom(scriptNumberArray[1] - scriptNumberArray[0] + 1) + scriptNumberArray[0] - 1;
 				int16 counter;
 				for (counter = 0; counter < _teamSize; ++counter) {
-					if (giveItemTo(_teamCharId[counter], scriptRandomItemId, 0xFF)) {
+					if (giveItemTo(_teamChar[counter]._id, scriptRandomItemId, 0xFF)) {
 						found = true;
 						break;
 					}
@@ -389,7 +389,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 					scriptRandomItemId = displayBoxWithText("Nothing...", 1, 2, true);
 					displayFctFullScreen();
 				} else {
-					_enemyNamePt2 = _npcBuf[_teamCharId[counter]]._name;
+					_enemyNamePt2 = _npcBuf[_teamChar[counter]._id]._name;
 					_nameBuffer = _items[scriptRandomItemId]._name;
 					curLine = Common::String::format("%s finds a %s!", _enemyNamePt2.c_str(), _nameBuffer.c_str());
 					drawMapWindow();
@@ -484,7 +484,7 @@ int16 EfhEngine::script_parse(Common::String stringBuffer, int16 posX, int16 pos
 		displayLowStatusScreen(true);
 		int16 teamSlot = handleCharacterJoining();
 		if (teamSlot > -1) {
-			_teamCharId[teamSlot] = joiningNpcId;
+			_teamChar[teamSlot]._id = joiningNpcId;
 		}
 		refreshTeamSize();
 	}


Commit: 41e39d27cf75b575118137e5ef48b50c268dde9a
    https://github.com/scummvm/scummvm/commit/41e39d27cf75b575118137e5ef48b50c268dde9a
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:49+01:00

Commit Message:
EFH: Fix bug when using bugle

Changed paths:
    engines/efh/menu.cpp


diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 79722cbcb14..3e9d586d279 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1324,7 +1324,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
-				if (_teamChar[teamCharId]._status._type == kEfhStatusNormal) { // BUG (likely) 
+				if (_teamChar[teamCharId]._status._type == kEfhStatusSleeping) {
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
 					_teamChar[teamCharId]._status._type = kEfhStatusNormal;
 					_teamChar[teamCharId]._status._duration = 0;


Commit: fdd742bfbfba09001247242524a64b79a77e1bf8
    https://github.com/scummvm/scummvm/commit/fdd742bfbfba09001247242524a64b79a77e1bf8
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:50+01:00

Commit Message:
EFH: refactor TeamMonster

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 942f657378b..de0cdc44673 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -1494,7 +1494,7 @@ bool EfhEngine::checkWeaponRange(int16 monsterId, int16 weaponId) {
 bool EfhEngine::checkMonsterMovementType(int16 id, bool teamFlag) {
 	debugC(6, kDebugEngine, "checkMonsterMovementType %d %s", id, teamFlag ? "True" : "False");
 
-	int16 monsterId = teamFlag ? _teamMonsterIdArray[id] : id;
+	int16 monsterId = teamFlag ? _teamMonster[id]._id : id;
 	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
 
 	if ((curMapMonst->_additionalInfo & 0xF) >= 8) // Check hostility
@@ -1513,7 +1513,7 @@ bool EfhEngine::checkTeamWeaponRange(int16 monsterId) {
 		return true;
 
 	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[_techId][monsterId]._weaponItemId))
+		if (_teamMonster[counter]._id == monsterId && checkMonsterMovementType(monsterId, false) && checkWeaponRange(monsterId, _mapMonsters[_techId][monsterId]._weaponItemId))
 			return false;
 	}
 
@@ -2180,12 +2180,12 @@ void EfhEngine::computeInitiatives() {
 	}
 
 	for (int counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == -1) {
+		if (_teamMonster[counter]._id == -1) {
 			_initiatives[counter + 3]._id = -1;
 			_initiatives[counter + 3]._initiative = -1;
 		} else {
 			_initiatives[counter + 3]._id = counter;
-			_initiatives[counter + 3]._initiative = _mapMonsters[_techId][_teamMonsterIdArray[counter]]._npcId + getRandom(20);
+			_initiatives[counter + 3]._initiative = _mapMonsters[_techId][_teamMonster[counter]._id]._npcId + getRandom(20);
 		}
 	}
 
@@ -2261,7 +2261,7 @@ bool EfhEngine::hasObjectEquipped(int16 charId, int16 objectId) {
 void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask) {
 	debugC(2, kDebugEngine, "setMapMonsterAggressivenessAndMovementType %d 0x%X", id, mask);
 
-	int16 monsterId = _teamMonsterIdArray[id];
+	int16 monsterId = _teamMonster[id]._id;
 	MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
 
 	mask &= 0x0F;
@@ -2272,7 +2272,7 @@ void EfhEngine::setMapMonsterAggressivenessAndMovementType(int16 id, uint8 mask)
 bool EfhEngine::isMonsterActive(int16 groupId, int16 id) {
 	debugC(5, kDebugEngine, "isMonsterActive %d %d", groupId, id);
 
-	if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[id] > 0 && _teamMonsterEffects[groupId]._effect[id] == 0)
+	if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[id] > 0 && _teamMonster[groupId]._mobsterStatus[id]._type == kEfhStatusNormal)
 		return true;
 	return false;
 }
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 9b7676a8a7c..f402f5d5247 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -224,13 +224,6 @@ struct MapMonster {
 	uint8 getPronoun();
 };
 
-struct TeamMonsterEffect {
-	int16 _effect[9];
-	int16 _duration[9];
-
-	void init();
-};
-
 struct InitiativeStruct {
 	int16 _id;
 	int16 _initiative;
@@ -255,6 +248,13 @@ struct TeamChar {
 	int16 _lastAction;
 };
 
+struct TeamMonster {
+	int16 _id;
+	CharStatus _mobsterStatus[9];
+
+	void init();
+};
+
 class EfhEngine : public Engine {
 public:
 	EfhEngine(OSystem *syst, const ADGameDescription *gd);
@@ -617,9 +617,7 @@ private:
 	int16 _menuItemCounter;
 
 	TeamChar _teamChar[3];
-
-	int16 _teamMonsterIdArray[5];
-	TeamMonsterEffect _teamMonsterEffects[5];
+	TeamMonster _teamMonster[5];
 
 	InitiativeStruct _initiatives[8];
 
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index d5ebd27c055..d53e2cb6f81 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -29,7 +29,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 	int16 counter = 0;
 	if (monsterTeamId != -1 && countAliveMonsters(monsterTeamId) > 0) {
 		counter = 1;
-		_teamMonsterIdArray[0] = monsterTeamId;
+		_teamMonster[0]._id = monsterTeamId;
 	}
 
 	for (int counter2 = 1; counter2 <= 3; ++counter2) {
@@ -57,7 +57,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 
 			if (found) {
 				if (computeMonsterGroupDistance(monsterId) <= counter2 && !isMonsterAlreadyFighting(monsterId, counter)) {
-					_teamMonsterIdArray[counter] = monsterId;
+					_teamMonster[counter]._id = monsterId;
 					if (++counter >= 5)
 						break;
 				}
@@ -69,7 +69,7 @@ void EfhEngine::createOpponentList(int16 monsterTeamId) {
 		return;
 
 	for (uint id = counter; id < 5; ++id)
-		_teamMonsterIdArray[id] = -1;
+		_teamMonster[id]._id = -1;
 }
 
 void EfhEngine::initFight(int16 monsterId) {
@@ -85,7 +85,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 
 	initFight(monsterId);
 
-	if (_teamMonsterIdArray[0] == -1) {
+	if (_teamMonster[0]._id == -1) {
 		resetTeamMonsterIdArray();
 		_ongoingFightFl = false;
 		displayAnimFrames(0xFE, true);
@@ -102,7 +102,7 @@ bool EfhEngine::handleFight(int16 monsterId) {
 			return false;
 		}
 
-		if (_teamMonsterIdArray[0] == -1) {
+		if (_teamMonster[0]._id == -1) {
 			resetTeamMonsterIdArray();
 			_ongoingFightFl = false;
 			displayAnimFrames(0xFE, true);
@@ -243,7 +243,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 
 	bool var6E = true;
 	for (int16 groupId = minMonsterGroupId; groupId < maxMonsterGroupId; ++groupId) {
-		if (_teamMonsterIdArray[groupId] == -1)
+		if (_teamMonster[groupId]._id == -1)
 			continue;
 
 		for (int16 ctrMobsterId = minTeamMemberId; ctrMobsterId < maxTeamMemberId; ++ctrMobsterId) {
@@ -258,12 +258,12 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			} else
 				noticedFl = false;
 
-			int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._maxDamageAbsorption);
+			int16 randomDamageAbsorbed = getRandom(_mapMonsters[_techId][_teamMonster[groupId]._id]._maxDamageAbsorption);
 			int16 enemyPronoun = _npcBuf[_teamChar[teamCharId]._id].getPronoun();
-			int16 monsterId = _teamMonsterIdArray[groupId];
+			int16 monsterId = _teamMonster[groupId]._id;
 			int16 characterPronoun = kEncounters[_mapMonsters[_techId][monsterId]._monsterRef]._nameArticle;
 			int16 charScore = getCharacterScore(_teamChar[teamCharId]._id, teamCharItemId);
-			int16 hitPointsBefore = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId];
+			int16 hitPointsBefore = _mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId];
 			int16 hitCount = 0;
 			int16 originalDamage = 0;
 			int16 damagePointsAbsorbed = 0;
@@ -273,7 +273,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			for (int attackCounter = 0; attackCounter < attackSpeed; ++attackCounter) {
 				if (getRandom(100) < charScore) {
 					++hitCount;
-					if (!hasAdequateDefense(_teamMonsterIdArray[groupId], _items[teamCharItemId]._attackType)) {
+					if (!hasAdequateDefense(_teamMonster[groupId]._id, _items[teamCharItemId]._attackType)) {
 						int16 randomDamage = getRandom(_items[teamCharItemId]._damage);
 						int16 residualDamage = randomDamage - randomDamageAbsorbed;
 						if (residualDamage > 0) {
@@ -296,7 +296,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				hitCount = 0;
 
 			if (hitCount > 0) {
-				_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] -= originalDamage;
+				_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] -= originalDamage;
 				if (hitCount > 1) {
 					_attackBuffer = Common::String::format("%d times ", hitCount);
 				} else {
@@ -306,7 +306,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 			int16 verbId = (3 * _items[teamCharItemId]._attackType + 1) + getRandom(3) - 1;
 
 			_characterNamePt1 = getArticle(characterPronoun);
-			_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+			_characterNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._name;
 
 			_enemyNamePt1 = getArticle(enemyPronoun);
 			_enemyNamePt2 = _npcBuf[_teamChar[teamCharId]._id]._name;
@@ -320,17 +320,17 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s, but does no damage!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
 				} else if (hitPoints == 1) {
 					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for 1 point", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str());
-					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+					if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
-						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonster[groupId]._id);
 					} else {
 						_messageToBePrinted += "!";
 					}
 				} else {
 					_messageToBePrinted = Common::String::format("%s%s %s %s%s %swith %s %s for %d points", _enemyNamePt1.c_str(), _enemyNamePt2.c_str(), kAttackVerbs[verbId], _characterNamePt1.c_str(), _characterNamePt2.c_str(), _attackBuffer.c_str(), kPossessive[enemyPronoun], _nameBuffer.c_str(), hitPoints);
-					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] <= 0) {
+					if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] <= 0) {
 						getDeathTypeDescription(groupId, teamCharId + 1000);
-						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonsterIdArray[groupId]);
+						getXPAndSearchCorpse(_teamChar[teamCharId]._id, _enemyNamePt1, _enemyNamePt2, _teamMonster[groupId]._id);
 					} else {
 						_messageToBePrinted += "!";
 					}
@@ -338,16 +338,16 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				// Action A - Check damages - End
 
 				// Action A - Add reaction text - Start
-				if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-					if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
+				if (hitCount != 0 && originalDamage > 0 && getRandom(100) <= 35 && _mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] > 0) {
+					if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] - 5 <= originalDamage) {
 						addReactionText(kEfhReactionReels);
-					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
+					} else if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] < hitPointsBefore / 8) {
 						addReactionText(kEfhReactionCriesOut);
-					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
+					} else if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] < hitPointsBefore / 4) {
 						addReactionText(kEfhReactionFalters);
-					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
+					} else if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] < hitPointsBefore / 2) {
 						addReactionText(kEfhReactionWinces);
-					} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
+					} else if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] < hitPointsBefore / 3) {
 						// CHECKME: Doesn't make any sense to check /3 after /2... I don't get it. Looks like an original bug
 						addReactionText(kEfhReactionScreams);
 					} else if (hitPointsBefore / 8 >= originalDamage) {
@@ -360,7 +360,7 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				// Action A - Add reaction text - End
 
 				// Action A - Add armor absorb text - Start
-				if (randomDamageAbsorbed && hitCount && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+				if (randomDamageAbsorbed && hitCount && _mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] > 0) {
 					if (damagePointsAbsorbed <= 1)
 						_messageToBePrinted += Common::String::format("  %s%s's armor absorbs 1 point!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 					else
@@ -390,15 +390,15 @@ void EfhEngine::handleFight_lastAction_A(int16 teamCharId) {
 				// Action A - Check item durability - End
 
 				// Action A - Check effect - Start
-				if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
+				if (_items[teamCharItemId]._specialEffect == 1 && _mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] > 0) {
 					if (getRandom(100) < 35) {
-						_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 1;
-						_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
+						_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusSleeping;
+						_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._duration = getRandom(10);
 						_messageToBePrinted += Common::String::format("  %s%s falls asleep!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 					}
-				} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0) {
-					_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 2;
-					_teamMonsterEffects[groupId]._duration[ctrMobsterId] = getRandom(10);
+				} else if (_items[teamCharItemId]._specialEffect == 2 && _mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] > 0) {
+					_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusFrozen;
+					_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._duration = getRandom(10);
 					_messageToBePrinted += Common::String::format("  %s%s is frozen!", _characterNamePt1.c_str(), _characterNamePt2.c_str());
 				}
 				// Action A - Check effect - End
@@ -472,7 +472,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 	// handleFight - Loop on mobsterId - Start
 	for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
 		if (isMonsterActive(groupId, ctrMobsterId)) {
-			int16 monsterWeaponItemId = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._weaponItemId;
+			int16 monsterWeaponItemId = _mapMonsters[_techId][_teamMonster[groupId]._id]._weaponItemId;
 			if (monsterWeaponItemId == 0xFF)
 				monsterWeaponItemId = 0x3F;
 			int16 minTeamMemberId = -1;
@@ -480,7 +480,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 			if (_items[monsterWeaponItemId]._range < 3) {
 				for (uint attackTry = 0; attackTry < 10; ++attackTry) {
 					minTeamMemberId = getRandom(_teamSize) - 1;
-					if (checkWeaponRange(_teamMonsterIdArray[groupId], monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamChar[minTeamMemberId]._pctVisible) {
+					if (checkWeaponRange(_teamMonster[groupId]._id, monsterWeaponItemId) && isTeamMemberStatusNormal(minTeamMemberId) && getRandom(100) < _teamChar[minTeamMemberId]._pctVisible) {
 						break;
 					}
 					minTeamMemberId = -1;
@@ -501,7 +501,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 
 				int16 randomDefense = getRandom(getEquipmentDefense(_teamChar[targetId]._id));
 
-				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle;
+				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._nameArticle;
 				int16 characterPronoun = _npcBuf[_teamChar[targetId]._id].getPronoun();
 
 				_teamChar[targetId]._pctDodgeMiss += (_items[monsterWeaponItemId].field_13 * 5);
@@ -509,7 +509,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				int16 originalDamage = 0;
 				int16 damagePointsAbsorbed = 0;
 
-				int16 var64 = _mapMonsters[_techId][_teamMonsterIdArray[groupId]]._npcId * _items[monsterWeaponItemId]._attacks;
+				int16 var64 = _mapMonsters[_techId][_teamMonster[groupId]._id]._npcId * _items[monsterWeaponItemId]._attacks;
 				for (int var84 = 0; var84 < var64; ++var84) {
 					// handleFight - Loop var84 on var64 (objectId) - Start
 					if (getRandom(100) > _teamChar[targetId]._pctDodgeMiss)
@@ -551,7 +551,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				int16 var6A = getRandom(3);
 
 				_enemyNamePt1 = getArticle(enemyPronoun);
-				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
+				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._name;
 
 				_characterNamePt1 = getArticle(characterPronoun);
 				_characterNamePt2 = _npcBuf[_teamChar[targetId]._id]._name;
@@ -646,24 +646,24 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				displayBoxWithText(_messageToBePrinted, 1, 2, true);
 			}
 			// handleFight - Loop on targetId - End
-		} else if (_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._hitPoints[ctrMobsterId] > 0 && _teamMonsterEffects[groupId]._effect[ctrMobsterId] > 0) {
-			--_teamMonsterEffects[groupId]._duration[ctrMobsterId];
-			if (_teamMonsterEffects[groupId]._duration[ctrMobsterId] <= 0) {
-				_enemyNamePt1 = getArticle(kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._nameArticle);
-				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[groupId]]._monsterRef]._name;
-
-				switch (_teamMonsterEffects[groupId]._effect[ctrMobsterId]) {
-				case 1:
+		} else if (_mapMonsters[_techId][_teamMonster[groupId]._id]._hitPoints[ctrMobsterId] > 0 && _teamMonster[groupId]._mobsterStatus[ctrMobsterId]._type != kEfhStatusNormal) {
+			--_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._duration;
+			if (_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._duration <= 0) {
+				_enemyNamePt1 = getArticle(kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._nameArticle);
+				_enemyNamePt2 = kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._name;
+
+				switch (_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._type) {
+				case kEfhStatusSleeping:
 					_messageToBePrinted = Common::String::format("%s%s wakes up!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 					break;
-				case 2:
+				case kEfhStatusFrozen:
 					_messageToBePrinted = Common::String::format("%s%s thaws out!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 					break;
 				default:
 					_messageToBePrinted = Common::String::format("%s%s recovers!", _enemyNamePt1.c_str(), _enemyNamePt2.c_str());
 					break;
 				}
-				_teamMonsterEffects[groupId]._effect[ctrMobsterId] = 0;
+				_teamMonster[groupId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusNormal;
 				displayBoxWithText(_messageToBePrinted, 1, 2, true);
 			}
 		}
@@ -687,7 +687,7 @@ bool EfhEngine::isMonsterAlreadyFighting(int16 monsterId, int16 teamMonsterId) {
 	debugC(6, kDebugFight, "isMonsterAlreadyFighting %d %d", monsterId, teamMonsterId);
 
 	for (int counter = 0; counter < teamMonsterId; ++counter) {
-		if (_teamMonsterIdArray[counter] == monsterId)
+		if (_teamMonster[counter]._id == monsterId)
 			return true;
 	}
 	return false;
@@ -697,8 +697,8 @@ void EfhEngine::resetTeamMonsterEffects() {
 	debugC(6, kDebugFight, "resetTeamMonsterEffects");
 	for (uint ctrGroupId = 0; ctrGroupId < 5; ++ctrGroupId) {
 		for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-			_teamMonsterEffects[ctrGroupId]._effect[ctrMobsterId] = 0;
-			_teamMonsterEffects[ctrGroupId]._duration[ctrMobsterId] = 0;
+			_teamMonster[ctrGroupId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusNormal;
+			_teamMonster[ctrGroupId]._mobsterStatus[ctrMobsterId]._duration = 0;
 		}
 	}
 }
@@ -707,7 +707,7 @@ void EfhEngine::resetTeamMonsterIdArray() {
 	debugC(6, kDebugFight, "resetTeamMonsterIdArray");
 
 	for (int i = 0; i < 5; ++i) {
-		_teamMonsterIdArray[i] = -1;
+		_teamMonster[i]._id = -1;
 	}
 }
 
@@ -729,7 +729,7 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 		int16 charId = _teamChar[victimId - 1000]._id;
 		pronoun = _npcBuf[charId].getPronoun();
 	} else {
-		int16 charId = _teamMonsterIdArray[victimId];
+		int16 charId = _teamMonster[victimId]._id;
 		pronoun = _mapMonsters[_techId][charId].getPronoun();
 	}
 
@@ -750,10 +750,10 @@ void EfhEngine::getDeathTypeDescription(int16 victimId, int16 attackerId) {
 			else
 				deathType = _items[exclusiveItemId]._attackType + 1;
 		}
-	} else if (_teamMonsterIdArray[attackerId] == -1) {
+	} else if (_teamMonster[attackerId]._id == -1) {
 		deathType = 0;
 	} else {
-		int16 itemId = _mapMonsters[_techId][_teamMonsterIdArray[attackerId]]._weaponItemId;
+		int16 itemId = _mapMonsters[_techId][_teamMonster[attackerId]._id]._weaponItemId;
 		deathType = _items[itemId]._attackType + 1;
 	}
 
@@ -998,20 +998,20 @@ int16 EfhEngine::determineTeamTarget(int16 charId, int16 unkFied18Val, bool chec
 	do {
 		for (uint counter = 0; counter < 2; ++counter) {
 			drawCombatScreen(charId, true, false);
-			if (_teamMonsterIdArray[1] != -1)
+			if (_teamMonster[1]._id != -1)
 				displayBoxWithText("Select Monster Group:", 3, 0, false);
 
 			if (counter == 0)
 				displayFctFullScreen();
 		}
 
-		retVal = (_teamMonsterIdArray[1] == -1) ? 0 : selectMonsterGroup();
+		retVal = (_teamMonster[1]._id == -1) ? 0 : selectMonsterGroup();
 
 		if (!checkDistanceFl) {
 			if (retVal == 27) // Esc
 				retVal = 0;
 		} else if (retVal != 27) {
-			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonsterIdArray[retVal]);
+			int16 monsterGroupDistance = computeMonsterGroupDistance(_teamMonster[retVal]._id);
 			if (monsterGroupDistance > realRange) {
 				retVal = 27;
 				displayBoxWithText("That Group Is Out Of Range!", 3, 1, false);
@@ -1318,10 +1318,10 @@ void EfhEngine::displayEncounterInfo(bool whiteFl) {
 
 	int16 textPosY = 20;
 	for (uint counter = 0; counter < 5; ++counter) {
-		if (_teamMonsterIdArray[counter] == -1)
+		if (_teamMonster[counter]._id == -1)
 			continue;
 
-		int16 monsterDistance = computeMonsterGroupDistance(_teamMonsterIdArray[counter]);
+		int16 monsterDistance = computeMonsterGroupDistance(_teamMonster[counter]._id);
 		int16 mobsterCount = countMonsterGroupMembers(counter);
 		if (whiteFl)
 			setTextColorWhite();
@@ -1332,16 +1332,16 @@ void EfhEngine::displayEncounterInfo(bool whiteFl) {
 		Common::String buffer = Common::String::format("%c)", 'A' + counter);
 		displayStringAtTextPos(buffer);
 		setTextColorRed();
-		int16 var1 = _mapMonsters[_techId][_teamMonsterIdArray[counter]]._possessivePronounSHL6 & 0x3F;
+		int16 var1 = _mapMonsters[_techId][_teamMonster[counter]._id]._possessivePronounSHL6 & 0x3F;
 		if (var1 <= 0x3D) {
-			buffer = Common::String::format("%d %s", mobsterCount, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[counter]]._monsterRef]._name);
+			buffer = Common::String::format("%d %s", mobsterCount, kEncounters[_mapMonsters[_techId][_teamMonster[counter]._id]._monsterRef]._name);
 			displayStringAtTextPos(buffer);
 			if (mobsterCount > 1)
 				displayStringAtTextPos("s");
 		} else if (var1 == 0x3E) {
 			displayStringAtTextPos("(NOT DEFINED)");
 		} else if (var1 == 0x3F) {
-			Common::String stringToDisplay = _npcBuf[_mapMonsters[_techId][_teamMonsterIdArray[counter]]._npcId]._name;
+			Common::String stringToDisplay = _npcBuf[_mapMonsters[_techId][_teamMonster[counter]._id]._npcId]._name;
 			displayStringAtTextPos(stringToDisplay);
 		}
 
@@ -1378,7 +1378,7 @@ int16 EfhEngine::getWeakestMobster(int16 groupNumber) {
 	debugC(3, kDebugFight, "getWeakestMobster %d", groupNumber);
 
 	int16 weakestMobsterId = -1;
-	int16 monsterId = _teamMonsterIdArray[groupNumber];
+	int16 monsterId = _teamMonster[groupNumber]._id;
 
 	if (monsterId == -1)
 		return -1;
@@ -1545,28 +1545,28 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 			continue;
 
 		for (uint ctrMobster = 0; ctrMobster < 9; ++ctrMobster) {
-			_mapMonsters[_techId][_teamMonsterIdArray[ctrGroupId]]._hitPoints[ctrMobster] = 0;
-			_teamMonsterEffects[ctrGroupId]._effect[ctrMobster] = 0;
-			_teamMonsterEffects[ctrGroupId]._duration[ctrMobster] = 0;
+			_mapMonsters[_techId][_teamMonster[ctrGroupId]._id]._hitPoints[ctrMobster] = 0;
+			_teamMonster[ctrGroupId]._mobsterStatus[ctrMobster]._type = kEfhStatusNormal;
+			_teamMonster[ctrGroupId]._mobsterStatus[ctrMobster]._duration = 0;
 		}
 
-		_teamMonsterIdArray[ctrGroupId] = -1;
+		_teamMonster[ctrGroupId]._id = -1;
 
 		// CHECKME: ctrGroupId is not incrementing, which is very, very suspicious as we are copying over and over to the same destination
 		// if the purpose is compact the array, it should be handle differently
 		for (uint counter2 = ctrGroupId + 1; counter2 < 5; ++counter2) {
 			for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-				_teamMonsterEffects[ctrGroupId]._effect[ctrMobsterId] = _teamMonsterEffects[counter2]._effect[ctrMobsterId];
-				_teamMonsterEffects[ctrGroupId]._duration[ctrMobsterId] = _teamMonsterEffects[counter2]._duration[ctrMobsterId];
+				_teamMonster[ctrGroupId]._mobsterStatus[ctrMobsterId]._type = _teamMonster[counter2]._mobsterStatus[ctrMobsterId]._type;
+				_teamMonster[ctrGroupId]._mobsterStatus[ctrMobsterId]._duration = _teamMonster[counter2]._mobsterStatus[ctrMobsterId]._duration;
 			}
-			_teamMonsterIdArray[ctrGroupId] = _teamMonsterIdArray[counter2];
+			_teamMonster[ctrGroupId]._id = _teamMonster[counter2]._id;
 		}
 	}
 	// addNewOpponents - 1rst loop counter1_monsterId - End
 
 	int16 teamMonsterId = -1;
 	for (uint counter1 = 0; counter1 < 5; ++counter1) {
-		if (_teamMonsterIdArray[counter1] == -1) {
+		if (_teamMonster[counter1]._id == -1) {
 			teamMonsterId = counter1;
 			break;
 		}
@@ -1601,13 +1601,13 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 						if (isMonsterAlreadyFighting(ctrMapMonsterId, teamMonsterId))
 							continue;
 
-						_teamMonsterIdArray[teamMonsterId] = ctrMapMonsterId;
+						_teamMonster[teamMonsterId]._id = ctrMapMonsterId;
 
 						// The original at this point was doing a loop on counter1, which is not a good idea as
 						// it was resetting the counter1 to 9 whatever its value before the loop.
 						// I therefore decided to use another counter as it looks like an original misbehavior/bug.
 						for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-							_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 0;
+							_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusNormal;
 						}
 
 						if (++teamMonsterId >= 5)
@@ -1624,9 +1624,9 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 
 	// addNewOpponents - last loop counter1_monsterId - Start
 	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
-		_teamMonsterIdArray[ctrTeamMonsterId] = -1;
+		_teamMonster[ctrTeamMonsterId]._id = -1;
 		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-			_teamMonsterEffects[ctrTeamMonsterId]._effect[ctrEffectId] = (int16)0x8000;
+			_teamMonster[ctrTeamMonsterId]._mobsterStatus[ctrEffectId]._type = (int16)0x8000;
 		}
 	}
 	// addNewOpponents - last loop counter1_monsterId - End
@@ -1637,7 +1637,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 
 	int16 retVal = 0xFF;
 	for (uint counter = 0; counter < 5; ++counter) {
-		int16 monsterId = _teamMonsterIdArray[counter];
+		int16 monsterId = _teamMonster[counter]._id;
 		if (monsterId == -1)
 			continue;
 
@@ -1649,7 +1649,7 @@ int16 EfhEngine::getTeamMonsterAnimId() {
 	}
 
 	if (retVal == 0xFF)
-		retVal = kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[0]]._monsterRef]._animId;
+		retVal = kEncounters[_mapMonsters[_techId][_teamMonster[0]._id]._monsterRef]._animId;
 
 	return retVal;
 }
@@ -1671,7 +1671,7 @@ int16 EfhEngine::selectMonsterGroup() {
 		case Common::KEYCODE_d:
 		case Common::KEYCODE_e:
 			retVal = input - Common::KEYCODE_a;
-			if (_teamMonsterIdArray[retVal] == -1)
+			if (_teamMonster[retVal]._id == -1)
 				retVal = -1;
 			break;
 		default:
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 59b2ff80cfc..37c13d0c43d 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -201,10 +201,11 @@ uint8 MapMonster::getPronoun() {
 	return _possessivePronounSHL6 >> 6;
 }
 
-void TeamMonsterEffect::init() {
+void TeamMonster::init() {
+	_id = -1;
 	for (int ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-		_effect[ctrMobsterId] = 0;
-		_duration[ctrMobsterId] = 0;
+		_mobsterStatus[ctrMobsterId]._type = 0;
+		_mobsterStatus[ctrMobsterId]._duration = 0;
 	}
 }
 
@@ -318,8 +319,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	}
 
 	for (int i = 0; i < 5; ++i) {
-		_teamMonsterIdArray[i] = -1;
-		_teamMonsterEffects[i].init();
+		_teamMonster[i].init();
 	}
 
 	_teamSize = 1;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 3e9d586d279..087301cf043 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -908,8 +908,8 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				for (uint ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
 					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victims;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 1;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusSleeping;
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._duration = getRandom(8);
 					}
 				}
 			} else {
@@ -921,16 +921,16 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victims;
 						--NumberOfTargets;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 1;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusSleeping;
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._duration = getRandom(8);
 					}
 				}
 			}
 			// The original was duplicating this code in each branch of the previous random check.
 			if (victims > 1) {
-				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss fall asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s falls asleep!", victims, kEncounters[_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 		}
@@ -947,8 +947,8 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 				for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
 					if (isMonsterActive(teamMonsterId, ctrEffectId)) {
 						++victim;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrEffectId] = 2;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrEffectId] = getRandom(8);
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrEffectId]._type = kEfhStatusFrozen;
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrEffectId]._duration = getRandom(8);
 					}
 				}
 			} else {
@@ -960,17 +960,17 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 					if (isMonsterActive(teamMonsterId, ctrMobsterId)) {
 						++victim;
 						--varAC;
-						_teamMonsterEffects[teamMonsterId]._effect[ctrMobsterId] = 2;
-						_teamMonsterEffects[teamMonsterId]._duration[ctrMobsterId] = getRandom(8);
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._type = kEfhStatusFrozen;
+						_teamMonster[teamMonsterId]._mobsterStatus[ctrMobsterId]._duration = getRandom(8);
 					}
 				}
 			}
 			// <CHECKME>: This part is only present in the original in the case < 50, but for me
 			// it's missing in the other case as there's an effect (frozen enemies) but no feedback to the player
 			if (victim > 1) {
-				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %ss are frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._monsterRef]._name);
 			} else {
-				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._monsterRef]._name);
+				buffer1 = Common::String::format("%d %s is frozen in place!", victim, kEncounters[_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._monsterRef]._name);
 			}
 			_messageToBePrinted += buffer1;
 			// </CHECKME>
@@ -996,14 +996,14 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (getRandom(100) < 50) {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (getRandom(100) < 50) {
-						_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+						_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._hitPoints[counter] = 0;
 					}
 				}
 			} else {
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
 						if (getRandom(100) < 50) {
-							_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+							_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._hitPoints[counter] = 0;
 						}
 						break;
 					}
@@ -1019,13 +1019,13 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			if (getRandom(100) < 50) {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and all targeted die!";
 				for (uint counter = 0; counter < 9; ++counter) {
-					_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+					_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._hitPoints[counter] = 0;
 				}
 			} else {
 				_messageToBePrinted += "  A dark fiery whirlwind surrounds the poor victim...the power fades and one victim dies!";
 				for (uint counter = 0; counter < 9; ++counter) {
 					if (isMonsterActive(teamMonsterId, counter)) {
-						_mapMonsters[_techId][_teamMonsterIdArray[teamMonsterId]]._hitPoints[counter] = 0;
+						_mapMonsters[_techId][_teamMonster[teamMonsterId]._id]._hitPoints[counter] = 0;
 					}
 				}
 			}


Commit: 3a68ef3cf1a8167bd7f1121301e40a498aabe3f7
    https://github.com/scummvm/scummvm/commit/3a68ef3cf1a8167bd7f1121301e40a498aabe3f7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:50+01:00

Commit Message:
EFH: Simplify code in addNewOpponents, add a comment in useObject() about the description of a cure to being frozen

Changed paths:
    engines/efh/fight.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp


diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index d53e2cb6f81..fb9372236f7 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -1622,14 +1622,9 @@ void EfhEngine::addNewOpponents(int16 monsterId) {
 	if (teamMonsterId == -1 || teamMonsterId > 4)
 		return;
 
-	// addNewOpponents - last loop counter1_monsterId - Start
-	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId) {
-		_teamMonster[ctrTeamMonsterId]._id = -1;
-		for (uint ctrEffectId = 0; ctrEffectId < 9; ++ctrEffectId) {
-			_teamMonster[ctrTeamMonsterId]._mobsterStatus[ctrEffectId]._type = (int16)0x8000;
-		}
-	}
-	// addNewOpponents - last loop counter1_monsterId - End
+	// Reset the unused groups
+	for (int16 ctrTeamMonsterId = teamMonsterId; ctrTeamMonsterId < 5; ++ctrTeamMonsterId)
+		_teamMonster[ctrTeamMonsterId].init();
 }
 
 int16 EfhEngine::getTeamMonsterAnimId() {
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index 37c13d0c43d..b93b8b49a6b 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -204,7 +204,7 @@ uint8 MapMonster::getPronoun() {
 void TeamMonster::init() {
 	_id = -1;
 	for (int ctrMobsterId = 0; ctrMobsterId < 9; ++ctrMobsterId) {
-		_mobsterStatus[ctrMobsterId]._type = 0;
+		_mobsterStatus[ctrMobsterId]._type = kEfhStatusNormal;
 		_mobsterStatus[ctrMobsterId]._duration = 0;
 	}
 }
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 087301cf043..61cd1fc3a3b 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1166,7 +1166,9 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		} else {
 			int16 teamCharId = teamMonsterId;
 			if (teamCharId != 0x1B) {
-				if (_teamChar[teamCharId]._status._type == kEfhStatusFrozen) { // frozen
+				if (_teamChar[teamCharId]._status._type == kEfhStatusFrozen) {
+					// The message is weird because it's a duplicate of case 28, which is about "curing" sleep... But it's about being frozen.
+					// We could improve the description, but that's the way the original deals with it
 					_messageToBePrinted += "  The item makes a loud noise, awakening the character!";
 					_teamChar[teamCharId]._status._type = kEfhStatusNormal;
 					_teamChar[teamCharId]._status._duration = 0;


Commit: 9c02a5b55f0c2c9fb2b47c9b38f4703ad967a2b7
    https://github.com/scummvm/scummvm/commit/9c02a5b55f0c2c9fb2b47c9b38f4703ad967a2b7
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:50+01:00

Commit Message:
EFH: rename _tileBankSubFileArray, move teamChar initialization to its own init()

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/init.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index de0cdc44673..d3734cd694e 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -610,10 +610,10 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 		for (int16 counterX = minX; counterX <= maxX; ++counterX) {
 			if (largeMapFl) {
 				int16 curTile = _mapGameMaps[_techId][counterX][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[curTile], drawPosX, drawPosY);
+				displayRawDataAtPos(_tileBankSubFilesArray[curTile], drawPosX, drawPosY);
 			} else {
 				int16 curTile = _curPlace[counterX][counterY];
-				displayRawDataAtPos(_imageSetSubFilesArray[curTile], drawPosX, drawPosY);
+				displayRawDataAtPos(_tileBankSubFilesArray[curTile], drawPosX, drawPosY);
 			}
 			drawPosX += 16;
 		}
@@ -624,7 +624,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 		// Draw hero
 		int16 drawPosX = 128 + shiftPosX * 16;
 		drawPosY = 8 + shiftPosY * 16;
-		displayRawDataAtPos(_imageSetSubFilesArray[_imageSetSubFilesIdx], drawPosX, drawPosY);
+		displayRawDataAtPos(_tileBankSubFilesArray[_imageSetSubFilesIdx], drawPosX, drawPosY);
 	}
 
 	if (drawMonstersFl) {
@@ -653,7 +653,7 @@ void EfhEngine::drawMap(bool largeMapFl, int16 mapPosX, int16 mapPosY, int16 map
 
 				int16 drawPosX = 128 + (posX - minX) * 16;
 				drawPosY = 8 + (posY - minY) * 16;
-				displayRawDataAtPos(_imageSetSubFilesArray[imageSetIdx], drawPosX, drawPosY);
+				displayRawDataAtPos(_tileBankSubFilesArray[imageSetIdx], drawPosX, drawPosY);
 			}
 		}
 	}
@@ -2447,7 +2447,7 @@ void EfhEngine::loadImageSetToTileBank(int16 tileBankId, int16 imageSetId) {
 		_mapBitmapRefArr[_techId]._setId2 = setId;
 
 	int16 ptrIndex = bankId * 72;
-	loadImageSet(setId, _tileBank[bankId], &_imageSetSubFilesArray[ptrIndex], _decompBuf);
+	loadImageSet(setId, _tileBank[bankId], &_tileBankSubFilesArray[ptrIndex], _decompBuf);
 }
 
 void EfhEngine::restoreAnimImageSetId() {
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index f402f5d5247..0d790c87bd7 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -246,6 +246,8 @@ struct TeamChar {
 	int16 _nextAttack;
 	int16 _lastInventoryUsed;
 	int16 _lastAction;
+
+	void init();
 };
 
 struct TeamMonster {
@@ -570,7 +572,7 @@ private:
 	int16 _animImageSetId;
 	uint8 _paletteTransformationConstant;
 	uint8 *_circleImageSubFileArray[12];
-	uint8 *_imageSetSubFilesArray[214]; // CHECKME : logically it should be 216
+	uint8 *_tileBankSubFilesArray[214]; // CHECKME : logically it should be 216
 	BufferBM _imageDataPtr;
 	int16 _currentTileBankImageSetId[3];
 	int16 _unkRelatedToAnimImageSetId;
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index b93b8b49a6b..cce48b89214 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -217,6 +217,17 @@ void TileFactStruct::init() {
 	_field0 = _tileId = 0;
 }
 
+void TeamChar::init() {
+	_id = -1;
+	_status._type = kEfhStatusNormal;
+	_status._duration = 0;
+	_pctVisible = 0;
+	_pctDodgeMiss = 0;
+	_nextAttack = -1;
+	_lastInventoryUsed = 0;
+	_lastAction = 0;
+}
+
 EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst), _gameDescription(gd) {
 	const Common::FSNode gameDataDir(ConfMan.get("path"));
 
@@ -305,18 +316,11 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 	_guessAnimationAmount = 9;
 	_largeMapFlag = 0xFFFF;
 	_alertDelay = 0;
+
+	for (int i = 0; i < 3; ++i)
+		_teamChar[i].init();
+
 	_teamChar[0]._id = 0;
-	_teamChar[1]._id = _teamChar[2]._id = -1;
-
-	for (int i = 0; i < 3; ++i) {
-		_teamChar[i]._status._type = kEfhStatusNormal;
-		_teamChar[i]._status._duration = 0;
-		_teamChar[i]._pctVisible = 0;
-		_teamChar[i]._pctDodgeMiss = 0;
-		_teamChar[i]._nextAttack = -1;
-		_teamChar[i]._lastInventoryUsed = 0;
-		_teamChar[i]._lastAction = 0;
-	}
 
 	for (int i = 0; i < 5; ++i) {
 		_teamMonster[i].init();
@@ -380,7 +384,7 @@ EfhEngine::EfhEngine(OSystem *syst, const ADGameDescription *gd) : Engine(syst),
 		memset(_mapMonsters[i], 0, ARRAYSIZE(_mapMonsters[i]));
 		memset(_mapGameMaps[i], 0, ARRAYSIZE(_mapGameMaps[i]));
 	}
-	memset(_imageSetSubFilesArray, 0, ARRAYSIZE(_imageSetSubFilesArray));
+	memset(_tileBankSubFilesArray, 0, ARRAYSIZE(_tileBankSubFilesArray));
 	_regenCounter = 0;
 
 	// If requested, load a savegame instead of showing the intro


Commit: a24acf909de73f985de6fa88b170911635eb8f51
    https://github.com/scummvm/scummvm/commit/a24acf909de73f985de6fa88b170911635eb8f51
Author: Strangerke (arnaud.boutonne at gmail.com)
Date: 2023-02-05T21:30:50+01:00

Commit Message:
EFH: Some renaming and comments

Changed paths:
    engines/efh/efh.cpp
    engines/efh/efh.h
    engines/efh/fight.cpp
    engines/efh/files.cpp
    engines/efh/graphics.cpp
    engines/efh/init.cpp
    engines/efh/menu.cpp
    engines/efh/savegames.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index d3734cd694e..96850e94d6d 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -2055,35 +2055,35 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 		if (imageSetId != -1 && *_imp2PtrArray[imageSetId] != 0x30)
 			displayMiddleLeftTempText(_imp2PtrArray[imageSetId], true);
 	} else if (arg8 == 0) {
-		if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFF) {
+		if (_mapSpecialTiles[_techId][tileId]._triggerType == 0xFF) {
 			displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 			return true;
 		}
 
-		if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFE) {
+		if (_mapSpecialTiles[_techId][tileId]._triggerType == 0xFE) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamChar[counter]._id == -1)
 					continue;
-				if (_teamChar[counter]._id == _mapSpecialTiles[_techId][tileId]._triggerId) {
+				if (_teamChar[counter]._id == _mapSpecialTiles[_techId][tileId]._triggerValue) {
 					displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 					return true;
 				}
 			}
-		} else if (_mapSpecialTiles[_techId][tileId]._field3 == 0xFD) {
+		} else if (_mapSpecialTiles[_techId][tileId]._triggerType == 0xFD) {
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamChar[counter]._id == -1)
 					continue;
 
 				for (uint var2 = 0; var2 < 10; ++var2) {
-					if (_npcBuf[_teamChar[counter]._id]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerId) {
+					if (_npcBuf[_teamChar[counter]._id]._inventory[var2]._ref == _mapSpecialTiles[_techId][tileId]._triggerValue) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
-		// original makes a useless check on (_mapSpecialTile[tileId]._field3 > 0x7F)
-		} else if (_mapSpecialTiles[_techId][tileId]._field3 <= 0x77) {
-			int16 scoreId = _mapSpecialTiles[_techId][tileId]._field3;
+		// original makes a useless check on (_mapSpecialTile[tileId]._triggerType > 0x7F)
+		} else if (_mapSpecialTiles[_techId][tileId]._triggerType <= 0x77) {
+			int16 scoreId = _mapSpecialTiles[_techId][tileId]._triggerType;
 			for (int counter = 0; counter < _teamSize; ++counter) {
 				if (_teamChar[counter]._id == -1)
 					continue;
@@ -2092,25 +2092,26 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 					// CHECKME : the whole loop doesn't make much sense as it's using scoreId instead of var2, plus _activeScore is an array of 15 bytes, not 0x77...
 					// Also, 39 correspond to the size of activeScore + passiveScore + infoScore + the 2 remaining bytes of the struct
 					warning("handleInteractionText - _activeScore[%d]", scoreId);
-					if (_npcBuf[_teamChar[counter]._id]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerId) {
+					if (_npcBuf[_teamChar[counter]._id]._activeScore[scoreId] >= _mapSpecialTiles[_techId][tileId]._triggerValue) {
 						displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 						return true;
 					}
 				}
 			}
 		}
-	} else if ((_mapSpecialTiles[_techId][tileId]._field3 == 0xFA && arg8 == 1) || (_mapSpecialTiles[_techId][tileId]._field3 == 0xFC && arg8 == 2) || (_mapSpecialTiles[_techId][tileId]._field3 == 0xFB && arg8 == 3)) {
-		if (_mapSpecialTiles[_techId][tileId]._triggerId == itemId) {
+	} else if ((_mapSpecialTiles[_techId][tileId]._triggerType == 0xFA && arg8 == 1) || (_mapSpecialTiles[_techId][tileId]._triggerType == 0xFC && arg8 == 2) || (_mapSpecialTiles[_techId][tileId]._triggerType == 0xFB && arg8 == 3)) {
+		if (_mapSpecialTiles[_techId][tileId]._triggerValue == itemId) {
 			displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 			return true;
 		}
 	} else if (arg8 == 4) {
-		int16 var6 = _mapSpecialTiles[_techId][tileId]._field3;
+		int16 var6 = _mapSpecialTiles[_techId][tileId]._triggerType;
 		if (var6 >= 0x78 && var6 <= 0xEF) {
 			var6 -= 0x78;
 			warning("handleInteractionText - _activeScore[%d]", var6);
-			// The 2 checks on var6 are useless, as [0x78..0xEF] - 0x78 => [0x00..0x77]
-			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTiles[_techId][tileId]._triggerId <= _npcBuf[charId]._activeScore[itemId]) {
+			// Note: The 2 checks on var6 are useless, as [0x78..0xEF] - 0x78 => [0x00..0x77]
+			// Note: In the data,all resulting values are between 2 and 14, so it's working
+			if (var6 >= 0 && var6 <= 0x8B && var6 == itemId && _mapSpecialTiles[_techId][tileId]._triggerValue <= _npcBuf[charId]._activeScore[itemId]) {
 				displayImp1Text(_mapSpecialTiles[_techId][tileId]._field5_textId);
 				return true;
 			}
@@ -2123,7 +2124,7 @@ bool EfhEngine::handleInteractionText(int16 mapPosX, int16 mapPosY, int16 charId
 	}
 
 	// CHECKME: there's suspiciously no check on tileId
-	if ((arg8 == 4 && _mapSpecialTiles[_techId][tileId]._field3 < 0xFA) || arg8 != 4) {
+	if ((arg8 == 4 && _mapSpecialTiles[_techId][tileId]._triggerType < 0xFA) || arg8 != 4) {
 		if (_mapSpecialTiles[_techId][tileId]._field7_textId > 0xFE)
 			return false;
 		displayImp1Text(_mapSpecialTiles[_techId][tileId]._field7_textId);
diff --git a/engines/efh/efh.h b/engines/efh/efh.h
index 0d790c87bd7..3bf5fbd7ad0 100644
--- a/engines/efh/efh.h
+++ b/engines/efh/efh.h
@@ -94,23 +94,23 @@ struct MapSpecialTileStruct {
 	uint8 _placeId;
 	uint8 _posX;
 	uint8 _posY;
-	uint8 _field3;
-	uint8 _triggerId;
+	uint8 _triggerType; // 0xFD = Check inventory 0xFE = Check Character in team 0xFF Display description <= 0x77 = check score (all values in this case in data are <= 0xF)
+	uint8 _triggerValue;
 	uint16 _field5_textId;
 	uint16 _field7_textId;
 
 	void init();
 };
 
-struct UnkAnimStruct {
-	int8 _field[4];
+struct FrameList {
+	int8 _subFileId[4];
 
 	void init();
 };
 struct AnimInfo {
-	UnkAnimStruct _unkAnimArray[15];
-	uint8 _field3C_startY[10];
-	uint16 _field46_startX[10];
+	uint16 _posX[10];
+	uint8 _posY[10];
+	FrameList _frameList[15];
 
 	void init();
 };
@@ -121,11 +121,11 @@ struct ItemStruct {
 	uint8 _defense;
 	uint8 _attacks;
 	uint8 _uses;
-	int8 field_13; // data contains values from -8 to +8
+	int8 _agilityModifier; // data contains values from -8 to +8
 	uint8 _range;
 	uint8 _attackType;
 	uint8 _specialEffect;
-	uint8 _field17_attackTypeDefense;
+	uint8 _defenseType;
 	uint8 _exclusiveType;
 	uint8 _field19_mapPosX_or_maxDeltaPoints;
 	uint8 _mapPosY;
diff --git a/engines/efh/fight.cpp b/engines/efh/fight.cpp
index fb9372236f7..c36361fb05b 100644
--- a/engines/efh/fight.cpp
+++ b/engines/efh/fight.cpp
@@ -504,7 +504,7 @@ void EfhEngine::handleFight_MobstersAttack(int groupId) {
 				int16 enemyPronoun = kEncounters[_mapMonsters[_techId][_teamMonster[groupId]._id]._monsterRef]._nameArticle;
 				int16 characterPronoun = _npcBuf[_teamChar[targetId]._id].getPronoun();
 
-				_teamChar[targetId]._pctDodgeMiss += (_items[monsterWeaponItemId].field_13 * 5);
+				_teamChar[targetId]._pctDodgeMiss += (_items[monsterWeaponItemId]._agilityModifier * 5);
 				int16 hitCount = 0;
 				int16 originalDamage = 0;
 				int16 damagePointsAbsorbed = 0;
@@ -1480,7 +1480,7 @@ int16 EfhEngine::getCharacterScore(int16 charId, int16 itemId) {
 		break;
 	}
 
-	extraScore += _items[itemId].field_13;
+	extraScore += _items[itemId]._agilityModifier;
 
 	int16 grandTotalScore = CLIP(totalScore + extraScore + 30, 5, 90);
 
@@ -1513,7 +1513,7 @@ bool EfhEngine::hasAdequateDefense(int16 monsterId, uint8 attackType) {
 	if (_items[itemId]._specialEffect != 0)
 		return false;
 
-	return _items[itemId]._field17_attackTypeDefense == attackType;
+	return _items[itemId]._defenseType == attackType;
 }
 
 bool EfhEngine::hasAdequateDefenseNPC(int16 charId, uint8 attackType) {
@@ -1521,7 +1521,7 @@ bool EfhEngine::hasAdequateDefenseNPC(int16 charId, uint8 attackType) {
 
 	int16 itemId = _npcBuf[charId]._defaultDefenseItemId;
 
-	if (_items[itemId]._specialEffect == 0 && _items[itemId]._field17_attackTypeDefense == attackType)
+	if (_items[itemId]._specialEffect == 0 && _items[itemId]._defenseType == attackType)
 		return true;
 
 	for (uint counter = 0; counter < 10; ++counter) {
@@ -1529,7 +1529,7 @@ bool EfhEngine::hasAdequateDefenseNPC(int16 charId, uint8 attackType) {
 			continue;
 
 		itemId = _npcBuf[charId]._inventory[counter]._ref;
-		if (_items[itemId]._specialEffect == 0 && _items[itemId]._field17_attackTypeDefense == attackType)
+		if (_items[itemId]._specialEffect == 0 && _items[itemId]._defenseType == attackType)
 			return true;
 	}
 	return false;
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 909e41be2cf..3ab9ffa1ad4 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -45,27 +45,28 @@ void EfhEngine::readAnimInfo() {
 
 	for (int i = 0; i < 100; ++i) {
 		for (int id = 0; id < 15; ++id) {
-			_animInfo[i]._unkAnimArray[id]._field[0] = f.readByte();
-			_animInfo[i]._unkAnimArray[id]._field[1] = f.readByte();
-			_animInfo[i]._unkAnimArray[id]._field[2] = f.readByte();
-			_animInfo[i]._unkAnimArray[id]._field[3] = f.readByte();
+			Common::String txtBuffer = "->";
+			for (int frameId = 0; frameId < 4; ++frameId) {
+				_animInfo[i]._frameList[id]._subFileId[frameId] = f.readByte();
+				txtBuffer += Common::String::format(" %d", _animInfo[i]._frameList[id]._subFileId[frameId]);
+			}
 
-			debugC(6, kDebugEngine, "%d %d %d %d", _animInfo[i]._unkAnimArray[id]._field[0], _animInfo[i]._unkAnimArray[id]._field[1], _animInfo[i]._unkAnimArray[id]._field[2], _animInfo[i]._unkAnimArray[id]._field[3]);
+			debugC(6, kDebugEngine, txtBuffer.c_str());
 		}
 
 		Common::String debugStr = "";
 		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field3C_startY[id] = f.readByte();
-			debugStr += Common::String::format("%d ", _animInfo[i]._field3C_startY[id]);
+			_animInfo[i]._posY[id] = f.readByte();
+			debugStr += Common::String::format("%d ", _animInfo[i]._posY[id]);
 		}
-		debugC(6, kDebugEngine, "%s", debugStr.c_str());
+		debugC(6, kDebugEngine, debugStr.c_str());
 
 		debugStr = "";
 		for (int id = 0; id < 10; ++id) {
-			_animInfo[i]._field46_startX[id] = f.readUint16LE();
-			debugStr += Common::String::format("%d ", _animInfo[i]._field46_startX[id]);
+			_animInfo[i]._posX[id] = f.readUint16LE();
+			debugStr += Common::String::format("%d ", _animInfo[i]._posX[id]);
 		}
-		debugC(6, kDebugEngine, "%s", debugStr.c_str());
+		debugC(6, kDebugEngine, debugStr.c_str());
 		debugC(6, kDebugEngine, "---------");
 	}
 }
@@ -144,16 +145,16 @@ void EfhEngine::readItems() {
 		_items[i]._defense = f.readByte();
 		_items[i]._attacks = f.readByte();
 		_items[i]._uses = f.readByte();
-		_items[i].field_13 = f.readByte();
+		_items[i]._agilityModifier = f.readByte();
 		_items[i]._range = f.readByte();
 		_items[i]._attackType = f.readByte();
 		_items[i]._specialEffect = f.readByte();
-		_items[i]._field17_attackTypeDefense = f.readByte();
+		_items[i]._defenseType = f.readByte();
 		_items[i]._exclusiveType = f.readByte();
 		_items[i]._field19_mapPosX_or_maxDeltaPoints = f.readByte();
 		_items[i]._mapPosY = f.readByte();
 
-		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i].field_13, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i]._field17_attackTypeDefense, _items[i]._exclusiveType, _items[i]._field19_mapPosX_or_maxDeltaPoints, _items[i]._mapPosY);
+		debugC(7, kDebugEngine, "%s\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x\t%x", _items[i]._name, _items[i]._damage, _items[i]._defense, _items[i]._attacks, _items[i]._uses, _items[i]._agilityModifier, _items[i]._range, _items[i]._attackType, _items[i]._specialEffect, _items[i]._defenseType, _items[i]._exclusiveType, _items[i]._field19_mapPosX_or_maxDeltaPoints, _items[i]._mapPosY);
 	}
 }
 
@@ -323,9 +324,8 @@ void EfhEngine::loadNPCS() {
  */
 void EfhEngine::preLoadMaps() {
 	Common::DumpFile dump;
-	if (ConfMan.getBool("dump_scripts")) {
+	if (ConfMan.getBool("dump_scripts"))
 		dump.open("efhMaps.dump");
-	}
 
 	for (int idx = 0; idx < 19; ++idx) {
 		Common::String fileName = Common::String::format("tech.%d", idx);
@@ -345,16 +345,16 @@ void EfhEngine::preLoadMaps() {
 			_mapSpecialTiles[idx][i]._placeId = mapSpecialTilePtr[9 * i];
 			_mapSpecialTiles[idx][i]._posX = mapSpecialTilePtr[9 * i + 1];
 			_mapSpecialTiles[idx][i]._posY = mapSpecialTilePtr[9 * i + 2];
-			_mapSpecialTiles[idx][i]._field3 = mapSpecialTilePtr[9 * i + 3];
-			_mapSpecialTiles[idx][i]._triggerId = mapSpecialTilePtr[9 * i + 4];
+			_mapSpecialTiles[idx][i]._triggerType = mapSpecialTilePtr[9 * i + 3];
+			_mapSpecialTiles[idx][i]._triggerValue = mapSpecialTilePtr[9 * i + 4];
 			_mapSpecialTiles[idx][i]._field5_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 5]);
 			_mapSpecialTiles[idx][i]._field7_textId = READ_LE_UINT16(&mapSpecialTilePtr[9 * i + 7]);
 
 			if (ConfMan.getBool("dump_scripts") && _mapSpecialTiles[idx][i]._placeId != 0xFF) {
 				// dump a decoded version of the maps
-				Common::String buffer = Common::String::format("[%d][%d] _ placeId: 0x%02X _pos: %d, %d _field3: 0x%02X (%d), triggerId: %d, _field5/7: %d %d\n"
-					, idx, i, _mapSpecialTiles[idx][i]._placeId, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._field3
-					, _mapSpecialTiles[idx][i]._field3, _mapSpecialTiles[idx][i]._triggerId, _mapSpecialTiles[idx][i]._field5_textId, _mapSpecialTiles[idx][i]._field7_textId);
+				Common::String buffer = Common::String::format("[%d][%d] _ placeId: 0x%02X _pos: %d, %d _triggerType: 0x%02X (%d), triggerId: %d, _field5/7: %d %d\n"
+					, idx, i, _mapSpecialTiles[idx][i]._placeId, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._posX, _mapSpecialTiles[idx][i]._triggerType
+					, _mapSpecialTiles[idx][i]._triggerType, _mapSpecialTiles[idx][i]._triggerValue, _mapSpecialTiles[idx][i]._field5_textId, _mapSpecialTiles[idx][i]._field7_textId);
 				dump.write(buffer.c_str(), buffer.size());
 			}
 		}
diff --git a/engines/efh/graphics.cpp b/engines/efh/graphics.cpp
index 2ac0736e1b4..7460a660f3b 100644
--- a/engines/efh/graphics.cpp
+++ b/engines/efh/graphics.cpp
@@ -79,10 +79,10 @@ void EfhEngine::displayAnimFrame() {
 
 	displayRawDataAtPos(_portraitSubFilesArray[0], 16, 8);
 	for (int i = 0; i < 4; ++i) {
-		int8 var2 = _animInfo[_animImageSetId]._unkAnimArray[_unkAnimRelatedIndex]._field[i];
+		int8 var2 = _animInfo[_animImageSetId]._frameList[_unkAnimRelatedIndex]._subFileId[i];
 		if (var2 == -1)
 			continue;
-		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._field46_startX[var2] + 16, _animInfo[_animImageSetId]._field3C_startY[var2] + 8);
+		displayRawDataAtPos(_portraitSubFilesArray[var2 + 1], _animInfo[_animImageSetId]._posX[var2] + 16, _animInfo[_animImageSetId]._posY[var2] + 8);
 	}
 }
 
diff --git a/engines/efh/init.cpp b/engines/efh/init.cpp
index cce48b89214..448650c7201 100644
--- a/engines/efh/init.cpp
+++ b/engines/efh/init.cpp
@@ -45,22 +45,23 @@ void InvObject::init() {
 }
 
 void MapSpecialTileStruct::init() {
-	_placeId = _posX = _posY = _field3 = _triggerId = 0;
+	_placeId = _posX = _posY = _triggerType = _triggerValue = 0;
 	_field5_textId = _field7_textId = 0;
 }
 
-void UnkAnimStruct::init() {
-	memset(_field, 0, 4);
+void FrameList::init() {
+	for (int i = 0; i < 4; ++i)
+		_subFileId[i] = -1;
 }
 
 void AnimInfo::init() {
-	for (int i = 0; i < 15; ++i)
-		_unkAnimArray[i].init();
-
 	for (int i = 0; i < 10; ++i) {
-		_field3C_startY[i] = 0;
-		_field46_startX[i] = 0;
+		_posX[i] = 0;
+		_posY[i] = 0;
 	}
+
+	for (int i = 0; i < 15; ++i)
+		_frameList[i].init();
 }
 
 void ItemStruct::init() {
@@ -71,11 +72,11 @@ void ItemStruct::init() {
 	_defense = 0;
 	_attacks = 0;
 	_uses = 0;
-	field_13 = 0;
+	_agilityModifier = 0;
 	_range = 0;
 	_attackType = 0;
 	_specialEffect = 0;
-	_field17_attackTypeDefense = 0;
+	_defenseType = 0;
 	_exclusiveType = 0;
 	_field19_mapPosX_or_maxDeltaPoints = 0;
 	_mapPosY = 0;
diff --git a/engines/efh/menu.cpp b/engines/efh/menu.cpp
index 61cd1fc3a3b..a939521a005 100644
--- a/engines/efh/menu.cpp
+++ b/engines/efh/menu.cpp
@@ -1038,7 +1038,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			displayStringInSmallWindowWithBorder("There is no apparent affect!", false, charId, teamMonsterId, menuId, curMenuLine);
 		} else {
 			_messageToBePrinted += "  The magic sparkles brilliant hues in the air!";
-			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._field17_attackTypeDefense);
+			setMapMonsterAggressivenessAndMovementType(teamMonsterId, _items[itemId]._defenseType);
 		}
 		objectUsedFl = true;
 		break;
@@ -1236,7 +1236,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
+			uint8 varAE = _items[itemId]._defenseType;
 			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
 			_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] += effectPoints;
 			if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20) {
@@ -1266,7 +1266,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 			teamCharId = teamMonsterId;
 
 		if (teamCharId != 0x1B) {
-			uint8 varAE = _items[itemId]._field17_attackTypeDefense;
+			uint8 varAE = _items[itemId]._defenseType;
 			uint8 effectPoints = getRandom(_items[itemId]._field19_mapPosX_or_maxDeltaPoints);
 			_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] -= effectPoints;
 			if (_npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] > 20 || _npcBuf[_teamChar[teamCharId]._id]._activeScore[varAE] < 0) {
@@ -1348,7 +1348,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 
 		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
+			int16 effectPoints = getRandom(_items[itemId]._defenseType);
 			_npcBuf[_teamChar[teamCharId]._id]._hitPoints += effectPoints;
 			if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints > _npcBuf[_teamChar[teamCharId]._id]._maxHP)
 				_npcBuf[_teamChar[teamCharId]._id]._hitPoints = _npcBuf[_teamChar[teamCharId]._id]._maxHP;
@@ -1378,7 +1378,7 @@ int16 EfhEngine::useObject(int16 charId, int16 objectId, int16 teamMonsterId, in
 		}
 
 		if (teamCharId != 0x1B) {
-			int16 effectPoints = getRandom(_items[itemId]._field17_attackTypeDefense);
+			int16 effectPoints = getRandom(_items[itemId]._defenseType);
 			_npcBuf[_teamChar[teamCharId]._id]._hitPoints -= effectPoints;
 			if (_npcBuf[_teamChar[teamCharId]._id]._hitPoints < 0)
 				_npcBuf[_teamChar[teamCharId]._id]._hitPoints = 0;
diff --git a/engines/efh/savegames.cpp b/engines/efh/savegames.cpp
index b0045e64a8b..33ab3d7fa29 100644
--- a/engines/efh/savegames.cpp
+++ b/engines/efh/savegames.cpp
@@ -157,8 +157,8 @@ void EfhEngine::synchronize(Common::Serializer &s) {
 			s.syncAsByte(_mapSpecialTiles[i][idx]._placeId);
 			s.syncAsByte(_mapSpecialTiles[i][idx]._posX);
 			s.syncAsByte(_mapSpecialTiles[i][idx]._posY);
-			s.syncAsByte(_mapSpecialTiles[i][idx]._field3);
-			s.syncAsByte(_mapSpecialTiles[i][idx]._triggerId);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._triggerType);
+			s.syncAsByte(_mapSpecialTiles[i][idx]._triggerValue);
 			s.syncAsUint16LE(_mapSpecialTiles[i][idx]._field5_textId);
 			s.syncAsUint16LE(_mapSpecialTiles[i][idx]._field7_textId);
 		}


Commit: c28da3a729c4df1b265e264f8595f7c94eaa5124
    https://github.com/scummvm/scummvm/commit/c28da3a729c4df1b265e264f8595f7c94eaa5124
Author: Eugene Sandulenko (sev at scummvm.org)
Date: 2023-02-05T21:33:55+01:00

Commit Message:
EFH: Fix warnings

Changed paths:
    engines/efh/efh.cpp
    engines/efh/files.cpp


diff --git a/engines/efh/efh.cpp b/engines/efh/efh.cpp
index 96850e94d6d..5c167b68172 100644
--- a/engines/efh/efh.cpp
+++ b/engines/efh/efh.cpp
@@ -50,7 +50,7 @@ int8 InvObject::getUsesLeft() {
 EfhEngine::~EfhEngine() {
 	_mainSurface->free();
 	delete _mainSurface;
-	
+
 	delete _rnd;
 	delete _graphicsStruct;
 	delete _vgaGraphicsStruct1;
@@ -467,7 +467,7 @@ void EfhEngine::initMapMonsters() {
 
 		if (groupSize == 0)
 			continue;
-		
+
 		for (uint counter = 0; counter < groupSize; ++counter) {
 			uint rand100 = getRandom(100);
 			uint16 pictureRef = kEncounters[curMons->_monsterRef]._pictureRef;
@@ -484,7 +484,7 @@ void EfhEngine::initMapMonsters() {
 }
 
 void EfhEngine::loadMapArrays(int idx) {
-	// No longer required as everything is in memory. 
+	// No longer required as everything is in memory.
 }
 
 void EfhEngine::saveAnimImageSetId() {
@@ -495,7 +495,7 @@ void EfhEngine::saveAnimImageSetId() {
 }
 
 int16 EfhEngine::getEquipmentDefense(int16 charId) {
-	debugC(2, kDebugGraphics, "getEquipmentDefense %d %s", charId);
+	debugC(2, kDebugGraphics, "getEquipmentDefense %d", charId);
 
 	int16 altDef = 0;
 
@@ -1082,7 +1082,7 @@ int16 EfhEngine::findMapSpecialTileIndex(int16 posX, int16 posY) {
 	debugC(5, kDebugEngine, "findMapSpecialTileIndex %d %d", posX, posY);
 
 	uint16 searchPlaceId = _largeMapFlag ? 0xFE : _fullPlaceId;
-	
+
 	for (uint counter = 0; counter < 100; ++counter) {
 		MapSpecialTileStruct *curTile = &_mapSpecialTiles[_techId][counter];
 		if (curTile->_posX == posX && curTile->_posY == posY && curTile->_placeId == searchPlaceId)
@@ -2001,7 +2001,7 @@ void EfhEngine::displayImp1Text(int16 textId) {
 					maxReached = false;
 					stringIdx = 0;
 					charCounter = 0;
-					uint8 firstChar = _messageToBePrinted.firstChar(); 
+					uint8 firstChar = _messageToBePrinted.firstChar();
 					if (firstChar == 0x5E || firstChar == 0) {
 						if (firstChar == 0x5E) {
 							nextTextId = script_parse(_messageToBePrinted, 0, 0, 319, 199, true);
@@ -2319,7 +2319,7 @@ bool EfhEngine::checkMonsterCollision() {
 			continue;
 
 		MapMonster *curMapMonst = &_mapMonsters[_techId][monsterId];
-	
+
 		if (!(_largeMapFlag && curMapMonst->_fullPlaceId == 0xFE) && !(!_largeMapFlag && curMapMonst->_fullPlaceId == _fullPlaceId))
 			continue;
 
diff --git a/engines/efh/files.cpp b/engines/efh/files.cpp
index 3ab9ffa1ad4..a5e87fbc877 100644
--- a/engines/efh/files.cpp
+++ b/engines/efh/files.cpp
@@ -51,7 +51,7 @@ void EfhEngine::readAnimInfo() {
 				txtBuffer += Common::String::format(" %d", _animInfo[i]._frameList[id]._subFileId[frameId]);
 			}
 
-			debugC(6, kDebugEngine, txtBuffer.c_str());
+			debugC(6, kDebugEngine, "%s", txtBuffer.c_str());
 		}
 
 		Common::String debugStr = "";
@@ -59,14 +59,14 @@ void EfhEngine::readAnimInfo() {
 			_animInfo[i]._posY[id] = f.readByte();
 			debugStr += Common::String::format("%d ", _animInfo[i]._posY[id]);
 		}
-		debugC(6, kDebugEngine, debugStr.c_str());
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
 
 		debugStr = "";
 		for (int id = 0; id < 10; ++id) {
 			_animInfo[i]._posX[id] = f.readUint16LE();
 			debugStr += Common::String::format("%d ", _animInfo[i]._posX[id]);
 		}
-		debugC(6, kDebugEngine, debugStr.c_str());
+		debugC(6, kDebugEngine, "%s", debugStr.c_str());
 		debugC(6, kDebugEngine, "---------");
 	}
 }
@@ -390,4 +390,3 @@ void EfhEngine::preLoadMaps() {
 }
 
 } // End of namespace Efh
-




More information about the Scummvm-git-logs mailing list