From b612bc3c23d9ffc6a57eedd684f1d6b10dc3c6ab Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 12 Dec 2017 20:29:47 -0500 Subject: XEEN: Rename Town to LocationManager, added Locations namespace --- engines/xeen/dialogs_input.cpp | 6 +- engines/xeen/dialogs_query.cpp | 6 +- engines/xeen/dialogs_whowill.cpp | 4 +- engines/xeen/locations.cpp | 1661 ++++++++++++++++++++++++++++++++++++++ engines/xeen/locations.h | 371 +++++++++ engines/xeen/module.mk | 2 +- engines/xeen/scripts.cpp | 4 +- engines/xeen/town.cpp | 1658 ------------------------------------- engines/xeen/town.h | 368 --------- engines/xeen/xeen.cpp | 6 +- engines/xeen/xeen.h | 4 +- 11 files changed, 2048 insertions(+), 2042 deletions(-) create mode 100644 engines/xeen/locations.cpp create mode 100644 engines/xeen/locations.h delete mode 100644 engines/xeen/town.cpp delete mode 100644 engines/xeen/town.h (limited to 'engines/xeen') diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp index 2f4a1742b5..a0573d20ef 100644 --- a/engines/xeen/dialogs_input.cpp +++ b/engines/xeen/dialogs_input.cpp @@ -225,7 +225,7 @@ int Choose123::show(XeenEngine *vm, int numOptions) { int Choose123::execute(int numOptions) { EventsManager &events = *_vm->_events; Interface &intf = *_vm->_interface; - Town &town = *_vm->_town; + LocationManager &loc = *_vm->_locations; Windows &windows = *_vm->_windows; Mode oldMode = _vm->_mode; @@ -241,8 +241,8 @@ int Choose123::execute(int numOptions) { do { events.updateGameCounter(); int delay; - if (town.isActive()) { - town.drawAnim(true); + if (loc.isActive()) { + loc.drawAnim(true); delay = 3; } else { intf.draw3d(true); diff --git a/engines/xeen/dialogs_query.cpp b/engines/xeen/dialogs_query.cpp index 7dd35a13c5..fd466938b3 100644 --- a/engines/xeen/dialogs_query.cpp +++ b/engines/xeen/dialogs_query.cpp @@ -102,7 +102,7 @@ bool YesNo::execute(bool type, bool townFlag) { Map &map = *_vm->_map; Party &party = *_vm->_party; Resources &res = *_vm->_resources; - Town &town = *_vm->_town; + LocationManager &loc = *_vm->_locations; Windows &windows = *_vm->_windows; SpriteResource confirmSprites; bool result = false; @@ -127,8 +127,8 @@ bool YesNo::execute(bool type, bool townFlag) { while (!_vm->shouldQuit()) { events.updateGameCounter(); - if (town.isActive()) { - town.drawAnim(townFlag); + if (loc.isActive()) { + loc.drawAnim(townFlag); //numFrames = 3; } else { intf.draw3d(true); diff --git a/engines/xeen/dialogs_whowill.cpp b/engines/xeen/dialogs_whowill.cpp index 36451dcea4..a2be4e3a94 100644 --- a/engines/xeen/dialogs_whowill.cpp +++ b/engines/xeen/dialogs_whowill.cpp @@ -40,7 +40,7 @@ int WhoWill::execute(int message, int action, bool type) { Map &map = *_vm->_map; Party &party = *_vm->_party; Scripts &scripts = *_vm->_scripts; - Town &town = *_vm->_town; + LocationManager &loc = *_vm->_locations; Windows &windows = *_vm->_windows; int numFrames; @@ -66,7 +66,7 @@ int WhoWill::execute(int message, int action, bool type) { events.updateGameCounter(); if (windows[11]._enabled) { - town.drawAnim(false); + loc.drawAnim(false); windows[36].frame(); numFrames = 3; } else { diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp new file mode 100644 index 0000000000..cc2320a7d9 --- /dev/null +++ b/engines/xeen/locations.cpp @@ -0,0 +1,1661 @@ +/* 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/locations.h" +#include "xeen/dialogs_input.h" +#include "xeen/dialogs_items.h" +#include "xeen/dialogs_query.h" +#include "xeen/dialogs_spells.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { +namespace Locations { + +BaseLocation::BaseLocation(LocationAction action) : ButtonContainer(g_vm), + _LocationActionId(action), _isDarkCc(g_vm->_files->_isDarkCc), + _vocName("hello1.voc") { + _townMaxId = (action >= SPHINX) ? 0 : Res.TOWN_MAXES[_isDarkCc][action]; + if (action < NO_ACTION) { + _songName = Res.TOWN_ACTION_MUSIC[_isDarkCc][action]; + _townSprites.resize(Res.TOWN_ACTION_FILES[_isDarkCc][action]); + } + + _animFrame = 0; + _drawFrameIndex = 0; + _farewellTime = 0; + _drawCtr1 = _drawCtr2 = 0; + _townPos = Common::Point(8, 8); +} + +BaseLocation::~BaseLocation() { + Interface &intf = *g_vm->_interface; + + for (uint idx = 0; idx < _townSprites.size(); ++idx) + _townSprites[idx].clear(); + intf.mainIconsPrint(); +} + +int BaseLocation::show() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + Sound &sound = *g_vm->_sound; + Windows &windows = *g_vm->_windows; + + // Play the appropriate music + sound.stopSound(); + sound.playSong(_songName, 223); + + // Load the needed sprite sets for the location + for (uint idx = 0; idx < _townSprites.size(); ++idx) { + Common::String shapesName = Common::String::format("%s%d.twn", + Res.TOWN_ACTION_SHAPES[_LocationActionId], idx + 1); + _townSprites[idx].load(shapesName); + } + + Character *charP = &party._activeParty[0]; + + // Draw the background and the text window + drawBackground(); + drawWindow(); + drawAnim(true); + + // Play the welcome speech + sound.playSound(_vocName, 1); + + do { + wait(); + charP = doOptions(charP); + if (_vm->shouldQuit()) + return 0; + + Common::String msg = createLocationText(*charP); + windows[10].writeString(msg); + drawButtons(&windows[0]); + } while (_buttonValue != Common::KEYCODE_ESCAPE); + + // Handle any farewell message + farewell(); + + int result; + if (party._mazeId != 0) { + map.load(party._mazeId); + _farewellTime += 1440; + party.addTime(_farewellTime); + result = 0; + } else { + _vm->_saves->saveChars(); + result = 2; + } + + return result; +} + +void BaseLocation::drawBackground() { + Interface &intf = *g_vm->_interface; + + intf._face1UIFrame = intf._face2UIFrame = 0; + intf._dangerSenseUIFrame = 0; + intf._spotDoorsUIFrame = 0; + intf._levitateUIFrame = 0; + _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); +} + +void BaseLocation::drawWindow() { + Interface &intf = *g_vm->_interface; + Party &party = *g_vm->_party; + Windows &windows = *g_vm->_windows; + + Character *charP = &party._activeParty[0]; + Common::String title = createLocationText(*charP); + + // Open up the window and write the string + intf.assembleBorder(); + windows[10].open(); + windows[10].writeString(title); + drawButtons(&windows[0]); + + windows[0].update(); + intf.highlightChar(0); +} + +void BaseLocation::drawAnim(bool flag) { + Interface &intf = *g_vm->_interface; + Sound &sound = *g_vm->_sound; + Windows &windows = *g_vm->_windows; + + // TODO: Figure out a clean way to split method into individual location classes + if (_LocationActionId == BLACKSMITH) { + if (sound.isPlaying()) { + if (_isDarkCc) { + _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); + _townSprites[2].draw(0, _vm->getRandomNumber(11) == 1 ? 9 : 10, + Common::Point(34, 33)); + _townSprites[2].draw(0, _vm->getRandomNumber(5) + 3, + Common::Point(34, 54)); + } + } else { + _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); + if (_isDarkCc) { + _townSprites[2].draw(0, _vm->getRandomNumber(11) == 1 ? 9 : 10, + Common::Point(34, 33)); + } + } + } else if (!_isDarkCc || _LocationActionId != TRAINING) { + if (!_townSprites[_drawFrameIndex / 8].empty()) + _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); + } + + switch (_LocationActionId) { + case BANK: + if (sound.isPlaying() || (_isDarkCc && _animFrame)) { + if (_isDarkCc) { + if (sound.isPlaying() || _animFrame == 1) { + _townSprites[4].draw(0, _vm->getRandomNumber(13, 18), + Common::Point(8, 30)); + } else if (_animFrame > 1) { + _townSprites[4].draw(0, 13 - _animFrame++, + Common::Point(8, 30)); + if (_animFrame > 14) + _animFrame = 0; + } + } else { + _townSprites[2].draw(0, _vm->getRandomNumber(7, 11), Common::Point(8, 8)); + } + } + break; + + case GUILD: + if (sound.isPlaying()) { + if (_isDarkCc) { + if (_animFrame) { + _animFrame ^= 1; + _townSprites[6].draw(0, _animFrame, Common::Point(8, 106)); + } else { + _townSprites[6].draw(0, _vm->getRandomNumber(3), Common::Point(16, 48)); + } + } + } + break; + + case TAVERN: + if (sound.isPlaying() && _isDarkCc) { + _townSprites[4].draw(0, _vm->getRandomNumber(7), Common::Point(153, 49)); + } + break; + + case TEMPLE: + if (sound.isPlaying()) { + _townSprites[3].draw(0, _vm->getRandomNumber(2, 4), Common::Point(8, 8)); + + } + break; + + case TRAINING: + if (sound.isPlaying()) { + if (_isDarkCc) { + _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); + } + } else { + if (_isDarkCc) { + _townSprites[0].draw(0, ++_animFrame % 8, Common::Point(8, 8)); + _townSprites[5].draw(0, _vm->getRandomNumber(5), Common::Point(61, 74)); + } else { + _townSprites[1].draw(0, _vm->getRandomNumber(8, 12), Common::Point(8, 8)); + } + } + break; + + default: + break; + } + + if (flag) { + intf._face1UIFrame = 0; + intf._face2UIFrame = 0; + intf._dangerSenseUIFrame = 0; + intf._spotDoorsUIFrame = 0; + intf._levitateUIFrame = 0; + + intf.assembleBorder(); + } + + if (windows[11]._enabled) { + _drawCtr1 = (_drawCtr1 + 1) % 2; + if (!_drawCtr1 || !_drawCtr2) { + _drawFrameIndex = 0; + _drawCtr2 = 0; + } else { + _drawFrameIndex = _vm->getRandomNumber(3); + } + } else { + _drawFrameIndex = (_drawFrameIndex + 1) % _townMaxId; + } + + if (_isDarkCc) { + if (_LocationActionId == BLACKSMITH && (_drawFrameIndex == 4 || _drawFrameIndex == 13)) + sound.playFX(45); + + if (_LocationActionId == TRAINING && _drawFrameIndex == 23) { + sound.playSound("spit1.voc"); + } + } else { + if (_townMaxId == 32 && _drawFrameIndex == 0) + _drawFrameIndex = 17; + if (_townMaxId == 26 && _drawFrameIndex == 0) + _drawFrameIndex = 20; + if (_LocationActionId == BLACKSMITH && (_drawFrameIndex == 3 || _drawFrameIndex == 9)) + sound.playFX(45); + } + + windows[3].update(); + + if (_LocationActionId == BANK) + _animFrame = 2; +} + +int BaseLocation::wait() { + EventsManager &events = *g_vm->_events; + Windows &windows = *g_vm->_windows; + + _buttonValue = 0; + while (!_vm->shouldQuit() && !_buttonValue) { + events.updateGameCounter(); + while (!_vm->shouldQuit() && !_buttonValue && events.timeElapsed() < 3) { + events.pollEventsAndWait(); + checkEvents(_vm); + } + if (!_buttonValue) + drawAnim(!windows[11]._enabled); + } + + return _buttonValue; +} + +/*------------------------------------------------------------------------*/ + +BankLocation::BankLocation() : BaseLocation(BANK) { + _icons1.load("bank.icn"); + _icons2.load("bank2.icn"); + addButton(Common::Rect(234, 108, 259, 128), Common::KEYCODE_d, &_icons1); + addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_w, &_icons1); + addButton(Common::Rect(288, 108, 312, 128), Common::KEYCODE_ESCAPE, &_icons1); + _animFrame = 1; + + _vocName = _isDarkCc ? "bank1.voc" : "banker.voc"; +} + +Common::String BankLocation::createLocationText(Character &ch) { + Party &party = *g_vm->_party; + return Common::String::format(Res.BANK_TEXT, + XeenEngine::printMil(party._bankGold).c_str(), + XeenEngine::printMil(party._bankGems).c_str(), + XeenEngine::printMil(party._gold).c_str(), + XeenEngine::printMil(party._gems).c_str()); +} + +void BankLocation::drawBackground() { + if (_isDarkCc) { + _townSprites[4].draw(0, _vm->getRandomNumber(13, 18), + Common::Point(8, 30)); + } +} + +Character *BankLocation::doOptions(Character *c) { + if (_buttonValue == Common::KEYCODE_d) + _buttonValue = (int)WHERE_PARTY; + else if (_buttonValue == Common::KEYCODE_w) + _buttonValue = (int)WHERE_BANK; + else + return c; + + depositWithdrawl((PartyBank)_buttonValue); + return c; +} + +void BankLocation::depositWithdrawl(PartyBank whereId) { + Party &party = *g_vm->_party; + Sound &sound = *g_vm->_sound; + Windows &windows = *g_vm->_windows; + int gold, gems; + + if (whereId == WHERE_BANK) { + gold = party._bankGold; + gems = party._bankGems; + } else { + gold = party._gold; + gems = party._gems; + } + + for (uint idx = 0; idx < _buttons.size(); ++idx) + _buttons[idx]._sprites = &_icons2; + _buttons[0]._value = Common::KEYCODE_o; + _buttons[1]._value = Common::KEYCODE_e; + _buttons[2]._value = Common::KEYCODE_ESCAPE; + + Common::String msg = Common::String::format(Res.GOLD_GEMS, + Res.DEPOSIT_WITHDRAWL[whereId], + XeenEngine::printMil(gold).c_str(), + XeenEngine::printMil(gems).c_str()); + + windows[35].open(); + windows[35].writeString(msg); + drawButtons(&windows[35]); + windows[35].update(); + + sound.stopSound(); + File voc("coina.voc"); + ConsumableType consType = CONS_GOLD; + + do { + switch (wait()) { + case Common::KEYCODE_o: + consType = CONS_GOLD; + break; + case Common::KEYCODE_e: + consType = CONS_GEMS; + break; + case Common::KEYCODE_ESCAPE: + break; + default: + continue; + } + + if ((whereId == WHERE_BANK && !party._bankGems && consType == CONS_GEMS) || + (whereId == WHERE_BANK && !party._bankGold && consType == CONS_GOLD) || + (whereId == WHERE_PARTY && !party._gems && consType == CONS_GEMS) || + (whereId == WHERE_PARTY && !party._gold && consType == CONS_GOLD)) { + party.notEnough(consType, whereId, WHERE_BANK, WT_2); + } else { + windows[35].writeString(Res.AMOUNT); + int amount = NumericInput::show(_vm, 35, 10, 77); + + if (amount) { + if (consType == CONS_GEMS) { + if (party.subtract(CONS_GEMS, amount, whereId, WT_2)) { + if (whereId == WHERE_BANK) { + party._gems += amount; + } else { + party._bankGems += amount; + } + } + } else { + if (party.subtract(CONS_GOLD, amount, whereId, WT_2)) { + if (whereId == WHERE_BANK) { + party._gold += amount; + } else { + party._bankGold += amount; + } + } + } + } + + if (whereId == WHERE_BANK) { + gold = party._bankGold; + gems = party._bankGems; + } + else { + gold = party._gold; + gems = party._gems; + } + + sound.playSound(voc); + msg = Common::String::format(Res.GOLD_GEMS_2, Res.DEPOSIT_WITHDRAWL[whereId], + XeenEngine::printMil(gold).c_str(), XeenEngine::printMil(gems).c_str()); + windows[35].writeString(msg); + windows[35].update(); + } + // TODO + } while (!g_vm->shouldQuit() && _buttonValue != Common::KEYCODE_ESCAPE); + + for (uint idx = 0; idx < _buttons.size(); ++idx) + _buttons[idx]._sprites = &_icons1; + _buttons[0]._value = Common::KEYCODE_d; + _buttons[1]._value = Common::KEYCODE_w; + _buttons[2]._value = Common::KEYCODE_ESCAPE; +} + +/*------------------------------------------------------------------------*/ + +BlacksmithLocation::BlacksmithLocation() : BaseLocation(BLACKSMITH) { + _icons1.load("esc.icn"); + addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); + addButton(Common::Rect(234, 54, 308, 62), 0); + addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_b); + addButton(Common::Rect(234, 74, 308, 82), 0); + addButton(Common::Rect(234, 84, 308, 92), 0); + + _vocName = _isDarkCc ? "see2.voc" : "whaddayo.voc"; +} + +Common::String BlacksmithLocation::createLocationText(Character &ch) { + Party &party = *g_vm->_party; + return Common::String::format(Res.BLACKSMITH_TEXT, + ch._name.c_str(), XeenEngine::printMil(party._gold).c_str()); +} + +Character *BlacksmithLocation::doOptions(Character *c) { + Interface &intf = *g_vm->_interface; + Party &party = *g_vm->_party; + + if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { + // Switch character + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + } + } else if (_buttonValue == Common::KEYCODE_b) { + c = ItemsDialog::show(_vm, c, ITEMMODE_BLACKSMITH); + _buttonValue = 0; + } + + return c; +} + +void BlacksmithLocation::farewell() { + Sound &sound = *g_vm->_sound; + + if (_isDarkCc) { + sound.stopSound(); + sound.playSound("come1.voc", 1); + } +} + +/*------------------------------------------------------------------------*/ + +GuildLocation::GuildLocation() : BaseLocation(GUILD) { + loadStrings("spldesc.bin"); + _icons1.load("esc.icn"); + addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); + addButton(Common::Rect(234, 54, 308, 62), 0); + addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_b); + addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_s); + addButton(Common::Rect(234, 84, 308, 92), 0); + g_vm->_mode = MODE_17; + + _vocName = _isDarkCc ? "parrot1.voc" : "guild10.voc"; +} + +Common::String GuildLocation::createLocationText(Character &ch) { + return !ch.guildMember() ? Res.GUILD_NOT_MEMBER_TEXT : + Common::String::format(Res.GUILD_TEXT, ch._name.c_str()); +} + +Character *GuildLocation::doOptions(Character *c) { + Interface &intf = *g_vm->_interface; + Party &party = *g_vm->_party; + Sound &sound = *g_vm->_sound; + + if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { + // Switch character + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + + if (!c->guildMember()) { + sound.stopSound(); + _animFrame = 5; + sound.playSound(_isDarkCc ? "skull1.voc" : "guild11.voc", 1); + } + } + } else if (_buttonValue == Common::KEYCODE_s) { + if (c->guildMember()) + c = SpellsDialog::show(_vm, nullptr, c, 0x80); + _buttonValue = 0; + } else if (_buttonValue == Common::KEYCODE_c) { + if (!c->noActions()) { + if (c->guildMember()) + c = SpellsDialog::show(_vm, nullptr, c, 0); + _buttonValue = 0; + } + } + + return c; +} + +/*------------------------------------------------------------------------*/ + +TavernLocation::TavernLocation() : BaseLocation(TAVERN) { + _v21 = 0; + _v22 = 0; + _v23 = 0; + _v24 = 0; + + loadStrings("tavern.bin"); + _icons1.load("tavern.icn"); + addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons1); + addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_s, &_icons1); + addButton(Common::Rect(234, 54, 308, 62), Common::KEYCODE_d); + addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_f); + addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_t); + addButton(Common::Rect(234, 84, 308, 92), Common::KEYCODE_r); + g_vm->_mode = MODE_17; + + _vocName = _isDarkCc ? "hello1.voc" : "hello.voc"; +} + +Common::String TavernLocation::createLocationText(Character &ch) { + Party &party = *g_vm->_party; + return Common::String::format(Res.TAVERN_TEXT, ch._name.c_str(), + Res.FOOD_AND_DRINK, XeenEngine::printMil(party._gold).c_str()); +} + +Character *TavernLocation::doOptions(Character *c) { + Interface &intf = *g_vm->_interface; + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + Sound &sound = *g_vm->_sound; + Windows &windows = *g_vm->_windows; + 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 < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + _v21 = 0; + } + break; + + case Common::KEYCODE_d: + // Drink + if (!c->noActions()) { + if (party.subtract(CONS_GOLD, 1, WHERE_PARTY, WT_2)) { + sound.stopSound(); + sound.playSound("gulp.voc"); + _v21 = 1; + + windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, + c->_name.c_str(), Res.GOOD_STUFF, + XeenEngine::printMil(party._gold).c_str())); + drawButtons(&windows[0]); + windows[10].update(); + + if (_vm->getRandomNumber(100) < 26) { + ++c->_conditions[DRUNK]; + intf.drawParty(true); + sound.playFX(28); + } + + wait(); + } + } + break; + + case Common::KEYCODE_f: { + // Food + if (party._mazeId == (_isDarkCc ? 29 : 28)) { + _v22 = party._activeParty.size() * 15; + _v23 = 10; + idx = 0; + } else if (_isDarkCc && party._mazeId == 31) { + _v22 = party._activeParty.size() * 60; + _v23 = 100; + idx = 1; + } else if (!_isDarkCc && party._mazeId == 30) { + _v22 = party._activeParty.size() * 50; + _v23 = 50; + idx = 1; + } else if (_isDarkCc) { + _v22 = party._activeParty.size() * 120; + _v23 = 250; + idx = 2; + } else if (party._mazeId == 49) { + _v22 = party._activeParty.size() * 120; + _v23 = 100; + idx = 2; + } else { + _v22 = party._activeParty.size() * 15; + _v23 = 10; + idx = 0; + } + + Common::String msg = _textStrings[(_isDarkCc ? 60 : 75) + idx]; + windows[10].close(); + windows[12].open(); + windows[12].writeString(msg); + windows[12].update(); + + if (YesNo::show(_vm, false, true)) { + if (party._food >= _v22) { + ErrorScroll::show(_vm, Res.FOOD_PACKS_FULL, WT_2); + } else if (party.subtract(CONS_GOLD, _v23, WHERE_PARTY, WT_2)) { + party._food = _v22; + sound.stopSound(); + sound.playSound(_isDarkCc ? "thanks2.voc" : "thankyou.voc", 1); + } + } + + windows[12].close(); + windows[10].open(); + _buttonValue = 0; + break; + } + + case Common::KEYCODE_r: { + // Rumors + 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].c_str()); + Window &w = windows[12]; + w.open(); + w.writeString(msg); + w.update(); + + wait(); + w.close(); + break; + } + + case Common::KEYCODE_s: { + // Sign In + idx = _isDarkCc ? (party._mazeId - 29) >> 1 : party._mazeId - 28; + assert(idx >= 0); + party._mazePosition.x = Res.TAVERN_EXIT_LIST[_isDarkCc ? 1 : 0][_LocationActionId][idx][0]; + party._mazePosition.y = Res.TAVERN_EXIT_LIST[_isDarkCc ? 1 : 0][_LocationActionId][idx][1]; + + if (!_isDarkCc || party._mazeId == 29) + party._mazeDirection = DIR_WEST; + else if (party._mazeId == 31) + party._mazeDirection = DIR_EAST; + else + party._mazeDirection = DIR_SOUTH; + + party._priorMazeId = party._mazeId; + for (idx = 0; idx < (int)party._activeParty.size(); ++idx) { + party._activeParty[idx]._savedMazeId = party._mazeId; + party._activeParty[idx]._xeenSide = map._loadDarkSide; + } + + party.addTime(1440); + party._mazeId = 0; + _vm->_quitMode = 2; + break; + } + + case Common::KEYCODE_t: + if (!c->noActions()) { + if (!_v21) { + windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, + c->_name.c_str(), Res.HAVE_A_DRINK, + XeenEngine::printMil(party._gold).c_str())); + drawButtons(&windows[0]); + windows[10].update(); + wait(); + } else { + _v21 = 0; + if (c->_conditions[DRUNK]) { + windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, + c->_name.c_str(), Res.YOURE_DRUNK, + XeenEngine::printMil(party._gold).c_str())); + drawButtons(&windows[0]); + windows[10].update(); + wait(); + } else if (party.subtract(CONS_GOLD, 1, WHERE_PARTY, WT_2)) { + sound.stopSound(); + sound.playSound(_isDarkCc ? "thanks2.voc" : "thankyou.voc", 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); + + Window &w = windows[12]; + w.open(); + w.writeString(Common::String::format("\x03""c\x0B""012%s", msg.c_str())); + w.update(); + wait(); + w.close(); + } + } + } + break; + + default: + break; + } + + return c; +} + +void TavernLocation::farewell() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + Sound &sound = *g_vm->_sound; + + sound.stopSound(); + sound.playSound(_isDarkCc ? "gdluck1.voc" : "goodbye.voc", 1); + + map.mazeData()._mazeNumber = party._mazeId; +} + +/*------------------------------------------------------------------------*/ + +TempleLocation::TempleLocation() : BaseLocation(TEMPLE) { + _currentCharLevel = 0; + _donation = 0; + _healCost = 0; + _uncurseCost = 0; + _dayOfWeek = 0; + _v10 = _v11 = 0; + _v12 = _v13 = 0; + _v14 = 0; + _flag1 = false; + _v5 = _v6 = 0; + + _icons1.load("esc.icn"); + addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); + addButton(Common::Rect(234, 54, 308, 62), Common::KEYCODE_h); + addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_d); + addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_u); + addButton(Common::Rect(234, 84, 308, 92), 0); + + _vocName = _isDarkCc ? "help2.voc" : "maywe2.voc"; +} + +Common::String TempleLocation::createLocationText(Character &ch) { + Party &party = *g_vm->_party; + + if (party._mazeId == (_isDarkCc ? 29 : 28)) { + _v10 = _v11 = _v12 = _v13 = 0; + _v14 = 10; + } else if (party._mazeId == (_isDarkCc ? 31 : 30)) { + _v13 = 10; + _v12 = 50; + _v11 = 500; + _v10 = 100; + _v14 = 25; + } else if (party._mazeId == (_isDarkCc ? 37 : 73)) { + _v13 = 20; + _v12 = 100; + _v11 = 1000; + _v10 = 200; + _v14 = 50; + } else if (_isDarkCc || party._mazeId == 49) { + _v13 = 100; + _v12 = 500; + _v11 = 5000; + _v10 = 300; + _v14 = 100; + } + + _currentCharLevel = ch.getCurrentLevel(); + if (ch._currentHp < ch.getMaxHP()) { + _healCost = _currentCharLevel * 10 + _v13; + } + + for (int attrib = HEART_BROKEN; attrib <= UNCONSCIOUS; ++attrib) { + if (ch._conditions[attrib]) + _healCost += _currentCharLevel * 10; + } + + _v6 = 0; + if (ch._conditions[DEAD]) { + _v6 += (_currentCharLevel * 100) + (ch._conditions[DEAD] * 50) + _v12; + } + if (ch._conditions[STONED]) { + _v6 += (_currentCharLevel * 100) + (ch._conditions[STONED] * 50) + _v12; + } + if (ch._conditions[ERADICATED]) { + _v5 = (_currentCharLevel * 1000) + (ch._conditions[ERADICATED] * 500) + _v11; + } + + for (int idx = 0; idx < 9; ++idx) { + _uncurseCost |= ch._weapons[idx]._bonusFlags & 0x40; + _uncurseCost |= ch._armor[idx]._bonusFlags & 0x40; + _uncurseCost |= ch._accessories[idx]._bonusFlags & 0x40; + _uncurseCost |= ch._misc[idx]._bonusFlags & 0x40; + } + + if (_uncurseCost || ch._conditions[CURSED]) + _v5 = (_currentCharLevel * 20) + _v10; + + _donation = _flag1 ? 0 : _v14; + _healCost += _v6 + _v5; + + return Common::String::format(Res.TEMPLE_TEXT, ch._name.c_str(), + _healCost, _donation, XeenEngine::printK(_uncurseCost).c_str(), + XeenEngine::printMil(party._gold).c_str()); +} + +Character *TempleLocation::doOptions(Character *c) { + Interface &intf = *g_vm->_interface; + Party &party = *g_vm->_party; + Sound &sound = *g_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 < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + _dayOfWeek = 0; + } + break; + + case Common::KEYCODE_d: + if (_donation && party.subtract(CONS_GOLD, _donation, WHERE_PARTY, WT_2)) { + sound.stopSound(); + sound.playSound("coina.voc", 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.drawParty(true); + sound.stopSound(); + sound.playSound("ahh.voc"); + _flag1 = true; + _donation = 0; + } + } + break; + + case Common::KEYCODE_h: + if (_healCost && party.subtract(CONS_GOLD, _healCost, WHERE_PARTY, 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); + + _farewellTime = 1440; + intf.drawParty(true); + sound.stopSound(); + sound.playSound("ahh.voc", 1); + } + break; + + case Common::KEYCODE_u: + if (_uncurseCost && party.subtract(CONS_GOLD, _uncurseCost, WHERE_PARTY, WT_2)) { + for (int idx = 0; idx < 9; ++idx) { + c->_weapons[idx]._bonusFlags &= ~ITEMFLAG_CURSED; + c->_armor[idx]._bonusFlags &= ~ITEMFLAG_CURSED; + c->_accessories[idx]._bonusFlags &= ~ITEMFLAG_CURSED; + c->_misc[idx]._bonusFlags &= ~ITEMFLAG_CURSED; + } + + _farewellTime = 1440; + intf.drawParty(true); + sound.stopSound(); + sound.playSound("ahh.voc", 1); + } + break; + + default: + break; + } + + return c; +} + +/*------------------------------------------------------------------------*/ + +TrainingLocation::TrainingLocation() : BaseLocation(TRAINING) { + Common::fill(&_charsTrained[0], &_charsTrained[6], 0); + _maxLevel = 0; + _experienceToNextLevel = 0; + _charIndex = 0; + + _icons1.load("train.icn"); + addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons1); + addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_icons1); + + _vocName = _isDarkCc ? "training.voc" : "youtrn1.voc"; +} + +Common::String TrainingLocation::createLocationText(Character &ch) { + Party &party = *g_vm->_party; + if (_isDarkCc) { + switch (party._mazeId) { + case 29: + // Castleview + _maxLevel = 30; + break; + case 31: + // Sandcaster + _maxLevel = 50; + break; + case 37: + // Olympus + _maxLevel = 200; + break; + default: + // Kalindra's Castle + _maxLevel = 100; + break; + } + } else { + switch (party._mazeId) { + case 28: + // Vertigo + _maxLevel = 10; + break; + case 30: + // Rivercity + _maxLevel = 15; + break; + default: + // Newcastle + _maxLevel = 20; + break; + } + } + + _experienceToNextLevel = ch.experienceToNextLevel(); + + Common::String msg; + if (_experienceToNextLevel && ch._level._permanent < _maxLevel) { + // Need more experience + int nextLevel = ch._level._permanent + 1; + msg = Common::String::format(Res.EXPERIENCE_FOR_LEVEL, + ch._name.c_str(), _experienceToNextLevel, nextLevel); + } else if (ch._level._permanent >= _maxLevel) { + // At maximum level + _experienceToNextLevel = 1; + msg = Common::String::format(Res.LEARNED_ALL, ch._name.c_str()); + } else { + // Eligble for level increase + msg = Common::String::format(Res.ELIGIBLE_FOR_LEVEL, + ch._name.c_str(), ch._level._permanent + 1); + } + + return Common::String::format(Res.TRAINING_TEXT, msg.c_str(), + XeenEngine::printMil(party._gold).c_str()); +} + +Character *TrainingLocation::doOptions(Character *c) { + Interface &intf = *g_vm->_interface; + Party &party = *g_vm->_party; + Sound &sound = *g_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 < (int)party._activeParty.size()) { + _charIndex = _buttonValue; + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + } + break; + + case Common::KEYCODE_t: + if (_experienceToNextLevel) { + sound.stopSound(); + _drawFrameIndex = 0; + + Common::String name; + if (c->_level._permanent >= _maxLevel) { + name = _isDarkCc ? "gtlost.voc" : "trainin1.voc"; + } else { + name = _isDarkCc ? "gtlost.voc" : "trainin0.voc"; + } + + sound.playSound(name); + + } else if (!c->noActions()) { + if (party.subtract(CONS_GOLD, (c->_level._permanent * c->_level._permanent) * 10, WHERE_PARTY, WT_2)) { + _drawFrameIndex = 0; + sound.stopSound(); + sound.playSound(_isDarkCc ? "prtygd.voc" : "trainin2.voc", 1); + + c->_experience -= c->nextExperienceLevel() - + (c->getCurrentExperience() - c->_experience); + c->_level._permanent++; + + if (!_charsTrained[_charIndex]) { + party.addTime(1440); + _charsTrained[_charIndex] = true; + } + + party.resetTemps(); + c->_currentHp = c->getMaxHP(); + c->_currentSp = c->getMaxSP(); + intf.drawParty(true); + } + } + break; + + default: + break; + } + + return c; +} + +/*------------------------------------------------------------------------*/ + +ArenaLocation::ArenaLocation() : BaseLocation(ARENA) { + // TODO +} + +/*------------------------------------------------------------------------*/ + +CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action), + _animCtr(0), _mazeFlag(false) { + Party &party = *g_vm->_party; + _mazeId = party._mazeId; + _mazePos = party._mazePosition; + _mazeDir = party._mazeDirection; +} + +void CutsceneLocation::cutsceneAnimUpdate() { + // TODO +} + +void CutsceneLocation::setNewLocation() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + map.load(_mazeId); + party._mazePosition = _mazePos; + party._mazeDirection = _mazeDir; +} + +/*------------------------------------------------------------------------*/ + +ReaperCutscene::ReaperCutscene() : CutsceneLocation(REAPER) { + // TODO +} + +/*------------------------------------------------------------------------*/ + +GolemCutscene::GolemCutscene() : CutsceneLocation(GOLEM) { + // TODO +} + +/*------------------------------------------------------------------------*/ + +const int16 DWARF_X0[2][13] = { + { 0, -5, -7, -8, -11, -9, -3, 1, 6, 10, 15, 18, 23 }, + { 0, 4, 6, 8, 11, 12, 15, 17, 19, 22, 25, 0, 0 } +}; +const int DWARF_X1[2][13] = { + { 160, 145, 133, 122, 109, 101, 97, 91, 86, 80, 75, 68, 63 }, + { 160, 154, 146, 138, 131, 122, 115, 107, 99, 92, 85, 0, 0 } +}; +const int DWARF_X2[13] = { + 0, -1, -4, -7, -9, -13, -15, -18, -21, -23, -25, 0, 0 +}; +const int16 DWARF_Y[2][13] = { + { 0, 0, 4, 9, 13, 15, 20, 24, 30, 37, 45, 51, 58 }, + { 0, 12, 25, 36, 38, 40, 41, 42, 44, 45, 50, 0, 0 } +}; +const int16 DWARF2_X[2][16] = { + { 0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -20, -20, -20, -20, -20 }, + { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 } +}; +const int16 DWARF2_Y[2][16] = { + { 0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 187 }, + { 0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 186 } +}; + +DwarfCutscene::DwarfCutscene(bool isDwarf) : CutsceneLocation(NO_ACTION) { + _townMaxId = Res.TOWN_MAXES[_isDarkCc][isDwarf ? DWARF1 : DWARF2]; +} + +int DwarfCutscene::show() { + EventsManager &events = *g_vm->_events; + Interface &intf = *g_vm->_interface; + Screen &screen = *g_vm->_screen; + Sound &sound = *g_vm->_sound; + Windows &windows = *g_vm->_windows; + + SpriteResource sprites1(_isDarkCc ? "town1.zom" : "dwarf1.vga"); + SpriteResource sprites2(_isDarkCc ? "town2.zom" : "dwarf2.vga"); + SpriteResource sprites3(_isDarkCc ? "town3.zom" : "dwarf3.vga"); + SpriteResource boxSprites("box.vga"); + getNewLocation(); + + // Save the screen contents + Graphics::ManagedSurface savedBg; + savedBg.copyFrom(screen); + + for (int idx = 0; idx < (_isDarkCc ? 10 : 12); ++idx) { + screen.copyFrom(savedBg); + sprites1.draw(0, 0, + Common::Point(DWARF_X0[_isDarkCc][idx], DWARF_Y[_isDarkCc][idx])); + sprites1.draw(0, 1, + Common::Point(DWARF_X1[_isDarkCc][idx], DWARF_Y[_isDarkCc][idx])); + if (_isDarkCc) + sprites1.draw(0, 2, + Common::Point(DWARF_X2[idx], DWARF_Y[_isDarkCc][idx])); + + windows[0].update(); + events.wait(1); + } + + savedBg.copyFrom(screen); + for (int idx = 15; idx >= 0; --idx) { + screen.copyFrom(savedBg); + sprites2.draw(0, 0, Common::Point(DWARF2_X[_isDarkCc][idx], DWARF2_Y[_isDarkCc][idx])); + windows[0].update(); + events.wait(1); + } + + sound.setMusicVolume(48); + screen.copyFrom(savedBg); + sprites2.draw(0, 0); + windows[0].update(); + + for (int idx = 0; idx < (_isDarkCc ? 2 : 3); ++idx) { + switch (idx) { + case 0: + sound.playSound(_isDarkCc ? "pass2.voc" : "dwarf10.voc"); + break; + + case 1: + if (_isDarkCc) { + sprites2.draw(0, 0); + sprites3.draw(0, 0); + cutsceneAnimUpdate(); + + events.timeMark5(); + while (!g_vm->shouldQuit() && events.timeElapsed5() < 7) + events.pollEventsAndWait(); + + sound.playSound(_mazeFlag ? "ok2.voc" : "back2.voc"); + } else { + sound.playSound("dwarf11.voc"); + } + break; + + case 2: + sound.playSound("dwarf12.voc"); + break; + } + + events.updateGameCounter(); + do { + sprites2.draw(0, 0); + sprites3.draw(0, g_vm->getRandomNumber(_isDarkCc ? 8 : 9)); + cutsceneAnimUpdate(); + + events.timeMark5(); + while (!g_vm->shouldQuit() && events.timeElapsed5() < 2) + events.pollEventsAndWait(); + } while (!g_vm->shouldQuit() && (sound.isPlaying() || _animCtr)); + + while (!g_vm->shouldQuit() && events.timeElapsed() < 3) + events.pollEventsAndWait(); + } + + sprites2.draw(0, 0); + if (!_isDarkCc) + sprites3.draw(0, 1); + windows[0].update(); + + setNewLocation(); + + // Restore game screen + sound.setMusicVolume(95); + screen.loadBackground("back.raw"); + intf.drawParty(false); + intf.draw3d(false, false); + + events.clearEvents(); + return 0; +} + +void DwarfCutscene::getNewLocation() { + Party &party = *g_vm->_party; + + if (_isDarkCc) { + switch (party._mazeId) { + case 4: + if (party._questItems[35]) { + _mazeId = 29; + _mazePos = Common::Point(15, 31); + _mazeDir = DIR_SOUTH; + } + break; + + case 6: + if (party._questItems[38]) { + _mazeId = 35; + _mazePos = Common::Point(15, 8); + _mazeDir = DIR_WEST; + } + break; + + case 19: + if (party._questItems[36]) { + _mazeId = 31; + _mazePos = Common::Point(31, 16); + _mazeDir = DIR_WEST; + } + break; + + case 22: + if (party._questItems[37]) { + _mazeId = 33; + _mazePos = Common::Point(0, 3); + _mazeDir = DIR_EAST; + } + break; + + case 98: + if (party._questItems[39]) { + _mazeId = 37; + _mazePos = Common::Point(7, 0); + _mazeDir = DIR_NORTH; + } + break; + + default: + break; + } + + _mazeFlag = _mazeId != 0; + } else { + switch (party._mazeId) { + case 14: + _mazeId = 37; + _mazePos = Common::Point(1, 4); + _mazeDir = DIR_EAST; + break; + + case 18: + if (party._mazePosition.x == 9) { + _mazeId = 35; + _mazePos = Common::Point(1, 12); + _mazeDir = DIR_EAST; + } else { + _mazeId = 36; + _mazePos = Common::Point(7, 1); + _mazeDir = DIR_NORTH; + } + break; + + case 23: + if (party._mazePosition.x == 5) { + _mazeId = 33; + _mazePos = Common::Point(7, 1); + _mazeDir = DIR_NORTH; + } else { + _mazeId = 34; + _mazePos = Common::Point(7, 30); + _mazeDir = DIR_SOUTH; + } + break; + + default: + break; + } + } +} + +/*------------------------------------------------------------------------*/ + +SphinxCutscene::SphinxCutscene() : CutsceneLocation(SPHINX) { + SpriteResource sprites1("sphinx.vga"); + _boxSprites.load("box.vga"); + + + // TODO +} + +void SphinxCutscene::getNewLocation() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + + switch (party._mazeId) { + case 2: + if (party._questItems[51]) { + map._loadDarkSide = true; + _mazeId = 125; + _mazePos = Common::Point(7, 6); + _mazeDir = DIR_NORTH; + _mazeFlag = true; + } + break; + + case 5: + if (party._questItems[4]) { + _mazeId = 82; + _mazePos = Common::Point(7, 5); + _mazeDir = DIR_NORTH; + _mazeFlag = true; + } + break; + + default: + break; + } + + if (!_mazeFlag) { + _mazeId = party._mazeId; + _mazePos = party._mazePosition; + _mazeDir = party._mazeDirection; + } +} + + +/*------------------------------------------------------------------------*/ + +PyramidLocation::PyramidLocation() : BaseLocation(PYRAMID) { +} + +int PyramidLocation::show() { + EventsManager &events = *g_vm->_events; + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + Windows &windows = *g_vm->_windows; + int mapId; + Direction dir = DIR_NORTH; + Common::Point pt; + + if (g_vm->getGameID() == GType_WorldOfXeen) { + if (_isDarkCc) { + if (party._mazeId == 52) { + mapId = 49; + pt = Common::Point(7, 14); + dir = DIR_SOUTH; + } else { + mapId = 23; + pt = Common::Point(8, 10); + } + } else { + if (party._mazeId == 49) { + mapId = 52; + pt = Common::Point(2, 2); + } else { + mapId = 29; + pt = Common::Point(25, 21); + } + } + + // Load the destination map and set position and direction + map._loadDarkSide = !_isDarkCc; + map.load(mapId); + party._mazePosition = pt; + party._mazeDirection = dir; + } else { + // Playing Clouds or Dark Side on it's own, so can't switch sides + Window &win = windows[12]; + Common::String msg = Common::String::format(Res.MOONS_NOT_ALIGNED, + _isDarkCc ? "Clouds" : "Darkside"); + win.open(); + win.writeString(msg); + win.update(); + + events.waitForPressAnimated(); + win.close(); + } + + return 0; +} + +} // End of namespace Locations + +/*------------------------------------------------------------------------*/ + +LocationManager::LocationManager() : _location(nullptr) { +} + +int LocationManager::doAction(LocationAction actionId) { + // Create the desired location + switch (actionId) { + case BANK: + _location = new Locations::BankLocation(); + break; + case BLACKSMITH: + _location = new Locations::BlacksmithLocation(); + break; + case GUILD: + _location = new Locations::GuildLocation(); + break; + case TAVERN: + _location = new Locations::TavernLocation(); + break; + case TEMPLE: + _location = new Locations::TempleLocation(); + break; + case TRAINING: + _location = new Locations::TrainingLocation(); + break; + case ARENA: + _location = new Locations::ArenaLocation(); + break; + case REAPER: + _location = new Locations::ReaperCutscene(); + break; + case GOLEM: + _location = new Locations::GolemCutscene(); + break; + case DWARF1: + _location = new Locations::DwarfCutscene(true); + break; + case DWARF2: + _location = new Locations::DwarfCutscene(false); + break; + case SPHINX: + _location = new Locations::SphinxCutscene(); + break; + case PYRAMID: + _location = new Locations::PyramidLocation(); + break; + default: + return 0; + } + + // Show the location + int result = _location->show(); + delete _location; + _location = nullptr; + + return result; +} + +bool LocationManager::isActive() const { + return _location != nullptr; +} + +void LocationManager::drawAnim(bool flag) { + if (_location) + _location->drawAnim(flag); +} + +/*------------------------------------------------------------------------*/ + +bool LocationMessage::show(int portrait, const Common::String &name, + const Common::String &text, int confirm) { + LocationMessage *dlg = new LocationMessage(); + bool result = dlg->execute(portrait, name, text, confirm); + delete dlg; + + return result; +} + +bool LocationMessage::execute(int portrait, const Common::String &name, const Common::String &text, + int confirm) { + EventsManager &events = *g_vm->_events; + Interface &intf = *g_vm->_interface; + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + Resources &res = *g_vm->_resources; + Windows &windows = *g_vm->_windows; + Window &w = windows[11]; + + _townMaxId = 4; + _drawFrameIndex = 0; + _townPos = Common::Point(23, 22); + + if (!confirm) + loadButtons(); + + _townSprites.resize(2); + _townSprites[0].load(Common::String::format("face%02d.fac", portrait)); + _townSprites[1].load("frame.fac"); + + if (!w._enabled) + w.open(); + + int result = -1; + Common::String msgText = text; + do { + Common::String msg = Common::String::format("\r\v014\x03""c\t125%s\t000\v054%s", + name.c_str(), msgText.c_str()); + + // Count the number of words + const char *msgEnd = w.writeString(msg); + int wordCount = 0; + + for (const char *msgP = msg.c_str(); msgP != msgEnd && *msgP; ++msgP) { + if (*msgP == ' ') + ++wordCount; + } + + _drawCtr2 = wordCount * 2; // Set timeout + _townSprites[1].draw(0, 0, Common::Point(16, 16)); + _townSprites[0].draw(0, _drawFrameIndex, Common::Point(23, 22)); + w.update(); + + if (!msgEnd && !confirm) { + res._globalSprites.draw(0, 7, Common::Point(232, 74)); + res._globalSprites.draw(0, 0, Common::Point(235, 75)); + res._globalSprites.draw(0, 2, Common::Point(260, 75)); + windows[34].update(); + + intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; + intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; + } + + if (confirm == 2) { + intf._face1State = intf._face2State = 2; + return false; + } + + do { + events.clearEvents(); + events.updateGameCounter(); + if (msgEnd) + clearButtons(); + + do { + events.pollEventsAndWait(); + checkEvents(_vm); + + if (_vm->shouldQuit()) + return false; + + while (events.timeElapsed() >= 3) { + drawAnim(false); + events.updateGameCounter(); + } + } while (!_buttonValue); + + if (msgEnd) + // Another screen of text remaining + break; + + if (confirm || _buttonValue == Common::KEYCODE_ESCAPE || + _buttonValue == Common::KEYCODE_n) + result = 0; + else if (_buttonValue == Common::KEYCODE_y) + result = 1; + } while (result == -1); + + if (msgEnd) { + // Text remaining, so cut off already displayed page's + msgText = Common::String(msgEnd); + _drawCtr2 = wordCount; + continue; + } + } while (result == -1); + + intf._face1State = intf._face2State = 2; + if (!confirm) + intf.mainIconsPrint(); + + _townSprites[0].clear(); + _townSprites[1].clear(); + events.clearEvents(); + return result == 1; +} + +void LocationMessage::loadButtons() { + _iconSprites.load("confirm.icn"); + + addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_y, &_iconSprites); + addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_n, &_iconSprites); + addButton(Common::Rect(), Common::KEYCODE_ESCAPE); +} + +} // End of namespace Xeen diff --git a/engines/xeen/locations.h b/engines/xeen/locations.h new file mode 100644 index 0000000000..e0f4838fd6 --- /dev/null +++ b/engines/xeen/locations.h @@ -0,0 +1,371 @@ +/* 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_LOCATIONS_H +#define XEEN_LOCATIONS_H + +#include "common/scummsys.h" +#include "common/str-array.h" +#include "xeen/dialogs.h" +#include "xeen/dialogs_error.h" +#include "xeen/party.h" + +namespace Xeen { + +enum LocationAction { + BANK = 0, BLACKSMITH = 1, GUILD = 2, TAVERN = 3, TEMPLE = 4, + TRAINING = 5, ARENA = 6, NO_ACTION = 7, REAPER = 8, GOLEM = 9, + DWARF1 = 10, SPHINX = 11, PYRAMID = 12, DWARF2 = 13 +}; + +class XeenEngine; + +namespace Locations { + +class BaseLocation : public ButtonContainer { +protected: + LocationAction _LocationActionId; + Common::Array _townSprites; + SpriteResource _icons1, _icons2; + int _townMaxId; + const bool &_isDarkCc; + int _animFrame; + Common::String _vocName, _songName; + Common::Point _townPos; + int _drawFrameIndex; + uint _farewellTime; + int _drawCtr1, _drawCtr2; +protected: + /** + * Draw the window + */ + void drawWindow(); + + /** + * Waits for a brief pause, checking for any key or mouse events + */ + int wait(); + + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch) { return ""; } + + /** + * Draw the visual background + */ + virtual void drawBackground(); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c) { return c; } + + /** + * Handle any farewell + */ + virtual void farewell() {} +public: + BaseLocation(LocationAction action); + virtual ~BaseLocation(); + + /** + * Show the town location + */ + virtual int show(); + + /** + * Draws the animated parts + */ + void drawAnim(bool flag); +}; + +class BankLocation : public BaseLocation { +private: + /** + * Handles deposits or withdrawls fro the bank + */ + void depositWithdrawl(PartyBank whereId); +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Draw the visual background + */ + virtual void drawBackground(); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + BankLocation(); + virtual ~BankLocation() {} +}; + +class BlacksmithLocation : public BaseLocation { +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Handle any farewell + */ + virtual void farewell(); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + BlacksmithLocation(); + virtual ~BlacksmithLocation() {} +}; + +class GuildLocation : public BaseLocation { +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + GuildLocation(); + virtual ~GuildLocation() {} +}; + +class TavernLocation : public BaseLocation { +private: + int _v21; + uint _v22; + int _v23; + int _v24; +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Handle any farewell + */ + virtual void farewell(); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + TavernLocation(); + virtual ~TavernLocation() {} +}; + +class TempleLocation : public BaseLocation { +private: + int _currentCharLevel; + int _donation; + int _healCost; + int _uncurseCost; + int _dayOfWeek; + int _v10, _v11, _v12; + int _v13, _v14; + bool _flag1; + int _v5, _v6; +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + TempleLocation(); + virtual ~TempleLocation() {} +}; + +class TrainingLocation : public BaseLocation { +private: + int _charIndex; + bool _charsTrained[MAX_ACTIVE_PARTY]; + uint _experienceToNextLevel; + uint _maxLevel; +protected: + /** + * Generates the display text for the location, for a given character + */ + virtual Common::String createLocationText(Character &ch); + + /** + * Handles options for the particular location + */ + virtual Character *doOptions(Character *c); +public: + TrainingLocation(); + virtual ~TrainingLocation() {} +}; + +class ArenaLocation : public BaseLocation { +public: + ArenaLocation(); + virtual ~ArenaLocation() {} +}; + +class CutsceneLocation : public BaseLocation { +protected: + int _animCtr; + SpriteResource _boxSprites; + int _mazeId; + Direction _mazeDir; + Common::Point _mazePos; + bool _mazeFlag; +protected: + /** + * Handles cutscene animation update + */ + void cutsceneAnimUpdate(); + + /** + * Sets the new location + */ + void setNewLocation(); +public: + CutsceneLocation(LocationAction action); +}; + +class ReaperCutscene : public CutsceneLocation { +public: + ReaperCutscene(); + virtual ~ReaperCutscene() {} +}; + +class GolemCutscene : public CutsceneLocation { +public: + GolemCutscene(); + virtual ~GolemCutscene() {} +}; + +class DwarfCutscene : public CutsceneLocation { +private: + /** + * Get the new location + */ + void getNewLocation(); +public: + DwarfCutscene(bool isDwarf1); + virtual ~DwarfCutscene() {} + + /** + * Show the town location + */ + virtual int show(); +}; + +class SphinxCutscene : public CutsceneLocation { +private: + /** + * Get the new location + */ + void getNewLocation(); +public: + SphinxCutscene(); + virtual ~SphinxCutscene() {} +}; + +class PyramidLocation : public BaseLocation { +public: + PyramidLocation(); + virtual ~PyramidLocation() {} + + /** + * Show the town location + */ + virtual int show(); +}; + +} // End of namespace Locations + +class LocationMessage : public Locations::BaseLocation { +private: + SpriteResource _iconSprites; + + LocationMessage() : Locations::BaseLocation(NO_ACTION) {} + + bool execute(int portrait, const Common::String &name, + const Common::String &text, int confirm); + + void loadButtons(); +public: + static bool show(int portrait, const Common::String &name, + const Common::String &text, int confirm); +}; + +class LocationManager { +private: + Locations::BaseLocation *_location; +private: + int townWait(); + + Character *doBankOptions(Character *c); + + Character *doBlacksmithOptions(Character *c); + + Character *doGuildOptions(Character *c); + + Character *doTavernOptions(Character *c); + + Character *doTempleOptions(Character *c); + + Character *doTrainingOptions(Character *c); +public: + LocationManager(); + + /** + * Show a given location, and return any result + */ + int doAction(LocationAction actionId); + + /** + * Returns true if a town location (bank, blacksmith, etc.) is currently active + */ + bool isActive() const; + + /** + * Draws a currently active town location's animation + */ + void drawAnim(bool flag); +}; + +} // End of namespace Xeen + +#endif /* XEEN_LOCATIONS_H */ diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index 7656f4cac0..2e11e1936e 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -35,6 +35,7 @@ MODULE_OBJS := \ interface.o \ interface_minimap.o \ interface_scene.o \ + locations.o \ map.o \ music.o \ party.o \ @@ -45,7 +46,6 @@ MODULE_OBJS := \ sound.o \ spells.o \ sprites.o \ - town.o \ window.o \ xeen.o \ xsurface.o diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index e630893f41..cfdd9b7d42 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -442,7 +442,7 @@ bool Scripts::cmdNPC(ParamsIterator ¶ms) { int confirm = params.readByte(); int lineNum = params.readByte(); - if (TownMessage::show(portrait, _message, map._events._text[textNum], + if (LocationMessage::show(portrait, _message, map._events._text[textNum], confirm)) { _lineNum = lineNum; return false; @@ -839,7 +839,7 @@ bool Scripts::cmdSpawn(ParamsIterator ¶ms) { } bool Scripts::cmdDoTownEvent(ParamsIterator ¶ms) { - _scriptResult = _vm->_town->townAction((TownAction)params.readByte()); + _scriptResult = _vm->_locations->doAction((LocationAction)params.readByte()); _vm->_party->_stepped = true; _refreshIcons = true; diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp deleted file mode 100644 index 4a635c71a3..0000000000 --- a/engines/xeen/town.cpp +++ /dev/null @@ -1,1658 +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 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/town.h" -#include "xeen/dialogs_input.h" -#include "xeen/dialogs_items.h" -#include "xeen/dialogs_query.h" -#include "xeen/dialogs_spells.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -BaseLocation::BaseLocation(TownAction action) : ButtonContainer(g_vm), - _townActionId(action), _isDarkCc(g_vm->_files->_isDarkCc), - _vocName("hello1.voc") { - _townMaxId = (action >= SPHINX) ? 0 : Res.TOWN_MAXES[_isDarkCc][action]; - if (action < NO_ACTION) { - _songName = Res.TOWN_ACTION_MUSIC[_isDarkCc][action]; - _townSprites.resize(Res.TOWN_ACTION_FILES[_isDarkCc][action]); - } - - _animFrame = 0; - _drawFrameIndex = 0; - _farewellTime = 0; - _drawCtr1 = _drawCtr2 = 0; - _townPos = Common::Point(8, 8); -} - -BaseLocation::~BaseLocation() { - Interface &intf = *g_vm->_interface; - - for (uint idx = 0; idx < _townSprites.size(); ++idx) - _townSprites[idx].clear(); - intf.mainIconsPrint(); -} - -int BaseLocation::show() { - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - Sound &sound = *g_vm->_sound; - Windows &windows = *g_vm->_windows; - - // Play the appropriate music - sound.stopSound(); - sound.playSong(_songName, 223); - - // Load the needed sprite sets for the location - for (uint idx = 0; idx < _townSprites.size(); ++idx) { - Common::String shapesName = Common::String::format("%s%d.twn", - Res.TOWN_ACTION_SHAPES[_townActionId], idx + 1); - _townSprites[idx].load(shapesName); - } - - Character *charP = &party._activeParty[0]; - - // Draw the background and the text window - drawBackground(); - drawWindow(); - drawAnim(true); - - // Play the welcome speech - sound.playSound(_vocName, 1); - - do { - wait(); - charP = doOptions(charP); - if (_vm->shouldQuit()) - return 0; - - Common::String msg = createLocationText(*charP); - windows[10].writeString(msg); - drawButtons(&windows[0]); - } while (_buttonValue != Common::KEYCODE_ESCAPE); - - // Handle any farewell message - farewell(); - - int result; - if (party._mazeId != 0) { - map.load(party._mazeId); - _farewellTime += 1440; - party.addTime(_farewellTime); - result = 0; - } else { - _vm->_saves->saveChars(); - result = 2; - } - - return result; -} - -void BaseLocation::drawBackground() { - Interface &intf = *g_vm->_interface; - - intf._face1UIFrame = intf._face2UIFrame = 0; - intf._dangerSenseUIFrame = 0; - intf._spotDoorsUIFrame = 0; - intf._levitateUIFrame = 0; - _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); -} - -void BaseLocation::drawWindow() { - Interface &intf = *g_vm->_interface; - Party &party = *g_vm->_party; - Windows &windows = *g_vm->_windows; - - Character *charP = &party._activeParty[0]; - Common::String title = createLocationText(*charP); - - // Open up the window and write the string - intf.assembleBorder(); - windows[10].open(); - windows[10].writeString(title); - drawButtons(&windows[0]); - - windows[0].update(); - intf.highlightChar(0); -} - -void BaseLocation::drawAnim(bool flag) { - Interface &intf = *g_vm->_interface; - Sound &sound = *g_vm->_sound; - Windows &windows = *g_vm->_windows; - - // TODO: Figure out a clean way to split method into individual location classes - if (_townActionId == BLACKSMITH) { - if (sound.isPlaying()) { - if (_isDarkCc) { - _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); - _townSprites[2].draw(0, _vm->getRandomNumber(11) == 1 ? 9 : 10, - Common::Point(34, 33)); - _townSprites[2].draw(0, _vm->getRandomNumber(5) + 3, - Common::Point(34, 54)); - } - } else { - _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); - if (_isDarkCc) { - _townSprites[2].draw(0, _vm->getRandomNumber(11) == 1 ? 9 : 10, - Common::Point(34, 33)); - } - } - } else if (!_isDarkCc || _townActionId != TRAINING) { - if (!_townSprites[_drawFrameIndex / 8].empty()) - _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); - } - - switch (_townActionId) { - case BANK: - if (sound.isPlaying() || (_isDarkCc && _animFrame)) { - if (_isDarkCc) { - if (sound.isPlaying() || _animFrame == 1) { - _townSprites[4].draw(0, _vm->getRandomNumber(13, 18), - Common::Point(8, 30)); - } else if (_animFrame > 1) { - _townSprites[4].draw(0, 13 - _animFrame++, - Common::Point(8, 30)); - if (_animFrame > 14) - _animFrame = 0; - } - } else { - _townSprites[2].draw(0, _vm->getRandomNumber(7, 11), Common::Point(8, 8)); - } - } - break; - - case GUILD: - if (sound.isPlaying()) { - if (_isDarkCc) { - if (_animFrame) { - _animFrame ^= 1; - _townSprites[6].draw(0, _animFrame, Common::Point(8, 106)); - } else { - _townSprites[6].draw(0, _vm->getRandomNumber(3), Common::Point(16, 48)); - } - } - } - break; - - case TAVERN: - if (sound.isPlaying() && _isDarkCc) { - _townSprites[4].draw(0, _vm->getRandomNumber(7), Common::Point(153, 49)); - } - break; - - case TEMPLE: - if (sound.isPlaying()) { - _townSprites[3].draw(0, _vm->getRandomNumber(2, 4), Common::Point(8, 8)); - - } - break; - - case TRAINING: - if (sound.isPlaying()) { - if (_isDarkCc) { - _townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos); - } - } else { - if (_isDarkCc) { - _townSprites[0].draw(0, ++_animFrame % 8, Common::Point(8, 8)); - _townSprites[5].draw(0, _vm->getRandomNumber(5), Common::Point(61, 74)); - } else { - _townSprites[1].draw(0, _vm->getRandomNumber(8, 12), Common::Point(8, 8)); - } - } - break; - - default: - break; - } - - if (flag) { - intf._face1UIFrame = 0; - intf._face2UIFrame = 0; - intf._dangerSenseUIFrame = 0; - intf._spotDoorsUIFrame = 0; - intf._levitateUIFrame = 0; - - intf.assembleBorder(); - } - - if (windows[11]._enabled) { - _drawCtr1 = (_drawCtr1 + 1) % 2; - if (!_drawCtr1 || !_drawCtr2) { - _drawFrameIndex = 0; - _drawCtr2 = 0; - } else { - _drawFrameIndex = _vm->getRandomNumber(3); - } - } else { - _drawFrameIndex = (_drawFrameIndex + 1) % _townMaxId; - } - - if (_isDarkCc) { - if (_townActionId == BLACKSMITH && (_drawFrameIndex == 4 || _drawFrameIndex == 13)) - sound.playFX(45); - - if (_townActionId == TRAINING && _drawFrameIndex == 23) { - sound.playSound("spit1.voc"); - } - } else { - if (_townMaxId == 32 && _drawFrameIndex == 0) - _drawFrameIndex = 17; - if (_townMaxId == 26 && _drawFrameIndex == 0) - _drawFrameIndex = 20; - if (_townActionId == BLACKSMITH && (_drawFrameIndex == 3 || _drawFrameIndex == 9)) - sound.playFX(45); - } - - windows[3].update(); - - if (_townActionId == BANK) - _animFrame = 2; -} - -int BaseLocation::wait() { - EventsManager &events = *g_vm->_events; - Windows &windows = *g_vm->_windows; - - _buttonValue = 0; - while (!_vm->shouldQuit() && !_buttonValue) { - events.updateGameCounter(); - while (!_vm->shouldQuit() && !_buttonValue && events.timeElapsed() < 3) { - events.pollEventsAndWait(); - checkEvents(_vm); - } - if (!_buttonValue) - drawAnim(!windows[11]._enabled); - } - - return _buttonValue; -} - -/*------------------------------------------------------------------------*/ - -BankLocation::BankLocation() : BaseLocation(BANK) { - _icons1.load("bank.icn"); - _icons2.load("bank2.icn"); - addButton(Common::Rect(234, 108, 259, 128), Common::KEYCODE_d, &_icons1); - addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_w, &_icons1); - addButton(Common::Rect(288, 108, 312, 128), Common::KEYCODE_ESCAPE, &_icons1); - _animFrame = 1; - - _vocName = _isDarkCc ? "bank1.voc" : "banker.voc"; -} - -Common::String BankLocation::createLocationText(Character &ch) { - Party &party = *g_vm->_party; - return Common::String::format(Res.BANK_TEXT, - XeenEngine::printMil(party._bankGold).c_str(), - XeenEngine::printMil(party._bankGems).c_str(), - XeenEngine::printMil(party._gold).c_str(), - XeenEngine::printMil(party._gems).c_str()); -} - -void BankLocation::drawBackground() { - if (_isDarkCc) { - _townSprites[4].draw(0, _vm->getRandomNumber(13, 18), - Common::Point(8, 30)); - } -} - -Character *BankLocation::doOptions(Character *c) { - if (_buttonValue == Common::KEYCODE_d) - _buttonValue = (int)WHERE_PARTY; - else if (_buttonValue == Common::KEYCODE_w) - _buttonValue = (int)WHERE_BANK; - else - return c; - - depositWithdrawl((PartyBank)_buttonValue); - return c; -} - -void BankLocation::depositWithdrawl(PartyBank whereId) { - Party &party = *g_vm->_party; - Sound &sound = *g_vm->_sound; - Windows &windows = *g_vm->_windows; - int gold, gems; - - if (whereId == WHERE_BANK) { - gold = party._bankGold; - gems = party._bankGems; - } else { - gold = party._gold; - gems = party._gems; - } - - for (uint idx = 0; idx < _buttons.size(); ++idx) - _buttons[idx]._sprites = &_icons2; - _buttons[0]._value = Common::KEYCODE_o; - _buttons[1]._value = Common::KEYCODE_e; - _buttons[2]._value = Common::KEYCODE_ESCAPE; - - Common::String msg = Common::String::format(Res.GOLD_GEMS, - Res.DEPOSIT_WITHDRAWL[whereId], - XeenEngine::printMil(gold).c_str(), - XeenEngine::printMil(gems).c_str()); - - windows[35].open(); - windows[35].writeString(msg); - drawButtons(&windows[35]); - windows[35].update(); - - sound.stopSound(); - File voc("coina.voc"); - ConsumableType consType = CONS_GOLD; - - do { - switch (wait()) { - case Common::KEYCODE_o: - consType = CONS_GOLD; - break; - case Common::KEYCODE_e: - consType = CONS_GEMS; - break; - case Common::KEYCODE_ESCAPE: - break; - default: - continue; - } - - if ((whereId == WHERE_BANK && !party._bankGems && consType == CONS_GEMS) || - (whereId == WHERE_BANK && !party._bankGold && consType == CONS_GOLD) || - (whereId == WHERE_PARTY && !party._gems && consType == CONS_GEMS) || - (whereId == WHERE_PARTY && !party._gold && consType == CONS_GOLD)) { - party.notEnough(consType, whereId, WHERE_BANK, WT_2); - } else { - windows[35].writeString(Res.AMOUNT); - int amount = NumericInput::show(_vm, 35, 10, 77); - - if (amount) { - if (consType == CONS_GEMS) { - if (party.subtract(CONS_GEMS, amount, whereId, WT_2)) { - if (whereId == WHERE_BANK) { - party._gems += amount; - } else { - party._bankGems += amount; - } - } - } else { - if (party.subtract(CONS_GOLD, amount, whereId, WT_2)) { - if (whereId == WHERE_BANK) { - party._gold += amount; - } else { - party._bankGold += amount; - } - } - } - } - - if (whereId == WHERE_BANK) { - gold = party._bankGold; - gems = party._bankGems; - } - else { - gold = party._gold; - gems = party._gems; - } - - sound.playSound(voc); - msg = Common::String::format(Res.GOLD_GEMS_2, Res.DEPOSIT_WITHDRAWL[whereId], - XeenEngine::printMil(gold).c_str(), XeenEngine::printMil(gems).c_str()); - windows[35].writeString(msg); - windows[35].update(); - } - // TODO - } while (!g_vm->shouldQuit() && _buttonValue != Common::KEYCODE_ESCAPE); - - for (uint idx = 0; idx < _buttons.size(); ++idx) - _buttons[idx]._sprites = &_icons1; - _buttons[0]._value = Common::KEYCODE_d; - _buttons[1]._value = Common::KEYCODE_w; - _buttons[2]._value = Common::KEYCODE_ESCAPE; -} - -/*------------------------------------------------------------------------*/ - -BlacksmithLocation::BlacksmithLocation() : BaseLocation(BLACKSMITH) { - _icons1.load("esc.icn"); - addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); - addButton(Common::Rect(234, 54, 308, 62), 0); - addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_b); - addButton(Common::Rect(234, 74, 308, 82), 0); - addButton(Common::Rect(234, 84, 308, 92), 0); - - _vocName = _isDarkCc ? "see2.voc" : "whaddayo.voc"; -} - -Common::String BlacksmithLocation::createLocationText(Character &ch) { - Party &party = *g_vm->_party; - return Common::String::format(Res.BLACKSMITH_TEXT, - ch._name.c_str(), XeenEngine::printMil(party._gold).c_str()); -} - -Character *BlacksmithLocation::doOptions(Character *c) { - Interface &intf = *g_vm->_interface; - Party &party = *g_vm->_party; - - if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { - // Switch character - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - } - } else if (_buttonValue == Common::KEYCODE_b) { - c = ItemsDialog::show(_vm, c, ITEMMODE_BLACKSMITH); - _buttonValue = 0; - } - - return c; -} - -void BlacksmithLocation::farewell() { - Sound &sound = *g_vm->_sound; - - if (_isDarkCc) { - sound.stopSound(); - sound.playSound("come1.voc", 1); - } -} - -/*------------------------------------------------------------------------*/ - -GuildLocation::GuildLocation() : BaseLocation(GUILD) { - loadStrings("spldesc.bin"); - _icons1.load("esc.icn"); - addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); - addButton(Common::Rect(234, 54, 308, 62), 0); - addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_b); - addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_s); - addButton(Common::Rect(234, 84, 308, 92), 0); - g_vm->_mode = MODE_17; - - _vocName = _isDarkCc ? "parrot1.voc" : "guild10.voc"; -} - -Common::String GuildLocation::createLocationText(Character &ch) { - return !ch.guildMember() ? Res.GUILD_NOT_MEMBER_TEXT : - Common::String::format(Res.GUILD_TEXT, ch._name.c_str()); -} - -Character *GuildLocation::doOptions(Character *c) { - Interface &intf = *g_vm->_interface; - Party &party = *g_vm->_party; - Sound &sound = *g_vm->_sound; - - if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { - // Switch character - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - - if (!c->guildMember()) { - sound.stopSound(); - _animFrame = 5; - sound.playSound(_isDarkCc ? "skull1.voc" : "guild11.voc", 1); - } - } - } else if (_buttonValue == Common::KEYCODE_s) { - if (c->guildMember()) - c = SpellsDialog::show(_vm, nullptr, c, 0x80); - _buttonValue = 0; - } else if (_buttonValue == Common::KEYCODE_c) { - if (!c->noActions()) { - if (c->guildMember()) - c = SpellsDialog::show(_vm, nullptr, c, 0); - _buttonValue = 0; - } - } - - return c; -} - -/*------------------------------------------------------------------------*/ - -TavernLocation::TavernLocation() : BaseLocation(TAVERN) { - _v21 = 0; - _v22 = 0; - _v23 = 0; - _v24 = 0; - - loadStrings("tavern.bin"); - _icons1.load("tavern.icn"); - addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons1); - addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_s, &_icons1); - addButton(Common::Rect(234, 54, 308, 62), Common::KEYCODE_d); - addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_f); - addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_t); - addButton(Common::Rect(234, 84, 308, 92), Common::KEYCODE_r); - g_vm->_mode = MODE_17; - - _vocName = _isDarkCc ? "hello1.voc" : "hello.voc"; -} - -Common::String TavernLocation::createLocationText(Character &ch) { - Party &party = *g_vm->_party; - return Common::String::format(Res.TAVERN_TEXT, ch._name.c_str(), - Res.FOOD_AND_DRINK, XeenEngine::printMil(party._gold).c_str()); -} - -Character *TavernLocation::doOptions(Character *c) { - Interface &intf = *g_vm->_interface; - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - Sound &sound = *g_vm->_sound; - Windows &windows = *g_vm->_windows; - 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 < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - _v21 = 0; - } - break; - - case Common::KEYCODE_d: - // Drink - if (!c->noActions()) { - if (party.subtract(CONS_GOLD, 1, WHERE_PARTY, WT_2)) { - sound.stopSound(); - sound.playSound("gulp.voc"); - _v21 = 1; - - windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, - c->_name.c_str(), Res.GOOD_STUFF, - XeenEngine::printMil(party._gold).c_str())); - drawButtons(&windows[0]); - windows[10].update(); - - if (_vm->getRandomNumber(100) < 26) { - ++c->_conditions[DRUNK]; - intf.drawParty(true); - sound.playFX(28); - } - - wait(); - } - } - break; - - case Common::KEYCODE_f: { - // Food - if (party._mazeId == (_isDarkCc ? 29 : 28)) { - _v22 = party._activeParty.size() * 15; - _v23 = 10; - idx = 0; - } else if (_isDarkCc && party._mazeId == 31) { - _v22 = party._activeParty.size() * 60; - _v23 = 100; - idx = 1; - } else if (!_isDarkCc && party._mazeId == 30) { - _v22 = party._activeParty.size() * 50; - _v23 = 50; - idx = 1; - } else if (_isDarkCc) { - _v22 = party._activeParty.size() * 120; - _v23 = 250; - idx = 2; - } else if (party._mazeId == 49) { - _v22 = party._activeParty.size() * 120; - _v23 = 100; - idx = 2; - } else { - _v22 = party._activeParty.size() * 15; - _v23 = 10; - idx = 0; - } - - Common::String msg = _textStrings[(_isDarkCc ? 60 : 75) + idx]; - windows[10].close(); - windows[12].open(); - windows[12].writeString(msg); - windows[12].update(); - - if (YesNo::show(_vm, false, true)) { - if (party._food >= _v22) { - ErrorScroll::show(_vm, Res.FOOD_PACKS_FULL, WT_2); - } else if (party.subtract(CONS_GOLD, _v23, WHERE_PARTY, WT_2)) { - party._food = _v22; - sound.stopSound(); - sound.playSound(_isDarkCc ? "thanks2.voc" : "thankyou.voc", 1); - } - } - - windows[12].close(); - windows[10].open(); - _buttonValue = 0; - break; - } - - case Common::KEYCODE_r: { - // Rumors - 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].c_str()); - Window &w = windows[12]; - w.open(); - w.writeString(msg); - w.update(); - - wait(); - w.close(); - break; - } - - case Common::KEYCODE_s: { - // Sign In - idx = _isDarkCc ? (party._mazeId - 29) >> 1 : party._mazeId - 28; - assert(idx >= 0); - party._mazePosition.x = Res.TAVERN_EXIT_LIST[_isDarkCc ? 1 : 0][_townActionId][idx][0]; - party._mazePosition.y = Res.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 - party._mazeDirection = DIR_SOUTH; - - party._priorMazeId = party._mazeId; - for (idx = 0; idx < (int)party._activeParty.size(); ++idx) { - party._activeParty[idx]._savedMazeId = party._mazeId; - party._activeParty[idx]._xeenSide = map._loadDarkSide; - } - - party.addTime(1440); - party._mazeId = 0; - _vm->_quitMode = 2; - break; - } - - case Common::KEYCODE_t: - if (!c->noActions()) { - if (!_v21) { - windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, - c->_name.c_str(), Res.HAVE_A_DRINK, - XeenEngine::printMil(party._gold).c_str())); - drawButtons(&windows[0]); - windows[10].update(); - wait(); - } else { - _v21 = 0; - if (c->_conditions[DRUNK]) { - windows[10].writeString(Common::String::format(Res.TAVERN_TEXT, - c->_name.c_str(), Res.YOURE_DRUNK, - XeenEngine::printMil(party._gold).c_str())); - drawButtons(&windows[0]); - windows[10].update(); - wait(); - } else if (party.subtract(CONS_GOLD, 1, WHERE_PARTY, WT_2)) { - sound.stopSound(); - sound.playSound(_isDarkCc ? "thanks2.voc" : "thankyou.voc", 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); - - Window &w = windows[12]; - w.open(); - w.writeString(Common::String::format("\x03""c\x0B""012%s", msg.c_str())); - w.update(); - wait(); - w.close(); - } - } - } - break; - - default: - break; - } - - return c; -} - -void TavernLocation::farewell() { - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - Sound &sound = *g_vm->_sound; - - sound.stopSound(); - sound.playSound(_isDarkCc ? "gdluck1.voc" : "goodbye.voc", 1); - - map.mazeData()._mazeNumber = party._mazeId; -} - -/*------------------------------------------------------------------------*/ - -TempleLocation::TempleLocation() : BaseLocation(TEMPLE) { - _currentCharLevel = 0; - _donation = 0; - _healCost = 0; - _uncurseCost = 0; - _dayOfWeek = 0; - _v10 = _v11 = 0; - _v12 = _v13 = 0; - _v14 = 0; - _flag1 = false; - _v5 = _v6 = 0; - - _icons1.load("esc.icn"); - addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1); - addButton(Common::Rect(234, 54, 308, 62), Common::KEYCODE_h); - addButton(Common::Rect(234, 64, 308, 72), Common::KEYCODE_d); - addButton(Common::Rect(234, 74, 308, 82), Common::KEYCODE_u); - addButton(Common::Rect(234, 84, 308, 92), 0); - - _vocName = _isDarkCc ? "help2.voc" : "maywe2.voc"; -} - -Common::String TempleLocation::createLocationText(Character &ch) { - Party &party = *g_vm->_party; - - if (party._mazeId == (_isDarkCc ? 29 : 28)) { - _v10 = _v11 = _v12 = _v13 = 0; - _v14 = 10; - } else if (party._mazeId == (_isDarkCc ? 31 : 30)) { - _v13 = 10; - _v12 = 50; - _v11 = 500; - _v10 = 100; - _v14 = 25; - } else if (party._mazeId == (_isDarkCc ? 37 : 73)) { - _v13 = 20; - _v12 = 100; - _v11 = 1000; - _v10 = 200; - _v14 = 50; - } else if (_isDarkCc || party._mazeId == 49) { - _v13 = 100; - _v12 = 500; - _v11 = 5000; - _v10 = 300; - _v14 = 100; - } - - _currentCharLevel = ch.getCurrentLevel(); - if (ch._currentHp < ch.getMaxHP()) { - _healCost = _currentCharLevel * 10 + _v13; - } - - for (int attrib = HEART_BROKEN; attrib <= UNCONSCIOUS; ++attrib) { - if (ch._conditions[attrib]) - _healCost += _currentCharLevel * 10; - } - - _v6 = 0; - if (ch._conditions[DEAD]) { - _v6 += (_currentCharLevel * 100) + (ch._conditions[DEAD] * 50) + _v12; - } - if (ch._conditions[STONED]) { - _v6 += (_currentCharLevel * 100) + (ch._conditions[STONED] * 50) + _v12; - } - if (ch._conditions[ERADICATED]) { - _v5 = (_currentCharLevel * 1000) + (ch._conditions[ERADICATED] * 500) + _v11; - } - - for (int idx = 0; idx < 9; ++idx) { - _uncurseCost |= ch._weapons[idx]._bonusFlags & 0x40; - _uncurseCost |= ch._armor[idx]._bonusFlags & 0x40; - _uncurseCost |= ch._accessories[idx]._bonusFlags & 0x40; - _uncurseCost |= ch._misc[idx]._bonusFlags & 0x40; - } - - if (_uncurseCost || ch._conditions[CURSED]) - _v5 = (_currentCharLevel * 20) + _v10; - - _donation = _flag1 ? 0 : _v14; - _healCost += _v6 + _v5; - - return Common::String::format(Res.TEMPLE_TEXT, ch._name.c_str(), - _healCost, _donation, XeenEngine::printK(_uncurseCost).c_str(), - XeenEngine::printMil(party._gold).c_str()); -} - -Character *TempleLocation::doOptions(Character *c) { - Interface &intf = *g_vm->_interface; - Party &party = *g_vm->_party; - Sound &sound = *g_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 < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - _dayOfWeek = 0; - } - break; - - case Common::KEYCODE_d: - if (_donation && party.subtract(CONS_GOLD, _donation, WHERE_PARTY, WT_2)) { - sound.stopSound(); - sound.playSound("coina.voc", 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.drawParty(true); - sound.stopSound(); - sound.playSound("ahh.voc"); - _flag1 = true; - _donation = 0; - } - } - break; - - case Common::KEYCODE_h: - if (_healCost && party.subtract(CONS_GOLD, _healCost, WHERE_PARTY, 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); - - _farewellTime = 1440; - intf.drawParty(true); - sound.stopSound(); - sound.playSound("ahh.voc", 1); - } - break; - - case Common::KEYCODE_u: - if (_uncurseCost && party.subtract(CONS_GOLD, _uncurseCost, WHERE_PARTY, WT_2)) { - for (int idx = 0; idx < 9; ++idx) { - c->_weapons[idx]._bonusFlags &= ~ITEMFLAG_CURSED; - c->_armor[idx]._bonusFlags &= ~ITEMFLAG_CURSED; - c->_accessories[idx]._bonusFlags &= ~ITEMFLAG_CURSED; - c->_misc[idx]._bonusFlags &= ~ITEMFLAG_CURSED; - } - - _farewellTime = 1440; - intf.drawParty(true); - sound.stopSound(); - sound.playSound("ahh.voc", 1); - } - break; - - default: - break; - } - - return c; -} - -/*------------------------------------------------------------------------*/ - -TrainingLocation::TrainingLocation() : BaseLocation(TRAINING) { - Common::fill(&_charsTrained[0], &_charsTrained[6], 0); - _maxLevel = 0; - _experienceToNextLevel = 0; - _charIndex = 0; - - _icons1.load("train.icn"); - addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons1); - addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_icons1); - - _vocName = _isDarkCc ? "training.voc" : "youtrn1.voc"; -} - -Common::String TrainingLocation::createLocationText(Character &ch) { - Party &party = *g_vm->_party; - if (_isDarkCc) { - switch (party._mazeId) { - case 29: - // Castleview - _maxLevel = 30; - break; - case 31: - // Sandcaster - _maxLevel = 50; - break; - case 37: - // Olympus - _maxLevel = 200; - break; - default: - // Kalindra's Castle - _maxLevel = 100; - break; - } - } else { - switch (party._mazeId) { - case 28: - // Vertigo - _maxLevel = 10; - break; - case 30: - // Rivercity - _maxLevel = 15; - break; - default: - // Newcastle - _maxLevel = 20; - break; - } - } - - _experienceToNextLevel = ch.experienceToNextLevel(); - - Common::String msg; - if (_experienceToNextLevel && ch._level._permanent < _maxLevel) { - // Need more experience - int nextLevel = ch._level._permanent + 1; - msg = Common::String::format(Res.EXPERIENCE_FOR_LEVEL, - ch._name.c_str(), _experienceToNextLevel, nextLevel); - } else if (ch._level._permanent >= _maxLevel) { - // At maximum level - _experienceToNextLevel = 1; - msg = Common::String::format(Res.LEARNED_ALL, ch._name.c_str()); - } else { - // Eligble for level increase - msg = Common::String::format(Res.ELIGIBLE_FOR_LEVEL, - ch._name.c_str(), ch._level._permanent + 1); - } - - return Common::String::format(Res.TRAINING_TEXT, msg.c_str(), - XeenEngine::printMil(party._gold).c_str()); -} - -Character *TrainingLocation::doOptions(Character *c) { - Interface &intf = *g_vm->_interface; - Party &party = *g_vm->_party; - Sound &sound = *g_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 < (int)party._activeParty.size()) { - _charIndex = _buttonValue; - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - } - break; - - case Common::KEYCODE_t: - if (_experienceToNextLevel) { - sound.stopSound(); - _drawFrameIndex = 0; - - Common::String name; - if (c->_level._permanent >= _maxLevel) { - name = _isDarkCc ? "gtlost.voc" : "trainin1.voc"; - } else { - name = _isDarkCc ? "gtlost.voc" : "trainin0.voc"; - } - - sound.playSound(name); - - } else if (!c->noActions()) { - if (party.subtract(CONS_GOLD, (c->_level._permanent * c->_level._permanent) * 10, WHERE_PARTY, WT_2)) { - _drawFrameIndex = 0; - sound.stopSound(); - sound.playSound(_isDarkCc ? "prtygd.voc" : "trainin2.voc", 1); - - c->_experience -= c->nextExperienceLevel() - - (c->getCurrentExperience() - c->_experience); - c->_level._permanent++; - - if (!_charsTrained[_charIndex]) { - party.addTime(1440); - _charsTrained[_charIndex] = true; - } - - party.resetTemps(); - c->_currentHp = c->getMaxHP(); - c->_currentSp = c->getMaxSP(); - intf.drawParty(true); - } - } - break; - - default: - break; - } - - return c; -} - -/*------------------------------------------------------------------------*/ - -ArenaLocation::ArenaLocation() : BaseLocation(ARENA) { - // TODO -} - -/*------------------------------------------------------------------------*/ - -CutsceneLocation::CutsceneLocation(TownAction action) : BaseLocation(action), - _animCtr(0), _mazeFlag(false) { - Party &party = *g_vm->_party; - _mazeId = party._mazeId; - _mazePos = party._mazePosition; - _mazeDir = party._mazeDirection; -} - -void CutsceneLocation::cutsceneAnimUpdate() { - // TODO -} - -void CutsceneLocation::setNewLocation() { - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - map.load(_mazeId); - party._mazePosition = _mazePos; - party._mazeDirection = _mazeDir; -} - -/*------------------------------------------------------------------------*/ - -ReaperCutscene::ReaperCutscene() : CutsceneLocation(REAPER) { - // TODO -} - -/*------------------------------------------------------------------------*/ - -GolemCutscene::GolemCutscene() : CutsceneLocation(GOLEM) { - // TODO -} - -/*------------------------------------------------------------------------*/ - -const int16 DWARF_X0[2][13] = { - { 0, -5, -7, -8, -11, -9, -3, 1, 6, 10, 15, 18, 23 }, - { 0, 4, 6, 8, 11, 12, 15, 17, 19, 22, 25, 0, 0 } -}; -const int DWARF_X1[2][13] = { - { 160, 145, 133, 122, 109, 101, 97, 91, 86, 80, 75, 68, 63 }, - { 160, 154, 146, 138, 131, 122, 115, 107, 99, 92, 85, 0, 0 } -}; -const int DWARF_X2[13] = { - 0, -1, -4, -7, -9, -13, -15, -18, -21, -23, -25, 0, 0 -}; -const int16 DWARF_Y[2][13] = { - { 0, 0, 4, 9, 13, 15, 20, 24, 30, 37, 45, 51, 58 }, - { 0, 12, 25, 36, 38, 40, 41, 42, 44, 45, 50, 0, 0 } -}; -const int16 DWARF2_X[2][16] = { - { 0, -2, -4, -6, -8, -10, -12, -14, -16, -18, -20, -20, -20, -20, -20, -20 }, - { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150 } -}; -const int16 DWARF2_Y[2][16] = { - { 0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 187 }, - { 0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 186 } -}; - -DwarfCutscene::DwarfCutscene(bool isDwarf) : CutsceneLocation(NO_ACTION) { - _townMaxId = Res.TOWN_MAXES[_isDarkCc][isDwarf ? DWARF1 : DWARF2]; -} - -int DwarfCutscene::show() { - EventsManager &events = *g_vm->_events; - Interface &intf = *g_vm->_interface; - Screen &screen = *g_vm->_screen; - Sound &sound = *g_vm->_sound; - Windows &windows = *g_vm->_windows; - - SpriteResource sprites1(_isDarkCc ? "town1.zom" : "dwarf1.vga"); - SpriteResource sprites2(_isDarkCc ? "town2.zom" : "dwarf2.vga"); - SpriteResource sprites3(_isDarkCc ? "town3.zom" : "dwarf3.vga"); - SpriteResource boxSprites("box.vga"); - getNewLocation(); - - // Save the screen contents - Graphics::ManagedSurface savedBg; - savedBg.copyFrom(screen); - - for (int idx = 0; idx < (_isDarkCc ? 10 : 12); ++idx) { - screen.copyFrom(savedBg); - sprites1.draw(0, 0, - Common::Point(DWARF_X0[_isDarkCc][idx], DWARF_Y[_isDarkCc][idx])); - sprites1.draw(0, 1, - Common::Point(DWARF_X1[_isDarkCc][idx], DWARF_Y[_isDarkCc][idx])); - if (_isDarkCc) - sprites1.draw(0, 2, - Common::Point(DWARF_X2[idx], DWARF_Y[_isDarkCc][idx])); - - windows[0].update(); - events.wait(1); - } - - savedBg.copyFrom(screen); - for (int idx = 15; idx >= 0; --idx) { - screen.copyFrom(savedBg); - sprites2.draw(0, 0, Common::Point(DWARF2_X[_isDarkCc][idx], DWARF2_Y[_isDarkCc][idx])); - windows[0].update(); - events.wait(1); - } - - sound.setMusicVolume(48); - screen.copyFrom(savedBg); - sprites2.draw(0, 0); - windows[0].update(); - - for (int idx = 0; idx < (_isDarkCc ? 2 : 3); ++idx) { - switch (idx) { - case 0: - sound.playSound(_isDarkCc ? "pass2.voc" : "dwarf10.voc"); - break; - - case 1: - if (_isDarkCc) { - sprites2.draw(0, 0); - sprites3.draw(0, 0); - cutsceneAnimUpdate(); - - events.timeMark5(); - while (!g_vm->shouldQuit() && events.timeElapsed5() < 7) - events.pollEventsAndWait(); - - sound.playSound(_mazeFlag ? "ok2.voc" : "back2.voc"); - } else { - sound.playSound("dwarf11.voc"); - } - break; - - case 2: - sound.playSound("dwarf12.voc"); - break; - } - - events.updateGameCounter(); - do { - sprites2.draw(0, 0); - sprites3.draw(0, g_vm->getRandomNumber(_isDarkCc ? 8 : 9)); - cutsceneAnimUpdate(); - - events.timeMark5(); - while (!g_vm->shouldQuit() && events.timeElapsed5() < 2) - events.pollEventsAndWait(); - } while (!g_vm->shouldQuit() && (sound.isPlaying() || _animCtr)); - - while (!g_vm->shouldQuit() && events.timeElapsed() < 3) - events.pollEventsAndWait(); - } - - sprites2.draw(0, 0); - if (!_isDarkCc) - sprites3.draw(0, 1); - windows[0].update(); - - setNewLocation(); - - // Restore game screen - sound.setMusicVolume(95); - screen.loadBackground("back.raw"); - intf.drawParty(false); - intf.draw3d(false, false); - - events.clearEvents(); - return 0; -} - -void DwarfCutscene::getNewLocation() { - Party &party = *g_vm->_party; - - if (_isDarkCc) { - switch (party._mazeId) { - case 4: - if (party._questItems[35]) { - _mazeId = 29; - _mazePos = Common::Point(15, 31); - _mazeDir = DIR_SOUTH; - } - break; - - case 6: - if (party._questItems[38]) { - _mazeId = 35; - _mazePos = Common::Point(15, 8); - _mazeDir = DIR_WEST; - } - break; - - case 19: - if (party._questItems[36]) { - _mazeId = 31; - _mazePos = Common::Point(31, 16); - _mazeDir = DIR_WEST; - } - break; - - case 22: - if (party._questItems[37]) { - _mazeId = 33; - _mazePos = Common::Point(0, 3); - _mazeDir = DIR_EAST; - } - break; - - case 98: - if (party._questItems[39]) { - _mazeId = 37; - _mazePos = Common::Point(7, 0); - _mazeDir = DIR_NORTH; - } - break; - - default: - break; - } - - _mazeFlag = _mazeId != 0; - } else { - switch (party._mazeId) { - case 14: - _mazeId = 37; - _mazePos = Common::Point(1, 4); - _mazeDir = DIR_EAST; - break; - - case 18: - if (party._mazePosition.x == 9) { - _mazeId = 35; - _mazePos = Common::Point(1, 12); - _mazeDir = DIR_EAST; - } else { - _mazeId = 36; - _mazePos = Common::Point(7, 1); - _mazeDir = DIR_NORTH; - } - break; - - case 23: - if (party._mazePosition.x == 5) { - _mazeId = 33; - _mazePos = Common::Point(7, 1); - _mazeDir = DIR_NORTH; - } else { - _mazeId = 34; - _mazePos = Common::Point(7, 30); - _mazeDir = DIR_SOUTH; - } - break; - - default: - break; - } - } -} - -/*------------------------------------------------------------------------*/ - -SphinxCutscene::SphinxCutscene() : CutsceneLocation(SPHINX) { - SpriteResource sprites1("sphinx.vga"); - _boxSprites.load("box.vga"); - - - // TODO -} - -void SphinxCutscene::getNewLocation() { - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - - switch (party._mazeId) { - case 2: - if (party._questItems[51]) { - map._loadDarkSide = true; - _mazeId = 125; - _mazePos = Common::Point(7, 6); - _mazeDir = DIR_NORTH; - _mazeFlag = true; - } - break; - - case 5: - if (party._questItems[4]) { - _mazeId = 82; - _mazePos = Common::Point(7, 5); - _mazeDir = DIR_NORTH; - _mazeFlag = true; - } - break; - - default: - break; - } - - if (!_mazeFlag) { - _mazeId = party._mazeId; - _mazePos = party._mazePosition; - _mazeDir = party._mazeDirection; - } -} - - -/*------------------------------------------------------------------------*/ - -PyramidLocation::PyramidLocation() : BaseLocation(PYRAMID) { -} - -int PyramidLocation::show() { - EventsManager &events = *g_vm->_events; - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - Windows &windows = *g_vm->_windows; - int mapId; - Direction dir = DIR_NORTH; - Common::Point pt; - - if (g_vm->getGameID() == GType_WorldOfXeen) { - if (_isDarkCc) { - if (party._mazeId == 52) { - mapId = 49; - pt = Common::Point(7, 14); - dir = DIR_SOUTH; - } else { - mapId = 23; - pt = Common::Point(8, 10); - } - } else { - if (party._mazeId == 49) { - mapId = 52; - pt = Common::Point(2, 2); - } else { - mapId = 29; - pt = Common::Point(25, 21); - } - } - - // Load the destination map and set position and direction - map._loadDarkSide = !_isDarkCc; - map.load(mapId); - party._mazePosition = pt; - party._mazeDirection = dir; - } else { - // Playing Clouds or Dark Side on it's own, so can't switch sides - Window &win = windows[12]; - Common::String msg = Common::String::format(Res.MOONS_NOT_ALIGNED, - _isDarkCc ? "Clouds" : "Darkside"); - win.open(); - win.writeString(msg); - win.update(); - - events.waitForPressAnimated(); - win.close(); - } - - return 0; -} - -/*------------------------------------------------------------------------*/ - -Town::Town() : _location(nullptr) { -} - -int Town::townAction(TownAction actionId) { - // Create the desired location - switch (actionId) { - case BANK: - _location = new BankLocation(); - break; - case BLACKSMITH: - _location = new BlacksmithLocation(); - break; - case GUILD: - _location = new GuildLocation(); - break; - case TAVERN: - _location = new TavernLocation(); - break; - case TEMPLE: - _location = new TempleLocation(); - break; - case TRAINING: - _location = new TrainingLocation(); - break; - case ARENA: - _location = new ArenaLocation(); - break; - case REAPER: - _location = new ReaperCutscene(); - break; - case GOLEM: - _location = new GolemCutscene(); - break; - case DWARF1: - _location = new DwarfCutscene(true); - break; - case DWARF2: - _location = new DwarfCutscene(false); - break; - case SPHINX: - _location = new SphinxCutscene(); - break; - case PYRAMID: - _location = new PyramidLocation(); - break; - default: - return 0; - } - - // Show the location - int result = _location->show(); - delete _location; - _location = nullptr; - - return result; -} - -bool Town::isActive() const { - return _location != nullptr; -} - -void Town::drawAnim(bool flag) { - if (_location) - _location->drawAnim(flag); -} - -/*------------------------------------------------------------------------*/ - -bool TownMessage::show(int portrait, const Common::String &name, - const Common::String &text, int confirm) { - TownMessage *dlg = new TownMessage(); - bool result = dlg->execute(portrait, name, text, confirm); - delete dlg; - - return result; -} - -bool TownMessage::execute(int portrait, const Common::String &name, const Common::String &text, - int confirm) { - EventsManager &events = *g_vm->_events; - Interface &intf = *g_vm->_interface; - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - Resources &res = *g_vm->_resources; - Windows &windows = *g_vm->_windows; - Window &w = windows[11]; - - _townMaxId = 4; - _drawFrameIndex = 0; - _townPos = Common::Point(23, 22); - - if (!confirm) - loadButtons(); - - _townSprites.resize(2); - _townSprites[0].load(Common::String::format("face%02d.fac", portrait)); - _townSprites[1].load("frame.fac"); - - if (!w._enabled) - w.open(); - - int result = -1; - Common::String msgText = text; - do { - Common::String msg = Common::String::format("\r\v014\x03""c\t125%s\t000\v054%s", - name.c_str(), msgText.c_str()); - - // Count the number of words - const char *msgEnd = w.writeString(msg); - int wordCount = 0; - - for (const char *msgP = msg.c_str(); msgP != msgEnd && *msgP; ++msgP) { - if (*msgP == ' ') - ++wordCount; - } - - _drawCtr2 = wordCount * 2; // Set timeout - _townSprites[1].draw(0, 0, Common::Point(16, 16)); - _townSprites[0].draw(0, _drawFrameIndex, Common::Point(23, 22)); - w.update(); - - if (!msgEnd && !confirm) { - res._globalSprites.draw(0, 7, Common::Point(232, 74)); - res._globalSprites.draw(0, 0, Common::Point(235, 75)); - res._globalSprites.draw(0, 2, Common::Point(260, 75)); - windows[34].update(); - - intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; - intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; - } - - if (confirm == 2) { - intf._face1State = intf._face2State = 2; - return false; - } - - do { - events.clearEvents(); - events.updateGameCounter(); - if (msgEnd) - clearButtons(); - - do { - events.pollEventsAndWait(); - checkEvents(_vm); - - if (_vm->shouldQuit()) - return false; - - while (events.timeElapsed() >= 3) { - drawAnim(false); - events.updateGameCounter(); - } - } while (!_buttonValue); - - if (msgEnd) - // Another screen of text remaining - break; - - if (confirm || _buttonValue == Common::KEYCODE_ESCAPE || - _buttonValue == Common::KEYCODE_n) - result = 0; - else if (_buttonValue == Common::KEYCODE_y) - result = 1; - } while (result == -1); - - if (msgEnd) { - // Text remaining, so cut off already displayed page's - msgText = Common::String(msgEnd); - _drawCtr2 = wordCount; - continue; - } - } while (result == -1); - - intf._face1State = intf._face2State = 2; - if (!confirm) - intf.mainIconsPrint(); - - _townSprites[0].clear(); - _townSprites[1].clear(); - events.clearEvents(); - return result == 1; -} - -void TownMessage::loadButtons() { - _iconSprites.load("confirm.icn"); - - addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_y, &_iconSprites); - addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_n, &_iconSprites); - addButton(Common::Rect(), Common::KEYCODE_ESCAPE); -} - -} // End of namespace Xeen diff --git a/engines/xeen/town.h b/engines/xeen/town.h deleted file mode 100644 index 925bac9e7a..0000000000 --- a/engines/xeen/town.h +++ /dev/null @@ -1,368 +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 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_TOWN_H -#define XEEN_TOWN_H - -#include "common/scummsys.h" -#include "common/str-array.h" -#include "xeen/dialogs.h" -#include "xeen/dialogs_error.h" -#include "xeen/party.h" - -namespace Xeen { - -enum TownAction { - BANK = 0, BLACKSMITH = 1, GUILD = 2, TAVERN = 3, TEMPLE = 4, - TRAINING = 5, ARENA = 6, NO_ACTION = 7, REAPER = 8, GOLEM = 9, - DWARF1 = 10, SPHINX = 11, PYRAMID = 12, DWARF2 = 13 -}; - -class XeenEngine; -class TownMessage; - -class BaseLocation : public ButtonContainer { -protected: - TownAction _townActionId; - Common::Array _townSprites; - SpriteResource _icons1, _icons2; - int _townMaxId; - const bool &_isDarkCc; - int _animFrame; - Common::String _vocName, _songName; - Common::Point _townPos; - int _drawFrameIndex; - uint _farewellTime; - int _drawCtr1, _drawCtr2; -protected: - /** - * Draw the window - */ - void drawWindow(); - - /** - * Waits for a brief pause, checking for any key or mouse events - */ - int wait(); - - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch) { return ""; } - - /** - * Draw the visual background - */ - virtual void drawBackground(); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c) { return c; } - - /** - * Handle any farewell - */ - virtual void farewell() {} -public: - BaseLocation(TownAction action); - virtual ~BaseLocation(); - - /** - * Show the town location - */ - virtual int show(); - - /** - * Draws the animated parts - */ - void drawAnim(bool flag); -}; - -class BankLocation : public BaseLocation { -private: - /** - * Handles deposits or withdrawls fro the bank - */ - void depositWithdrawl(PartyBank whereId); -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Draw the visual background - */ - virtual void drawBackground(); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - BankLocation(); - virtual ~BankLocation() {} -}; - -class BlacksmithLocation : public BaseLocation { -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Handle any farewell - */ - virtual void farewell(); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - BlacksmithLocation(); - virtual ~BlacksmithLocation() {} -}; - -class GuildLocation : public BaseLocation { -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - GuildLocation(); - virtual ~GuildLocation() {} -}; - -class TavernLocation : public BaseLocation { -private: - int _v21; - uint _v22; - int _v23; - int _v24; -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Handle any farewell - */ - virtual void farewell(); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - TavernLocation(); - virtual ~TavernLocation() {} -}; - -class TempleLocation : public BaseLocation { -private: - int _currentCharLevel; - int _donation; - int _healCost; - int _uncurseCost; - int _dayOfWeek; - int _v10, _v11, _v12; - int _v13, _v14; - bool _flag1; - int _v5, _v6; -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - TempleLocation(); - virtual ~TempleLocation() {} -}; - -class TrainingLocation : public BaseLocation { -private: - int _charIndex; - bool _charsTrained[MAX_ACTIVE_PARTY]; - uint _experienceToNextLevel; - uint _maxLevel; -protected: - /** - * Generates the display text for the location, for a given character - */ - virtual Common::String createLocationText(Character &ch); - - /** - * Handles options for the particular location - */ - virtual Character *doOptions(Character *c); -public: - TrainingLocation(); - virtual ~TrainingLocation() {} -}; - -class ArenaLocation : public BaseLocation { -public: - ArenaLocation(); - virtual ~ArenaLocation() {} -}; - -class CutsceneLocation : public BaseLocation { -protected: - int _animCtr; - SpriteResource _boxSprites; - int _mazeId; - Direction _mazeDir; - Common::Point _mazePos; - bool _mazeFlag; -protected: - /** - * Handles cutscene animation update - */ - void cutsceneAnimUpdate(); - - /** - * Sets the new location - */ - void setNewLocation(); -public: - CutsceneLocation(TownAction action); -}; - -class ReaperCutscene : public CutsceneLocation { -public: - ReaperCutscene(); - virtual ~ReaperCutscene() {} -}; - -class GolemCutscene : public CutsceneLocation { -public: - GolemCutscene(); - virtual ~GolemCutscene() {} -}; - -class DwarfCutscene : public CutsceneLocation { -private: - /** - * Get the new location - */ - void getNewLocation(); -public: - DwarfCutscene(bool isDwarf1); - virtual ~DwarfCutscene() {} - - /** - * Show the town location - */ - virtual int show(); -}; - -class SphinxCutscene : public CutsceneLocation { -private: - /** - * Get the new location - */ - void getNewLocation(); -public: - SphinxCutscene(); - virtual ~SphinxCutscene() {} -}; - -class PyramidLocation : public BaseLocation { -public: - PyramidLocation(); - virtual ~PyramidLocation() {} - - /** - * Show the town location - */ - virtual int show(); -}; - -class Town { -private: - BaseLocation *_location; -private: - int townWait(); - - Character *doBankOptions(Character *c); - - Character *doBlacksmithOptions(Character *c); - - Character *doGuildOptions(Character *c); - - Character *doTavernOptions(Character *c); - - Character *doTempleOptions(Character *c); - - Character *doTrainingOptions(Character *c); -public: - Town(); - - /** - * Show a given location, and return any result - */ - int townAction(TownAction actionId); - - /** - * Returns true if a town location (bank, blacksmith, etc.) is currently active - */ - bool isActive() const; - - /** - * Draws a currently active town location's animation - */ - void drawAnim(bool flag); -}; - -class TownMessage : public BaseLocation { -private: - SpriteResource _iconSprites; - - TownMessage() : BaseLocation(NO_ACTION) {} - - bool execute(int portrait, const Common::String &name, - const Common::String &text, int confirm); - - void loadButtons(); -public: - static bool show(int portrait, const Common::String &name, - const Common::String &text, int confirm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_SPELLS_H */ diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp index ddecc9a6f7..67fb977572 100644 --- a/engines/xeen/xeen.cpp +++ b/engines/xeen/xeen.cpp @@ -48,6 +48,7 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc) _events = nullptr; _files = nullptr; _interface = nullptr; + _locations = nullptr; _map = nullptr; _party = nullptr; _resources = nullptr; @@ -56,7 +57,6 @@ XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc) _scripts = nullptr; _sound = nullptr; _spells = nullptr; - _town = nullptr; _windows = nullptr; _eventData = nullptr; _noDirectionSense = false; @@ -73,6 +73,7 @@ XeenEngine::~XeenEngine() { delete _debugger; delete _events; delete _interface; + delete _locations; delete _map; delete _party; delete _saves; @@ -80,7 +81,6 @@ XeenEngine::~XeenEngine() { delete _scripts; delete _sound; delete _spells; - delete _town; delete _windows; delete _eventData; delete _resources; @@ -96,6 +96,7 @@ void XeenEngine::initialize() { _debugger = new Debugger(this); _events = new EventsManager(this); _interface = new Interface(this); + _locations = new LocationManager(); _map = new Map(this); _party = new Party(this); _saves = new SavesManager(this, *_party); @@ -103,7 +104,6 @@ void XeenEngine::initialize() { _scripts = new Scripts(this); _sound = new Sound(this, _mixer); _spells = new Spells(this); - _town = new Town(); _windows = new Windows(); File f("029.obj"); diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h index cc187c9527..022ad6673a 100644 --- a/engines/xeen/xeen.h +++ b/engines/xeen/xeen.h @@ -37,6 +37,7 @@ #include "xeen/events.h" #include "xeen/files.h" #include "xeen/interface.h" +#include "xeen/locations.h" #include "xeen/map.h" #include "xeen/party.h" #include "xeen/resources.h" @@ -45,7 +46,6 @@ #include "xeen/scripts.h" #include "xeen/sound.h" #include "xeen/spells.h" -#include "xeen/town.h" #include "xeen/window.h" /** @@ -144,6 +144,7 @@ public: EventsManager *_events; FileManager *_files; Interface *_interface; + LocationManager *_locations; Map *_map; Party *_party; Resources *_resources; @@ -152,7 +153,6 @@ public: Scripts *_scripts; Sound *_sound; Spells *_spells; - Town *_town; Windows *_windows; Mode _mode; GameEvent _gameEvent; -- cgit v1.2.3