[Scummvm-git-logs] scummvm master -> a3cfd1fabdfdf55fb5c0f6ef99fc975a0c59a0a3
dreammaster
noreply at scummvm.org
Sat Jun 10 23:03:12 UTC 2023
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a3cfd1fabd MM: XEEN: add hp and sp bars for QoL
Commit: a3cfd1fabdfdf55fb5c0f6ef99fc975a0c59a0a3
https://github.com/scummvm/scummvm/commit/a3cfd1fabdfdf55fb5c0f6ef99fc975a0c59a0a3
Author: Alexander Izmailov (yarolig at gmail.com)
Date: 2023-06-10T16:03:08-07:00
Commit Message:
MM: XEEN: add hp and sp bars for QoL
Changed paths:
engines/mm/detection.h
engines/mm/detection_tables.h
engines/mm/metaengine.cpp
engines/mm/xeen/interface.cpp
engines/mm/xeen/interface.h
engines/mm/xeen/xeen.cpp
engines/mm/xeen/xeen.h
diff --git a/engines/mm/detection.h b/engines/mm/detection.h
index df26fa4dc0f..3034a1568ee 100644
--- a/engines/mm/detection.h
+++ b/engines/mm/detection.h
@@ -49,6 +49,7 @@ struct MightAndMagicGameDescription {
#define GAMEOPTION_SHOW_ITEM_COSTS GUIO_GAMEOPTIONS1
#define GAMEOPTION_DURABLE_ARMOR GUIO_GAMEOPTIONS2
+#define GAMEOPTION_SHOW_HP_SP_BARS GUIO_GAMEOPTIONS3
} // namespace MM
diff --git a/engines/mm/detection_tables.h b/engines/mm/detection_tables.h
index e0e07e0ac8e..e83cdd4ab03 100644
--- a/engines/mm/detection_tables.h
+++ b/engines/mm/detection_tables.h
@@ -19,8 +19,13 @@
*
*/
+#include "engines/advancedDetector.h"
+#include "engines/mm/detection.h"
+
namespace MM {
+#define GUIO_XEEN GUIO3(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR, GAMEOPTION_SHOW_HP_SP_BARS)
+
static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
#ifdef ENABLE_MM1
{
@@ -82,7 +87,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -98,7 +103,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -118,7 +123,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -134,7 +139,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -150,7 +155,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_CD,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -167,7 +172,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::FR_FRA,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_WorldOfXeen,
0
@@ -182,7 +187,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Clouds,
0
@@ -197,7 +202,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Clouds,
0
@@ -212,7 +217,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::RU_RUS,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Clouds,
0
@@ -227,7 +232,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::ZH_TWN,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Clouds,
0
@@ -243,7 +248,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::FR_FRA,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Clouds,
0
@@ -258,7 +263,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_DarkSide,
0
@@ -273,7 +278,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_DarkSide,
0
@@ -289,7 +294,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::DE_DEU,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_DarkSide,
0
@@ -304,7 +309,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::ZH_TWN,
Common::kPlatformDOS,
ADGF_UNSTABLE,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_DarkSide,
0
@@ -320,7 +325,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::FR_FRA,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_DarkSide,
0
@@ -335,7 +340,7 @@ static const MightAndMagicGameDescription GAME_DESCRIPTIONS[] = {
Common::EN_ANY,
Common::kPlatformDOS,
ADGF_NO_FLAGS,
- GUIO2(GAMEOPTION_SHOW_ITEM_COSTS, GAMEOPTION_DURABLE_ARMOR)
+ GUIO_XEEN
},
GType_Swords,
0
diff --git a/engines/mm/metaengine.cpp b/engines/mm/metaengine.cpp
index 85a62110f25..cca674bcd96 100644
--- a/engines/mm/metaengine.cpp
+++ b/engines/mm/metaengine.cpp
@@ -39,6 +39,43 @@
#include "mm/xeen/swordsofxeen/swordsofxeen.h"
#endif
+static const ADExtraGuiOptionsMap optionsList[] = {
+ {
+ GAMEOPTION_SHOW_ITEM_COSTS,
+ {
+ _s("Show item costs in standard inventory mode"),
+ _s("Shows item costs in standard inventory mode, allowing the value of items to be compared"),
+ "ShowItemCosts",
+ false,
+ 0,
+ 0
+ }
+ },
+ {
+ GAMEOPTION_DURABLE_ARMOR,
+ {
+ _s("More durable armor"),
+ _s("Armor won't break until character is at -80HP, rather than merely -10HP"),
+ "DurableArmor",
+ false,
+ 0,
+ 0
+ }
+ },
+ {
+ GAMEOPTION_SHOW_HP_SP_BARS,
+ {
+ _s("Hitpoint bars"),
+ _s("Replace a colored gem with bars for hit points and spell points."),
+ "ShowHpSpBars",
+ false,
+ 0,
+ 0
+ }
+ },
+ AD_EXTRA_GUI_OPTIONS_TERMINATOR
+};
+
class MMMetaEngine : public AdvancedMetaEngine {
private:
/**
@@ -60,6 +97,10 @@ public:
SaveStateList listSaves(const char *target) const override;
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
Common::KeymapArray initKeymaps(const char *target) const override;
+
+ const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override {
+ return optionsList;
+ }
};
bool MMMetaEngine::hasFeature(MetaEngineFeature f) const {
diff --git a/engines/mm/xeen/interface.cpp b/engines/mm/xeen/interface.cpp
index ca9827128a0..7ea8bc2e3c9 100644
--- a/engines/mm/xeen/interface.cpp
+++ b/engines/mm/xeen/interface.cpp
@@ -51,12 +51,124 @@ PartyDrawer::PartyDrawer(XeenEngine *vm): _vm(vm) {
_hiliteChar = HILIGHT_CHAR_NONE;
}
+static inline int clipToFaceWidth(int i) {
+ const int faceWidth = 32;
+ return CLIP(i, 0, faceWidth);
+}
+
+static inline int unzero(int i) {
+ if (i) return i;
+ return 1;
+}
+
+void PartyDrawer::drawHitPoints(int charIndex) {
+ Combat &combat = *_vm->_combat;
+ Party &party = *_vm->_party;
+ Windows &windows = *_vm->_windows;
+ bool inCombat = _vm->_mode == MODE_COMBAT;
+ Window &win = windows[0];
+ Character &c = inCombat ? *combat._combatParty[charIndex] : party._activeParty[charIndex];
+
+ enum {
+ BLACK = 0,
+ STONE = 20,
+
+ BRIGHT_GREEN = 80,
+ GREEN = 85,
+ YELLOW = 55,
+ RED = 185,
+ DARK_BLUE = 78,
+
+ BRIGHT_BLUE = 70,
+ BLUE = 75
+ };
+
+ int hp = c._currentHp;
+ int sp = c._currentSp;
+
+ int maxHp = c.getMaxHP();
+ int maxSp = c.getMaxSP();
+
+ int gemFrame;
+ int hpColor = GREEN;
+
+ if (hp < 1) {
+ gemFrame = 4;
+ } else if (hp > maxHp) {
+ gemFrame = 3;
+ } else if (hp == maxHp) {
+ gemFrame = 0;
+ } else if (hp < (maxHp / 4)) {
+ gemFrame = 2;
+ hpColor = RED;
+ } else{
+ hpColor = YELLOW;
+ gemFrame = 1;
+ }
+ if (!g_vm->_extOptions._showHpSpBars) {
+ _hpSprites.draw(0, gemFrame, Common::Point(Res.HP_BARS_X[charIndex], 182));
+ } else {
+ const int faceWidth = 32;
+
+ const int barLeft = Res.CHAR_FACES_X[charIndex];
+ const int barRight = Res.CHAR_FACES_X[charIndex] + 32;
+ const int barHeight = 3;
+
+ const int frameTop = 183;
+ const int frameBottom = 190;
+ const int frameColor = STONE;
+ const int hpBarTop = 184;
+ const int hpBarBottom = hpBarTop + barHeight;
+
+ const int spBarTop = 188;
+ const int spBarBottom = spBarTop + barHeight;
+
+ int hpPart = clipToFaceWidth( (hp * faceWidth) / unzero(maxHp) );
+ int boostedHpPart = 0;
+ if (hp > maxHp) {
+ boostedHpPart = clipToFaceWidth(faceWidth * (hp - maxHp) / unzero(hp + maxHp) );
+ }
+
+ int spPart = clipToFaceWidth( (sp * faceWidth) / unzero(maxSp) );
+ int boostedSpPart = 0;
+ if (sp > maxSp) {
+ boostedSpPart = clipToFaceWidth( faceWidth * (sp - maxSp) / unzero(sp + maxSp) );
+ }
+
+ int negativeHpPart = 32;
+ if (hp < 0) {
+ negativeHpPart = faceWidth - clipToFaceWidth((-hp * faceWidth) / unzero(maxHp));
+ }
+
+ win.fillRect(Common::Rect(barLeft, frameTop, barRight, frameBottom), frameColor);
+
+ win.fillRect(Common::Rect(barLeft, hpBarTop, barRight, hpBarBottom), BLACK);
+ win.fillRect(Common::Rect(barLeft, hpBarTop, barLeft + hpPart, hpBarBottom), hpColor);
+ if (boostedHpPart != 0) {
+ win.fillRect(Common::Rect(barLeft, hpBarTop, barLeft + boostedHpPart, hpBarBottom), BRIGHT_GREEN);
+ }
+
+ if (negativeHpPart != 32) {
+ win.fillRect(Common::Rect(barLeft + negativeHpPart, hpBarTop, barLeft + faceWidth, hpBarBottom), DARK_BLUE);
+ }
+
+ if (maxSp != 0) {
+ win.fillRect(Common::Rect(barLeft, spBarTop, barRight, spBarBottom), BLACK);
+ win.fillRect(Common::Rect(barLeft, spBarTop, barLeft + spPart, spBarBottom), BLUE);
+ if (boostedSpPart) {
+ win.fillRect(Common::Rect(barLeft, spBarTop, barLeft + boostedSpPart, spBarBottom), BRIGHT_BLUE);
+ }
+ }
+ }
+}
+
void PartyDrawer::drawParty(bool updateFlag) {
Combat &combat = *_vm->_combat;
Party &party = *_vm->_party;
Resources &res = *_vm->_resources;
Windows &windows = *_vm->_windows;
bool inCombat = _vm->_mode == MODE_COMBAT;
+
_restoreSprites.draw(0, 0, Common::Point(8, 149));
// Handle drawing the party faces
@@ -75,23 +187,7 @@ void PartyDrawer::drawParty(bool updateFlag) {
}
for (uint idx = 0; idx < partyCount; ++idx) {
- Character &c = inCombat ? *combat._combatParty[idx] : party._activeParty[idx];
-
- // Draw the Hp bar
- int maxHp = c.getMaxHP();
- int frame;
- if (c._currentHp < 1)
- frame = 4;
- else if (c._currentHp > maxHp)
- frame = 3;
- else if (c._currentHp == maxHp)
- frame = 0;
- else if (c._currentHp < (maxHp / 4))
- frame = 2;
- else
- frame = 1;
-
- _hpSprites.draw(0, frame, Common::Point(Res.HP_BARS_X[idx], 182));
+ drawHitPoints(idx);
}
if (_hiliteChar != HILIGHT_CHAR_NONE)
@@ -533,6 +629,10 @@ void Interface::perform() {
if (CastSpell::show(_vm) != -1) {
chargeStep();
doStepCode();
+ // update spell point bar
+ if (g_vm->_extOptions._showHpSpBars) {
+ drawParty(true);
+ }
}
break;
@@ -1601,6 +1701,10 @@ void Interface::doCombat() {
// Cast spell
if (CastSpell::show(_vm) != -1) {
nextChar();
+ // update spell point bar
+ if (g_vm->_extOptions._showHpSpBars) {
+ drawParty(true);
+ }
} else {
highlightChar(combat._whosTurn);
}
diff --git a/engines/mm/xeen/interface.h b/engines/mm/xeen/interface.h
index ff3dd6bba8e..eda151c6a08 100644
--- a/engines/mm/xeen/interface.h
+++ b/engines/mm/xeen/interface.h
@@ -86,6 +86,9 @@ public:
void unhighlightChar();
void resetHighlight();
+
+private:
+ void drawHitPoints(int charIndex);
};
/**
diff --git a/engines/mm/xeen/xeen.cpp b/engines/mm/xeen/xeen.cpp
index c63c5c66c13..1799a4195e3 100644
--- a/engines/mm/xeen/xeen.cpp
+++ b/engines/mm/xeen/xeen.cpp
@@ -125,6 +125,7 @@ void XeenEngine::loadSettings() {
_extOptions._showItemCosts = ConfMan.hasKey("ShowItemCosts") && ConfMan.getBool("ShowItemCosts");
_extOptions._durableArmor = ConfMan.hasKey("DurableArmor") && ConfMan.getBool("DurableArmor");
+ _extOptions._showHpSpBars = ConfMan.hasKey("ShowHpSpBars") && ConfMan.getBool("ShowHpSpBars");
// If requested, load a savegame instead of showing the intro
if (ConfMan.hasKey("save_slot")) {
diff --git a/engines/mm/xeen/xeen.h b/engines/mm/xeen/xeen.h
index e3ed79f2ef0..b86f047cf5d 100644
--- a/engines/mm/xeen/xeen.h
+++ b/engines/mm/xeen/xeen.h
@@ -97,9 +97,13 @@ class XeenEngine : public MMEngine {
struct ExtendedOptions {
bool _showItemCosts;
bool _durableArmor;
+ bool _showHpSpBars;
- ExtendedOptions() : _showItemCosts(false), _durableArmor(false) {
- }
+ ExtendedOptions() :
+ _showItemCosts(false),
+ _durableArmor(false),
+ _showHpSpBars(false)
+ {}
};
private:
/**
More information about the Scummvm-git-logs
mailing list