aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/xeen/dialogs_yesno.cpp2
-rw-r--r--engines/xeen/dialogs_yesno.h2
-rw-r--r--engines/xeen/interface_map.cpp8
-rw-r--r--engines/xeen/items.h2
-rw-r--r--engines/xeen/party.cpp30
-rw-r--r--engines/xeen/party.h10
-rw-r--r--engines/xeen/resources.cpp30
-rw-r--r--engines/xeen/resources.h10
-rw-r--r--engines/xeen/scripts.cpp2
-rw-r--r--engines/xeen/sound.h2
-rw-r--r--engines/xeen/town.cpp478
-rw-r--r--engines/xeen/town.h21
12 files changed, 562 insertions, 35 deletions
diff --git a/engines/xeen/dialogs_yesno.cpp b/engines/xeen/dialogs_yesno.cpp
index 940f5b6e08..07de5a582f 100644
--- a/engines/xeen/dialogs_yesno.cpp
+++ b/engines/xeen/dialogs_yesno.cpp
@@ -25,7 +25,7 @@
namespace Xeen {
-bool YesNo::show(XeenEngine *vm, bool type, int v2) {
+bool YesNo::show(XeenEngine *vm, bool type, bool v2) {
YesNo *dlg = new YesNo(vm);
bool result = dlg->execute(type, v2);
delete dlg;
diff --git a/engines/xeen/dialogs_yesno.h b/engines/xeen/dialogs_yesno.h
index 82ac402c85..d083cd64d4 100644
--- a/engines/xeen/dialogs_yesno.h
+++ b/engines/xeen/dialogs_yesno.h
@@ -35,7 +35,7 @@ private:
bool execute(bool type, int v2);
public:
- static bool show(XeenEngine *vm, bool type, int v2);
+ static bool show(XeenEngine *vm, bool type, bool v2);
};
} // End of namespace Xeen
diff --git a/engines/xeen/interface_map.cpp b/engines/xeen/interface_map.cpp
index c9ea2589c6..f90d3e369a 100644
--- a/engines/xeen/interface_map.cpp
+++ b/engines/xeen/interface_map.cpp
@@ -4552,26 +4552,26 @@ void InterfaceMap::assembleBorder() {
// Draw UI element for blessed
_blessSprites.draw(screen, 16, Common::Point(33, 137));
- if (_vm->_party->_blessedActive) {
+ if (_vm->_party->_blessed) {
_blessedUIFrame = (_blessedUIFrame + 1) % 4;
_blessSprites.draw(screen, _blessedUIFrame, Common::Point(33, 137));
}
// Draw UI element for power shield
- if (_vm->_party->_powerShieldActive) {
+ if (_vm->_party->_powerShield) {
_powerShieldUIFrame = (_powerShieldUIFrame + 1) % 4;
_blessSprites.draw(screen, _powerShieldUIFrame + 4,
Common::Point(55, 137));
}
// Draw UI element for holy bonus
- if (_vm->_party->_holyBonusActive) {
+ if (_vm->_party->_holyBonus) {
_holyBonusUIFrame = (_holyBonusUIFrame + 1) % 4;
_blessSprites.draw(screen, _holyBonusUIFrame + 8, Common::Point(160, 137));
}
// Draw UI element for heroism
- if (_vm->_party->_heroismActive) {
+ if (_vm->_party->_heroism) {
_heroismUIFrame = (_heroismUIFrame + 1) % 4;
_blessSprites.draw(screen, _heroismUIFrame + 12, Common::Point(182, 137));
}
diff --git a/engines/xeen/items.h b/engines/xeen/items.h
index 95a5519400..958a0b8afc 100644
--- a/engines/xeen/items.h
+++ b/engines/xeen/items.h
@@ -30,6 +30,8 @@ namespace Xeen {
#define TOTAL_ITEMS 10
+enum BonusFlags { FLAG_CURSED = 0x40 };
+
class XeenItem {
public:
int _material;
diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp
index 1baa25404f..66ba405909 100644
--- a/engines/xeen/party.cpp
+++ b/engines/xeen/party.cpp
@@ -60,7 +60,7 @@ Character::Character() {
_lloydSide = 0;
Common::fill(&_conditions[0], &_conditions[16], 0);
_townUnknown = 0;
- _unknown2 = 0;
+ _savedMazeId = 0;
_currentHp = 0;
_currentSp = 0;
_ybDay = 0;
@@ -140,7 +140,7 @@ void Character::synchronize(Common::Serializer &s) {
s.syncAsByte(_conditions[i]);
s.syncAsUint16LE(_townUnknown);
- s.syncAsByte(_unknown2);
+ s.syncAsByte(_savedMazeId);
s.syncAsUint16LE(_currentHp);
s.syncAsUint16LE(_currentSp);
s.syncAsUint16LE(_ybDay);
@@ -381,7 +381,7 @@ int Character::getArmorClass(bool baseOnly) const {
int result = statBonus(getStat(SPEED)) + itemScan(9);
if (!baseOnly)
- result += (party._blessedActive ? 1 : 0) + _ACTemp;
+ result += party._blessed + _ACTemp;
return MAX(result, 0);
}
@@ -842,10 +842,10 @@ Party::Party(XeenEngine *vm) {
_wizardEyeActive = false;
_clairvoyanceActive = false;
_walkOnWaterActive = false;
- _blessedActive = false;
- _powerShieldActive = false;
- _holyBonusActive = false;
- _heroismActive = false;
+ _blessed = 0;
+ _powerShield = 0;
+ _holyBonus = 0;
+ _heroism = 0;
_difficulty = ADVENTURER;
_cloudsEnd = false;
_darkSideEnd = false;
@@ -912,10 +912,10 @@ void Party::synchronize(Common::Serializer &s) {
s.syncAsByte(_wizardEyeActive);
s.syncAsByte(_clairvoyanceActive);
s.syncAsByte(_walkOnWaterActive);
- s.syncAsByte(_blessedActive);
- s.syncAsByte(_powerShieldActive);
- s.syncAsByte(_holyBonusActive);
- s.syncAsByte(_heroismActive);
+ s.syncAsByte(_blessed);
+ s.syncAsByte(_powerShield);
+ s.syncAsByte(_holyBonus);
+ s.syncAsByte(_heroism);
s.syncAsByte(_difficulty);
for (int i = 0; i < ITEMS_COUNT; ++i)
@@ -1194,10 +1194,10 @@ void Party::resetTemps() {
_walkOnWaterActive = false;
_wizardEyeActive = false;
_clairvoyanceActive = false;
- _heroismActive = false;
- _holyBonusActive = false;
- _powerShieldActive = false;
- _blessedActive = false;
+ _heroism = 0;
+ _holyBonus = 0;
+ _powerShield = 0;
+ _blessed = 0;
}
void Party::handleLight() {
diff --git a/engines/xeen/party.h b/engines/xeen/party.h
index 883b378e55..10f4027dfe 100644
--- a/engines/xeen/party.h
+++ b/engines/xeen/party.h
@@ -127,7 +127,7 @@ public:
AttributePair _magicResistence;
int _conditions[16];
int _townUnknown;
- int _unknown2;
+ int _savedMazeId;
int _currentHp;
int _currentSp;
int _ybDay;
@@ -202,10 +202,10 @@ public:
bool _wizardEyeActive;
bool _clairvoyanceActive;
bool _walkOnWaterActive;
- bool _blessedActive;
- bool _powerShieldActive;
- bool _holyBonusActive;
- bool _heroismActive;
+ int _blessed;
+ int _powerShield;
+ int _holyBonus;
+ int _heroism;
Difficulty _difficulty;
XeenItem _blacksmithWeapons[ITEMS_COUNT];
XeenItem _blacksmithArmor[ITEMS_COUNT];
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index 3be2617e6b..5eec5be89e 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -626,6 +626,34 @@ const char *const FOOD_AND_DRINK =
"\x09""017\x0C""37T\x0C""dip\n"
"\x09""017\x0C""37R\x0C""dumors";
+const char *const GOOD_STUFF = "\n"
+ "\n"
+ "Good Stuff\n"
+ "\n"
+ "Hit a key!";
+
+const char *const HAVE_A_DRINK = "\n\nHave a Drink\n\nHit a key!";
+
+const char *const YOURE_DRUNK = "\n\nYou're Drunk\n\nHit a key!";
+
+const int TAVERN_EXIT_LIST[2][6][5][2] = {
+ {
+ { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
+ { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
+ { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
+ { { 18, 4 }, { 0, 0 }, { 19, 16 }, { 0, 0 }, { 11, 12 } },
+ { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
+ { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } },
+ }, {
+ { { 21, 17 }, { 0, 0 }, { 20, 3 }, { 0, 0 }, { 0, 0 } },
+ { { 13, 4 }, { 0, 0 }, { 19, 9 }, { 0, 0 }, { 0, 0 } },
+ { { 20, 10 }, { 12, 8 }, { 5, 26 }, { 3, 4 }, { 7, 5 } },
+ { { 17, 24 }, { 14, 13 }, { 0, 0 }, { 0, 0 }, { 9, 4 } },
+ { { 15, 21 }, { 0, 0 }, { 13, 21 }, { 0, 0 }, { 0, 0 } },
+ { { 10, 8 }, { 0, 0 }, { 15, 12 }, { 0, 0 }, { 0, 0 } }
+ }
+};
+
const char *const TEMPLE_TEXT =
"\x0D\x03""c\x0B""000\x09""000Temple Options for"
"\x09""039\x0B""027%s\x03l\x09""000\x0B""046"
@@ -683,4 +711,6 @@ const char *const WHERE_NAMES[2] = { "Party", "Bank" };
const char *const AMOUNT = "\x03""c\x09""000\x0B""051Amount\x03l\n";
+const char *const FOOD_PACKS_FULL = "\v007Your food packs are already full!";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 5dbc32174a..497b02515b 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -170,6 +170,14 @@ extern const char *const GUILD_TEXT;
extern const char *const TAVERN_TEXT;
+extern const char *const GOOD_STUFF;
+
+extern const char *const HAVE_A_DRINK;
+
+extern const char *const YOURE_DRUNK;
+
+extern const int TAVERN_EXIT_LIST[2][6][5][2];
+
extern const char *const FOOD_AND_DRINK;
extern const char *const TEMPLE_TEXT;
@@ -200,6 +208,8 @@ extern const char *const WHERE_NAMES[2];
extern const char *const AMOUNT;
+extern const char *const FOOD_PACKS_FULL;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index e3cc682069..c84ec91d11 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -1077,7 +1077,7 @@ bool Scripts::ifProc(int action, uint32 mask, int mode, int charIndex) {
v = ps._luck._temporary;
break;
case 44:
- v = YesNo::show(_vm, mask, 0);
+ v = YesNo::show(_vm, mask, false);
v = (!v && !mask) ? 2 : mask;
break;
case 45:
diff --git a/engines/xeen/sound.h b/engines/xeen/sound.h
index d38e16b5b9..b6f1948726 100644
--- a/engines/xeen/sound.h
+++ b/engines/xeen/sound.h
@@ -43,7 +43,7 @@ public:
void playSong(Common::SeekableReadStream &f) {}
- void playSample(const Common::SeekableReadStream *stream, int v2) {}
+ void playSample(const Common::SeekableReadStream *stream, int v2 = 1) {}
void playFX(int id) {}
};
diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp
index 9e1f04785f..81cc88bb2c 100644
--- a/engines/xeen/town.cpp
+++ b/engines/xeen/town.cpp
@@ -22,6 +22,7 @@
#include "xeen/town.h"
#include "xeen/dialogs_input.h"
+#include "xeen/dialogs_yesno.h"
#include "xeen/resources.h"
#include "xeen/xeen.h"
@@ -42,6 +43,11 @@ Town::Town(XeenEngine *vm) : _vm(vm) {
_v12 = _v13 = 0;
_v14 = 0;
_v20 = 0;
+ _v21 = 0;
+ _v22 = 0;
+ _v23 = 0;
+ _v24 = 0;
+ _dayOfWeek = 0;
_uncurseCost = 0;
_flag1 = false;
_nextExperienceLevel = 0;
@@ -474,19 +480,469 @@ Common::String Town::createTownText(Character &ch) {
Character *Town::doTownOptions(Character *c) {
switch (_townActionId) {
case 0:
- if (_buttonValue == Common::KEYCODE_d)
+ // Bank
+ c = doBankOptions(c);
+ break;
+ case 1:
+ // Blacksmith
+ c = doBlacksmithOptions(c);
+ break;
+ case 2:
+ // Guild
+ c = doGuildOptions(c);
+ break;
+ case 3:
+ // Tavern
+ c = doTavernOptions(c);
+ break;
+ case 4:
+ // Temple
+ c = doTempleOptions(c);
+ case 5:
+ // Training
+ c = doTrainingOptions(c);
+ break;
+ default:
+ break;
+ }
+
+ return c;
+}
+
+Character *Town::doBankOptions(Character *c) {
+ if (_buttonValue == Common::KEYCODE_d)
+ _buttonValue = 0;
+ else if (_buttonValue == Common::KEYCODE_w)
+ _buttonValue = 1;
+ else
+ return c;
+
+ depositWithdrawl(_buttonValue);
+ return c;
+}
+
+Character *Town::doBlacksmithOptions(Character *c) {
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+
+ if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) {
+ // Switch character
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ c = &party._activeParty[_buttonValue];
+ intf.highlightChar(_buttonValue);
+ }
+ }
+ else if (_buttonValue == Common::KEYCODE_c) {
+ c = showItems(c, 1);
+ _buttonValue = 0;
+ }
+
+ return c;
+}
+
+Character *Town::doGuildOptions(Character *c) {
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+ bool isDarkCc = _vm->_files->_isDarkCc;
+
+ if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) {
+ // Switch character
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ c = &party._activeParty[_buttonValue];
+ intf.highlightChar(_buttonValue);
+
+ if (!c->guildMember()) {
+ sound.playSample(nullptr, 0);
+ intf._overallFrame = 5;
+ File f(isDarkCc ? "skull1.voc" : "guild11.voc");
+ sound.playSample(&f, 1);
+ }
+ }
+ }
+ else if (_buttonValue == Common::KEYCODE_s) {
+ if (c->guildMember())
+ c = showAvailableSpells(c);
+ _buttonValue = 0;
+ } else if (_buttonValue == Common::KEYCODE_c) {
+ if (!c->noActions()) {
+ if (c->guildMember())
+ c = showAvailableSpells(c);
_buttonValue = 0;
- else if (_buttonValue == Common::KEYCODE_w)
- _buttonValue = 1;
+ }
+ }
+
+ return c;
+}
+
+Character *Town::doTavernOptions(Character *c) {
+ Interface &intf = *_vm->_interface;
+ Map &map = *_vm->_map;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+ Screen &screen = *_vm->_screen;
+ bool isDarkCc = _vm->_files->_isDarkCc;
+ int idx = 0;
+
+ 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:
+ // Switch character
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ c = &party._activeParty[_buttonValue];
+ intf.highlightChar(_buttonValue);
+ _v21 = 0;
+ }
+ break;
+ case Common::KEYCODE_d:
+ // Drink
+ if (!c->noActions()) {
+ if (subtract(0, 1, 0, WT_2)) {
+ sound.playSample(nullptr, 0);
+ File f("gulp.voc");
+ sound.playSample(&f, 0);
+ _v21 = 1;
+
+ screen._windows[10].writeString(Common::String::format(TAVERN_TEXT,
+ c->_name.c_str(), GOOD_STUFF,
+ XeenEngine::printMil(party._gold)));
+ drawButtons(&screen._windows[0]);
+ screen._windows[10].update();
+
+ if (_vm->getRandomNumber(100) < 26) {
+ ++c->_conditions[DRUNK];
+ intf.charIconsPrint(true);
+ sound.playFX(28);
+ }
+
+ townWait();
+ }
+ }
+ break;
+ case Common::KEYCODE_f: {
+ if (party._mazeId == (isDarkCc ? 29 : 28)) {
+ _v22 = party._partyCount * 15;
+ _v23 = 10;
+ idx = 0;
+ } else if (isDarkCc && party._mazeId == 31) {
+ _v22 = party._partyCount * 60;
+ _v23 = 100;
+ idx = 1;
+ } else if (!isDarkCc && party._mazeId == 30) {
+ _v22 = party._partyCount * 50;
+ _v23 = 50;
+ idx = 1;
+ } else if (isDarkCc) {
+ _v22 = party._partyCount * 120;
+ _v23 = 250;
+ idx = 2;
+ } else if (party._mazeId == 49) {
+ _v22 = party._partyCount * 120;
+ _v23 = 100;
+ idx = 2;
+ } else {
+ _v22 = party._partyCount * 15;
+ _v23 = 10;
+ idx = 0;
+ }
+
+ Common::String msg = _textStrings[(isDarkCc ? 60 : 75) + idx];
+ screen._windows[10].close();
+ screen._windows[12].open();
+ screen._windows[12].writeString(msg);
+
+ if (YesNo::show(_vm, false, true)) {
+ if (party._food >= _v22) {
+ ErrorScroll::show(_vm, FOOD_PACKS_FULL, WT_2);
+ } else if (subtract(0, _v23, 0, WT_2)) {
+ party._food = _v22;
+ sound.playSample(nullptr, 0);
+ File f(isDarkCc ? "thanks2.voc" : "thankyou.voc");
+ sound.playSample(&f, 1);
+ }
+ }
+
+ screen._windows[12].close();
+ screen._windows[10].open();
+ _buttonValue = 0;
+ break;
+ }
+
+ case Common::KEYCODE_r: {
+ if (party._mazeId == (isDarkCc ? 29 : 28)) {
+ idx = 0;
+ } else if (party._mazeId == (isDarkCc ? 31 : 30)) {
+ idx = 10;
+ } else if (isDarkCc || party._mazeId == 49) {
+ idx = 20;
+ }
+
+ Common::String msg = Common::String::format("\x03""c\x0B""012%s",
+ _textStrings[(party._day % 10) + idx]);
+ Window &w = screen._windows[12];
+ w.open();
+ w.writeString(msg);
+ w.update();
+
+ townWait();
+ w.close();
+ break;
+ }
+
+ case Common::KEYCODE_s: {
+ // Save game
+ // TODO: This needs to be fit in better with ScummVM framework
+ int idx = isDarkCc ? (party._mazeId - 29) >> 1 : party._mazeId - 28;
+ assert(idx >= 0);
+ party._mazePosition.x = TAVERN_EXIT_LIST[isDarkCc ? 1 : 0][_townActionId][idx][0];
+ party._mazePosition.y = TAVERN_EXIT_LIST[isDarkCc ? 1 : 0][_townActionId][idx][1];
+
+ if (!isDarkCc || party._mazeId == 29)
+ party._mazeDirection = DIR_WEST;
+ else if (party._mazeId == 31)
+ party._mazeDirection = DIR_EAST;
else
- break;
+ party._mazeDirection = DIR_SOUTH;
+
+ party._priorMazeId = party._mazeId;
+ for (int idx = 0; idx < party._partyCount; ++idx) {
+ party._activeParty[idx]._savedMazeId = party._mazeId;
+ party._activeParty[idx]._xeenSide = map._loadDarkSide;
+ }
+
+ party.addTime(1440);
+ party._mazeId = 0;
+ _vm->quitGame();
+ break;
+ }
+
+ case Common::KEYCODE_t:
+ if (!c->noActions()) {
+ if (!_v21) {
+ screen._windows[10].writeString(Common::String::format(TAVERN_TEXT,
+ c->_name.c_str(), HAVE_A_DRINK,
+ XeenEngine::printMil(party._gold)));
+ drawButtons(&screen);
+ screen._windows[10].update();
+ townWait();
+ } else {
+ _v21 = 0;
+ if (c->_conditions[DRUNK]) {
+ screen._windows[10].writeString(Common::String::format(TAVERN_TEXT,
+ c->_name.c_str(), YOURE_DRUNK,
+ XeenEngine::printMil(party._gold)));
+ drawButtons(&screen);
+ screen._windows[10].update();
+ townWait();
+ } else if (subtract(0, 1, 0, WT_2)) {
+ sound.playSample(nullptr, 0);
+ File f(isDarkCc ? "thanks2.voc" : "thankyou.voc");
+ sound.playSample(&f, 1);
+
+ if (party._mazeId == (isDarkCc ? 29 : 28)) {
+ _v24 = 30;
+ } else if (isDarkCc && party._mazeId == 31) {
+ _v24 = 40;
+ } else if (!isDarkCc && party._mazeId == 45) {
+ _v24 = 45;
+ } else if (!isDarkCc && party._mazeId == 49) {
+ _v24 = 60;
+ } else if (isDarkCc) {
+ _v24 = 50;
+ }
+
+ Common::String msg = _textStrings[map.mazeData()._tavernTips + _v24];
+ map.mazeData()._tavernTips = (map.mazeData()._tavernTips + 1) /
+ (isDarkCc ? 10 : 15);
- depositWithdrawl(_buttonValue);
+ Window &w = screen._windows[12];
+ w.open();
+ w.writeString(Common::String::format("\x03""c\x0B""012%s", msg.c_str()));
+ w.update();
+ townWait();
+ w.close();
+ }
+ }
+ }
break;
default:
- // TODO: remaining cases
- error("TODO: doTownOptions");
+ break;
+ }
+
+ return c;
+}
+
+Character *Town::doTempleOptions(Character *c) {
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ 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:
+ // Switch character
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ c = &party._activeParty[_buttonValue];
+ intf.highlightChar(_buttonValue);
+ _dayOfWeek = 0;
+ }
+ break;
+
+ case Common::KEYCODE_d:
+ if (_donation && subtract(0, _donation, 0, WT_2)) {
+ sound.playSample(nullptr, 0);
+ File f("coina.voc");
+ sound.playSample(&f, 1);
+ _dayOfWeek = (_dayOfWeek + 1) / 10;
+
+ if (_dayOfWeek == (party._day / 10)) {
+ party._clairvoyanceActive = true;
+ party._lightCount = 1;
+
+ int amt = _dayOfWeek ? _dayOfWeek : 10;
+ party._heroism = amt;
+ party._holyBonus = amt;
+ party._powerShield = amt;
+ party._blessed = amt;
+
+ intf.charIconsPrint(true);
+ sound.playSample(nullptr, 0);
+ File f("ahh.voc");
+ sound.playSample(&f, 1);
+ _flag1 = true;
+ _donation = 0;
+ }
+ }
+ break;
+
+ case Common::KEYCODE_h:
+ if (_healCost && subtract(0, _healCost, 0, WT_2)) {
+ c->_magicResistence._temporary = 0;
+ c->_energyResistence._temporary = 0;
+ c->_poisonResistence._temporary = 0;
+ c->_electricityResistence._temporary = 0;
+ c->_coldResistence._temporary = 0;
+ c->_fireResistence._temporary = 0;
+ c->_ACTemp = 0;
+ c->_level._temporary = 0;
+ c->_luck._temporary = 0;
+ c->_accuracy._temporary = 0;
+ c->_speed._temporary = 0;
+ c->_endurance._temporary = 0;
+ c->_personality._temporary = 0;
+ c->_intellect._temporary = 0;
+ c->_might._temporary = 0;
+ c->_currentHp = c->getMaxHP();
+ Common::fill(&c->_conditions[HEART_BROKEN], &c->_conditions[NO_CONDITION], 0);
+
+ _v1 = 1440;
+ intf.charIconsPrint(true);
+ sound.playSample(nullptr, 0);
+ File f("ahh.voc");
+ sound.playSample(&f, 1);
+ }
+ break;
+
+ case Common::KEYCODE_u:
+ if (_uncurseCost && subtract(0, _uncurseCost, 0, WT_2)) {
+ for (int idx = 0; idx < 9; ++idx) {
+ c->_weapons[idx]._bonusFlags &= ~FLAG_CURSED;
+ c->_armor[idx]._bonusFlags &= ~FLAG_CURSED;
+ c->_accessories[idx]._bonusFlags &= ~FLAG_CURSED;
+ c->_misc[idx]._bonusFlags &= ~FLAG_CURSED;
+ }
+
+ _v1 = 1440;
+ intf.charIconsPrint(true);
+ sound.playSample(nullptr, 0);
+ File f("ahh.voc");
+ sound.playSample(&f, 1);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return c;
+}
+
+Character *Town::doTrainingOptions(Character *c) {
+ Interface &intf = *_vm->_interface;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+ bool isDarkCc = _vm->_files->_isDarkCc;
+
+ 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:
+ // Switch character
+ _buttonValue -= Common::KEYCODE_F1;
+ if (_buttonValue < party._partyCount) {
+ _v2 = _buttonValue;
+ c = &party._activeParty[_buttonValue];
+ intf.highlightChar(_buttonValue);
+ }
+ break;
+
+ case Common::KEYCODE_t:
+ if (_nextExperienceLevel) {
+ sound.playSample(nullptr, 0);
+ _townCurrent = 0;
+
+ Common::String name;
+ if (c->_level._permanent >= _v20) {
+ name = isDarkCc ? "gtlost.voc" : "trainin1.voc";
+ } else {
+ name = isDarkCc ? "gtlost.voc" : "trainin0.voc";
+ }
+
+ File f(name);
+ sound.playSample(&f);
+
+ } else if (!c->noActions()) {
+ if (subtract(0, (c->_level._permanent * c->_level._permanent) * 10, 0, WT_2)) {
+ _townCurrent = 0;
+ sound.playSample(nullptr, 0);
+ File f(isDarkCc ? "prtygd.voc" : "trainin2.voc");
+ sound.playSample(&f, 1);
+
+ c->_experience -= c->currentExperienceLevel() -
+ (c->getCurrentExperience() - c->_experience);
+ c->_level._permanent++;
+
+ if (!_arr1[_v2]) {
+ party.addTime(1440);
+ _arr1[_v2] = 1;
+ }
+
+ party.resetTemps();
+ c->_currentHp = c->getMaxHP();
+ c->_currentSp = c->getMaxSP();
+ intf.charIconsPrint(true);
+ }
+ }
+ break;
+
+ default:
+ break;
}
return c;
@@ -660,4 +1116,12 @@ int Town::subtract(int mode, uint amount, int whereId, ErrorWaitType wait) {
return true;
}
+Character *Town::showItems(Character *c, int v2) {
+ error("TODO: showItems");
+}
+
+Character *Town::showAvailableSpells(Character *c) {
+ error("TODO: showAvailableSpells");
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/town.h b/engines/xeen/town.h
index df754d5cef..950d702d4a 100644
--- a/engines/xeen/town.h
+++ b/engines/xeen/town.h
@@ -49,6 +49,11 @@ private:
int _v10, _v11, _v12;
int _v13, _v14;
int _v20;
+ int _v21;
+ uint _v22;
+ int _v23;
+ int _v24;
+ int _dayOfWeek;
int _uncurseCost;
Common::Point _townPos;
int _arr1[6];
@@ -76,11 +81,27 @@ private:
Character *doTownOptions(Character *c);
+ Character *doBankOptions(Character *c);
+
+ Character *doBlacksmithOptions(Character *c);
+
+ Character *doGuildOptions(Character *c);
+
+ Character *doTavernOptions(Character *c);
+
+ Character *doTempleOptions(Character *c);
+
+ Character *doTrainingOptions(Character *c);
+
void depositWithdrawl(int choice);
void notEnough(int consumableId, int whereId, bool mode, ErrorWaitType wait);
int subtract(int mode, uint amount, int whereId, ErrorWaitType wait);
+
+ Character *showItems(Character *c, int v2);
+
+ Character *showAvailableSpells(Character *c);
public:
Town(XeenEngine *vm);