aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/xeen/dialogs_automap.cpp3
-rw-r--r--engines/xeen/dialogs_char_info.cpp567
-rw-r--r--engines/xeen/dialogs_char_info.h58
-rw-r--r--engines/xeen/dialogs_spells.cpp18
-rw-r--r--engines/xeen/interface.cpp17
-rw-r--r--engines/xeen/interface_map.cpp2
-rw-r--r--engines/xeen/items.cpp1
-rw-r--r--engines/xeen/items.h1
-rw-r--r--engines/xeen/module.mk1
-rw-r--r--engines/xeen/party.cpp47
-rw-r--r--engines/xeen/party.h19
-rw-r--r--engines/xeen/resources.cpp111
-rw-r--r--engines/xeen/resources.h51
-rw-r--r--engines/xeen/town.h2
-rw-r--r--engines/xeen/xeen.h3
15 files changed, 869 insertions, 32 deletions
diff --git a/engines/xeen/dialogs_automap.cpp b/engines/xeen/dialogs_automap.cpp
index 61821425dd..d9b7e8d6c7 100644
--- a/engines/xeen/dialogs_automap.cpp
+++ b/engines/xeen/dialogs_automap.cpp
@@ -40,7 +40,6 @@ void AutoMapDialog::execute() {
Map &map = *_vm->_map;
Party &party = *_vm->_party;
int frame2 = intf._overallFrame * 2;
- int varSI = 1;
bool frameEndFlag = false;
Common::Point pt = party._mazePosition;
@@ -74,7 +73,7 @@ void AutoMapDialog::execute() {
}
screen._windows[5].open();
- MazeData &mazeData = map.mazeDataCurrent();
+// MazeData &mazeData = map.mazeDataCurrent();
bool drawFlag = true;
int v;
diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp
new file mode 100644
index 0000000000..3ff40034a3
--- /dev/null
+++ b/engines/xeen/dialogs_char_info.cpp
@@ -0,0 +1,567 @@
+/* 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 "xeen/dialogs_char_info.h"
+#include "xeen/resources.h"
+#include "xeen/xeen.h"
+
+namespace Xeen {
+
+void CharacterInfo::show(XeenEngine *vm, int charIndex) {
+ CharacterInfo *dlg = new CharacterInfo(vm);
+ dlg->execute(charIndex);
+ delete dlg;
+}
+
+void CharacterInfo::execute(int charIndex) {
+ Screen &screen = *_vm->_screen;
+ EventsManager &events = *_vm->_events;
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+
+ bool redrawFlag = false;
+ Mode oldMode = _vm->_mode;
+ _vm->_mode = MODE_CHARACTER_INFO;
+ loadDrawStructs();
+ addButtons();
+
+ Character *c = (oldMode != MODE_InCombat) ? &party._activeParty[charIndex] : party._combatParty[charIndex];
+ intf.highlightChar(charIndex);
+ Window &w = screen._windows[24];
+ w.open();
+
+ do {
+ if (redrawFlag) {
+ Common::String charDetails = loadCharacterDetails(*c);
+ w.writeString(Common::String::format(CHARACTER_TEMPLATE, charDetails.c_str()));
+ w.drawList(_drawList, 24);
+ w.update();
+ redrawFlag = false;
+ }
+
+ // Wait for keypress, showing a blinking cursor
+ events.updateGameCounter();
+ bool cursorFlag = false;
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed()) {
+ if (events.timeElapsed() > 4) {
+ cursorFlag = !cursorFlag;
+ events.updateGameCounter();
+ }
+
+ showCursor(cursorFlag);
+ w.update();
+ }
+ checkEvents(_vm);
+ events.clearEvents();
+
+ switch (_buttonValue) {
+ case Common::KEYCODE_F1:
+ case Common::KEYCODE_F2:
+ case Common::KEYCODE_F3:
+ case Common::KEYCODE_F4:
+ case Common::KEYCODE_F5:
+ case Common::KEYCODE_F6:
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < (int)(oldMode == MODE_InCombat ? party._combatParty.size() : party._activeParty.size())) {
+ charIndex = _buttonValue;
+ c = (oldMode != MODE_InCombat) ? &party._activeParty[charIndex] : party._combatParty[charIndex];
+ }
+ else {
+ _iconSprites.load("view.icn");
+ _vm->_mode = MODE_CHARACTER_INFO;
+ }
+ break;
+
+ case Common::KEYCODE_UP:
+ case Common::KEYCODE_KP8:
+ if (_cursorCell > 0) {
+ showCursor(false);
+ --_cursorCell;
+ showCursor(true);
+ }
+ w.update();
+ break;
+
+ case Common::KEYCODE_DOWN:
+ case Common::KEYCODE_KP2:
+ if (_cursorCell < 20) {
+ showCursor(false);
+ ++_cursorCell;
+ showCursor(true);
+ }
+ w.update();
+ break;
+
+ case Common::KEYCODE_LEFT:
+ case Common::KEYCODE_KP4:
+ if (_cursorCell >= 5) {
+ showCursor(false);
+ _cursorCell -= 5;
+ showCursor(true);
+ }
+ w.update();
+ break;
+
+ case Common::KEYCODE_RIGHT:
+ case Common::KEYCODE_KP6:
+ if (_cursorCell <= 15) {
+ showCursor(false);
+ _cursorCell += 5;
+ showCursor(true);
+ }
+ w.update();
+ break;
+
+ case Common::KEYCODE_RETURN:
+ case Common::KEYCODE_KP_ENTER:
+ _buttonValue = _cursorCell + Common::KEYCODE_a;
+ // Deliberate fall-through
+
+ case 1001:
+ case 1002:
+ case 1003:
+ case 1004:
+ case 1005:
+ case 1006:
+ case 1007:
+ case 1008:
+ case 1009:
+ case 1010:
+ case 1011:
+ case 1012:
+ case 1013:
+ case 1014:
+ case 1015:
+ case 1016:
+ case 1017:
+ case 1018:
+ case 1019:
+ case 1020: {
+ showCursor(false);
+ _cursorCell = _buttonValue - 1001;
+ showCursor(true);
+ w.update();
+
+ bool result = expandStat(_cursorCell, *c);
+ _vm->_mode = MODE_InCombat;
+ if (result)
+ redrawFlag = true;
+ break;
+ }
+
+ case Common::KEYCODE_e:
+ if (oldMode == MODE_InCombat) {
+ ErrorScroll::show(_vm, EXCHANGING_IN_COMBAT, WT_FREEZE_WAIT);
+ } else {
+ _vm->_mode = oldMode;
+ error("c = exchangeChar(&charIndex)");
+ _vm->_mode = MODE_CHARACTER_INFO;
+ redrawFlag = true;
+ }
+ break;
+
+ case Common::KEYCODE_i:
+ _vm->_mode = oldMode;
+ _vm->_treasure._v1 = _vm->_mode == MODE_InCombat;
+ error("TODO: c = ItemDialog::show");
+
+ if (!c) {
+ party._stepped = true;
+ goto exit;
+ }
+
+ _vm->_mode = MODE_CHARACTER_INFO;
+ break;
+
+ case Common::KEYCODE_ESCAPE:
+ goto exit;
+ }
+ } while (!_vm->shouldQuit());
+exit:
+ w.close();
+ intf.unhighlightChar();
+ _vm->_mode = oldMode;
+ _vm->_treasure._v1 = false;
+}
+
+/**
+ * Load the draw structure list with frame numbers and positions
+ */
+void CharacterInfo::loadDrawStructs() {
+ _drawList[0] = DrawStruct(0, 2, 16);
+ _drawList[1] = DrawStruct(2, 2, 39);
+ _drawList[2] = DrawStruct(4, 2, 62);
+ _drawList[3] = DrawStruct(6, 2, 85);
+ _drawList[4] = DrawStruct(8, 2, 108);
+ _drawList[5] = DrawStruct(10, 53, 16);
+ _drawList[6] = DrawStruct(12, 53, 39);
+ _drawList[7] = DrawStruct(14, 53, 62);
+ _drawList[8] = DrawStruct(16, 53, 85);
+ _drawList[9] = DrawStruct(18, 53, 108);
+ _drawList[10] = DrawStruct(20, 104, 16);
+ _drawList[11] = DrawStruct(22, 104, 39);
+ _drawList[12] = DrawStruct(24, 104, 62);
+ _drawList[13] = DrawStruct(26, 104, 85);
+ _drawList[14] = DrawStruct(28, 104, 108);
+ _drawList[15] = DrawStruct(30, 169, 16);
+ _drawList[16] = DrawStruct(32, 169, 39);
+ _drawList[17] = DrawStruct(34, 169, 62);
+ _drawList[18] = DrawStruct(36, 169, 85);
+ _drawList[19] = DrawStruct(38, 169, 108);
+ _drawList[20] = DrawStruct(40, 277, 3);
+ _drawList[21] = DrawStruct(42, 277, 35);
+ _drawList[22] = DrawStruct(44, 277, 67);
+ _drawList[23] = DrawStruct(46, 277, 99);
+
+ _iconSprites.load("view.icn");
+ for (int idx = 0; idx < 24; ++idx)
+ _drawList[idx]._sprites = &_iconSprites;
+}
+
+/**
+ * Set up the button list for the dialog
+ */
+void CharacterInfo::addButtons() {
+ addButton(Common::Rect(10, 24, 34, 64), 1001, &_iconSprites);
+ addButton(Common::Rect(10, 47, 34, 67), 1002, &_iconSprites);
+ addButton(Common::Rect(10, 70, 34, 90), 1003, &_iconSprites);
+ addButton(Common::Rect(10, 93, 34, 113), 1004, &_iconSprites);
+ addButton(Common::Rect(10, 116, 34, 136), 1005, &_iconSprites);
+ addButton(Common::Rect(61, 24, 85, 44), 1006, &_iconSprites);
+ addButton(Common::Rect(61, 47, 85, 67), 1007, &_iconSprites);
+ addButton(Common::Rect(61, 70, 85, 90), 1008, &_iconSprites);
+ addButton(Common::Rect(61, 93, 85, 113), 1009, &_iconSprites);
+ addButton(Common::Rect(61, 116, 85, 136), 1010, &_iconSprites);
+ addButton(Common::Rect(112, 24, 136, 44), 1011, &_iconSprites);
+ addButton(Common::Rect(112, 47, 136, 67), 1012, &_iconSprites);
+ addButton(Common::Rect(112, 70, 136, 90), 1013, &_iconSprites);
+ addButton(Common::Rect(112, 93, 136, 113), 1014, &_iconSprites);
+ addButton(Common::Rect(112, 116, 136, 136), 1015, &_iconSprites);
+ addButton(Common::Rect(177, 24, 201, 44), 1016, &_iconSprites);
+ addButton(Common::Rect(177, 47, 201, 67), 1017, &_iconSprites);
+ addButton(Common::Rect(177, 70, 201, 90), 1018, &_iconSprites);
+ addButton(Common::Rect(177, 93, 201, 113), 1019, &_iconSprites);
+ addButton(Common::Rect(177, 116, 201, 136), 1020, &_iconSprites);
+ addButton(Common::Rect(285, 11, 309, 31), Common::KEYCODE_i, &_iconSprites);
+ addButton(Common::Rect(285, 43, 309, 63), Common::KEYCODE_q, &_iconSprites);
+ addButton(Common::Rect(285, 75, 309, 95), Common::KEYCODE_e, &_iconSprites);
+ addButton(Common::Rect(285, 107, 309, 127), Common::KEYCODE_ESCAPE, &_iconSprites);
+}
+
+/**
+ * Return a string containing the details of the character
+ */
+Common::String CharacterInfo::loadCharacterDetails(const Character &c) {
+ Condition condition = c.worstCondition();
+ Party &party = *_vm->_party;
+ int foodVal = party._food / party._partyCount / 3;
+
+ int totalResist =
+ c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary +
+ c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary +
+ c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary +
+ c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary +
+ c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary +
+ c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary;
+
+ return Common::String::format(CHARACTER_DETAILS,
+ PARTY_GOLD, c._name.c_str(), SEX_NAMES[c._sex],
+ RACE_NAMES[c._race], CLASS_NAMES[c._class],
+ c.statColor(c.getStat(MIGHT), c.getStat(MIGHT, true)), c.getStat(MIGHT),
+ c.statColor(c.getStat(ACCURACY), c.getStat(ACCURACY, true)), c.getStat(ACCURACY),
+ c.statColor(c._currentHp, c.getMaxHP()),
+ c.getCurrentExperience(),
+ c.statColor(c.getStat(INTELLECT), c.getStat(INTELLECT, true)), c.getStat(INTELLECT),
+ c.statColor(c.getStat(LUCK), c.getStat(LUCK, true)), c.getStat(LUCK),
+ c.statColor(c._currentSp, c.getMaxSP()), c._currentSp,
+ party._gold,
+ c.statColor(c.getStat(PERSONALITY), c.getStat(PERSONALITY, true)), c.getStat(PERSONALITY),
+ c.statColor(c.getAge(), c.getAge(true)), c.getAge(),
+ totalResist,
+ party._gems,
+ c.statColor(c.getStat(ENDURANCE), c.getStat(ENDURANCE, true)), c.getStat(ENDURANCE),
+ c.statColor(c.getCurrentLevel(), c._level._permanent), c.getCurrentLevel(),
+ c.getNumSkills(),
+ foodVal, (foodVal == 1) ? ' ' : 's',
+ c.statColor(c.getStat(SPEED), c.getStat(SPEED, true)), c.getStat(SPEED),
+ c.statColor(c.getArmorClass(), c.getArmorClass(true)), c.getArmorClass(),
+ c.getNumAwards(),
+ CONDITION_COLORS[condition], CONDITION_NAMES[condition],
+ condition == NO_CONDITION && party._blessed ? PLUS_14 : "",
+ condition == NO_CONDITION && party._powerShield ? PLUS_14 : "",
+ condition == NO_CONDITION && party._holyBonus ? PLUS_14 : "",
+ condition == NO_CONDITION && party._heroism ? PLUS_14 : ""
+ );
+}
+
+/**
+ * Cursor display handling
+ */
+void CharacterInfo::showCursor(bool flag) {
+ Screen &screen = *_vm->_screen;
+ const int CURSOR_X[5] = { 9, 60, 111, 176, 0 };
+ const int CURSOR_Y[5] = { 23, 46, 69, 92, 115 };
+
+ if (_cursorCell < 20) {
+ _iconSprites.draw(screen, flag ? 49 : 48,
+ Common::Point(CURSOR_X[_cursorCell / 5], CURSOR_Y[_cursorCell % 5]));
+ }
+}
+
+bool CharacterInfo::expandStat(int attrib, const Character &c) {
+ const int STAT_POS[2][20] = {
+ {
+ 61, 61, 61, 61, 61, 112, 112, 112, 112, 112,
+ 177, 177, 177, 177, 177, 34, 34, 34, 34, 34
+ }, {
+ 24, 47, 70, 93, 116, 24, 47, 70, 93, 116,
+ 24, 47, 70, 93, 116, 24, 47, 70, 93, 116
+ }
+ };
+ assert(attrib < 20);
+ Common::Rect bounds(STAT_POS[0][attrib], STAT_POS[1][attrib],
+ STAT_POS[0][attrib] + 143, STAT_POS[1][attrib] + 52);
+ Party &party = *_vm->_party;
+ int stat1, stat2;
+ uint idx;
+ Common::String msg;
+
+ switch (attrib) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ // Basic attributes
+ stat1 = c.getStat((Attribute)attrib, false);
+ stat2 = c.getStat((Attribute)attrib, true);
+ idx = 0;
+ while (STAT_VALUES[idx] <= stat1)
+ ++idx;
+
+ msg = Common::String::format(CURRENT_MAXIMUM_RATING_TEXT, STAT_NAMES[attrib],
+ stat1, stat2, RATING_TEXT[idx]);
+ break;
+
+ case 7:
+ // Age
+ stat1 = c.getAge(false);
+ stat2 = c.getAge(true);
+ msg = Common::String::format(AGE_TEXT, STAT_NAMES[attrib],
+ stat2, c._dbDay, c._ybDay);
+ break;
+
+ case 8: {
+ // Level
+ const int CLASS_ATTACK_GAINS[10] = { 5, 6, 6, 7, 8, 6, 5, 4, 7, 6 };
+ idx = c.getCurrentLevel() / CLASS_ATTACK_GAINS[c._class] + 1;
+
+ msg = Common::String::format(LEVEL_TEXT, STAT_NAMES[attrib],
+ c.getCurrentLevel(), c._level._permanent,
+ idx, idx > 1 ? "s" : "",
+ c._level._permanent);
+ break;
+ }
+
+ case 9:
+ // Armor Class
+ stat1 = c.getArmorClass(false);
+ stat2 = c.getArmorClass(true);
+ msg = Common::String::format(CURRENT_MAXIMUM_TEXT, STAT_NAMES[attrib],
+ stat1, stat2);
+ bounds.setHeight(42);
+ break;
+
+ case 10:
+ // Hit Points
+ stat1 = c._currentHp;
+ stat2 = c.getMaxHP();
+ msg = Common::String::format(CURRENT_MAXIMUM_TEXT, STAT_NAMES[attrib],
+ stat1, stat2);
+ bounds.setHeight(42);
+ break;
+
+ case 11:
+ // Spell Points
+ stat1 = c._currentSp;
+ stat2 = c.getMaxSP();
+ msg = Common::String::format(CURRENT_MAXIMUM_TEXT, STAT_NAMES[attrib],
+ stat1, stat2);
+ bounds.setHeight(42);
+ break;
+
+ case 12:
+ // Resistences
+ msg = Common::String::format(RESISTENCES_TEXT, STAT_NAMES[attrib],
+ c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary,
+ c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary,
+ c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary,
+ c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary,
+ c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary,
+ c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary);
+ break;
+
+ case 13: {
+ // Skills
+ Common::String lines[20];
+ int numLines = c.getNumSkills();
+ if (numLines > 0) {
+ for (int skill = THIEVERY; skill <= DANGER_SENSE; ++skill) {
+ if (c._skills[skill]) {
+ if (skill == THIEVERY) {
+ lines[0] = Common::String::format("\n\t020%s%u",
+ SKILL_NAMES[THIEVERY], c.getThievery());
+ } else {
+ lines[skill] = Common::String::format("\n\t020%s", SKILL_NAMES[skill]);
+ }
+ }
+ }
+ } else {
+ lines[0] = NONE;
+ numLines = 1;
+ }
+
+ msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(),
+ lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), lines[5].c_str(),
+ lines[17].c_str(), lines[6].c_str(), lines[7].c_str(), lines[8].c_str(),
+ lines[9].c_str(), lines[10].c_str(), lines[11].c_str(), lines[12].c_str(),
+ lines[13].c_str(), lines[16].c_str(), lines[14].c_str(), lines[15].c_str());
+
+ bounds.top -= (numLines / 2) * 8;
+ bounds.setHeight(numLines * 9 + 26);
+ if (bounds.bottom >= SCREEN_HEIGHT)
+ bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1);
+ break;
+ }
+
+ case 14:
+ // Awards
+ error("AwardsDialog::show");
+ return false;
+
+ case 15:
+ // Experience
+ stat1 = c.getCurrentExperience();
+ stat2 = c.nextExperienceLevel();
+ msg = Common::String::format(EXPERIENCE_TEXT,
+ STAT_NAMES[attrib], stat1,
+ stat2 == 0 ? ELIGIBLE : Common::String::format("%d", stat2)
+ );
+ bounds.setHeight(43);
+ break;
+
+ case 16:
+ // Gold
+ msg = Common::String::format(IN_PARTY_IN_BANK, STAT_NAMES[attrib],
+ party._gold, party._bankGold);
+ break;
+
+ case 17:
+ // Gems
+ msg = Common::String::format(IN_PARTY_IN_BANK, STAT_NAMES[attrib],
+ party._gems, party._bankGems);
+ bounds.setHeight(43);
+ break;
+
+ case 18: {
+ // Food
+ int food = (party._food / party._partyCount) / 3;
+ msg = Common::String::format(FOOD_TEXT, STAT_NAMES[attrib],
+ party._food, food, food != 1 ? "s" : "");
+ break;
+ }
+
+ case 19: {
+ // Conditions
+ Common::String lines[20];
+ int total = 0;
+ for (int condition = CURSED; condition <= ERADICATED; ++condition) {
+ if (c._conditions[condition]) {
+ if (condition >= UNCONSCIOUS) {
+ lines[condition] = Common::String::format("\n\t020%s",
+ CONDITION_NAMES[condition]);
+ } else {
+ lines[condition] = Common::String::format("\n\t020%s\t095-%d",
+ CONDITION_NAMES[condition], c._conditions[condition]);
+ }
+
+ ++total;
+ }
+ }
+
+ Condition condition = c.worstCondition();
+ if (condition == NO_CONDITION) {
+ lines[0] = Common::String::format("\n\t020%s", GOOD);
+ }
+
+ if (party._blessed)
+ lines[16] = Common::String::format(BLESSED, party._blessed);
+ if (party._powerShield)
+ lines[17] = Common::String::format(POWER_SHIELD, party._powerShield);
+ if (party._holyBonus)
+ lines[18] = Common::String::format(HOLY_BONUS, party._holyBonus);
+ if (party._heroism)
+ lines[19] = Common::String::format(HEROISM, party._heroism);
+
+ msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1",
+ STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(),
+ lines[2].c_str(), lines[3].c_str(), lines[4].c_str(),
+ lines[5].c_str(), lines[6].c_str(), lines[7].c_str(),
+ lines[8].c_str(), lines[9].c_str(), lines[10].c_str(),
+ lines[11].c_str(), lines[12].c_str(), lines[13].c_str(),
+ lines[14].c_str(), lines[15].c_str(), lines[16].c_str(),
+ lines[17].c_str(), lines[18].c_str(), lines[19].c_str()
+ );
+
+ bounds.top = ((total - 1) / 2) * 8;
+ bounds.setHeight(total * 9 + 26);
+ if (bounds.bottom >= SCREEN_HEIGHT)
+ bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ // Write the data for the stat display
+ Window &w = _vm->_screen->_windows[28];
+ w.setBounds(bounds);
+ w.open();
+ w.writeString(msg);
+ w.update();
+
+ // Wait for a user key/click
+ EventsManager &events = *_vm->_events;
+ while (!_vm->shouldQuit() && !events.isKeyMousePressed())
+ events.pollEventsAndWait();
+ events.clearEvents();
+
+ w.close();
+ return false;
+}
+
+
+} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_char_info.h b/engines/xeen/dialogs_char_info.h
new file mode 100644
index 0000000000..5a20ff2248
--- /dev/null
+++ b/engines/xeen/dialogs_char_info.h
@@ -0,0 +1,58 @@
+/* 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 XEEN_DIALOGS_CHAR_INFO_H
+#define XEEN_DIALOGS_CHAR_INFO_H
+
+#include "xeen/dialogs.h"
+#include "xeen/party.h"
+#include "xeen/screen.h"
+
+namespace Xeen {
+
+class CharacterInfo : public ButtonContainer {
+private:
+ XeenEngine *_vm;
+ SpriteResource _iconSprites;
+ DrawStruct _drawList[24];
+ int _cursorCell;
+
+ CharacterInfo(XeenEngine *vm) : ButtonContainer(), _vm(vm), _cursorCell(0) {}
+
+ void execute(int charIndex);
+
+ void loadDrawStructs();
+
+ void addButtons();
+
+ Common::String loadCharacterDetails(const Character &c);
+
+ void showCursor(bool flag);
+
+ bool expandStat(int attrib, const Character &c);
+public:
+ static void show(XeenEngine *vm, int charIndex);
+};
+
+} // End of namespace Xeen
+
+#endif /* XEEN_DIALOGS_CHAR_INFO_H */
diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp
index 7ae5e7ad90..714e881128 100644
--- a/engines/xeen/dialogs_spells.cpp
+++ b/engines/xeen/dialogs_spells.cpp
@@ -50,7 +50,7 @@ Character *SpellsScroll::execute(Character *c, int v2) {
int v2Copy = v2;
v2 &= 0x7f;
int selection = -1;
- int topIndex = 0;
+ uint topIndex = 0;
int newSelection;
screen._windows[25].open();
@@ -109,7 +109,7 @@ Character *SpellsScroll::execute(Character *c, int v2) {
switch (_buttonValue) {
case Common::KEYCODE_F1:
case Common::KEYCODE_F6:
- if (_vm->_mode != MODE_2) {
+ if (_vm->_mode != MODE_InCombat) {
_buttonValue -= Common::KEYCODE_F1;
if (_buttonValue < party._partyCount) {
c = &party._activeParty[_buttonValue];
@@ -233,12 +233,12 @@ Character *SpellsScroll::execute(Character *c, int v2) {
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
- topIndex = MAX(topIndex - 10, 0);
+ topIndex = MAX((int)topIndex - 10, 0);
break;
case Common::KEYCODE_PAGEDOWN:
case Common::KEYCODE_KP3:
- topIndex = MIN(topIndex + 10, (((int)_spells.size() - 1) / 10) * 10);
+ topIndex = MIN(topIndex + 10, ((_spells.size() - 1) / 10) * 10);
break;
case Common::KEYCODE_UP:
@@ -249,7 +249,7 @@ Character *SpellsScroll::execute(Character *c, int v2) {
case Common::KEYCODE_DOWN:
case Common::KEYCODE_KP2:
- if (topIndex < ((int)_spells.size() - 10))
+ if (topIndex < (_spells.size() - 10))
++topIndex;
break;
}
@@ -321,7 +321,7 @@ const char *SpellsScroll::setSpellText(Character *c, int v2) {
if (category != -1) {
if (party._mazeId == 49 || party._mazeId == 37) {
- for (int spellId = 0; spellId < 76; ++spellId) {
+ for (uint spellId = 0; spellId < 76; ++spellId) {
int idx = 0;
while (idx < MAX_SPELLS_PER_CLASS && SPELLS_ALLOWED[category][idx] == spellId)
++idx;
@@ -338,8 +338,8 @@ const char *SpellsScroll::setSpellText(Character *c, int v2) {
}
} else if (isDarkCc) {
int groupIndex = (party._mazeId - 29) / 2;
- for (int spellId = DARK_SPELL_RANGES[category][0];
- spellId < DARK_SPELL_RANGES[category][1]; ++spellId) {
+ for (int spellId = DARK_SPELL_RANGES[groupIndex][0];
+ spellId < DARK_SPELL_RANGES[groupIndex][1]; ++spellId) {
int idx = 0;
while (idx < 40 && SPELLS_ALLOWED[category][idx] ==
DARK_SPELL_OFFSETS[category][spellId]);
@@ -357,7 +357,7 @@ const char *SpellsScroll::setSpellText(Character *c, int v2) {
for (int spellId = 0; spellId < 20; ++spellId) {
int idx = 0;
while (CLOUDS_SPELL_OFFSETS[party._mazeId - 29][spellId] !=
- SPELLS_ALLOWED[category][idx] && idx < 40) ;
+ (int)SPELLS_ALLOWED[category][idx] && idx < 40) ;
if (idx < 40) {
if (!c->_spells[idx] || (v2 & 0x80)) {
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 0ea5a8df83..a33c726fd3 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -21,6 +21,7 @@
*/
#include "xeen/interface.h"
+#include "xeen/dialogs_char_info.h"
#include "xeen/dialogs_error.h"
#include "xeen/dialogs_automap.h"
#include "xeen/dialogs_info.h"
@@ -331,7 +332,7 @@ void Interface::setupFaces(int charIndex, Common::Array<int> xeenSideChars, bool
void Interface::charIconsPrint(bool updateFlag) {
Screen &screen = *_vm->_screen;
- bool stateFlag = _vm->_mode == MODE_2;
+ bool stateFlag = _vm->_mode == MODE_InCombat;
_restoreSprites.draw(screen, 0, Common::Point(8, 149));
// Handle drawing the party faces
@@ -669,6 +670,20 @@ void Interface::perform() {
}
break;
+ case Common::KEYCODE_F1:
+ case Common::KEYCODE_F2:
+ case Common::KEYCODE_F3:
+ case Common::KEYCODE_F4:
+ case Common::KEYCODE_F5:
+ case Common::KEYCODE_F6:
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ CharacterInfo::show(_vm, _buttonValue);
+ if (party._stepped)
+ moveMonsters();
+ }
+ break;
+
case Common::KEYCODE_EQUALS:
case Common::KEYCODE_KP_EQUALS:
// Toggle minimap
diff --git a/engines/xeen/interface_map.cpp b/engines/xeen/interface_map.cpp
index 84f8fa6aa1..c8683a7e50 100644
--- a/engines/xeen/interface_map.cpp
+++ b/engines/xeen/interface_map.cpp
@@ -426,7 +426,7 @@ void InterfaceMap::draw3d(bool updateFlag) {
_flipUIFrame = (_flipUIFrame + 1) % 4;
if (_flipUIFrame == 0)
_flipWater = !_flipWater;
- if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_2) &&
+ if (_tillMove && (_vm->_mode == MODE_1 || _vm->_mode == MODE_InCombat) &&
!_flag1 && _vm->_moveMonsters) {
if (--_tillMove == 0)
moveMonsters();
diff --git a/engines/xeen/items.cpp b/engines/xeen/items.cpp
index f7dfeccbb1..c55a227502 100644
--- a/engines/xeen/items.cpp
+++ b/engines/xeen/items.cpp
@@ -56,6 +56,7 @@ int XeenItem::getAttributeCategory() const {
Treasure::Treasure() {
_hasItems = false;
+ _v1 = false;
}
} // End of namespace Xeen
diff --git a/engines/xeen/items.h b/engines/xeen/items.h
index 958a0b8afc..8e8f172790 100644
--- a/engines/xeen/items.h
+++ b/engines/xeen/items.h
@@ -55,6 +55,7 @@ public:
XeenItem _armor[TOTAL_ITEMS];
XeenItem _weapons[TOTAL_ITEMS];
bool _hasItems;
+ bool _v1;
public:
Treasure();
};
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index 4bb8bd99c0..6a9ff3012c 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -10,6 +10,7 @@ MODULE_OBJS := \
dialogs.o \
automap.o \
dialogs_automap.o \
+ dialogs_char_info.o \
dialogs_confirm.o \
dialogs_error.o \
dialogs_options.o \
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 66078b67e8..3cfc56e1ec 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -238,7 +238,7 @@ int Character::getMaxSP() const {
/**
* Get the effective value of a given stat for the character
*/
-int Character::getStat(Attribute attrib, bool baseOnly) const {
+uint Character::getStat(Attribute attrib, bool baseOnly) const {
AttributePair attr;
int mode = 0;
@@ -289,7 +289,24 @@ int Character::getStat(Attribute attrib, bool baseOnly) const {
attr._permanent += attr._temporary;
}
- return MAX(attr._permanent, 0);
+ return MAX(attr._permanent, (uint)0);
+}
+
+/**
+ * Return the color number to use for a given stat value in the character
+ * info or quick reference dialogs
+ */
+int Character::statColor(int amount, int threshold) {
+ if (amount < 1)
+ return 6;
+ else if (amount > threshold)
+ return 2;
+ else if (amount == threshold)
+ return 15;
+ else if (amount <= (threshold / 4))
+ return 9;
+ else
+ return 32;
}
int Character::statBonus(int statValue) const {
@@ -422,8 +439,8 @@ int Character::getThievery() const {
return MAX(result, 0);
}
-int Character::getCurrentLevel() const {
- return MAX(_level._permanent + _level._temporary, 0);
+uint Character::getCurrentLevel() const {
+ return MAX(_level._permanent + _level._temporary, (uint)0);
}
int Character::itemScan(int itemId) const {
@@ -817,6 +834,28 @@ uint Character::getCurrentExperience() const {
_experience;
}
+
+int Character::getNumSkills() const {
+ int total = 0;
+ for (int idx = THIEVERY; idx <= DANGER_SENSE; ++idx) {
+ if (_skills[idx])
+ ++total;
+ }
+
+ return total;
+}
+
+int Character::getNumAwards() const {
+ int total = 0;
+ for (int idx = 0; idx < 88; ++idx) {
+ if (hasAward(idx))
+ ++total;
+ }
+
+ return total;
+}
+
+
/*------------------------------------------------------------------------*/
void Roster::synchronize(Common::Serializer &s) {
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index e00b42476a..b793b5c696 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -80,8 +80,8 @@ class XeenEngine;
class AttributePair {
public:
- int _permanent;
- int _temporary;
+ uint _permanent;
+ uint _temporary;
public:
AttributePair();
void synchronize(Common::Serializer &s);
@@ -141,13 +141,15 @@ public:
Condition worstCondition() const;
- int getAge(bool ignoreTemp) const;
+ int getAge(bool ignoreTemp = false) const;
int getMaxHP() const;
int getMaxSP() const;
- int getStat(Attribute attrib, bool baseOnly = false) const;
+ uint getStat(Attribute attrib, bool baseOnly = false) const;
+
+ static int statColor(int amount, int threshold);
int statBonus(int statValue) const;
@@ -159,11 +161,11 @@ public:
bool hasAward(int awardId) const;
- int getArmorClass(bool baseOnly) const;
+ int getArmorClass(bool baseOnly = false) const;
int getThievery() const;
- int getCurrentLevel() const;
+ uint getCurrentLevel() const;
int itemScan(int itemId) const;
@@ -176,6 +178,10 @@ public:
uint currentExperienceLevel() const;
uint getCurrentExperience() const;
+
+ int getNumSkills() const;
+
+ int getNumAwards() const;
};
class Roster: public Common::Array<Character> {
@@ -247,6 +253,7 @@ public:
public:
// Other party related runtime data
Common::Array<Character> _activeParty;
+ Common::Array<Character *> _combatParty;
int _combatPartyCount;
bool _partyDead;
bool _newDay;
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index dafe321ab5..4e958a155d 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -287,6 +287,13 @@ const char *const ALIGNMENT_NAMES[3] = { "Good", "Neutral", "Evil" };
const char *const SEX_NAMES[2] = { "Male", "Female" };
+const char *const SKILL_NAMES[18] = {
+ "Thievery", "Arms Master", "Astrologer", "Body Builder", "Cartographer",
+ "Crusader", "Direction Sense", "Linguist", "Merchant", "Mountaineer",
+ "Navigator", "Path Finder", "Prayer Master", "Prestidigitator",
+ "Swimmer", "Tracker", "Spot Secret Door", "Danger Sense"
+};
+
const char *const CLASS_NAMES[11] = {
"Knight", "Paladin", "Archer", "Cleric", "Sorcerer", "Robber",
"Ninja", "Barbarian", "Druid", "Ranger", nullptr
@@ -296,12 +303,26 @@ const uint CLASS_EXP_LEVELS[10] = {
1500, 2000, 2000, 1500, 2000, 1000, 1500, 1500, 1500, 2000
};
-const char *const CONDITION_NAMES[18] = {
+const char *const CONDITION_NAMES[17] = {
nullptr, "Cursed", "Heart Broken", "Weak", "Poisoned", "Diseased",
"Insane", "In Love", "Drunk", "Asleep", "Depressed", "Confused",
- "Paralyzed", "Unconscious", "Dead", "Stone", "Eradicated", "Good"
+ "Paralyzed", "Unconscious", "Dead", "Stone", "Eradicated"
};
+const int CONDITION_COLORS[17] = {
+ 9, 9, 9, 9, 9, 9, 9, 9, 32, 32, 32, 32, 6, 6, 6, 6, 15
+};
+
+const char *const GOOD = "Good";
+
+const char *const BLESSED = "\n\t020Blessed\t095%+d";
+
+const char *const POWER_SHIELD = "\n\t020Power Shield\t095%+d";
+
+const char *const HOLY_BONUS = "\n\t020Holy Bonus\t095%+d";
+
+const char *const HEROISM = "\n\t020Heroism\t095%+d";
+
const char *const IN_PARTY = "\014""15In Party\014""d";
const char *const PARTY_DETAILS = "\015\003l\002\014""00"
@@ -494,7 +515,7 @@ const int MONSTER_EFFECT_FLAGS[15][8] = {
{ 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108, 0x108 }
};
-const int SPELLS_ALLOWED[3][40] = {
+const uint SPELLS_ALLOWED[3][40] = {
{
0, 1, 2, 3, 5, 6, 7, 8, 9, 10,
12, 14, 16, 23, 26, 27, 28, 30, 31, 32,
@@ -760,7 +781,7 @@ const int CLOUDS_SPELL_OFFSETS[5][20] = {
}
};
-const int DARK_SPELL_OFFSETS[3][39] = {
+const uint DARK_SPELL_OFFSETS[3][39] = {
{
42, 1, 26, 59, 27, 10, 50, 68, 55, 62, 67, 73, 2,
5, 3, 31, 30, 52, 49, 28, 74, 0, 9, 7, 14, 8,
@@ -866,4 +887,86 @@ const char *const WEEK_DAY_STRINGS[10] = {
"Ten", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"
};
+const char *const CHARACTER_DETAILS =
+ "\x3l\xB""041\x9""196%s\x9""000\xB""002%s : %s %s %s"
+ "\x3r\x9""053\xB""028\xC%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""%02u%d\xC""d\x9""196\xC""15%lu\xC""d\x3r"
+ "\x9""053\xB""051\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""%02u%u\xC""d\x9""196\xC""15%lu\xC""d"
+ "\x3r\x9""053\xB""074\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%lu\xC""d"
+ "\x3r\x9""053\xB""097\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""15%u day%c\xC""d"
+ "\x3r\x9""053\xB""120\xC""%02u%u\xC""d\x9""103\xC""%02u%u\xC""d"
+ "\x3l\x9""131\xC""15%u\xC""d\x9""196\xC""%02u%s\xC""d"
+ "\x9""230%s%s%s%s\xC""d";
+
+const char *const PARTY_GOLD = "Party Gold";
+
+const char *const PLUS_14 = "14+";
+
+const char *const CHARACTER_TEMPLATE =
+ "\x1\xC""00\xD\x3l\x9""029\xB""018Mgt\x9""080Acy\x9""131H.P.\x9""196Experience"
+ "\x9""029\xB""041Int\x9""080Lck\x9""131S.P.\x9""029\xB""064Per\x9""080Age"
+ "\x9""131Resis\x9""196Party Gems\x9""029\xB""087End\x9""080Lvl\x9""131Skills"
+ "\x9""196Party Food\x9""029\xB""110Spd\x9""080AC\x9""131Awrds\x9""196Condition\x3""c"
+ "\x9""290\xB""025\xC""37I\xC""dtem\x9""290\xB""057\xC""37Q"
+ "\xC""duick\x9""290\xB""089\xC""37E\xC""dxch\x9""290\xB""121Exit\x3l%s";
+
+const char *const EXCHANGING_IN_COMBAT = "\x3""c\xB""007\x9""000Exchanging in combat is not allowed!";
+
+const char *const CURRENT_MAXIMUM_RATING_TEXT = "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%lu\x3l\x9""058/ %lu\n"
+ "\x3""cRating: %s";
+
+const char *const CURRENT_MAXIMUM_TEXT = "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%u\x3l\x9""058/ %u";
+
+const char *const RATING_TEXT[24] = {
+ "Nonexistant", "Very Poor", "Poor", "Very Low", "Low", "Averarage", "Good",
+ "Very Good", "High", "Very High", "Great", "Super", "Amazing", "Incredible",
+ "Gigantic", "Fantastic", "Astoundig", "Astonishing", "Monumental", "Tremendous",
+ "Collosal", "Awesome", "AweInspiring", "aUltimate"
+};
+
+const char *const AGE_TEXT = "\x2\x3""c%s\n"
+ "Current / Natural\n"
+ "\x3r\x9""057%u\x3l\x9""061/ %u\n"
+ "\x3""cBorn: %u / %u\x1";
+
+const char *const LEVEL_TEXT =
+ "\x2\x3""c%s\n"
+ "Current / Maximum\n"
+ "\x3r\x9""054%u\x3l\x9""058/ %u\n"
+ "\x3""c%u Attack%s/Round\x1";
+
+const char *const RESISTENCES_TEXT =
+ "\x2\x3""c%s\x3l\n"
+ "\x9""020Fire\x9""100%u\n"
+ "\x9""020Cold\x9""100%u\n"
+ "\x9""020Electricity\x9""100%u\n"
+ "\x9""020Poison\x9""100%u\n"
+ "\x9""020Energy\x9""100%u\n"
+ "\x9""020Magic\x9""100%u";
+
+const char *const NONE = "\n\x9""020";
+
+const char *const EXPERIENCE_TEXT = "\x2\x3""c%s\x3l\n"
+ "\x9""010Current:\x9""070%lu\n"
+ "\x9""010Next Level:\x9""070%s\x1";
+
+const char *const ELIGIBLE = "\xC""12Eligible\xC""d";
+
+const char *const IN_PARTY_IN_BANK =
+ "\x2\x3""cParty %s\n"
+ "%lu on hand\n"
+ "%lu in bank\x1\x3l";
+
+const char *const FOOD_TEXT =
+ "\x2\x3""cParty %s\n"
+ "%u on hand\n"
+ "Enough for %u day%s\x3l";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 8beeb56442..a696e540e1 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -74,8 +74,21 @@ extern const char *const ALIGNMENT_NAMES[3];
extern const char *const SEX_NAMES[2];
-extern const char *const CONDITION_NAMES[18];
+extern const char *const SKILL_NAMES[18];
+extern const char *const CONDITION_NAMES[17];
+
+extern const int CONDITION_COLORS[17];
+
+extern const char *const GOOD;
+
+extern const char *const BLESSED;
+
+extern const char *const POWER_SHIELD;
+
+extern const char *const HOLY_BONUS;
+
+extern const char *const HEROISM;
extern const char *const IN_PARTY;
extern const char *const PARTY_DETAILS;
@@ -126,7 +139,7 @@ extern const int COMBAT_FLOAT_Y[8];
extern const int MONSTER_EFFECT_FLAGS[15][8];
-extern const int SPELLS_ALLOWED[3][40];
+extern const uint SPELLS_ALLOWED[3][40];
extern const int BASE_HP_BY_CLASS[10];
@@ -220,7 +233,7 @@ extern const int SPELL_COSTS[77];
extern const int CLOUDS_SPELL_OFFSETS[5][20];
-extern const int DARK_SPELL_OFFSETS[3][39];
+extern const uint DARK_SPELL_OFFSETS[3][39];
extern const int DARK_SPELL_RANGES[12][2];
@@ -276,6 +289,38 @@ extern const char *const SWORDS_GAME_TEXT;
extern const char *const WEEK_DAY_STRINGS[10];
+extern const char *const CHARACTER_DETAILS;
+
+extern const char *const PARTY_GOLD;
+
+extern const char *const PLUS_14;
+
+extern const char *const CHARACTER_TEMPLATE;
+
+extern const char *const EXCHANGING_IN_COMBAT;
+
+extern const char *const CURRENT_MAXIMUM_RATING_TEXT;
+
+extern const char *const CURRENT_MAXIMUM_TEXT;
+
+extern const char *const RATING_TEXT[24];
+
+extern const char *const AGE_TEXT;
+
+extern const char *const LEVEL_TEXT;
+
+extern const char *const RESISTENCES_TEXT;
+
+extern const char *const NONE;
+
+extern const char *const EXPERIENCE_TEXT;
+
+extern const char *const ELIGIBLE;
+
+extern const char *const IN_PARTY_IN_BANK;
+
+extern const char *const FOOD_TEXT;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/town.h b/engines/xeen/town.h
index 8237f8102e..807f6b5138 100644
--- a/engines/xeen/town.h
+++ b/engines/xeen/town.h
@@ -47,7 +47,7 @@ private:
int _v5, _v6;
int _v10, _v11, _v12;
int _v13, _v14;
- int _v20;
+ uint _v20;
int _v21;
uint _v22;
int _v23;
diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h
index cb09c280cd..7f1a2cd0f0 100644
--- a/engines/xeen/xeen.h
+++ b/engines/xeen/xeen.h
@@ -77,7 +77,7 @@ enum Mode {
MODE_FF = -1,
MODE_0 = 0,
MODE_1 = 1,
- MODE_2 = 2,
+ MODE_InCombat = 2,
MODE_3 = 3,
MODE_4 = 4,
MODE_5 = 5,
@@ -85,6 +85,7 @@ enum Mode {
MODE_7 = 7,
MODE_8 = 8,
MODE_9 = 9,
+ MODE_CHARACTER_INFO = 10,
MODE_17 = 17
};