aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2015-01-27 08:02:54 -0500
committerPaul Gilbert2015-01-27 08:02:54 -0500
commit88382b2d8f0f1fd27e2100a94ace74453d6186f7 (patch)
treeca87f8d2ada89aba116f08e0b380456c9d73bc94
parent81e1bd2930bf4192fa8bfdbb805c65795e68c6e1 (diff)
downloadscummvm-rg350-88382b2d8f0f1fd27e2100a94ace74453d6186f7.tar.gz
scummvm-rg350-88382b2d8f0f1fd27e2100a94ace74453d6186f7.tar.bz2
scummvm-rg350-88382b2d8f0f1fd27e2100a94ace74453d6186f7.zip
XEEN: Added NumericInput class and refactored existing string input
-rw-r--r--engines/xeen/dialogs_input.cpp187
-rw-r--r--engines/xeen/dialogs_input.h (renamed from engines/xeen/dialogs_string_input.h)27
-rw-r--r--engines/xeen/dialogs_string_input.cpp82
-rw-r--r--engines/xeen/module.mk2
-rw-r--r--engines/xeen/resources.cpp27
-rw-r--r--engines/xeen/resources.h16
-rw-r--r--engines/xeen/screen.cpp76
-rw-r--r--engines/xeen/screen.h2
-rw-r--r--engines/xeen/scripts.cpp2
-rw-r--r--engines/xeen/town.cpp108
-rw-r--r--engines/xeen/town.h9
11 files changed, 360 insertions, 178 deletions
diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp
new file mode 100644
index 0000000000..1394379910
--- /dev/null
+++ b/engines/xeen/dialogs_input.cpp
@@ -0,0 +1,187 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "xeen/dialogs_input.h"
+#include "xeen/scripts.h"
+#include "xeen/xeen.h"
+
+namespace Xeen {
+
+/**
+ * Allows the user to enter a string
+ */
+int Input::getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric) {
+ _vm->_noDirectionSense = true;
+ Common::String msg = Common::String::format("\x03""l\t000\x04%03d\x03""c", maxWidth);
+ _window->writeString(msg);
+ _window->update();
+
+ while (!_vm->shouldQuit()) {
+ Common::KeyCode keyCode = doCursor(msg);
+
+ if ((keyCode == Common::KEYCODE_BACKSPACE || keyCode == Common::KEYCODE_DELETE)
+ && line.size() > 0)
+ line.deleteLastChar();
+ else if (line.size() < maxLen && (line.size() > 0 || keyCode != Common::KEYCODE_SPACE)
+ && ((isNumeric && keyCode >= Common::KEYCODE_0 && keyCode < Common::KEYCODE_9) ||
+ (!isNumeric && keyCode >= Common::KEYCODE_SPACE && keyCode < Common::KEYCODE_DELETE))) {
+ line += (char)keyCode;
+ } else if (keyCode == Common::KEYCODE_RETURN || keyCode == Common::KEYCODE_KP_ENTER) {
+ break;
+ } else if (keyCode == Common::KEYCODE_ESCAPE) {
+ line = "";
+ break;
+ }
+ }
+
+ _vm->_noDirectionSense = false;
+ return line.size();
+}
+
+/**
+ * Draws the cursor and waits until the user presses a key
+ */
+Common::KeyCode Input::doCursor(const Common::String &msg) {
+ EventsManager &events = *_vm->_events;
+ Interface &intf = *_vm->_interface;
+ Screen &screen = *_vm->_screen;
+
+ bool oldUpDoorText = intf._upDoorText;
+ byte oldTillMove = intf._tillMove;
+ intf._upDoorText = false;
+ intf._tillMove = 0;
+
+ bool flag = !_vm->_startupWindowActive && !screen._windows[25]._enabled
+ && _vm->_mode != MODE_FF && _vm->_mode != MODE_17;
+
+ Common::KeyCode ch = Common::KEYCODE_INVALID;
+ while (!_vm->shouldQuit()) {
+ events.updateGameCounter();
+
+ if (flag)
+ intf.draw3d(false);
+ _window->writeString(msg);
+ _window->update();
+
+ if (flag)
+ screen._windows[3].update();
+
+ events.wait(1, true);
+ if (events.isKeyPending()) {
+ Common::KeyState keyState;
+ events.getKey(keyState);
+ ch = keyState.keycode;
+ break;
+ }
+ }
+
+ _window->writeString("");
+ _window->update();
+
+ intf._tillMove = oldTillMove;
+ intf._upDoorText = oldUpDoorText;
+
+ return ch;
+}
+
+/*------------------------------------------------------------------------*/
+
+StringInput::StringInput(XeenEngine *vm): Input(vm, &vm->_screen->_windows[6]) {
+}
+
+int StringInput::show(XeenEngine *vm, bool type, const Common::String &msg1,
+ const Common::String &msg2, int opcode) {
+ StringInput *dlg = new StringInput(vm);
+ int result = dlg->execute(type, msg1, msg2, opcode);
+ delete dlg;
+
+ return result;
+}
+
+int StringInput::execute(bool type, const Common::String &expected,
+ const Common::String &title, int opcode) {
+ Interface &intf = *_vm->_interface;
+ Screen &screen = *_vm->_screen;
+ Scripts &scripts = *_vm->_scripts;
+ Window &w = screen._windows[6];
+ SoundManager &sound = *_vm->_sound;
+ int result = 0;
+
+ w.open();
+ w.writeString(Common::String::format("\r\x03""c%s\v024\t000", title.c_str()));
+ w.update();
+
+ Common::String line;
+ if (getString(line, 30, 200, false)) {
+ if (type) {
+ if (line == intf._interfaceText) {
+ result = true;
+ } else if (line == expected) {
+ result = (opcode == 55) ? -1 : 1;
+ }
+ } else {
+ // Load in the mirror list
+ File f(Common::String::format("%smirr.txt",
+ _vm->_files->_isDarkCc ? "dark" : "xeen"));
+ MirrorEntry me;
+ scripts._mirror.clear();
+ while (me.synchronize(f))
+ scripts._mirror.push_back(me);
+
+ for (uint idx = 0; idx < scripts._mirror.size(); ++idx) {
+ if (line == scripts._mirror[idx]._name) {
+ result = idx;
+ sound.playFX(_vm->_files->_isDarkCc ? 35 : 61);
+ break;
+ }
+ }
+ }
+ }
+
+ w.close();
+ return result;
+}
+
+/*------------------------------------------------------------------------*/
+
+NumericInput::NumericInput(XeenEngine *vm, int window) : Input(vm, &vm->_screen->_windows[window]) {
+}
+
+int NumericInput::show(XeenEngine *vm, int window, int maxLength, int maxWidth) {
+ NumericInput *dlg = new NumericInput(vm, window);
+ int result = dlg->execute(maxLength, maxWidth);
+ delete dlg;
+
+ return result;
+}
+
+int NumericInput::execute(int maxLength, int maxWidth) {
+ Common::String line;
+
+ if (getString(line, maxLength, maxWidth, true))
+ return atoi(line.c_str());
+ else
+ return 0;
+}
+
+
+} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_string_input.h b/engines/xeen/dialogs_input.h
index 1e18726ff2..c6d832ce6b 100644
--- a/engines/xeen/dialogs_string_input.h
+++ b/engines/xeen/dialogs_input.h
@@ -23,21 +23,42 @@
#ifndef XEEN_DIALOGS_STRING_INPUT_H
#define XEEN_DIALOGS_STRING_INPUT_H
+#include "common/keyboard.h"
#include "xeen/dialogs.h"
+#include "xeen/screen.h"
namespace Xeen {
-class StringInput : public ButtonContainer {
+class Input : public ButtonContainer {
private:
+ Common::KeyCode doCursor(const Common::String &msg);
+protected:
XeenEngine *_vm;
+ Window *_window;
- StringInput(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
+ int getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric);
+
+ Input(XeenEngine *vm, Window *window) : _vm(vm), _window(window) {}
+};
+
+class StringInput : public Input {
+protected:
+ StringInput(XeenEngine *vm);
int execute(bool type, const Common::String &expected,
const Common::String &title, int opcode);
public:
static int show(XeenEngine *vm, bool type, const Common::String &msg1,
- const Common::String &msg2, int opcdoe);
+ const Common::String &msg2, int opcode);
+};
+
+class NumericInput : public Input {
+private:
+ NumericInput(XeenEngine *vm, int window);
+
+ int execute(int maxLength, int maxWidth);
+public:
+ static int show(XeenEngine *vm, int window, int maxLength, int maxWidth);
};
} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_string_input.cpp b/engines/xeen/dialogs_string_input.cpp
deleted file mode 100644
index ced4ad39ff..0000000000
--- a/engines/xeen/dialogs_string_input.cpp
+++ /dev/null
@@ -1,82 +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/dialogs_string_input.h"
-#include "xeen/scripts.h"
-#include "xeen/xeen.h"
-
-namespace Xeen {
-
-int StringInput::show(XeenEngine *vm, bool type, const Common::String &msg1,
- const Common::String &msg2, int opcdoe) {
- StringInput *dlg = new StringInput(vm);
- int result = dlg->execute(type, msg1, msg2, opcdoe);
- delete dlg;
-
- return result;
-}
-
-int StringInput::execute(bool type, const Common::String &expected,
- const Common::String &title, int opcode) {
- Interface &intf = *_vm->_interface;
- Screen &screen = *_vm->_screen;
- Scripts &scripts = *_vm->_scripts;
- Window &w = screen._windows[6];
- SoundManager &sound = *_vm->_sound;
- int result = 0;
-
- w.open();
- w.writeString(Common::String::format("\r\x03""c%s\v024\t000", title.c_str()));
- w.update();
-
- Common::String line;
- if (w.getString(line, 30, 200)) {
- if (type) {
- if (line == intf._interfaceText) {
- result = true;
- } else if (line == expected) {
- result = (opcode == 55) ? -1 : 1;
- }
- } else {
- // Load in the mirror list
- File f(Common::String::format("%smirr.txt",
- _vm->_files->_isDarkCc ? "dark" : "xeen"));
- MirrorEntry me;
- scripts._mirror.clear();
- while (me.synchronize(f))
- scripts._mirror.push_back(me);
-
- for (uint idx = 0; idx < scripts._mirror.size(); ++idx) {
- if (line == scripts._mirror[idx]._name) {
- result = idx;
- sound.playFX(_vm->_files->_isDarkCc ? 35 : 61);
- break;
- }
- }
- }
- }
-
- w.close();
- return result;
-}
-
-} // End of namespace Xeen
diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk
index c9ea03fafb..c361c472cf 100644
--- a/engines/xeen/module.mk
+++ b/engines/xeen/module.mk
@@ -10,7 +10,7 @@ MODULE_OBJS := \
dialogs.o \
dialogs_error.o \
dialogs_options.o \
- dialogs_string_input.o \
+ dialogs_input.o \
dialogs_whowill.o \
dialogs_yesno.o \
events.o \
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index c1951d704c..cab6e2643d 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -649,4 +649,31 @@ const char *const TRAINING_TEXT =
"000%s\x02\x03""c\x0B""122\x09""021"
"\x0C""37T\x0C""drain\x09""060ESC\x01";
+const char *const GOLD_GEMS =
+ "\x03""c\x0B""000\x09""000%s\x03l\n"
+ "\n"
+ "Gold\x03r\x09""000%s\x03l\n"
+ "Gems\x03r\x09""000%s\x02\x03""c\x0B""096\x09""013G"
+ "\x0C""37o\x0C""dld\x09""040G\x0C\x03""7e"
+ "\x0C""dms\x09""067ESC\x01";
+
+const char *const DEPOSIT_WITHDRAWL[2] = { "Deposit", "Withdrawl" };
+
+const char *const NOT_ENOUGH_X_IN_THE_Y =
+ "\x03""c\x0B""012Not enough %s in the %s!\x03l";
+
+const char *const NO_X_IN_THE_Y = "\x03""c\x0B""012No %s in the %s!\x03l";
+
+const char *const STAT_NAMES[16] = {
+ "Might", "Intellect", "Personality", "Endurance", "Speed",
+ "Accuracy", "Luck", "Age", "Level", "Armor Class", "Hit Points",
+ "Spell Points", "Resistances", "Skills", "Awards", "Experience"
+};
+
+const char *const CONSUMABLE_NAMES[4] = { "Gold", "Gems", "Food", "Condition" };
+
+const char *const WHERE_NAMES[2] = { "Party", "Bank" };
+
+const char *const AMOUNT = "\x03""c\x09""000\x0B""051Amount\x03l\n";
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index a6f52cb50e..7461888c05 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -182,6 +182,22 @@ extern const char *const ELIGIBLE_FOR_LEVEL;
extern const char *const TRAINING_TEXT;
+extern const char *const GOLD_GEMS;
+
+extern const char *const DEPOSIT_WITHDRAWL[2];
+
+extern const char *const NOT_ENOUGH_X_IN_THE_Y;
+
+extern const char *const NO_X_IN_THE_Y;
+
+extern const char *const STAT_NAMES[16];
+
+extern const char *const CONSUMABLE_NAMES[4];
+
+extern const char *const WHERE_NAMES[2];
+
+extern const char *const AMOUNT;
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/screen.cpp b/engines/xeen/screen.cpp
index 5088829cf6..87062dc5ec 100644
--- a/engines/xeen/screen.cpp
+++ b/engines/xeen/screen.cpp
@@ -177,82 +177,6 @@ void Window::drawList(DrawStruct *items, int count) {
}
}
-/**
- * Allows the user to enter a string
- */
-int Window::getString(Common::String &line, uint maxLen, int maxWidth) {
- _vm->_noDirectionSense = true;
- Common::String msg = Common::String::format("\x03""l\t000\x04%03d\x03""c", maxWidth);
- writeString(msg);
- update();
-
- while (!_vm->shouldQuit()) {
- Common::KeyCode keyCode = doCursor(msg);
-
- if ((keyCode == Common::KEYCODE_BACKSPACE || keyCode == Common::KEYCODE_DELETE)
- && line.size() > 0)
- line.deleteLastChar();
- else if (keyCode >= Common::KEYCODE_SPACE && keyCode < Common::KEYCODE_DELETE
- && line.size() < maxLen && (line.size() > 0 || keyCode != Common::KEYCODE_SPACE)) {
-
- } else if (keyCode == Common::KEYCODE_RETURN || keyCode == Common::KEYCODE_KP_ENTER) {
- break;
- } else if (keyCode == Common::KEYCODE_ESCAPE) {
- line = "";
- break;
- }
- }
-
- _vm->_noDirectionSense = false;
- return line.size();
-}
-
-/**
- * Draws the cursor and waits until the user presses a key
- */
-Common::KeyCode Window::doCursor(const Common::String &msg) {
- EventsManager &events = *_vm->_events;
- Interface &intf = *_vm->_interface;
- Screen &screen = *_vm->_screen;
-
- bool oldUpDoorText = intf._upDoorText;
- byte oldTillMove = intf._tillMove;
- intf._upDoorText = false;
- intf._tillMove = 0;
-
- bool flag = !_vm->_startupWindowActive && !screen._windows[25]._enabled
- && _vm->_mode != MODE_FF && _vm->_mode != MODE_17;
-
- Common::KeyCode ch = Common::KEYCODE_INVALID;
- while (!_vm->shouldQuit()) {
- events.updateGameCounter();
-
- if (flag)
- intf.draw3d(false);
- writeString(msg);
- update();
-
- if (flag)
- screen._windows[3].update();
-
- events.wait(1, true);
- if (events.isKeyPending()) {
- Common::KeyState keyState;
- events.getKey(keyState);
- ch = keyState.keycode;
- break;
- }
- }
-
- writeString("");
- update();
-
- intf._tillMove = oldTillMove;
- intf._upDoorText = oldUpDoorText;
-
- return ch;
-}
-
/*------------------------------------------------------------------------*/
/**
diff --git a/engines/xeen/screen.h b/engines/xeen/screen.h
index 6e805c2aa3..85affe3aa2 100644
--- a/engines/xeen/screen.h
+++ b/engines/xeen/screen.h
@@ -67,8 +67,6 @@ private:
int _ycL, _ycH;
void open2();
-
- Common::KeyCode doCursor(const Common::String &msg);
public:
bool _enabled;
public:
diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp
index 097216523c..e3cc682069 100644
--- a/engines/xeen/scripts.cpp
+++ b/engines/xeen/scripts.cpp
@@ -21,7 +21,7 @@
*/
#include "xeen/scripts.h"
-#include "xeen/dialogs_string_input.h"
+#include "xeen/dialogs_input.h"
#include "xeen/dialogs_whowill.h"
#include "xeen/dialogs_yesno.h"
#include "xeen/party.h"
diff --git a/engines/xeen/town.cpp b/engines/xeen/town.cpp
index bb8590fc48..dceb79c354 100644
--- a/engines/xeen/town.cpp
+++ b/engines/xeen/town.cpp
@@ -195,8 +195,8 @@ int Town::townAction(int actionId) {
sound.loadMusic(TOWN_ACTION_MUSIC[actionId], 223);
- _townSprites.clear();
- for (int idx = 0; idx < TOWN_ACTION_FILES[isDarkCc][actionId]; ++idx) {
+ _townSprites.resize(TOWN_ACTION_FILES[isDarkCc][actionId]);
+ for (uint idx = 0; idx < _townSprites.size(); ++idx) {
Common::String shapesName = Common::String::format("%s%d.twn",
TOWN_ACTION_SHAPES[actionId], idx + 1);
_townSprites[idx].load(shapesName);
@@ -281,20 +281,20 @@ int Town::townAction(int actionId) {
return result;
}
-void Town::townWait() {
+int Town::townWait() {
EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;
- while (!_vm->shouldQuit()) {
+ while (!_vm->shouldQuit() && !_buttonValue) {
events.updateGameCounter();
while (!_vm->shouldQuit() && !_buttonValue && events.timeElapsed() < 3) {
checkEvents(_vm);
}
- if (_buttonValue)
- return;
-
- intf.drawTownAnim(!_vm->_screen->_windows[11]._enabled);
+ if (!_buttonValue)
+ intf.drawTownAnim(!_vm->_screen->_windows[11]._enabled);
}
+
+ return _buttonValue;
}
void Town::pyramidEvent() {
@@ -471,10 +471,96 @@ Common::String Town::createTownText(Character &ch) {
}
}
-Character *Town::doTownOptions(Character *charP) {
- Common::String result;
+Character *Town::doTownOptions(Character *c) {
+ switch (_townActionId) {
+ case 0:
+ if (_buttonValue == Common::KEYCODE_d)
+ _buttonValue = 0;
+ else if (_buttonValue == Common::KEYCODE_w)
+ _buttonValue = 1;
+ else
+ break;
+
+ depositWithdrawl(_buttonValue);
+ break;
+
+ default:
+ // TODO: remaining cases
+ error("TODO: doTownOptions");
+ }
+
+ return c;
+}
+
+void Town::depositWithdrawl(int choice) {
+ Party &party = *_vm->_party;
+ Screen &screen = *_vm->_screen;
+ SoundManager &sound = *_vm->_sound;
+ int gold, gems;
+
+ if (choice) {
+ gold = party._bankGold;
+ gems = party._bankGems;
+ } else {
+ gold = party._gold;
+ gems = party._gems;
+ }
+
+ for (uint idx = 0; idx < _buttons.size(); ++idx)
+ _buttons[idx]._sprites = &_icons1;
+ _buttons[0]._value = Common::KEYCODE_o;
+ _buttons[1]._value = Common::KEYCODE_e;
+ _buttons[2]._value = Common::KEYCODE_ESCAPE;
+
+ Common::String msg = Common::String::format(GOLD_GEMS,
+ DEPOSIT_WITHDRAWL[choice],
+ XeenEngine::printMil(gold).c_str(),
+ XeenEngine::printMil(gems).c_str());
+
+ screen._windows[35].open();
+ screen._windows[35].writeString(msg);
+ drawButtons(&screen._windows[35]);
+ screen._windows[35].update();
+
+ sound.playSample(nullptr, 0);
+ File f("coina.voc");
+ bool flag;
+
+ do {
+ bool flag;
+ switch (townWait()) {
+ case Common::KEYCODE_o:
+ continue;
+ case Common::KEYCODE_e:
+ flag = 1;
+ break;
+ default:
+ flag = 0;
+ break;
+ }
+
+ if ((choice && !party._bankGems && flag) ||
+ (choice && !party._bankGold && !flag) ||
+ (choice && !party._gems && flag) ||
+ (choice && !party._gold && !flag)) {
+ notEnough(flag, choice, 1, WT_2);
+ } else {
+ screen._windows[35].writeString(AMOUNT);
+
+ // TODO
+ }
+ // TODO
+ } while (!_vm->shouldQuit() && _buttonValue != Common::KEYCODE_ESCAPE);
+
+}
+
+void Town::notEnough(int consumableId, int whereId, bool mode, ErrorWaitType wait) {
+ SoundManager &sound = *_vm->_sound;
- error("TODO: doTownOptions");
+ Common::String msg = Common::String::format(
+ mode ? NO_X_IN_THE_Y : NOT_ENOUGH_X_IN_THE_Y,
+ CONSUMABLE_NAMES[consumableId], WHERE_NAMES[whereId]);
+ ErrorScroll::show(_vm, msg, wait);
}
diff --git a/engines/xeen/town.h b/engines/xeen/town.h
index 07e9badc46..068cc8252b 100644
--- a/engines/xeen/town.h
+++ b/engines/xeen/town.h
@@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/str-array.h"
#include "xeen/dialogs.h"
+#include "xeen/dialogs_error.h"
#include "xeen/party.h"
namespace Xeen {
@@ -71,9 +72,13 @@ private:
Common::String createTownText(Character &ch);
- void townWait();
+ int townWait();
- Character *doTownOptions(Character *charP);
+ Character *doTownOptions(Character *c);
+
+ void depositWithdrawl(int choice);
+
+ void notEnough(int consumableId, int whereId, bool mode, ErrorWaitType wait);
public:
Town(XeenEngine *vm);