[Scummvm-git-logs] scummvm master -> b612bc3c23d9ffc6a57eedd684f1d6b10dc3c6ab
dreammaster
dreammaster at scummvm.org
Wed Dec 13 02:30:03 CET 2017
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
a5590a3755 XEEN: Create CutsceneLocation base class for cutscene locations
b612bc3c23 XEEN: Rename Town to LocationManager, added Locations namespace
Commit: a5590a3755ca5a6ec7a52266384f908d1b4405f0
https://github.com/scummvm/scummvm/commit/a5590a3755ca5a6ec7a52266384f908d1b4405f0
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2017-12-12T20:08:51-05:00
Commit Message:
XEEN: Create CutsceneLocation base class for cutscene locations
Changed paths:
engines/xeen/town.cpp
engines/xeen/town.h
diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp
index 34d19da..4a635c7 100644
--- a/engines/xeen/town.cpp
+++ b/engines/xeen/town.cpp
@@ -30,7 +30,7 @@
namespace Xeen {
-TownLocation::TownLocation(TownAction action) : ButtonContainer(g_vm),
+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];
@@ -44,10 +44,9 @@ TownLocation::TownLocation(TownAction action) : ButtonContainer(g_vm),
_farewellTime = 0;
_drawCtr1 = _drawCtr2 = 0;
_townPos = Common::Point(8, 8);
- _animCtr = 0;
}
-TownLocation::~TownLocation() {
+BaseLocation::~BaseLocation() {
Interface &intf = *g_vm->_interface;
for (uint idx = 0; idx < _townSprites.size(); ++idx)
@@ -55,7 +54,7 @@ TownLocation::~TownLocation() {
intf.mainIconsPrint();
}
-int TownLocation::show() {
+int BaseLocation::show() {
Map &map = *g_vm->_map;
Party &party = *g_vm->_party;
Sound &sound = *g_vm->_sound;
@@ -110,7 +109,7 @@ int TownLocation::show() {
return result;
}
-void TownLocation::drawBackground() {
+void BaseLocation::drawBackground() {
Interface &intf = *g_vm->_interface;
intf._face1UIFrame = intf._face2UIFrame = 0;
@@ -120,7 +119,7 @@ void TownLocation::drawBackground() {
_townSprites[_drawFrameIndex / 8].draw(0, _drawFrameIndex % 8, _townPos);
}
-void TownLocation::drawWindow() {
+void BaseLocation::drawWindow() {
Interface &intf = *g_vm->_interface;
Party &party = *g_vm->_party;
Windows &windows = *g_vm->_windows;
@@ -138,7 +137,7 @@ void TownLocation::drawWindow() {
intf.highlightChar(0);
}
-void TownLocation::drawAnim(bool flag) {
+void BaseLocation::drawAnim(bool flag) {
Interface &intf = *g_vm->_interface;
Sound &sound = *g_vm->_sound;
Windows &windows = *g_vm->_windows;
@@ -273,7 +272,7 @@ void TownLocation::drawAnim(bool flag) {
_animFrame = 2;
}
-int TownLocation::wait() {
+int BaseLocation::wait() {
EventsManager &events = *g_vm->_events;
Windows &windows = *g_vm->_windows;
@@ -291,13 +290,9 @@ int TownLocation::wait() {
return _buttonValue;
}
-void TownLocation::animUpdate() {
- // TODO
-}
-
/*------------------------------------------------------------------------*/
-BankLocation::BankLocation() : TownLocation(BANK) {
+BankLocation::BankLocation() : BaseLocation(BANK) {
_icons1.load("bank.icn");
_icons2.load("bank2.icn");
addButton(Common::Rect(234, 108, 259, 128), Common::KEYCODE_d, &_icons1);
@@ -440,7 +435,7 @@ void BankLocation::depositWithdrawl(PartyBank whereId) {
/*------------------------------------------------------------------------*/
-BlacksmithLocation::BlacksmithLocation() : TownLocation(BLACKSMITH) {
+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);
@@ -487,7 +482,7 @@ void BlacksmithLocation::farewell() {
/*------------------------------------------------------------------------*/
-GuildLocation::GuildLocation() : TownLocation(GUILD) {
+GuildLocation::GuildLocation() : BaseLocation(GUILD) {
loadStrings("spldesc.bin");
_icons1.load("esc.icn");
addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_ESCAPE, &_icons1);
@@ -540,7 +535,7 @@ Character *GuildLocation::doOptions(Character *c) {
/*------------------------------------------------------------------------*/
-TavernLocation::TavernLocation() : TownLocation(TAVERN) {
+TavernLocation::TavernLocation() : BaseLocation(TAVERN) {
_v21 = 0;
_v22 = 0;
_v23 = 0;
@@ -781,7 +776,7 @@ void TavernLocation::farewell() {
/*------------------------------------------------------------------------*/
-TempleLocation::TempleLocation() : TownLocation(TEMPLE) {
+TempleLocation::TempleLocation() : BaseLocation(TEMPLE) {
_currentCharLevel = 0;
_donation = 0;
_healCost = 0;
@@ -966,7 +961,7 @@ Character *TempleLocation::doOptions(Character *c) {
/*------------------------------------------------------------------------*/
-TrainingLocation::TrainingLocation() : TownLocation(TRAINING) {
+TrainingLocation::TrainingLocation() : BaseLocation(TRAINING) {
Common::fill(&_charsTrained[0], &_charsTrained[6], 0);
_maxLevel = 0;
_experienceToNextLevel = 0;
@@ -1106,19 +1101,41 @@ Character *TrainingLocation::doOptions(Character *c) {
/*------------------------------------------------------------------------*/
-ArenaLocation::ArenaLocation() : TownLocation(ARENA) {
+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;
+}
+
/*------------------------------------------------------------------------*/
-ReaperLocation::ReaperLocation() : TownLocation(REAPER) {
+ReaperCutscene::ReaperCutscene() : CutsceneLocation(REAPER) {
// TODO
}
/*------------------------------------------------------------------------*/
-GolemLocation::GolemLocation() : TownLocation(GOLEM) {
+GolemCutscene::GolemCutscene() : CutsceneLocation(GOLEM) {
// TODO
}
@@ -1148,15 +1165,13 @@ const int16 DWARF2_Y[2][16] = {
{ 0, 12, 25, 37, 50, 62, 75, 87, 100, 112, 125, 137, 150, 162, 175, 186 }
};
-DwarfLocation::DwarfLocation(bool isDwarf) : TownLocation(NO_ACTION) {
+DwarfCutscene::DwarfCutscene(bool isDwarf) : CutsceneLocation(NO_ACTION) {
_townMaxId = Res.TOWN_MAXES[_isDarkCc][isDwarf ? DWARF1 : DWARF2];
- loadStrings("special.bin");
}
-int DwarfLocation::show() {
+int DwarfCutscene::show() {
EventsManager &events = *g_vm->_events;
Interface &intf = *g_vm->_interface;
- Party &party = *g_vm->_party;
Screen &screen = *g_vm->_screen;
Sound &sound = *g_vm->_sound;
Windows &windows = *g_vm->_windows;
@@ -1165,7 +1180,7 @@ int DwarfLocation::show() {
SpriteResource sprites2(_isDarkCc ? "town2.zom" : "dwarf2.vga");
SpriteResource sprites3(_isDarkCc ? "town3.zom" : "dwarf3.vga");
SpriteResource boxSprites("box.vga");
- bool mazeFlag = setNewLocation();
+ getNewLocation();
// Save the screen contents
Graphics::ManagedSurface savedBg;
@@ -1208,13 +1223,13 @@ int DwarfLocation::show() {
if (_isDarkCc) {
sprites2.draw(0, 0);
sprites3.draw(0, 0);
- animUpdate();
+ cutsceneAnimUpdate();
events.timeMark5();
while (!g_vm->shouldQuit() && events.timeElapsed5() < 7)
events.pollEventsAndWait();
- sound.playSound(mazeFlag ? "ok2.voc" : "back2.voc");
+ sound.playSound(_mazeFlag ? "ok2.voc" : "back2.voc");
} else {
sound.playSound("dwarf11.voc");
}
@@ -1229,7 +1244,7 @@ int DwarfLocation::show() {
do {
sprites2.draw(0, 0);
sprites3.draw(0, g_vm->getRandomNumber(_isDarkCc ? 8 : 9));
- animUpdate();
+ cutsceneAnimUpdate();
events.timeMark5();
while (!g_vm->shouldQuit() && events.timeElapsed5() < 2)
@@ -1245,6 +1260,8 @@ int DwarfLocation::show() {
sprites3.draw(0, 1);
windows[0].update();
+ setNewLocation();
+
// Restore game screen
sound.setMusicVolume(95);
screen.loadBackground("back.raw");
@@ -1255,54 +1272,48 @@ int DwarfLocation::show() {
return 0;
}
-bool DwarfLocation::setNewLocation() {
- Map &map = *g_vm->_map;
+void DwarfCutscene::getNewLocation() {
Party &party = *g_vm->_party;
- Common::Point mazePos;
- Direction mazeDir = DIR_NORTH;
- int mazeId = 0;
- bool mazeFlag = false;
- // Set
if (_isDarkCc) {
switch (party._mazeId) {
case 4:
if (party._questItems[35]) {
- mazeId = 29;
- mazePos = Common::Point(15, 31);
- mazeDir = DIR_SOUTH;
+ _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;
+ _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;
+ _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;
+ _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;
+ _mazeId = 37;
+ _mazePos = Common::Point(7, 0);
+ _mazeDir = DIR_NORTH;
}
break;
@@ -1310,41 +1321,36 @@ bool DwarfLocation::setNewLocation() {
break;
}
- mazeFlag = mazeId != 0;
- if (!mazeFlag) {
- mazeId = party._mazeId;
- mazePos = party._mazePosition;
- mazeDir = party._mazeDirection;
- }
+ _mazeFlag = _mazeId != 0;
} else {
switch (party._mazeId) {
case 14:
- mazeId = 37;
- mazePos = Common::Point(1, 4);
- mazeDir = DIR_EAST;
+ _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;
+ _mazeId = 35;
+ _mazePos = Common::Point(1, 12);
+ _mazeDir = DIR_EAST;
} else {
- mazeId = 36;
- mazePos = Common::Point(7, 1);
- mazeDir = DIR_NORTH;
+ _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;
+ _mazeId = 33;
+ _mazePos = Common::Point(7, 1);
+ _mazeDir = DIR_NORTH;
} else {
- mazeId = 34;
- mazePos = Common::Point(7, 30);
- mazeDir = DIR_SOUTH;
+ _mazeId = 34;
+ _mazePos = Common::Point(7, 30);
+ _mazeDir = DIR_SOUTH;
}
break;
@@ -1352,22 +1358,57 @@ bool DwarfLocation::setNewLocation() {
break;
}
}
-
- map.load(mazeId);
- party._mazePosition = mazePos;
- party._mazeDirection = mazeDir;
- return mazeFlag;
}
/*------------------------------------------------------------------------*/
-SphinxLocation::SphinxLocation() : TownLocation(SPHINX) {
+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() : TownLocation(PYRAMID) {
+PyramidLocation::PyramidLocation() : BaseLocation(PYRAMID) {
}
int PyramidLocation::show() {
@@ -1450,19 +1491,19 @@ int Town::townAction(TownAction actionId) {
_location = new ArenaLocation();
break;
case REAPER:
- _location = new ReaperLocation();
+ _location = new ReaperCutscene();
break;
case GOLEM:
- _location = new GolemLocation();
+ _location = new GolemCutscene();
break;
case DWARF1:
- _location = new DwarfLocation(true);
+ _location = new DwarfCutscene(true);
break;
case DWARF2:
- _location = new DwarfLocation(false);
+ _location = new DwarfCutscene(false);
break;
case SPHINX:
- _location = new SphinxLocation();
+ _location = new SphinxCutscene();
break;
case PYRAMID:
_location = new PyramidLocation();
diff --git a/engines/xeen/town.h b/engines/xeen/town.h
index b4b70fa..925bac9 100644
--- a/engines/xeen/town.h
+++ b/engines/xeen/town.h
@@ -40,7 +40,7 @@ enum TownAction {
class XeenEngine;
class TownMessage;
-class TownLocation : public ButtonContainer {
+class BaseLocation : public ButtonContainer {
protected:
TownAction _townActionId;
Common::Array<SpriteResource> _townSprites;
@@ -53,7 +53,6 @@ protected:
int _drawFrameIndex;
uint _farewellTime;
int _drawCtr1, _drawCtr2;
- int _animCtr;
protected:
/**
* Draw the window
@@ -66,11 +65,6 @@ protected:
int wait();
/**
- * Handles animation updates for Sphinx, Golem, Repear, and Dwarf events
- */
- void animUpdate();
-
- /**
* Generates the display text for the location, for a given character
*/
virtual Common::String createLocationText(Character &ch) { return ""; }
@@ -90,8 +84,8 @@ protected:
*/
virtual void farewell() {}
public:
- TownLocation(TownAction action);
- virtual ~TownLocation();
+ BaseLocation(TownAction action);
+ virtual ~BaseLocation();
/**
* Show the town location
@@ -104,7 +98,7 @@ public:
void drawAnim(bool flag);
};
-class BankLocation : public TownLocation {
+class BankLocation : public BaseLocation {
private:
/**
* Handles deposits or withdrawls fro the bank
@@ -130,7 +124,7 @@ public:
virtual ~BankLocation() {}
};
-class BlacksmithLocation : public TownLocation {
+class BlacksmithLocation : public BaseLocation {
protected:
/**
* Generates the display text for the location, for a given character
@@ -151,7 +145,7 @@ public:
virtual ~BlacksmithLocation() {}
};
-class GuildLocation : public TownLocation {
+class GuildLocation : public BaseLocation {
protected:
/**
* Generates the display text for the location, for a given character
@@ -167,7 +161,7 @@ public:
virtual ~GuildLocation() {}
};
-class TavernLocation : public TownLocation {
+class TavernLocation : public BaseLocation {
private:
int _v21;
uint _v22;
@@ -193,7 +187,7 @@ public:
virtual ~TavernLocation() {}
};
-class TempleLocation : public TownLocation {
+class TempleLocation : public BaseLocation {
private:
int _currentCharLevel;
int _donation;
@@ -219,7 +213,7 @@ public:
virtual ~TempleLocation() {}
};
-class TrainingLocation : public TownLocation {
+class TrainingLocation : public BaseLocation {
private:
int _charIndex;
bool _charsTrained[MAX_ACTIVE_PARTY];
@@ -240,33 +234,55 @@ public:
virtual ~TrainingLocation() {}
};
-class ArenaLocation : public TownLocation {
+class ArenaLocation : public BaseLocation {
public:
ArenaLocation();
virtual ~ArenaLocation() {}
};
-class ReaperLocation : public TownLocation {
+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:
- ReaperLocation();
- virtual ~ReaperLocation() {}
+ ReaperCutscene();
+ virtual ~ReaperCutscene() {}
};
-class GolemLocation : public TownLocation {
+class GolemCutscene : public CutsceneLocation {
public:
- GolemLocation();
- virtual ~GolemLocation() {}
+ GolemCutscene();
+ virtual ~GolemCutscene() {}
};
-class DwarfLocation : public TownLocation {
+class DwarfCutscene : public CutsceneLocation {
private:
/**
- * Set the new location
+ * Get the new location
*/
- bool setNewLocation();
+ void getNewLocation();
public:
- DwarfLocation(bool isDwarf1);
- virtual ~DwarfLocation() {}
+ DwarfCutscene(bool isDwarf1);
+ virtual ~DwarfCutscene() {}
/**
* Show the town location
@@ -274,13 +290,18 @@ public:
virtual int show();
};
-class SphinxLocation : public TownLocation {
+class SphinxCutscene : public CutsceneLocation {
+private:
+ /**
+ * Get the new location
+ */
+ void getNewLocation();
public:
- SphinxLocation();
- virtual ~SphinxLocation() {}
+ SphinxCutscene();
+ virtual ~SphinxCutscene() {}
};
-class PyramidLocation : public TownLocation {
+class PyramidLocation : public BaseLocation {
public:
PyramidLocation();
virtual ~PyramidLocation() {}
@@ -293,7 +314,7 @@ public:
class Town {
private:
- TownLocation *_location;
+ BaseLocation *_location;
private:
int townWait();
@@ -327,11 +348,11 @@ public:
void drawAnim(bool flag);
};
-class TownMessage : public TownLocation {
+class TownMessage : public BaseLocation {
private:
SpriteResource _iconSprites;
- TownMessage() : TownLocation(NO_ACTION) {}
+ TownMessage() : BaseLocation(NO_ACTION) {}
bool execute(int portrait, const Common::String &name,
const Common::String &text, int confirm);
Commit: b612bc3c23d9ffc6a57eedd684f1d6b10dc3c6ab
https://github.com/scummvm/scummvm/commit/b612bc3c23d9ffc6a57eedd684f1d6b10dc3c6ab
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2017-12-12T20:29:47-05:00
Commit Message:
XEEN: Rename Town to LocationManager, added Locations namespace
Changed paths:
A engines/xeen/locations.cpp
A engines/xeen/locations.h
R engines/xeen/town.cpp
R engines/xeen/town.h
engines/xeen/dialogs_input.cpp
engines/xeen/dialogs_query.cpp
engines/xeen/dialogs_whowill.cpp
engines/xeen/module.mk
engines/xeen/scripts.cpp
engines/xeen/xeen.cpp
engines/xeen/xeen.h
diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp
index 2f4a174..a0573d2 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 7dd35a1..fd46693 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 36451dc..a2be4e3 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 0000000..cc2320a
--- /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 0000000..e0f4838
--- /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<SpriteResource> _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 7656f4c..2e11e19 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 e630893..cfdd9b7 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 4a635c7..0000000
--- 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 925bac9..0000000
--- 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<SpriteResource> _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 ddecc9a..67fb977 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 cc187c9..022ad66 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;
More information about the Scummvm-git-logs
mailing list