From f2b574d64762d23a83cc682da0e622be99080688 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 4 Mar 2018 18:12:09 -0500 Subject: XEEN: Move all the dialog classes to their own sub-folder --- engines/xeen/character.cpp | 4 +- engines/xeen/dialogs.cpp | 257 ------ engines/xeen/dialogs.h | 137 --- engines/xeen/dialogs/dialogs.cpp | 257 ++++++ engines/xeen/dialogs/dialogs.h | 137 +++ engines/xeen/dialogs/dialogs_awards.cpp | 131 +++ engines/xeen/dialogs/dialogs_awards.h | 52 ++ engines/xeen/dialogs/dialogs_char_info.cpp | 571 ++++++++++++ engines/xeen/dialogs/dialogs_char_info.h | 69 ++ engines/xeen/dialogs/dialogs_control_panel.cpp | 220 +++++ engines/xeen/dialogs/dialogs_control_panel.h | 66 ++ engines/xeen/dialogs/dialogs_create_char.cpp | 648 ++++++++++++++ engines/xeen/dialogs/dialogs_create_char.h | 124 +++ engines/xeen/dialogs/dialogs_difficulty.cpp | 75 ++ engines/xeen/dialogs/dialogs_difficulty.h | 60 ++ engines/xeen/dialogs/dialogs_dismiss.cpp | 95 ++ engines/xeen/dialogs/dialogs_dismiss.h | 46 + engines/xeen/dialogs/dialogs_exchange.cpp | 80 ++ engines/xeen/dialogs/dialogs_exchange.h | 46 + engines/xeen/dialogs/dialogs_info.cpp | 129 +++ engines/xeen/dialogs/dialogs_info.h | 46 + engines/xeen/dialogs/dialogs_input.cpp | 323 +++++++ engines/xeen/dialogs/dialogs_input.h | 105 +++ engines/xeen/dialogs/dialogs_items.cpp | 1066 +++++++++++++++++++++++ engines/xeen/dialogs/dialogs_items.h | 89 ++ engines/xeen/dialogs/dialogs_map.cpp | 461 ++++++++++ engines/xeen/dialogs/dialogs_map.h | 62 ++ engines/xeen/dialogs/dialogs_message.cpp | 123 +++ engines/xeen/dialogs/dialogs_message.h | 61 ++ engines/xeen/dialogs/dialogs_party.cpp | 451 ++++++++++ engines/xeen/dialogs/dialogs_party.h | 87 ++ engines/xeen/dialogs/dialogs_query.cpp | 158 ++++ engines/xeen/dialogs/dialogs_query.h | 50 ++ engines/xeen/dialogs/dialogs_quests.cpp | 254 ++++++ engines/xeen/dialogs/dialogs_quests.h | 49 ++ engines/xeen/dialogs/dialogs_quick_fight.cpp | 105 +++ engines/xeen/dialogs/dialogs_quick_fight.h | 60 ++ engines/xeen/dialogs/dialogs_quick_ref.cpp | 88 ++ engines/xeen/dialogs/dialogs_quick_ref.h | 41 + engines/xeen/dialogs/dialogs_spells.cpp | 1045 ++++++++++++++++++++++ engines/xeen/dialogs/dialogs_spells.h | 151 ++++ engines/xeen/dialogs/dialogs_whowill.cpp | 105 +++ engines/xeen/dialogs/dialogs_whowill.h | 41 + engines/xeen/dialogs_awards.cpp | 131 --- engines/xeen/dialogs_awards.h | 52 -- engines/xeen/dialogs_char_info.cpp | 571 ------------ engines/xeen/dialogs_char_info.h | 69 -- engines/xeen/dialogs_control_panel.cpp | 220 ----- engines/xeen/dialogs_control_panel.h | 66 -- engines/xeen/dialogs_create_char.cpp | 648 -------------- engines/xeen/dialogs_create_char.h | 124 --- engines/xeen/dialogs_difficulty.cpp | 75 -- engines/xeen/dialogs_difficulty.h | 60 -- engines/xeen/dialogs_dismiss.cpp | 95 -- engines/xeen/dialogs_dismiss.h | 46 - engines/xeen/dialogs_exchange.cpp | 80 -- engines/xeen/dialogs_exchange.h | 46 - engines/xeen/dialogs_info.cpp | 129 --- engines/xeen/dialogs_info.h | 46 - engines/xeen/dialogs_input.cpp | 323 ------- engines/xeen/dialogs_input.h | 105 --- engines/xeen/dialogs_items.cpp | 1066 ----------------------- engines/xeen/dialogs_items.h | 89 -- engines/xeen/dialogs_map.cpp | 461 ---------- engines/xeen/dialogs_map.h | 62 -- engines/xeen/dialogs_message.cpp | 123 --- engines/xeen/dialogs_message.h | 61 -- engines/xeen/dialogs_party.cpp | 451 ---------- engines/xeen/dialogs_party.h | 87 -- engines/xeen/dialogs_query.cpp | 158 ---- engines/xeen/dialogs_query.h | 50 -- engines/xeen/dialogs_quests.cpp | 254 ------ engines/xeen/dialogs_quests.h | 49 -- engines/xeen/dialogs_quick_fight.cpp | 105 --- engines/xeen/dialogs_quick_fight.h | 60 -- engines/xeen/dialogs_quick_ref.cpp | 88 -- engines/xeen/dialogs_quick_ref.h | 41 - engines/xeen/dialogs_spells.cpp | 1045 ---------------------- engines/xeen/dialogs_spells.h | 151 ---- engines/xeen/dialogs_whowill.cpp | 105 --- engines/xeen/dialogs_whowill.h | 41 - engines/xeen/interface.cpp | 24 +- engines/xeen/interface.h | 2 +- engines/xeen/interface_scene.cpp | 2 +- engines/xeen/locations.cpp | 10 +- engines/xeen/locations.h | 4 +- engines/xeen/module.mk | 40 +- engines/xeen/party.cpp | 4 +- engines/xeen/party.h | 2 +- engines/xeen/scripts.cpp | 6 +- engines/xeen/spells.cpp | 4 +- engines/xeen/swordsofxeen/swordsofxeen_menu.cpp | 2 +- engines/xeen/swordsofxeen/swordsofxeen_menu.h | 2 +- engines/xeen/worldofxeen/worldofxeen_menu.cpp | 2 +- engines/xeen/worldofxeen/worldofxeen_menu.h | 2 +- engines/xeen/xeen.h | 2 +- 96 files changed, 7883 insertions(+), 7883 deletions(-) delete mode 100644 engines/xeen/dialogs.cpp delete mode 100644 engines/xeen/dialogs.h create mode 100644 engines/xeen/dialogs/dialogs.cpp create mode 100644 engines/xeen/dialogs/dialogs.h create mode 100644 engines/xeen/dialogs/dialogs_awards.cpp create mode 100644 engines/xeen/dialogs/dialogs_awards.h create mode 100644 engines/xeen/dialogs/dialogs_char_info.cpp create mode 100644 engines/xeen/dialogs/dialogs_char_info.h create mode 100644 engines/xeen/dialogs/dialogs_control_panel.cpp create mode 100644 engines/xeen/dialogs/dialogs_control_panel.h create mode 100644 engines/xeen/dialogs/dialogs_create_char.cpp create mode 100644 engines/xeen/dialogs/dialogs_create_char.h create mode 100644 engines/xeen/dialogs/dialogs_difficulty.cpp create mode 100644 engines/xeen/dialogs/dialogs_difficulty.h create mode 100644 engines/xeen/dialogs/dialogs_dismiss.cpp create mode 100644 engines/xeen/dialogs/dialogs_dismiss.h create mode 100644 engines/xeen/dialogs/dialogs_exchange.cpp create mode 100644 engines/xeen/dialogs/dialogs_exchange.h create mode 100644 engines/xeen/dialogs/dialogs_info.cpp create mode 100644 engines/xeen/dialogs/dialogs_info.h create mode 100644 engines/xeen/dialogs/dialogs_input.cpp create mode 100644 engines/xeen/dialogs/dialogs_input.h create mode 100644 engines/xeen/dialogs/dialogs_items.cpp create mode 100644 engines/xeen/dialogs/dialogs_items.h create mode 100644 engines/xeen/dialogs/dialogs_map.cpp create mode 100644 engines/xeen/dialogs/dialogs_map.h create mode 100644 engines/xeen/dialogs/dialogs_message.cpp create mode 100644 engines/xeen/dialogs/dialogs_message.h create mode 100644 engines/xeen/dialogs/dialogs_party.cpp create mode 100644 engines/xeen/dialogs/dialogs_party.h create mode 100644 engines/xeen/dialogs/dialogs_query.cpp create mode 100644 engines/xeen/dialogs/dialogs_query.h create mode 100644 engines/xeen/dialogs/dialogs_quests.cpp create mode 100644 engines/xeen/dialogs/dialogs_quests.h create mode 100644 engines/xeen/dialogs/dialogs_quick_fight.cpp create mode 100644 engines/xeen/dialogs/dialogs_quick_fight.h create mode 100644 engines/xeen/dialogs/dialogs_quick_ref.cpp create mode 100644 engines/xeen/dialogs/dialogs_quick_ref.h create mode 100644 engines/xeen/dialogs/dialogs_spells.cpp create mode 100644 engines/xeen/dialogs/dialogs_spells.h create mode 100644 engines/xeen/dialogs/dialogs_whowill.cpp create mode 100644 engines/xeen/dialogs/dialogs_whowill.h delete mode 100644 engines/xeen/dialogs_awards.cpp delete mode 100644 engines/xeen/dialogs_awards.h delete mode 100644 engines/xeen/dialogs_char_info.cpp delete mode 100644 engines/xeen/dialogs_char_info.h delete mode 100644 engines/xeen/dialogs_control_panel.cpp delete mode 100644 engines/xeen/dialogs_control_panel.h delete mode 100644 engines/xeen/dialogs_create_char.cpp delete mode 100644 engines/xeen/dialogs_create_char.h delete mode 100644 engines/xeen/dialogs_difficulty.cpp delete mode 100644 engines/xeen/dialogs_difficulty.h delete mode 100644 engines/xeen/dialogs_dismiss.cpp delete mode 100644 engines/xeen/dialogs_dismiss.h delete mode 100644 engines/xeen/dialogs_exchange.cpp delete mode 100644 engines/xeen/dialogs_exchange.h delete mode 100644 engines/xeen/dialogs_info.cpp delete mode 100644 engines/xeen/dialogs_info.h delete mode 100644 engines/xeen/dialogs_input.cpp delete mode 100644 engines/xeen/dialogs_input.h delete mode 100644 engines/xeen/dialogs_items.cpp delete mode 100644 engines/xeen/dialogs_items.h delete mode 100644 engines/xeen/dialogs_map.cpp delete mode 100644 engines/xeen/dialogs_map.h delete mode 100644 engines/xeen/dialogs_message.cpp delete mode 100644 engines/xeen/dialogs_message.h delete mode 100644 engines/xeen/dialogs_party.cpp delete mode 100644 engines/xeen/dialogs_party.h delete mode 100644 engines/xeen/dialogs_query.cpp delete mode 100644 engines/xeen/dialogs_query.h delete mode 100644 engines/xeen/dialogs_quests.cpp delete mode 100644 engines/xeen/dialogs_quests.h delete mode 100644 engines/xeen/dialogs_quick_fight.cpp delete mode 100644 engines/xeen/dialogs_quick_fight.h delete mode 100644 engines/xeen/dialogs_quick_ref.cpp delete mode 100644 engines/xeen/dialogs_quick_ref.h delete mode 100644 engines/xeen/dialogs_spells.cpp delete mode 100644 engines/xeen/dialogs_spells.h delete mode 100644 engines/xeen/dialogs_whowill.cpp delete mode 100644 engines/xeen/dialogs_whowill.h (limited to 'engines') diff --git a/engines/xeen/character.cpp b/engines/xeen/character.cpp index 69fbc1666a..c6ebde8a39 100644 --- a/engines/xeen/character.cpp +++ b/engines/xeen/character.cpp @@ -21,8 +21,8 @@ */ #include "xeen/character.h" -#include "xeen/dialogs_query.h" -#include "xeen/dialogs_message.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/dialogs/dialogs_message.h" #include "xeen/resources.h" #include "xeen/xeen.h" diff --git a/engines/xeen/dialogs.cpp b/engines/xeen/dialogs.cpp deleted file mode 100644 index 4ca69ec4cb..0000000000 --- a/engines/xeen/dialogs.cpp +++ /dev/null @@ -1,257 +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 "common/scummsys.h" -#include "xeen/dialogs.h" -#include "xeen/events.h" -#include "xeen/resources.h" -#include "xeen/screen.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void ButtonContainer::saveButtons() { - _savedButtons.push(_buttons); - clearButtons(); -} - -/* - * Clears the current list of defined buttons - */ -void ButtonContainer::clearButtons() { - _buttons.clear(); -} - -void ButtonContainer::restoreButtons() { - _buttons = _savedButtons.pop(); -} - -void ButtonContainer::addButton(const Common::Rect &bounds, int val, - SpriteResource *sprites) { - _buttons.push_back(UIButton(bounds, val, _buttons.size() * 2, sprites, sprites != nullptr)); -} - -void ButtonContainer::addButton(const Common::Rect &bounds, int val, - int frameNum, SpriteResource *sprites) { - _buttons.push_back(UIButton(bounds, val, frameNum, sprites, sprites != nullptr)); -} - -void ButtonContainer::addPartyButtons(XeenEngine *vm) { - for (uint idx = 0; idx < MAX_ACTIVE_PARTY; ++idx) { - addButton(Common::Rect(Res.CHAR_FACES_X[idx], 150, Res.CHAR_FACES_X[idx] + 32, 182), - Common::KEYCODE_F1 + idx); - } -} - -bool ButtonContainer::checkEvents(XeenEngine *vm) { - EventsManager &events = *vm->_events; - Party &party = *vm->_party; - Windows &windows = *_vm->_windows; - _buttonValue = 0; - - if (events._leftButton) { - Common::Point pt = events._mousePos; - - // Check for party member glyphs being clicked - Common::Rect r(0, 0, 32, 32); - for (uint idx = 0; idx < party._activeParty.size(); ++idx) { - r.moveTo(Res.CHAR_FACES_X[idx], 150); - if (r.contains(pt)) { - _buttonValue = Common::KEYCODE_F1 + idx; - break; - } - } - - // Check whether any button is selected - for (uint i = 0; i < _buttons.size(); ++i) { - if (_buttons[i]._bounds.contains(pt)) { - events.debounceMouse(); - - _buttonValue = _buttons[i]._value; - break; - } - } - - if (!_buttonValue && Common::Rect(8, 8, 224, 135).contains(pt)) { - _buttonValue = 1; - return true; - } - } else if (events.isKeyPending()) { - Common::KeyState keyState; - events.getKey(keyState); - - _buttonValue = keyState.keycode; - if (_buttonValue == Common::KEYCODE_KP8) - _buttonValue = Common::KEYCODE_UP; - else if (_buttonValue == Common::KEYCODE_KP2) - _buttonValue = Common::KEYCODE_DOWN; - else if (_buttonValue == Common::KEYCODE_KP_ENTER) - _buttonValue = Common::KEYCODE_RETURN; - - _buttonValue |= (keyState.flags & ~Common::KBD_STICKY) << 16; - } - - if (_buttonValue) { - // Check for a button matching the selected _buttonValue - Window &win = windows[39]; - for (uint btnIndex = 0; btnIndex < _buttons.size(); ++btnIndex) { - UIButton &btn = _buttons[btnIndex]; - if (btn._draw && btn._value == _buttonValue) { - // Found the correct button - // Draw button depressed - btn._sprites->draw(0, btn._frameNum + 1, - Common::Point(btn._bounds.left, btn._bounds.top)); - win.setBounds(btn._bounds); - win.update(); - - // Slight delay - events.updateGameCounter(); - events.wait(2); - - // Redraw button in it's original non-depressed form - btn._sprites->draw(0, btn._frameNum, - Common::Point(btn._bounds.left, btn._bounds.top)); - win.setBounds(btn._bounds); - win.update(); - break; - } - } - - return true; - } - - return false; -} - -void ButtonContainer::drawButtons(XSurface *surface) { - for (uint btnIndex = 0; btnIndex < _buttons.size(); ++btnIndex) { - UIButton &btn = _buttons[btnIndex]; - if (btn._draw) { - btn._sprites->draw(*surface, btn._frameNum, - Common::Point(btn._bounds.left, btn._bounds.top)); - } - } -} - -bool ButtonContainer::doScroll(bool rollUp, bool fadeIn) { - if (_vm->_files->_isDarkCc) { - return Cutscenes::doScroll(rollUp, fadeIn); - } else { - saveButtons(); - clearButtons(); - bool result = Cutscenes::doScroll(rollUp, fadeIn); - restoreButtons(); - return result; - } -} - -void ButtonContainer::loadStrings(const Common::String &name) { - File f(name); - _textStrings.clear(); - while (f.pos() < f.size()) - _textStrings.push_back(f.readString()); - f.close(); -} - -void ButtonContainer::loadStrings(const Common::String &name, int ccMode) { - File f(name, ccMode); - _textStrings.clear(); - while (f.pos() < f.size()) - _textStrings.push_back(f.readString()); - f.close(); -} - -/*------------------------------------------------------------------------*/ - -void SettingsBaseDialog::showContents(SpriteResource &title1, bool waitFlag) { - _vm->_events->pollEventsAndWait(); - checkEvents(_vm); -} - -/*------------------------------------------------------------------------*/ - -void CreditsScreen::show(XeenEngine *vm) { - CreditsScreen *dlg = new CreditsScreen(vm); - - switch (vm->getGameID()) { - case GType_Clouds: - dlg->execute(Res.CLOUDS_CREDITS); - break; - case GType_Swords: - dlg->execute(Res.SWORDS_CREDITS1); - dlg->execute(Res.SWORDS_CREDITS2); - break; - default: - dlg->execute(Res.DARK_SIDE_CREDITS); - break; - } - - delete dlg; -} - -void CreditsScreen::execute(const char *content) { - Screen &screen = *_vm->_screen; - Windows &windows = *_vm->_windows; - EventsManager &events = *_vm->_events; - - // Handle drawing the credits screen - doScroll(true, false); - windows[GAME_WINDOW].close(); - - screen.loadBackground("marb.raw"); - windows[0].writeString(content); - doScroll(false, false); - - events.setCursor(0); - windows[0].update(); - clearButtons(); - - // Wait for keypress - while (!events.isKeyMousePressed()) - events.pollEventsAndWait(); - - doScroll(true, false); -} - -/*------------------------------------------------------------------------*/ - -PleaseWait::PleaseWait(bool isOops) { - _msg = isOops ? Res.OOPS : Res.PLEASE_WAIT; -} - -PleaseWait::~PleaseWait() { - Windows &windows = *g_vm->_windows; - windows[9].close(); -} - -void PleaseWait::show() { - Windows &windows = *g_vm->_windows; - Window &w = windows[9]; - - if (g_vm->_mode != MODE_0) { - w.open(); - w.writeString(_msg); - w.update(); - } -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs.h b/engines/xeen/dialogs.h deleted file mode 100644 index cabc921536..0000000000 --- a/engines/xeen/dialogs.h +++ /dev/null @@ -1,137 +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_DIALOGS_H -#define XEEN_DIALOGS_H - -#include "common/array.h" -#include "common/stack.h" -#include "common/rect.h" -#include "xeen/cutscenes.h" -#include "xeen/sprites.h" -#include "xeen/xsurface.h" - -namespace Xeen { - -class XeenEngine; - -class UIButton { -public: - Common::Rect _bounds; - SpriteResource *_sprites; - int _value; - uint _frameNum; - bool _draw; - - UIButton(const Common::Rect &bounds, int value, uint frameNum, SpriteResource *sprites, bool draw) : - _bounds(bounds), _value(value), _frameNum(frameNum), - _sprites(sprites), _draw(draw) {} - - UIButton() : _value(0), _frameNum(0), _sprites(nullptr), _draw(false) {} -}; - -class ButtonContainer : public Cutscenes { -private: - Common::Stack< Common::Array > _savedButtons; -protected: - Common::Array _buttons; - Common::StringArray _textStrings; - int _buttonValue; - - bool checkEvents(XeenEngine *vm); - - /** - * Draws the scroll in the background - * @param rollUp If true, rolls up the scroll. If false, unrolls. - * @param fadeIn If true, does an initial fade in - * @returns True if key or mouse pressed - */ - virtual bool doScroll(bool rollUp, bool fadeIn); - - /** - * Load a set of text strings from the given resource - * @param name Name of resource containing strings - */ - void loadStrings(const Common::String &name); - - /** - * Load a set of text strings from the given resource - * @param name Name of resource containing strings - * @param ccMode Optional cc file number to explicitly use - */ - void loadStrings(const Common::String &name, int ccMode); -public: - ButtonContainer(XeenEngine *vm) : Cutscenes(vm), _buttonValue(0) {} - - /** - * Saves the current list of buttons - */ - void saveButtons(); - - void clearButtons(); - - void restoreButtons(); - - void addButton(const Common::Rect &bounds, int val, - SpriteResource *sprites = nullptr); - void addButton(const Common::Rect &bounds, int val, - int frameNum, SpriteResource *sprites = nullptr); - - void addPartyButtons(XeenEngine *vm); - - /** - * Draws the buttons onto the passed surface - */ - void drawButtons(XSurface *surface); -}; - -class SettingsBaseDialog : public ButtonContainer { -protected: - virtual void showContents(SpriteResource &title1, bool mode); -public: - SettingsBaseDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - virtual ~SettingsBaseDialog() {} -}; - -class CreditsScreen: public ButtonContainer { -private: - CreditsScreen(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(const char *content); -public: - static void show(XeenEngine *vm); -}; - -class PleaseWait { -private: - Common::String _msg; -public: - PleaseWait(bool isOops = false); - ~PleaseWait(); - - void show(); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_H */ diff --git a/engines/xeen/dialogs/dialogs.cpp b/engines/xeen/dialogs/dialogs.cpp new file mode 100644 index 0000000000..c9b5658a0e --- /dev/null +++ b/engines/xeen/dialogs/dialogs.cpp @@ -0,0 +1,257 @@ +/* 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 "common/scummsys.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/events.h" +#include "xeen/resources.h" +#include "xeen/screen.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void ButtonContainer::saveButtons() { + _savedButtons.push(_buttons); + clearButtons(); +} + +/* + * Clears the current list of defined buttons + */ +void ButtonContainer::clearButtons() { + _buttons.clear(); +} + +void ButtonContainer::restoreButtons() { + _buttons = _savedButtons.pop(); +} + +void ButtonContainer::addButton(const Common::Rect &bounds, int val, + SpriteResource *sprites) { + _buttons.push_back(UIButton(bounds, val, _buttons.size() * 2, sprites, sprites != nullptr)); +} + +void ButtonContainer::addButton(const Common::Rect &bounds, int val, + int frameNum, SpriteResource *sprites) { + _buttons.push_back(UIButton(bounds, val, frameNum, sprites, sprites != nullptr)); +} + +void ButtonContainer::addPartyButtons(XeenEngine *vm) { + for (uint idx = 0; idx < MAX_ACTIVE_PARTY; ++idx) { + addButton(Common::Rect(Res.CHAR_FACES_X[idx], 150, Res.CHAR_FACES_X[idx] + 32, 182), + Common::KEYCODE_F1 + idx); + } +} + +bool ButtonContainer::checkEvents(XeenEngine *vm) { + EventsManager &events = *vm->_events; + Party &party = *vm->_party; + Windows &windows = *_vm->_windows; + _buttonValue = 0; + + if (events._leftButton) { + Common::Point pt = events._mousePos; + + // Check for party member glyphs being clicked + Common::Rect r(0, 0, 32, 32); + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + r.moveTo(Res.CHAR_FACES_X[idx], 150); + if (r.contains(pt)) { + _buttonValue = Common::KEYCODE_F1 + idx; + break; + } + } + + // Check whether any button is selected + for (uint i = 0; i < _buttons.size(); ++i) { + if (_buttons[i]._bounds.contains(pt)) { + events.debounceMouse(); + + _buttonValue = _buttons[i]._value; + break; + } + } + + if (!_buttonValue && Common::Rect(8, 8, 224, 135).contains(pt)) { + _buttonValue = 1; + return true; + } + } else if (events.isKeyPending()) { + Common::KeyState keyState; + events.getKey(keyState); + + _buttonValue = keyState.keycode; + if (_buttonValue == Common::KEYCODE_KP8) + _buttonValue = Common::KEYCODE_UP; + else if (_buttonValue == Common::KEYCODE_KP2) + _buttonValue = Common::KEYCODE_DOWN; + else if (_buttonValue == Common::KEYCODE_KP_ENTER) + _buttonValue = Common::KEYCODE_RETURN; + + _buttonValue |= (keyState.flags & ~Common::KBD_STICKY) << 16; + } + + if (_buttonValue) { + // Check for a button matching the selected _buttonValue + Window &win = windows[39]; + for (uint btnIndex = 0; btnIndex < _buttons.size(); ++btnIndex) { + UIButton &btn = _buttons[btnIndex]; + if (btn._draw && btn._value == _buttonValue) { + // Found the correct button + // Draw button depressed + btn._sprites->draw(0, btn._frameNum + 1, + Common::Point(btn._bounds.left, btn._bounds.top)); + win.setBounds(btn._bounds); + win.update(); + + // Slight delay + events.updateGameCounter(); + events.wait(2); + + // Redraw button in it's original non-depressed form + btn._sprites->draw(0, btn._frameNum, + Common::Point(btn._bounds.left, btn._bounds.top)); + win.setBounds(btn._bounds); + win.update(); + break; + } + } + + return true; + } + + return false; +} + +void ButtonContainer::drawButtons(XSurface *surface) { + for (uint btnIndex = 0; btnIndex < _buttons.size(); ++btnIndex) { + UIButton &btn = _buttons[btnIndex]; + if (btn._draw) { + btn._sprites->draw(*surface, btn._frameNum, + Common::Point(btn._bounds.left, btn._bounds.top)); + } + } +} + +bool ButtonContainer::doScroll(bool rollUp, bool fadeIn) { + if (_vm->_files->_isDarkCc) { + return Cutscenes::doScroll(rollUp, fadeIn); + } else { + saveButtons(); + clearButtons(); + bool result = Cutscenes::doScroll(rollUp, fadeIn); + restoreButtons(); + return result; + } +} + +void ButtonContainer::loadStrings(const Common::String &name) { + File f(name); + _textStrings.clear(); + while (f.pos() < f.size()) + _textStrings.push_back(f.readString()); + f.close(); +} + +void ButtonContainer::loadStrings(const Common::String &name, int ccMode) { + File f(name, ccMode); + _textStrings.clear(); + while (f.pos() < f.size()) + _textStrings.push_back(f.readString()); + f.close(); +} + +/*------------------------------------------------------------------------*/ + +void SettingsBaseDialog::showContents(SpriteResource &title1, bool waitFlag) { + _vm->_events->pollEventsAndWait(); + checkEvents(_vm); +} + +/*------------------------------------------------------------------------*/ + +void CreditsScreen::show(XeenEngine *vm) { + CreditsScreen *dlg = new CreditsScreen(vm); + + switch (vm->getGameID()) { + case GType_Clouds: + dlg->execute(Res.CLOUDS_CREDITS); + break; + case GType_Swords: + dlg->execute(Res.SWORDS_CREDITS1); + dlg->execute(Res.SWORDS_CREDITS2); + break; + default: + dlg->execute(Res.DARK_SIDE_CREDITS); + break; + } + + delete dlg; +} + +void CreditsScreen::execute(const char *content) { + Screen &screen = *_vm->_screen; + Windows &windows = *_vm->_windows; + EventsManager &events = *_vm->_events; + + // Handle drawing the credits screen + doScroll(true, false); + windows[GAME_WINDOW].close(); + + screen.loadBackground("marb.raw"); + windows[0].writeString(content); + doScroll(false, false); + + events.setCursor(0); + windows[0].update(); + clearButtons(); + + // Wait for keypress + while (!events.isKeyMousePressed()) + events.pollEventsAndWait(); + + doScroll(true, false); +} + +/*------------------------------------------------------------------------*/ + +PleaseWait::PleaseWait(bool isOops) { + _msg = isOops ? Res.OOPS : Res.PLEASE_WAIT; +} + +PleaseWait::~PleaseWait() { + Windows &windows = *g_vm->_windows; + windows[9].close(); +} + +void PleaseWait::show() { + Windows &windows = *g_vm->_windows; + Window &w = windows[9]; + + if (g_vm->_mode != MODE_0) { + w.open(); + w.writeString(_msg); + w.update(); + } +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs.h b/engines/xeen/dialogs/dialogs.h new file mode 100644 index 0000000000..cabc921536 --- /dev/null +++ b/engines/xeen/dialogs/dialogs.h @@ -0,0 +1,137 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_H +#define XEEN_DIALOGS_H + +#include "common/array.h" +#include "common/stack.h" +#include "common/rect.h" +#include "xeen/cutscenes.h" +#include "xeen/sprites.h" +#include "xeen/xsurface.h" + +namespace Xeen { + +class XeenEngine; + +class UIButton { +public: + Common::Rect _bounds; + SpriteResource *_sprites; + int _value; + uint _frameNum; + bool _draw; + + UIButton(const Common::Rect &bounds, int value, uint frameNum, SpriteResource *sprites, bool draw) : + _bounds(bounds), _value(value), _frameNum(frameNum), + _sprites(sprites), _draw(draw) {} + + UIButton() : _value(0), _frameNum(0), _sprites(nullptr), _draw(false) {} +}; + +class ButtonContainer : public Cutscenes { +private: + Common::Stack< Common::Array > _savedButtons; +protected: + Common::Array _buttons; + Common::StringArray _textStrings; + int _buttonValue; + + bool checkEvents(XeenEngine *vm); + + /** + * Draws the scroll in the background + * @param rollUp If true, rolls up the scroll. If false, unrolls. + * @param fadeIn If true, does an initial fade in + * @returns True if key or mouse pressed + */ + virtual bool doScroll(bool rollUp, bool fadeIn); + + /** + * Load a set of text strings from the given resource + * @param name Name of resource containing strings + */ + void loadStrings(const Common::String &name); + + /** + * Load a set of text strings from the given resource + * @param name Name of resource containing strings + * @param ccMode Optional cc file number to explicitly use + */ + void loadStrings(const Common::String &name, int ccMode); +public: + ButtonContainer(XeenEngine *vm) : Cutscenes(vm), _buttonValue(0) {} + + /** + * Saves the current list of buttons + */ + void saveButtons(); + + void clearButtons(); + + void restoreButtons(); + + void addButton(const Common::Rect &bounds, int val, + SpriteResource *sprites = nullptr); + void addButton(const Common::Rect &bounds, int val, + int frameNum, SpriteResource *sprites = nullptr); + + void addPartyButtons(XeenEngine *vm); + + /** + * Draws the buttons onto the passed surface + */ + void drawButtons(XSurface *surface); +}; + +class SettingsBaseDialog : public ButtonContainer { +protected: + virtual void showContents(SpriteResource &title1, bool mode); +public: + SettingsBaseDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + virtual ~SettingsBaseDialog() {} +}; + +class CreditsScreen: public ButtonContainer { +private: + CreditsScreen(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(const char *content); +public: + static void show(XeenEngine *vm); +}; + +class PleaseWait { +private: + Common::String _msg; +public: + PleaseWait(bool isOops = false); + ~PleaseWait(); + + void show(); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_H */ diff --git a/engines/xeen/dialogs/dialogs_awards.cpp b/engines/xeen/dialogs/dialogs_awards.cpp new file mode 100644 index 0000000000..8e8bfcf67f --- /dev/null +++ b/engines/xeen/dialogs/dialogs_awards.cpp @@ -0,0 +1,131 @@ +/* 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/dialogs_awards.h" +#include "xeen/party.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void Awards::show(XeenEngine *vm, const Character *ch) { + Awards *dlg = new Awards(vm); + dlg->execute(ch); + delete dlg; +} + +void Awards::execute(const Character *ch) { + EventsManager &events = *g_vm->_events; + Windows &windows = *g_vm->_windows; + Common::StringArray awards; + int numAwards; + Mode oldMode = g_vm->_mode; + int topIndex = 0; + + loadStrings("award.bin", 1); + addButtons(); + + // Open the window and draw contents + bool win29Open = windows[29]._enabled; + if (!win29Open) { + windows[29].open(); + windows[30].open(); + } + + windows[29].writeString(Res.AWARDS_TEXT); + drawButtons(&windows[0]); + + while (!_vm->shouldExit()) { + // Build up a list of awards the character has + awards.clear(); + awards.resize(AWARDS_TOTAL); + numAwards = 0; + + for (int awardNum = 0; awardNum < AWARDS_TOTAL; ++awardNum) { + if (ch->hasAward(awardNum)) { + if (awardNum == 9) { + // # Warzone Wins + awards[numAwards] = Common::String::format(_textStrings[9].c_str(), 28); + } else if (awardNum == 17) { + // Legendary Race + awards[numAwards] = Common::String::format(_textStrings[17].c_str(), + Res.RACE_NAMES[ch->_race]); + } else { + awards[numAwards] = _textStrings[awardNum]; + } + ++numAwards; + } + } + + // If no awards, add in a message indicating so + if (numAwards == 0) { + awards[1] = Res.NO_AWARDS; + } + + Common::String msg = Common::String::format(Res.AWARDS_FOR, + ch->_name.c_str(), Res.CLASS_NAMES[ch->_class], + awards[topIndex].c_str(), + awards[topIndex + 1].c_str(), + awards[topIndex + 2].c_str(), + awards[topIndex + 3].c_str(), + awards[topIndex + 4].c_str(), + awards[topIndex + 5].c_str(), + awards[topIndex + 6].c_str(), + awards[topIndex + 7].c_str(), + awards[topIndex + 8].c_str() + ); + windows[30].writeString(msg); + windows[24].update(); + + // Wait for keypress + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!g_vm->shouldExit() && !_buttonValue); + + if (_buttonValue == Common::KEYCODE_ESCAPE) { + break; + } else if (_buttonValue == Common::KEYCODE_u) { + topIndex = MAX(topIndex - 1, 0); + } else if (_buttonValue == Common::KEYCODE_d) { + if ((++topIndex + 9) > numAwards) + --topIndex; + } + } + + // Close the window + if (win29Open) { + windows[30].close(); + windows[29].close(); + } + + g_vm->_mode = oldMode; +} + +void Awards::addButtons() { + _iconSprites.load("award.icn"); + addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_u, &_iconSprites); + addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_d, &_iconSprites); + addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_awards.h b/engines/xeen/dialogs/dialogs_awards.h new file mode 100644 index 0000000000..2ca68171a4 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_awards.h @@ -0,0 +1,52 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_AWARDS_H +#define XEEN_DIALOGS_AWARDS_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/character.h" + +namespace Xeen { + +class Awards : public ButtonContainer { +private: + SpriteResource _iconSprites; +private: + Awards(XeenEngine *vm) : ButtonContainer(vm) {} + + /** + * Executes the dialog + */ + void execute(const Character *ch); + + /** + * Add buttons for the dialog + */ + void addButtons(); +public: + static void show(XeenEngine *vm, const Character *ch); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_AWARDS_H */ diff --git a/engines/xeen/dialogs/dialogs_char_info.cpp b/engines/xeen/dialogs/dialogs_char_info.cpp new file mode 100644 index 0000000000..0ae64ed608 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_char_info.cpp @@ -0,0 +1,571 @@ +/* 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/dialogs_awards.h" +#include "xeen/dialogs/dialogs_char_info.h" +#include "xeen/dialogs/dialogs_exchange.h" +#include "xeen/dialogs/dialogs_items.h" +#include "xeen/dialogs/dialogs_quick_ref.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void CharacterInfo::show(XeenEngine *vm, int charIndex) { + CharacterInfo *dlg = new CharacterInfo(vm); + dlg->execute(charIndex); + delete dlg; +} + +void CharacterInfo::execute(int charIndex) { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + + bool redrawFlag = true; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_CHARACTER_INFO; + loadDrawStructs(); + addButtons(); + + Character *c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : combat._combatParty[charIndex]; + intf.highlightChar(charIndex); + Window &w = windows[24]; + w.open(); + + do { + if (redrawFlag) { + Common::String charDetails = loadCharacterDetails(*c); + w.writeString(Common::String::format(Res.CHARACTER_TEMPLATE, charDetails.c_str())); + w.drawList(_drawList, 24); + w.update(); + redrawFlag = false; + } + + // Wait for keypress, showing a blinking cursor + events.updateGameCounter(); + bool cursorFlag = false; + _buttonValue = 0; + while (!_vm->shouldExit() && !_buttonValue) { + events.pollEventsAndWait(); + if (events.timeElapsed() > 4) { + cursorFlag = !cursorFlag; + events.updateGameCounter(); + } + + showCursor(cursorFlag); + w.update(); + checkEvents(_vm); + } + events.clearEvents(); + + switch (_buttonValue) { + case Common::KEYCODE_F1: + case Common::KEYCODE_F2: + case Common::KEYCODE_F3: + case Common::KEYCODE_F4: + case Common::KEYCODE_F5: + case Common::KEYCODE_F6: + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)(oldMode == MODE_COMBAT ? combat._combatParty.size() : party._activeParty.size())) { + charIndex = _buttonValue; + c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : combat._combatParty[charIndex]; + } else { + _vm->_mode = MODE_CHARACTER_INFO; + } + + intf.highlightChar(_buttonValue); + redrawFlag = true; + break; + + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + if (_cursorCell > 0) { + showCursor(false); + --_cursorCell; + showCursor(true); + } + w.update(); + break; + + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + if (_cursorCell < 20) { + showCursor(false); + ++_cursorCell; + showCursor(true); + } + w.update(); + break; + + case Common::KEYCODE_LEFT: + case Common::KEYCODE_KP4: + if (_cursorCell >= 5) { + showCursor(false); + _cursorCell -= 5; + showCursor(true); + } + w.update(); + break; + + case Common::KEYCODE_RIGHT: + case Common::KEYCODE_KP6: + if (_cursorCell <= 15) { + showCursor(false); + _cursorCell += 5; + showCursor(true); + } + w.update(); + break; + + case Common::KEYCODE_RETURN: + case Common::KEYCODE_KP_ENTER: + _buttonValue = _cursorCell + Common::KEYCODE_a; + // Deliberate fall-through + + case 1001: + case 1002: + case 1003: + case 1004: + case 1005: + case 1006: + case 1007: + case 1008: + case 1009: + case 1010: + case 1011: + case 1012: + case 1013: + case 1014: + case 1015: + case 1016: + case 1017: + case 1018: + case 1019: + case 1020: { + showCursor(false); + _cursorCell = _buttonValue - 1001; + showCursor(true); + w.update(); + + bool result = expandStat(_cursorCell, *c); + _vm->_mode = MODE_COMBAT; + if (result) + redrawFlag = true; + break; + } + + case Common::KEYCODE_e: + if (oldMode == MODE_COMBAT) { + ErrorScroll::show(_vm, Res.EXCHANGING_IN_COMBAT, WT_FREEZE_WAIT); + } else { + _vm->_mode = oldMode; + ExchangeDialog::show(_vm, c, charIndex); + _vm->_mode = MODE_CHARACTER_INFO; + redrawFlag = true; + } + break; + + case Common::KEYCODE_i: + _vm->_mode = oldMode; + _vm->_combat->_itemFlag = _vm->_mode == MODE_COMBAT; + c = ItemsDialog::show(_vm, c, ITEMMODE_CHAR_INFO); + + if (!c) { + party._stepped = true; + goto exit; + } + + _vm->_mode = MODE_CHARACTER_INFO; + break; + + case Common::KEYCODE_q: + QuickReferenceDialog::show(_vm); + redrawFlag = true; + break; + + case Common::KEYCODE_ESCAPE: + goto exit; + } + } while (!_vm->shouldExit()); +exit: + w.close(); + intf.unhighlightChar(); + _vm->_mode = oldMode; + _vm->_combat->_itemFlag = false; +} + +void CharacterInfo::loadDrawStructs() { + _drawList[0] = DrawStruct(0, 2, 16); + _drawList[1] = DrawStruct(2, 2, 39); + _drawList[2] = DrawStruct(4, 2, 62); + _drawList[3] = DrawStruct(6, 2, 85); + _drawList[4] = DrawStruct(8, 2, 108); + _drawList[5] = DrawStruct(10, 53, 16); + _drawList[6] = DrawStruct(12, 53, 39); + _drawList[7] = DrawStruct(14, 53, 62); + _drawList[8] = DrawStruct(16, 53, 85); + _drawList[9] = DrawStruct(18, 53, 108); + _drawList[10] = DrawStruct(20, 104, 16); + _drawList[11] = DrawStruct(22, 104, 39); + _drawList[12] = DrawStruct(24, 104, 62); + _drawList[13] = DrawStruct(26, 104, 85); + _drawList[14] = DrawStruct(28, 104, 108); + _drawList[15] = DrawStruct(30, 169, 16); + _drawList[16] = DrawStruct(32, 169, 39); + _drawList[17] = DrawStruct(34, 169, 62); + _drawList[18] = DrawStruct(36, 169, 85); + _drawList[19] = DrawStruct(38, 169, 108); + _drawList[20] = DrawStruct(40, 277, 3); + _drawList[21] = DrawStruct(42, 277, 35); + _drawList[22] = DrawStruct(44, 277, 67); + _drawList[23] = DrawStruct(46, 277, 99); + + _iconSprites.load("view.icn"); + for (int idx = 0; idx < 24; ++idx) + _drawList[idx]._sprites = &_iconSprites; +} + +void CharacterInfo::addButtons() { + addButton(Common::Rect(10, 24, 34, 44), 1001, &_iconSprites); + addButton(Common::Rect(10, 47, 34, 67), 1002, &_iconSprites); + addButton(Common::Rect(10, 70, 34, 90), 1003, &_iconSprites); + addButton(Common::Rect(10, 93, 34, 113), 1004, &_iconSprites); + addButton(Common::Rect(10, 116, 34, 136), 1005, &_iconSprites); + addButton(Common::Rect(61, 24, 85, 44), 1006, &_iconSprites); + addButton(Common::Rect(61, 47, 85, 67), 1007, &_iconSprites); + addButton(Common::Rect(61, 70, 85, 90), 1008, &_iconSprites); + addButton(Common::Rect(61, 93, 85, 113), 1009, &_iconSprites); + addButton(Common::Rect(61, 116, 85, 136), 1010, &_iconSprites); + addButton(Common::Rect(112, 24, 136, 44), 1011, &_iconSprites); + addButton(Common::Rect(112, 47, 136, 67), 1012, &_iconSprites); + addButton(Common::Rect(112, 70, 136, 90), 1013, &_iconSprites); + addButton(Common::Rect(112, 93, 136, 113), 1014, &_iconSprites); + addButton(Common::Rect(112, 116, 136, 136), 1015, &_iconSprites); + addButton(Common::Rect(177, 24, 201, 44), 1016, &_iconSprites); + addButton(Common::Rect(177, 47, 201, 67), 1017, &_iconSprites); + addButton(Common::Rect(177, 70, 201, 90), 1018, &_iconSprites); + addButton(Common::Rect(177, 93, 201, 113), 1019, &_iconSprites); + addButton(Common::Rect(177, 116, 201, 136), 1020, &_iconSprites); + addButton(Common::Rect(285, 11, 309, 31), Common::KEYCODE_i, &_iconSprites); + addButton(Common::Rect(285, 43, 309, 63), Common::KEYCODE_q, &_iconSprites); + addButton(Common::Rect(285, 75, 309, 95), Common::KEYCODE_e, &_iconSprites); + addButton(Common::Rect(285, 107, 309, 127), Common::KEYCODE_ESCAPE, &_iconSprites); + addPartyButtons(_vm); +} + +Common::String CharacterInfo::loadCharacterDetails(const Character &c) { + Condition condition = c.worstCondition(); + Party &party = *_vm->_party; + int foodVal = party._food / party._activeParty.size() / 3; + + int totalResist = + c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary + + c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary + + c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary + + c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary + + c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary + + c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary; + + return Common::String::format(Res.CHARACTER_DETAILS, + Res.PARTY_GOLD, c._name.c_str(), Res.SEX_NAMES[c._sex], + Res.RACE_NAMES[c._race], Res.CLASS_NAMES[c._class], + c.statColor(c.getStat(MIGHT), c.getStat(MIGHT, true)), c.getStat(MIGHT), + c.statColor(c.getStat(ACCURACY), c.getStat(ACCURACY, true)), c.getStat(ACCURACY), + c.statColor(c._currentHp, c.getMaxHP()), c._currentHp, + c.getCurrentExperience(), + c.statColor(c.getStat(INTELLECT), c.getStat(INTELLECT, true)), c.getStat(INTELLECT), + c.statColor(c.getStat(LUCK), c.getStat(LUCK, true)), c.getStat(LUCK), + c.statColor(c._currentSp, c.getMaxSP()), c._currentSp, + party._gold, + c.statColor(c.getStat(PERSONALITY), c.getStat(PERSONALITY, true)), c.getStat(PERSONALITY), + c.statColor(c.getAge(), c.getAge(true)), c.getAge(), + totalResist, + party._gems, + c.statColor(c.getStat(ENDURANCE), c.getStat(ENDURANCE, true)), c.getStat(ENDURANCE), + c.statColor(c.getCurrentLevel(), c._level._permanent), c.getCurrentLevel(), + c.getNumSkills(), + foodVal, (foodVal == 1) ? ' ' : 's', + c.statColor(c.getStat(SPEED), c.getStat(SPEED, true)), c.getStat(SPEED), + c.statColor(c.getArmorClass(), c.getArmorClass(true)), c.getArmorClass(), + c.getNumAwards(), + Res.CONDITION_COLORS[condition], Res.CONDITION_NAMES[condition], + condition == NO_CONDITION && party._blessed ? Res.PLUS_14 : "", + condition == NO_CONDITION && party._powerShield ? Res.PLUS_14 : "", + condition == NO_CONDITION && party._holyBonus ? Res.PLUS_14 : "", + condition == NO_CONDITION && party._heroism ? Res.PLUS_14 : "" + ); +} + +void CharacterInfo::showCursor(bool flag) { + const int CURSOR_X[5] = { 9, 60, 111, 176, 0 }; + const int CURSOR_Y[5] = { 23, 46, 69, 92, 115 }; + + if (_cursorCell < 20) { + _iconSprites.draw(0, flag ? 49 : 48, + Common::Point(CURSOR_X[_cursorCell / 5], CURSOR_Y[_cursorCell % 5])); + } +} + +bool CharacterInfo::expandStat(int attrib, const Character &c) { + const int STAT_POS[2][20] = { + { + 61, 61, 61, 61, 61, 112, 112, 112, 112, 112, + 177, 177, 177, 177, 177, 34, 34, 34, 34, 34 + }, { + 24, 47, 70, 93, 116, 24, 47, 70, 93, 116, + 24, 47, 70, 93, 116, 24, 47, 70, 93, 116 + } + }; + assert(attrib < 20); + Common::Rect bounds(STAT_POS[0][attrib], STAT_POS[1][attrib], + STAT_POS[0][attrib] + 143, STAT_POS[1][attrib] + 52); + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + uint stat1, stat2; + uint idx; + Common::String msg; + + switch (attrib) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + // Basic attributes + stat1 = c.getStat((Attribute)attrib, false); + stat2 = c.getStat((Attribute)attrib, true); + idx = 0; + while (Res.STAT_VALUES[idx] <= (int)stat1) + ++idx; + + msg = Common::String::format(Res.CURRENT_MAXIMUM_RATING_TEXT, Res.STAT_NAMES[attrib], + stat1, stat2, Res.RATING_TEXT[idx]); + break; + + case 7: + // Age + stat1 = c.getAge(false); + stat2 = c.getAge(true); + msg = Common::String::format(Res.AGE_TEXT, Res.STAT_NAMES[attrib], + stat1, stat2, c._birthDay, c._birthYear); + break; + + case 8: { + // Level + const int CLASS_ATTACK_GAINS[10] = { 5, 6, 6, 7, 8, 6, 5, 4, 7, 6 }; + idx = c.getCurrentLevel() / CLASS_ATTACK_GAINS[c._class] + 1; + + msg = Common::String::format(Res.LEVEL_TEXT, Res.STAT_NAMES[attrib], + c.getCurrentLevel(), c._level._permanent, + idx, idx > 1 ? "s" : "", + c._level._permanent); + break; + } + + case 9: + // Armor Class + stat1 = c.getArmorClass(false); + stat2 = c.getArmorClass(true); + msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], + stat1, stat2); + bounds.setHeight(42); + break; + + case 10: + // Hit Points + stat1 = c._currentHp; + stat2 = c.getMaxHP(); + msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], + stat1, stat2); + bounds.setHeight(42); + break; + + case 11: + // Spell Points + stat1 = c._currentSp; + stat2 = c.getMaxSP(); + msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], + stat1, stat2); + bounds.setHeight(42); + break; + + case 12: + // Resistences + msg = Common::String::format(Res.RESISTENCES_TEXT, Res.STAT_NAMES[attrib], + c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary, + c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary, + c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary, + c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary, + c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary, + c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary); + bounds.setHeight(80); + break; + + case 13: { + // Skills + Common::String lines[20]; + int numLines = c.getNumSkills(); + if (numLines > 0) { + for (int skill = THIEVERY; skill <= DANGER_SENSE; ++skill) { + if (c._skills[skill]) { + if (skill == THIEVERY) { + lines[0] = Common::String::format("\n\t020%s%u", + Res.SKILL_NAMES[THIEVERY], c.getThievery()); + } else { + lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill]); + } + } + } + } else { + lines[0] = Res.NONE; + numLines = 1; + } + + msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + Res.STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(), + lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), lines[5].c_str(), + lines[17].c_str(), lines[6].c_str(), lines[7].c_str(), lines[8].c_str(), + lines[9].c_str(), lines[10].c_str(), lines[11].c_str(), lines[12].c_str(), + lines[13].c_str(), lines[16].c_str(), lines[14].c_str(), lines[15].c_str()); + + bounds.top -= (numLines / 2) * 8; + bounds.setHeight(numLines * 9 + 26); + if (bounds.bottom >= SCREEN_HEIGHT) + bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1); + break; + } + + case 14: + // Awards + Awards::show(_vm, &c); + return false; + + case 15: + // Experience + stat1 = c.getCurrentExperience(); + stat2 = c.experienceToNextLevel(); + msg = Common::String::format(Res.EXPERIENCE_TEXT, + Res.STAT_NAMES[attrib], stat1, + stat2 == 0 ? Res.ELIGIBLE : Common::String::format("%d", stat2).c_str() + ); + bounds.setHeight(43); + break; + + case 16: + // Gold + msg = Common::String::format(Res.IN_PARTY_IN_BANK, Res.CONSUMABLE_NAMES[0], + party._gold, party._bankGold); + bounds.setHeight(43); + break; + + case 17: + // Gems + msg = Common::String::format(Res.IN_PARTY_IN_BANK, Res.CONSUMABLE_NAMES[1], + party._gems, party._bankGems); + bounds.setHeight(43); + break; + + case 18: { + // Food + int food = (party._food / party._activeParty.size()) / 3; + msg = Common::String::format(Res.FOOD_TEXT, Res.CONSUMABLE_NAMES[2], + party._food, food, food != 1 ? "s" : ""); + break; + } + + case 19: { + // Conditions + Common::String lines[20]; + int total = 0; + for (int condition = CURSED; condition <= ERADICATED; ++condition) { + if (c._conditions[condition]) { + if (condition >= UNCONSCIOUS) { + lines[condition] = Common::String::format("\n\t020%s", + Res.CONDITION_NAMES[condition]); + } else { + lines[condition] = Common::String::format("\n\t020%s\t095-%d", + Res.CONDITION_NAMES[condition], c._conditions[condition]); + } + + ++total; + } + } + + Condition condition = c.worstCondition(); + if (condition == NO_CONDITION) { + lines[0] = Common::String::format("\n\t020%s", Res.GOOD); + ++total; + } + + if (party._blessed) + lines[16] = Common::String::format(Res.BLESSED, party._blessed); + if (party._powerShield) + lines[17] = Common::String::format(Res.POWER_SHIELD, party._powerShield); + if (party._holyBonus) + lines[18] = Common::String::format(Res.HOLY_BONUS, party._holyBonus); + if (party._heroism) + lines[19] = Common::String::format(Res.HEROISM, party._heroism); + + msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1", + Res.CONSUMABLE_NAMES[3], lines[0].c_str(), lines[1].c_str(), + lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), + lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), + lines[8].c_str(), lines[9].c_str(), lines[10].c_str(), + lines[11].c_str(), lines[12].c_str(), lines[13].c_str(), + lines[14].c_str(), lines[15].c_str(), lines[16].c_str(), + lines[17].c_str(), lines[18].c_str(), lines[19].c_str() + ); + + bounds.top -= ((total - 1) / 2) * 8; + bounds.setHeight(total * 9 + 26); + if (bounds.bottom >= SCREEN_HEIGHT) + bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1); + break; + } + + default: + break; + } + + // Write the data for the stat display + Window &w = windows[28]; + w.setBounds(bounds); + w.open(); + w.writeString(msg); + w.update(); + + // Wait for a user key/click + EventsManager &events = *_vm->_events; + while (!_vm->shouldExit() && !events.isKeyMousePressed()) + events.pollEventsAndWait(); + events.clearEvents(); + + w.close(); + return false; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_char_info.h b/engines/xeen/dialogs/dialogs_char_info.h new file mode 100644 index 0000000000..6dc7eaa51a --- /dev/null +++ b/engines/xeen/dialogs/dialogs_char_info.h @@ -0,0 +1,69 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_CHAR_INFO_H +#define XEEN_DIALOGS_CHAR_INFO_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" +#include "xeen/window.h" + +namespace Xeen { + +class CharacterInfo : public ButtonContainer { +private: + SpriteResource _iconSprites; + DrawStruct _drawList[24]; + int _cursorCell; + + CharacterInfo(XeenEngine *vm) : ButtonContainer(vm), _cursorCell(0) {} + + void execute(int charIndex); + + /** + * Load the draw structure list with frame numbers and positions + */ + void loadDrawStructs(); + + /** + * Set up the button list for the dialog + */ + void addButtons(); + + /** + * Return a string containing the details of the character + */ + Common::String loadCharacterDetails(const Character &c); + + /** + * Cursor display handling + */ + void showCursor(bool flag); + + bool expandStat(int attrib, const Character &c); +public: + static void show(XeenEngine *vm, int charIndex); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_CHAR_INFO_H */ diff --git a/engines/xeen/dialogs/dialogs_control_panel.cpp b/engines/xeen/dialogs/dialogs_control_panel.cpp new file mode 100644 index 0000000000..9c933b30a3 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_control_panel.cpp @@ -0,0 +1,220 @@ +/* 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/dialogs_control_panel.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/party.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +int ControlPanel::show(XeenEngine *vm) { + ControlPanel *dlg = new ControlPanel(vm); + int result = dlg->execute(); + delete dlg; + + return result; +} + +int ControlPanel::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + SavesManager &saves = *_vm->_saves; + Sound &sound = *_vm->_sound; + Windows &windows = *_vm->_windows; + Window &w = windows[23]; + Window &w3 = windows[3]; + + loadButtons(); + + int result = 0, debugCtr = 0; + w.open(); + + do { + Common::String btnText = getButtonText(); + Common::String text = Common::String::format(Res.CONTROL_PANEL_TEXT, btnText.c_str()); + + drawButtons(&w); + w.writeString(text); + w.writeString("\xB""000\t000\x1"); + w.update(); + + do { + events.updateGameCounter(); + intf.draw3d(false, false); + w.writeString("\r"); + drawButtons(&w); + w.writeString(text); + w.writeString("\v000\t000"); + w.frame(); + + if (_debugFlag) + w.writeString(getTimeText()); + + w3.update(); + w.update(); + + events.pollEventsAndWait(); + checkEvents(_vm); + if (_vm->shouldExit()) + return 0; + } while (!_buttonValue && !events.timeElapsed()); + + switch (_buttonValue) { + case Common::KEYCODE_q: + if (Confirm::show(g_vm, Res.CONFIRM_QUIT)) { + g_vm->_gameMode = GMODE_QUIT; + result = 1; + } + break; + + case Common::KEYCODE_w: + if (Confirm::show(g_vm, Res.MR_WIZARD)) { + w.close(); + if (!windows[2]._enabled) { + sound.playFX(51); + + if (g_vm->getGameID() == GType_WorldOfXeen) { + map._loadDarkSide = false; + map.load(28); + party._mazeDirection = DIR_EAST; + } else { + map._loadDarkSide = true; + map.load(29); + party._mazeDirection = DIR_SOUTH; + } + party.moveToRunLocation(); + } + + party._gems = 0; + result = 2; + } + break; + + case Common::KEYCODE_l: + if (_vm->_mode == MODE_COMBAT) { + ErrorScroll::show(_vm, Res.NO_LOADING_IN_COMBAT); + } else { + // Close dialog and show loading dialog + result = 3; + } + break; + + case Common::KEYCODE_s: + if (_vm->_mode == MODE_COMBAT) { + ErrorScroll::show(_vm, Res.NO_SAVING_IN_COMBAT); + } else { + // Close dialog and show saving dialog + result = 4; + } + break; + + case Common::KEYCODE_e: + sound.setEffectsOn(!sound._soundOn); + break; + + case Common::KEYCODE_m: + sound.setMusicOn(!sound._musicOn); + break; + + case Common::KEYCODE_ESCAPE: + result = 1; + break; + + // Goober cheat sequence + case Common::KEYCODE_g: + debugCtr = 1; + break; + case Common::KEYCODE_o: + debugCtr = (debugCtr == 1 || debugCtr == 2) ? 2 : 0; + break; + case Common::KEYCODE_b: + debugCtr = (debugCtr == 2) ? 3 : 0; + break; + case Common::KEYCODE_r: + if (debugCtr == 3) + _debugFlag = true; + else + debugCtr = 0; + break; + + default: + break; + } + } while (!result); + + w.close(); + intf.drawParty(true); + + if (result == 3) { + saves.loadGame(); + } else if (result == 4) { + saves.saveGame(); + } + + return result; +} + +void ControlPanel::loadButtons() { + _iconSprites.load("cpanel.icn"); + + addButton(Common::Rect(214, 56, 244, 69), Common::KEYCODE_e, 0, &_iconSprites); + addButton(Common::Rect(214, 75, 244, 88), Common::KEYCODE_m, 0, &_iconSprites); + addButton(Common::Rect(135, 56, 165, 69), Common::KEYCODE_l, 0, &_iconSprites); + addButton(Common::Rect(135, 75, 165, 88), Common::KEYCODE_s, 0, &_iconSprites); + + // For ScummVM we've merged both Save and Save As into a single + // save item, so we don't need this one + addButton(Common::Rect(), 0); + + addButton(Common::Rect(135, 94, 165, 107), Common::KEYCODE_q, 0, &_iconSprites); + addButton(Common::Rect(175, 113, 205, 126), Common::KEYCODE_w, 0, &_iconSprites); +} + +Common::String ControlPanel::getButtonText() { + Sound &sound = *g_vm->_sound; + _btnSoundText = sound._soundOn ? Res.ON : Res.OFF; + _btnMusicText = sound._musicOn ? Res.ON : Res.OFF; + + return Common::String::format(Res.CONTROL_PANEL_BUTTONS, + _btnSoundText.c_str(), _btnMusicText.c_str()); +} + +Common::String ControlPanel::getTimeText() const { + TimeDate td; + g_system->getTimeAndDate(td); + Common::String timeStr = Common::String::format("%d:%.2d:%.2d%c", + td.tm_hour == 0 || td.tm_hour == 12 ? 12 : (td.tm_hour % 12), + td.tm_min, td.tm_sec, (td.tm_hour >= 12) ? 'p' : 'c'); + + uint32 playtime = g_vm->_events->playTime() / GAME_FRAME_RATE; + Common::String playtimeStr = Common::String::format("%d:%.2d:%.2d", + playtime / 3600, (playtime / 60) % 60, playtime % 60); + return Common::String::format( + "\x2\x3l\xB""000\t000\x4""160%s\x3r\xB""000\t000%s\x1", + timeStr.c_str(), playtimeStr.c_str()); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_control_panel.h b/engines/xeen/dialogs/dialogs_control_panel.h new file mode 100644 index 0000000000..5181825630 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_control_panel.h @@ -0,0 +1,66 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_CONTROL_PANEL_H +#define XEEN_DIALOGS_CONTROL_PANEL_H + +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class ControlPanel : public ButtonContainer { +private: + SpriteResource _iconSprites; + Common::String _btnSoundText, _btnMusicText; + bool _debugFlag; +private: + ControlPanel(XeenEngine *vm) : ButtonContainer(vm), _debugFlag(false) {} + + /** + * Inner handler for showing the dialog + */ + int execute(); + + /** + * Loads the buttons for the dialog + */ + void loadButtons(); + + /** + * Gets the text for the dialog buttons + */ + Common::String getButtonText(); + + /** + * Gets the current time + */ + Common::String getTimeText() const; +public: + /** + * Show the control panel + */ + static int show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_CONTROL_PANEL_H */ diff --git a/engines/xeen/dialogs/dialogs_create_char.cpp b/engines/xeen/dialogs/dialogs_create_char.cpp new file mode 100644 index 0000000000..577ae5314b --- /dev/null +++ b/engines/xeen/dialogs/dialogs_create_char.cpp @@ -0,0 +1,648 @@ +/* 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/dialogs_create_char.h" +#include "xeen/dialogs/dialogs_input.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void CreateCharacterDialog::show(XeenEngine *vm) { + CreateCharacterDialog *dlg = new CreateCharacterDialog(vm); + dlg->execute(); + delete dlg; +} + +CreateCharacterDialog::CreateCharacterDialog(XeenEngine *vm) : ButtonContainer(vm) { + Common::fill(&_attribs[0], &_attribs[TOTAL_ATTRIBUTES], 0); + Common::fill(&_allowedClasses[0], &_allowedClasses[TOTAL_CLASSES], false); + _dicePos[0] = Common::Point(20, 17); + _dicePos[1] = Common::Point(112, 35); + _dicePos[2] = Common::Point(61, 50); + _diceFrame[0] = 0; + _diceFrame[1] = 2; + _diceFrame[2] = 4; + _diceInc[0] = Common::Point(10, -10); + _diceInc[1] = Common::Point(-10, -10); + _diceInc[2] = Common::Point(-10, 10); + + _dice.load("dice.vga"); + _diceSize = _dice.getFrameSize(0); + + loadButtons(); +} + +void CreateCharacterDialog::execute() { + EventsManager &events = *_vm->_events; + Party &party = *_vm->_party; + Screen &screen = *_vm->_screen; + Windows &windows = *_vm->_windows; + Window &w = windows[0]; + Common::Array freeCharList; + int classId = -1; + int selectedClass = 0; + bool hasFadedIn = false; + bool restartFlag = true; + Race race = HUMAN; + Sex sex = MALE; + Common::String msg, details; + int charIndex = 0; + + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_4; + + // Load the background + screen.loadBackground("create.raw"); + events.setCursor(0); + + while (!_vm->shouldExit()) { + if (restartFlag) { + // Build up list of roster slot indexes that are free + freeCharList.clear(); + for (uint idx = 0; idx < XEEN_TOTAL_CHARACTERS; ++idx) { + if (party._roster[idx]._name.empty()) + freeCharList.push_back(idx); + } + charIndex = 0; + + if (freeCharList.size() == XEEN_TOTAL_CHARACTERS) + break; + + // Get and race and sex for the given character + race = (Race)((freeCharList[charIndex] / 4) % 5); + sex = (Sex)(freeCharList[charIndex] & 1); + + // Randomly determine attributes, and which classes they allow + rollAttributes(); + + // Get the display of the rolled character details + selectedClass = newCharDetails(race, sex, classId, selectedClass, details); + msg = Common::String::format(Res.CREATE_CHAR_DETAILS, + details.c_str()); + + // Draw the icons and the currently selected headshot + drawIcons(); + party._roster[freeCharList[charIndex]]._faceSprites->draw( + w, 0, Common::Point(27, 102)); + + // Render all on-screen text + w.writeString(msg); + w.update(); + + // Draw the arrow for the selected class, if applicable + if (selectedClass != -1) + printSelectionArrow(selectedClass); + + // Draw the dice + drawDice(); + if (!hasFadedIn) { + screen.fadeIn(); + hasFadedIn = true; + } + + restartFlag = false; + } + + // Animate the dice until a user action occurs + _buttonValue = 0; + while (!_vm->shouldExit() && !_buttonValue) + drawDice(); + + // Handling for different actions + if (_buttonValue == Common::KEYCODE_ESCAPE) + break; + + switch (_buttonValue) { + case Common::KEYCODE_UP: + if (charIndex == 0) + continue; + + --charIndex; + race = (Race)((freeCharList[charIndex] / 4) % 5); + sex = (Sex)(freeCharList[charIndex] & 1); + break; + + case Common::KEYCODE_DOWN: + if (++charIndex == (int)freeCharList.size()) { + --charIndex; + continue; + } else { + race = (Race)((freeCharList[charIndex] / 4) % 5); + sex = (Sex)(freeCharList[charIndex] & 1); + } + break; + + case Common::KEYCODE_PAGEUP: + for (int tempClass = selectedClass - 1; tempClass >= 0; --tempClass) { + if (_allowedClasses[tempClass]) { + selectedClass = tempClass; + break; + } + } + + printSelectionArrow(selectedClass); + continue; + + case Common::KEYCODE_PAGEDOWN: + break; + + case Common::KEYCODE_m: + case Common::KEYCODE_i: + case Common::KEYCODE_p: + case Common::KEYCODE_e: + case Common::KEYCODE_s: + case Common::KEYCODE_a: + case Common::KEYCODE_l: + if (swapAttributes(_buttonValue)) { + checkClass(); + classId = -1; + selectedClass = newCharDetails(race, sex, classId, selectedClass, msg); + } + break; + + case 1000: + case 1001: + case 1002: + case 1003: + case 1004: + case 1005: + case 1006: + case 1007: + case 1008: + case 1009: + if (_allowedClasses[_buttonValue - 1000]) { + selectedClass = classId = _buttonValue - 1000; + } + break; + + case Common::KEYCODE_c: { + _vm->_mode = MODE_FF; + bool result = saveCharacter(party._roster[freeCharList[charIndex]], + classId, race, sex); + _vm->_mode = MODE_4; + + if (result) + restartFlag = true; + continue; + } + + case Common::KEYCODE_RETURN: + classId = selectedClass; + break; + + case Common::KEYCODE_SPACE: + case Common::KEYCODE_r: + // Re-roll the attributes + rollAttributes(); + classId = -1; + break; + + default: + // For all other keypresses, skip the code below the switch + // statement, and go to wait for the next key + continue; + } + + if (_buttonValue != Common::KEYCODE_PAGEDOWN) { + selectedClass = newCharDetails(race, sex, classId, selectedClass, msg); + + drawIcons2(); + party._roster[freeCharList[charIndex]]._faceSprites->draw(w, 0, + Common::Point(27, 102)); + + w.writeString(msg); + w.update(); + + if (selectedClass != -1) { + printSelectionArrow(selectedClass); + continue; + } + } + + // Move to next available class, or if the code block above resulted in + // selectedClass being -1, move to select the first available class + for (int tempClass = selectedClass + 1; tempClass <= CLASS_RANGER; ++tempClass) { + if (_allowedClasses[tempClass]) { + selectedClass = tempClass; + break; + } + } + + printSelectionArrow(selectedClass); + } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); + + _vm->_mode = oldMode; +} + +void CreateCharacterDialog::loadButtons() { + _icons.load("create.icn"); + + // Add buttons + addButton(Common::Rect(132, 98, 156, 118), Common::KEYCODE_r, &_icons); + addButton(Common::Rect(132, 128, 156, 148), Common::KEYCODE_c, &_icons); + addButton(Common::Rect(132, 158, 156, 178), Common::KEYCODE_ESCAPE, &_icons); + addButton(Common::Rect(86, 98, 110, 118), Common::KEYCODE_UP, &_icons); + addButton(Common::Rect(86, 120, 110, 140), Common::KEYCODE_DOWN, &_icons); + addButton(Common::Rect(168, 19, 192, 39), Common::KEYCODE_n, nullptr); + addButton(Common::Rect(168, 43, 192, 63), Common::KEYCODE_i, nullptr); + addButton(Common::Rect(168, 67, 192, 87), Common::KEYCODE_p, nullptr); + addButton(Common::Rect(168, 91, 192, 111), Common::KEYCODE_e, nullptr); + addButton(Common::Rect(168, 115, 192, 135), Common::KEYCODE_s, nullptr); + addButton(Common::Rect(168, 139, 192, 159), Common::KEYCODE_a, nullptr); + addButton(Common::Rect(168, 163, 192, 183), Common::KEYCODE_l, nullptr); + addButton(Common::Rect(227, 19, 239, 29), 1000, nullptr); + addButton(Common::Rect(227, 30, 239, 40), 1001, nullptr); + addButton(Common::Rect(227, 41, 239, 51), 1002, nullptr); + addButton(Common::Rect(227, 52, 239, 62), 1003, nullptr); + addButton(Common::Rect(227, 63, 239, 73), 1004, nullptr); + addButton(Common::Rect(227, 74, 239, 84), 1005, nullptr); + addButton(Common::Rect(227, 85, 239, 95), 1006, nullptr); + addButton(Common::Rect(227, 96, 239, 106), 1007, nullptr); + addButton(Common::Rect(227, 107, 239, 117), 1008, nullptr); + addButton(Common::Rect(227, 118, 239, 128), 1009, nullptr); +} + +void CreateCharacterDialog::drawIcons() { + // Draw the screen + _icons.draw(0, 10, Common::Point(168, 19)); + _icons.draw(0, 12, Common::Point(168, 43)); + _icons.draw(0, 14, Common::Point(168, 67)); + _icons.draw(0, 16, Common::Point(168, 91)); + _icons.draw(0, 18, Common::Point(168, 115)); + _icons.draw(0, 20, Common::Point(168, 139)); + _icons.draw(0, 22, Common::Point(168, 163)); + for (int idx = 0; idx < 9; ++idx) + _icons.draw(0, 24 + idx * 2, Common::Point(227, 19 + 11 * idx)); + + for (int idx = 0; idx < 7; ++idx) + _icons.draw(0, 50 + idx, Common::Point(195, 31 + 24 * idx)); + + _icons.draw(0, 57, Common::Point(62, 148)); + _icons.draw(0, 58, Common::Point(62, 158)); + _icons.draw(0, 59, Common::Point(62, 168)); + _icons.draw(0, 61, Common::Point(220, 19)); + _icons.draw(0, 64, Common::Point(220, 155)); + _icons.draw(0, 65, Common::Point(220, 170)); + + _icons.draw(0, 0, Common::Point(132, 98)); + _icons.draw(0, 2, Common::Point(132, 128)); + _icons.draw(0, 4, Common::Point(132, 158)); + _icons.draw(0, 6, Common::Point(86, 98)); + _icons.draw(0, 8, Common::Point(86, 120)); +} + +void CreateCharacterDialog::drawIcons2() { + for (int idx = 0; idx < 7; ++idx) + _icons.draw(0, 10 + idx * 2, Common::Point(168, 19 + idx * 24)); + for (int idx = 0; idx < 10; ++idx) + _icons.draw(0, 24 + idx * 2, Common::Point(227, 19 + idx * 11)); + for (int idx = 0; idx < 8; ++idx) + _icons.draw(0, 50 + idx, Common::Point(195, 31 + idx * 24)); + + _icons.draw(0, 57, Common::Point(62, 148)); + _icons.draw(0, 58, Common::Point(62, 158)); + _icons.draw(0, 59, Common::Point(62, 168)); + _icons.draw(0, 61, Common::Point(220, 19)); + _icons.draw(0, 64, Common::Point(220, 155)); + _icons.draw(0, 65, Common::Point(220, 170)); + + _icons.draw(0, 0, Common::Point(132, 98)); + _icons.draw(0, 2, Common::Point(132, 128)); + _icons.draw(0, 4, Common::Point(132, 158)); + _icons.draw(0, 6, Common::Point(86, 98)); + _icons.draw(0, 8, Common::Point(86, 120)); +} + +void CreateCharacterDialog::rollAttributes() { + bool repeat = true; + do { + // Default all the attributes to zero + Common::fill(&_attribs[0], &_attribs[TOTAL_ATTRIBUTES], 0); + + // Assign random amounts to each attribute + for (int idx1 = 0; idx1 < 3; ++idx1) { + for (int idx2 = 0; idx2 < TOTAL_ATTRIBUTES; ++idx2) { + _attribs[idx2] += _vm->getRandomNumber(10, 79) / 10; + } + } + + // Check which classes are allowed based on the rolled attributes + checkClass(); + + // Only exit if the attributes allow for at least one class + for (int idx = 0; idx < TOTAL_CLASSES; ++idx) { + if (_allowedClasses[idx]) + repeat = false; + } + } while (repeat); +} + +void CreateCharacterDialog::checkClass() { + _allowedClasses[CLASS_KNIGHT] = _attribs[MIGHT] >= 15; + _allowedClasses[CLASS_PALADIN] = _attribs[MIGHT] >= 13 + && _attribs[PERSONALITY] >= 13 && _attribs[ENDURANCE] >= 13; + _allowedClasses[CLASS_ARCHER] = _attribs[INTELLECT] >= 13 && _attribs[ACCURACY] >= 13; + _allowedClasses[CLASS_CLERIC] = _attribs[PERSONALITY] >= 13; + _allowedClasses[CLASS_SORCERER] = _attribs[INTELLECT] >= 13; + _allowedClasses[CLASS_ROBBER] = _attribs[LUCK] >= 13; + _allowedClasses[CLASS_NINJA] = _attribs[SPEED] >= 13 && _attribs[ACCURACY] >= 13; + _allowedClasses[CLASS_BARBARIAN] = _attribs[ENDURANCE] >= 15; + _allowedClasses[CLASS_DRUID] = _attribs[INTELLECT] >= 15 && _attribs[PERSONALITY] >= 15; + _allowedClasses[CLASS_RANGER] = _attribs[INTELLECT] >= 12 && _attribs[PERSONALITY] >= 12 + && _attribs[ENDURANCE] >= 12 && _attribs[SPEED] >= 12; +} + +int CreateCharacterDialog::newCharDetails(Race race, Sex sex, int classId, + int selectedClass, Common::String &msg) { + int foundClass = -1; + Common::String skillStr, classStr, raceSkillStr; + + // If a selected class is provided, set the default skill for that class + if (classId != -1 && Res.NEW_CHAR_SKILLS[classId] != -1) { + const char *skillP = Res.SKILL_NAMES[Res.NEW_CHAR_SKILLS[classId]]; + skillStr = Common::String(skillP, skillP + Res.NEW_CHAR_SKILLS_LEN[classId]); + } + + // If a class is provided, set the class name + if (classId != -1) { + classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId]); + } + + // Set up default skill for the race, if any + if (Res.NEW_CHAR_RACE_SKILLS[race] != -1) { + raceSkillStr = Res.SKILL_NAMES[Res.NEW_CHAR_RACE_SKILLS[race]]; + } + + // Set up color to use for each skill string to be displayed, based + // on whether each class is allowed or not for the given attributes + int classColors[TOTAL_CLASSES]; + Common::fill(&classColors[0], &classColors[TOTAL_CLASSES], 0); + for (int classNum = CLASS_KNIGHT; classNum <= CLASS_RANGER; ++classNum) { + if (_allowedClasses[classNum]) { + if (classId == -1 && (foundClass == -1 || foundClass < classNum)) + foundClass = classNum; + classColors[classNum] = 4; + } + } + if (classId != -1) + classColors[selectedClass] = 12; + + // Return stats details and character class + msg = Common::String::format(Res.NEW_CHAR_STATS, Res.RACE_NAMES[race], Res.SEX_NAMES[sex], + _attribs[MIGHT], _attribs[INTELLECT], _attribs[PERSONALITY], + _attribs[ENDURANCE], _attribs[SPEED], _attribs[ACCURACY], _attribs[LUCK], + classColors[CLASS_KNIGHT], classColors[CLASS_PALADIN], + classColors[CLASS_ARCHER], classColors[CLASS_CLERIC], + classColors[CLASS_SORCERER], classColors[CLASS_ROBBER], + classColors[CLASS_NINJA], classColors[CLASS_BARBARIAN], + classColors[CLASS_DRUID], classColors[CLASS_RANGER], + skillStr.c_str(), raceSkillStr.c_str(), classStr.c_str() + ); + return classId == -1 ? foundClass : selectedClass; +} + +void CreateCharacterDialog::printSelectionArrow(int selectedClass) { + Windows &windows = *_vm->_windows; + Window &w = windows[0]; + + _icons.draw(0, 61, Common::Point(220, 19)); + _icons.draw(0, 63, Common::Point(220, selectedClass * 11 + 21)); + w.update(); +} + +void CreateCharacterDialog::drawDice() { + EventsManager &events = *_vm->_events; + Windows &windows = *_vm->_windows; + Window &w = windows[32]; + + // Draw the dice area background + events.updateGameCounter(); + _dice.draw(w, 7, Common::Point(12, 11)); + + // Iterate through each of the three dice + for (int diceNum = 0; diceNum < 3; ++diceNum) { + _diceFrame[diceNum] = (_diceFrame[diceNum] + 1) % 7; + _dicePos[diceNum] += _diceInc[diceNum]; + + if (_dicePos[diceNum].x < 13) { + _dicePos[diceNum].x = 13; + _diceInc[diceNum].x *= -1; + } else if (_dicePos[diceNum].x >= (163 - _diceSize.x)) { + _dicePos[diceNum].x = 163 - _diceSize.x; + _diceInc[diceNum].x *= -1; + } + + if (_dicePos[diceNum].y < 12) { + _dicePos[diceNum].y = 12; + _diceInc[diceNum].y *= -1; + } else if (_dicePos[diceNum].y >= (93 - _diceSize.y)) { + _dicePos[diceNum].y = 93 - _diceSize.y; + _diceInc[diceNum].y *= -1; + } + + _dice.draw(w, _diceFrame[diceNum], _dicePos[diceNum]); + } + + // Wait for a single frame, checking for any events + w.update(); + events.wait(1); + checkEvents(_vm); +} + +int CreateCharacterDialog::getAttribFromKeycode(int keycode) const { + switch (keycode) { + case Common::KEYCODE_m: + return MIGHT; + case Common::KEYCODE_i: + return INTELLECT; + case Common::KEYCODE_p: + return PERSONALITY; + case Common::KEYCODE_e: + return ENDURANCE; + case Common::KEYCODE_s: + return SPEED; + case Common::KEYCODE_a: + return ACCURACY; + case Common::KEYCODE_l: + return LUCK; + default: + return -1; + } +} + +bool CreateCharacterDialog::swapAttributes(int keycode) { + Windows &windows = *_vm->_windows; + Window &w = windows[0]; + + int srcAttrib = getAttribFromKeycode(keycode); + assert(srcAttrib >= 0); + + _vm->_mode = MODE_86; + _icons.draw(w, srcAttrib * 2 + 11, Common::Point( + _buttons[srcAttrib + 5]._bounds.left, _buttons[srcAttrib + 5]._bounds.top)); + w.update(); + + int destAttrib = exchangeAttribute(srcAttrib); + if (destAttrib != -1) { + _icons.draw(w, destAttrib * 2 + 11, Common::Point( + _buttons[destAttrib + 5]._bounds.left, + _buttons[destAttrib + 5]._bounds.top)); + + SWAP(_attribs[srcAttrib], _attribs[destAttrib]); + return true; + + } else { + _icons.draw(w, srcAttrib * 2 + 10, Common::Point( + _buttons[srcAttrib + 5]._bounds.left, + _buttons[srcAttrib + 5]._bounds.top)); + w.update(); + _vm->_mode = MODE_SLEEPING; + return false; + } +} + +int CreateCharacterDialog::exchangeAttribute(int srcAttr) { + EventsManager &events = *_vm->_events; + Windows &windows = *_vm->_windows; + SpriteResource icons; + icons.load("create2.icn"); + + saveButtons(); + addButton(Common::Rect(118, 58, 142, 78), Common::KEYCODE_ESCAPE, &_icons); + addButton(Common::Rect(168, 19, 192, 39), Common::KEYCODE_m); + addButton(Common::Rect(168, 43, 192, 63), Common::KEYCODE_i); + addButton(Common::Rect(168, 67, 192, 87), Common::KEYCODE_p); + addButton(Common::Rect(168, 91, 192, 111), Common::KEYCODE_e); + addButton(Common::Rect(168, 115, 192, 135), Common::KEYCODE_s); + addButton(Common::Rect(168, 139, 192, 159), Common::KEYCODE_a); + addButton(Common::Rect(168, 163, 192, 183), Common::KEYCODE_l); + + Window &w = windows[26]; + w.open(); + w.writeString(Common::String::format(Res.EXCHANGE_ATTR_WITH, Res.STAT_NAMES[srcAttr])); + icons.draw(w, 0, Common::Point(118, 58)); + w.update(); + + int result = -1; + bool breakFlag = false; + while (!_vm->shouldExit() && !breakFlag) { + // Wait for an action + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_vm->shouldExit() && !_buttonValue); + if (_buttonValue == Common::KEYCODE_ESCAPE) + break; + + int destAttr = getAttribFromKeycode(_buttonValue); + + if (destAttr != -1 && srcAttr != destAttr) { + result = destAttr; + break; + } + } + + w.close(); + restoreButtons(); + _buttonValue = 0; + return result; +} + +bool CreateCharacterDialog::saveCharacter(Character &c, int classId, Race race, Sex sex) { + if (classId == -1) { + ErrorScroll::show(_vm, Res.SELECT_CLASS_BEFORE_SAVING); + return false; + } + + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Common::String name; + int result; + bool isDarkCc = _vm->_files->_isDarkCc; + + // Prompt for a character name + w.open(); + w.writeString(Res.NAME_FOR_NEW_CHARACTER); + saveButtons(); + result = Input::show(_vm, &w, name, 10, 200); + restoreButtons(); + w.close(); + + if (!result) + // Name aborted, so exit + return false; + + // Save new character details + c.clear(); + c._name = name; + c._savedMazeId = party._priorMazeId; + c._xeenSide = map._loadDarkSide; + c._sex = sex; + c._race = race; + c._class = (CharacterClass)classId; + c._level._permanent = isDarkCc ? 5 : 1; + + c._might._permanent = _attribs[MIGHT]; + c._intellect._permanent = _attribs[INTELLECT]; + c._personality._permanent = _attribs[PERSONALITY]; + c._endurance._permanent = _attribs[ENDURANCE]; + c._speed._permanent = _attribs[SPEED]; + c._accuracy._permanent = _attribs[ACCURACY]; + c._luck._permanent = _attribs[LUCK]; + + c._magicResistence._permanent = Res.RACE_MAGIC_RESISTENCES[race]; + c._fireResistence._permanent = Res.RACE_FIRE_RESISTENCES[race]; + c._electricityResistence._permanent = Res.RACE_ELECTRIC_RESISTENCES[race]; + c._coldResistence._permanent = Res.RACE_COLD_RESISTENCES[race]; + c._energyResistence._permanent = Res.RACE_ENERGY_RESISTENCES[race]; + c._poisonResistence._permanent = Res.RACE_POISON_RESISTENCES[race]; + + c._birthYear = party._year - 18; + c._birthDay = party._day; + c._hasSpells = false; + c._currentSpell = -1; + + // Set up any default spells for the character's class + for (int idx = 0; idx < 4; ++idx) { + if (Res.NEW_CHARACTER_SPELLS[c._class][idx] != -1) { + c._hasSpells = true; + c._currentSpell = Res.NEW_CHARACTER_SPELLS[c._class][idx]; + c._spells[c._currentSpell] = true; + } + } + + int classSkill = Res.NEW_CHAR_SKILLS[c._class]; + if (classSkill != -1) + c._skills[classSkill] = 1; + + int raceSkill = Res.NEW_CHAR_RACE_SKILLS[c._race]; + if (raceSkill != -1) + c._skills[raceSkill] = 1; + + c._currentHp = c.getMaxHP(); + c._currentSp = c.getMaxSP(); + return true; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_create_char.h b/engines/xeen/dialogs/dialogs_create_char.h new file mode 100644 index 0000000000..dc1422eb23 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_create_char.h @@ -0,0 +1,124 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_CREATE_CHAR_H +#define XEEN_DIALOGS_CREATE_CHAR_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/character.h" + +namespace Xeen { + +class CreateCharacterDialog : public ButtonContainer { +private: + SpriteResource _icons; + SpriteResource _dice; + Common::Point _diceSize; + int _diceFrame[3]; + Common::Point _dicePos[3]; + Common::Point _diceInc[3]; + uint _attribs[TOTAL_ATTRIBUTES]; + bool _allowedClasses[TOTAL_CLASSES]; +private: + /** + * Constructor + */ + CreateCharacterDialog(XeenEngine *vm); + + /** + * Loads the buttons for the dialog + */ + void loadButtons(); + + /** + * Draws on-screen icons + */ + void drawIcons(); + + /** + * Draws on-screen icons + */ + void drawIcons2(); + + /** + * Animate the dice rolling around + */ + void drawDice(); + + /** + * Executes the dialog + */ + void execute(); + + /** + * Returns the attribute that a given keycode represents + */ + int getAttribFromKeycode(int keycode) const; + + /** + * Handles the logic for swapping attributes + * @param keycode Key pressed representing one of the attributes + * @returns True if swap occurred + */ + bool swapAttributes(int keycode); + + /** + * Exchanging two attributes for the character being rolled + */ + int exchangeAttribute(int srcAttr); + + /** + * Set a list of flags for which classes the passed attribute set meet the + * minimum requirements of + */ + void checkClass(); + + /** + * Return details of the generated character + */ + int newCharDetails(Race race, Sex sex, int classId, int selectedClass, Common::String &msg); + + /** + * Print the selection arrow to indicate the selected class + */ + void printSelectionArrow(int selectedClass); + + /** + * Saves the rolled character into the roster + */ + bool saveCharacter(Character &c, int classId, Race race, Sex sex); + + /** + * Roll up some random values for the attributes, and return both them as + * well as a list of classes that the attributes meet the requirements for + */ + void rollAttributes(); +public: + /** + * Shows the Create Character dialog + */ + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_CREATE_CHAR_H */ diff --git a/engines/xeen/dialogs/dialogs_difficulty.cpp b/engines/xeen/dialogs/dialogs_difficulty.cpp new file mode 100644 index 0000000000..0b024e1857 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_difficulty.cpp @@ -0,0 +1,75 @@ +/* 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/dialogs_difficulty.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +int DifficultyDialog::show(XeenEngine *vm) { + DifficultyDialog *dlg = new DifficultyDialog(vm); + int result = dlg->execute(); + delete dlg; + + return result; +} + +DifficultyDialog::DifficultyDialog(XeenEngine *vm) : ButtonContainer(vm) { + loadButtons(); +} + +int DifficultyDialog::execute() { + EventsManager &events = *_vm->_events; + Windows &windows = *_vm->_windows; + + Window &w = windows[6]; + w.open(); + w.writeString(Res.DIFFICULTY_TEXT); + drawButtons(&w); + + int result = -1; + while (!_vm->shouldExit()) { + events.pollEventsAndWait(); + checkEvents(_vm); + + if (_buttonValue == Common::KEYCODE_a) + result = ADVENTURER; + else if (_buttonValue == Common::KEYCODE_w) + result = WARRIOR; + else if (_buttonValue != Common::KEYCODE_ESCAPE) + continue; + + break; + } + + w.close(); + return result; +} + +void DifficultyDialog::loadButtons() { + _sprites.load("choice.icn"); + addButton(Common::Rect(68, 167, 158, 187), Common::KEYCODE_a, &_sprites); + addButton(Common::Rect(166, 167, 256, 187), Common::KEYCODE_w, &_sprites); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_difficulty.h b/engines/xeen/dialogs/dialogs_difficulty.h new file mode 100644 index 0000000000..5ff2c93a2b --- /dev/null +++ b/engines/xeen/dialogs/dialogs_difficulty.h @@ -0,0 +1,60 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_DIFFICULTY_H +#define XEEN_DIALOGS_DIFFICULTY_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" + +namespace Xeen { + +class DifficultyDialog : public ButtonContainer { +private: + SpriteResource _sprites; + + /** + * Constructor + */ + DifficultyDialog(XeenEngine *vm); + + /** + * Shows the dialog + */ + int execute(); + + /** + * Loads buttons for the dialog + */ + void loadButtons(); +public: + /** + * Shows the difficulty selection dialog + * @param vm Engine reference + * @returns 0=Adventurer, 1=Warrior, -1 exit + */ + static int show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_DIFFICULTY_H */ diff --git a/engines/xeen/dialogs/dialogs_dismiss.cpp b/engines/xeen/dialogs/dialogs_dismiss.cpp new file mode 100644 index 0000000000..716f8f0035 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_dismiss.cpp @@ -0,0 +1,95 @@ +/* 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/dialogs_dismiss.h" +#include "xeen/party.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void Dismiss::show(XeenEngine *vm) { + Dismiss *dlg = new Dismiss(vm); + dlg->execute(); + delete dlg; +} + +void Dismiss::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + loadButtons(); + + Window &w = windows[31]; + w.open(); + _iconSprites.draw(w, 0, Common::Point(225, 120)); + w.update(); + + bool breakFlag = false; + while (!_vm->shouldExit() && !breakFlag) { + do { + events.updateGameCounter(); + intf.draw3d(false); + w.frame(); + w.writeString("\r"); + _iconSprites.draw(w, 0, Common::Point(225, 120)); + windows[3].update(); + w.update(); + + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_vm->shouldExit() && !_buttonValue && events.timeElapsed() == 0); + } while (!_vm->shouldExit() && !_buttonValue); + + if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { + _buttonValue -= Common::KEYCODE_F1; + + if (_buttonValue < (int)party._activeParty.size()) { + if (party._activeParty.size() == 1) { + w.close(); + ErrorScroll::show(_vm, Res.CANT_DISMISS_LAST_CHAR, WT_NONFREEZED_WAIT); + w.open(); + } else { + // Remove the character from the party + party._activeParty.remove_at(_buttonValue); + breakFlag = true; + } + break; + } + } else if (_buttonValue == Common::KEYCODE_ESCAPE) { + breakFlag = true; + } + } +} + +void Dismiss::loadButtons() { + _iconSprites.load("esc.icn"); + addButton(Common::Rect(225, 120, 249, 140), Common::KEYCODE_ESCAPE, &_iconSprites); + addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); + addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); + addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); + addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_dismiss.h b/engines/xeen/dialogs/dialogs_dismiss.h new file mode 100644 index 0000000000..832f779a09 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_dismiss.h @@ -0,0 +1,46 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_DISMISS_H +#define XEEN_DIALOGS_DISMISS_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" + +namespace Xeen { + +class Dismiss : public ButtonContainer { +private: + SpriteResource _iconSprites; + + Dismiss(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(); + + void loadButtons(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_DISMISS_H */ diff --git a/engines/xeen/dialogs/dialogs_exchange.cpp b/engines/xeen/dialogs/dialogs_exchange.cpp new file mode 100644 index 0000000000..87dde1b0c3 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_exchange.cpp @@ -0,0 +1,80 @@ +/* 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/dialogs_exchange.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void ExchangeDialog::show(XeenEngine *vm, Character *&c, int &charIndex) { + ExchangeDialog *dlg = new ExchangeDialog(vm); + dlg->execute(c, charIndex); + delete dlg; +} + +void ExchangeDialog::execute(Character *&c, int &charIndex) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + loadButtons(); + + Window &w = windows[31]; + w.open(); + w.writeString(Res.EXCHANGE_WITH_WHOM); + _iconSprites.draw(w, 0, Common::Point(225, 120)); + w.update(); + + while (!_vm->shouldExit()) { + events.pollEventsAndWait(); + checkEvents(_vm); + + if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)party._activeParty.size()) { + SWAP(party._activeParty[charIndex], party._activeParty[_buttonValue]); + + charIndex = _buttonValue; + c = &party._activeParty[charIndex]; + break; + } + } else if (_buttonValue == Common::KEYCODE_ESCAPE) { + break; + } + } + + w.close(); + intf.drawParty(true); + intf.highlightChar(charIndex); +} + +void ExchangeDialog::loadButtons() { + _iconSprites.load("esc.icn"); + addButton(Common::Rect(225, 120, 249, 245), Common::KEYCODE_ESCAPE, &_iconSprites); + addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); + addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); + addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); + addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_exchange.h b/engines/xeen/dialogs/dialogs_exchange.h new file mode 100644 index 0000000000..ff7e214787 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_exchange.h @@ -0,0 +1,46 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_EXCHANGE_H +#define XEEN_DIALOGS_EXCHANGE_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" + +namespace Xeen { + +class ExchangeDialog : public ButtonContainer { +private: + SpriteResource _iconSprites; + + ExchangeDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(Character *&c, int &charIndex); + + void loadButtons(); +public: + static void show(XeenEngine *vm, Character *&c, int &charIndex); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_EXCHANGE_H */ diff --git a/engines/xeen/dialogs/dialogs_info.cpp b/engines/xeen/dialogs/dialogs_info.cpp new file mode 100644 index 0000000000..50558534d1 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_info.cpp @@ -0,0 +1,129 @@ +/* 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/dialogs_info.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void InfoDialog::show(XeenEngine *vm) { + InfoDialog *dlg = new InfoDialog(vm); + dlg->execute(); + delete dlg; +} + +void InfoDialog::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + + protectionText(); + Common::String statusText = ""; + for (uint idx = 0; idx < _lines.size(); ++idx) + statusText += _lines[idx]; + + Common::String gameName; + if (_vm->getGameID() == GType_Swords) + gameName = Res.SWORDS_GAME_TEXT; + else if (_vm->getGameID() == GType_Clouds) + gameName = Res.CLOUDS_GAME_TEXT; + else if (_vm->getGameID() == GType_DarkSide) + gameName = Res.DARKSIDE_GAME_TEXT; + else + gameName = Res.WORLD_GAME_TEXT; + + // Form the display message + int hour = party._minutes / 60; + Common::String details = Common::String::format(Res.GAME_INFORMATION, + gameName.c_str(), Res.WEEK_DAY_STRINGS[party._day % 10], + (hour > 12) ? hour - 12 : (!hour ? 12 : hour), + party._minutes % 60, (hour > 11) ? 'p' : 'a', + party._day, party._year, statusText.c_str()); + + Window &w = windows[28]; + w.setBounds(Common::Rect(88, 20, 248, 112 + (_lines.empty() ? 0 : _lines.size() * 9 + 13))); + w.open(); + w.writeString(details); + + do { + events.updateGameCounter(); + intf.draw3d(false, false); + w.frame(); + w.writeString(details); + w.update(); + + events.wait(1); + } while (!_vm->shouldExit() && !events.isKeyMousePressed()); + + events.clearEvents(); + w.close(); +} + +void InfoDialog::protectionText() { + Party &party = *_vm->_party; +// Common::StringArray _lines; + const char *const AA_L024 = "\x3l\n\x9""024"; + const char *const AA_R124 = "\x3r\x9""124"; + + if (party._lightCount) { + _lines.push_back(Common::String::format(Res.LIGHT_COUNT_TEXT, party._lightCount)); + } + + if (party._fireResistence) { + _lines.push_back(Common::String::format(Res.FIRE_RESISTENCE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._fireResistence)); + } + + if (party._electricityResistence) { + _lines.push_back(Common::String::format(Res.ELECRICITY_RESISTENCE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._electricityResistence)); + } + + if (party._coldResistence) { + _lines.push_back(Common::String::format(Res.COLD_RESISTENCE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._coldResistence)); + } + + if (party._poisonResistence) { + _lines.push_back(Common::String::format(Res.POISON_RESISTENCE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._poisonResistence)); + } + + if (party._clairvoyanceActive) { + _lines.push_back(Common::String::format(Res.CLAIRVOYANCE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); + } + + if (party._levitateCount) { + _lines.push_back(Common::String::format(Res.LEVITATE_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); + } + + if (party._walkOnWaterActive) { + _lines.push_back(Common::String::format(Res.WALK_ON_WATER_TEXT, + _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); + } +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_info.h b/engines/xeen/dialogs/dialogs_info.h new file mode 100644 index 0000000000..fdbbc22163 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_info.h @@ -0,0 +1,46 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_INFO_H +#define XEEN_DIALOGS_INFO_H + +#include "common/str-array.h" +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class InfoDialog : public ButtonContainer { +private: + Common::StringArray _lines; + + InfoDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(); + + void protectionText(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_INFO_H */ diff --git a/engines/xeen/dialogs/dialogs_input.cpp b/engines/xeen/dialogs/dialogs_input.cpp new file mode 100644 index 0000000000..1d05c81f32 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_input.cpp @@ -0,0 +1,323 @@ +/* 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/dialogs_input.h" +#include "xeen/scripts.h" +#include "xeen/xeen.h" + +namespace Xeen { + +int Input::show(XeenEngine *vm, Window *window, Common::String &line, + uint maxLen, int maxWidth, bool isNumeric) { + Input *dlg = new Input(vm, window); + int result = dlg->getString(line, maxLen, maxWidth, isNumeric); + delete dlg; + + return result; +} + +int Input::getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric) { + _vm->_noDirectionSense = true; + Common::String msg = Common::String::format("\x3""l\t000\x4%03d\x3""c", maxWidth); + _window->writeString(msg); + _window->update(); + + while (!_vm->shouldExit()) { + Common::KeyState keyState = waitForKey(msg); + const Common::KeyCode keyCode = keyState.keycode; + + bool refresh = false; + if ((keyCode == Common::KEYCODE_BACKSPACE || keyCode == Common::KEYCODE_DELETE) + && line.size() > 0) { + line.deleteLastChar(); + refresh = true; + } else if (line.size() < maxLen && (line.size() > 0 || keyCode != Common::KEYCODE_SPACE) + && ((isNumeric && keyState.ascii >= '0' && keyState.ascii <= '9') || + (!isNumeric && keyState.ascii >= ' ' && keyState.ascii <= (char)127))) { + line += keyState.ascii; + refresh = true; + } else if (keyCode == Common::KEYCODE_RETURN || keyCode == Common::KEYCODE_KP_ENTER) { + break; + } else if (keyCode == Common::KEYCODE_ESCAPE) { + line = ""; + break; + } + + if (refresh) { + msg = Common::String::format("\x3""l\t000\x4%03d\x3""c%s", maxWidth, line.c_str()); + _window->writeString(msg); + _window->update(); + } + } + + _vm->_noDirectionSense = false; + return line.size(); +} + +Common::KeyState Input::waitForKey(const Common::String &msg) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Windows &windows = *_vm->_windows; + + bool oldUpDoorText = intf._upDoorText; + byte oldTillMove = intf._tillMove; + intf._upDoorText = false; + intf._tillMove = 0; + + bool flag = !_vm->_startupWindowActive && !windows[25]._enabled + && _vm->_mode != MODE_FF && _vm->_mode != MODE_17; + + Common::KeyState ks; + while (!_vm->shouldExit()) { + events.updateGameCounter(); + + if (flag) + intf.draw3d(false); + _window->writeString(msg); + animateCursor(); + _window->update(); + + if (flag) + windows[3].update(); + + events.wait(1); + + if (events.isKeyPending()) { + events.getKey(ks); + break; + } + } + + _window->writeString(""); + _window->update(); + + intf._tillMove = oldTillMove; + intf._upDoorText = oldUpDoorText; + + return ks; +} + +void Input::animateCursor() { + // Iterate through each frame + _cursorAnimIndex = _cursorAnimIndex ? _cursorAnimIndex - 1 : 5; + static const char CURSOR_ANIMATION_IDS[] = { 32, 124, 126, 127, 126, 124 }; + + // Form a string for the cursor and write it out + Common::Point writePos = _window->_writePos; + _window->writeCharacter(CURSOR_ANIMATION_IDS[_cursorAnimIndex]); + _window->_writePos = writePos; +} + +/*------------------------------------------------------------------------*/ + +StringInput::StringInput(XeenEngine *vm): Input(vm, &(*vm->_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) { + FileManager &files = *_vm->_files; + Interface &intf = *_vm->_interface; + Scripts &scripts = *_vm->_scripts; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Sound &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 + MirrorEntry me; + scripts._mirror.clear(); + + File f(Common::String::format("%smirr.txt", files._isDarkCc ? "dark" : "xeen"), 1); + while (me.synchronize(f)) + scripts._mirror.push_back(me); + f.close(); + + // Load in any extended mirror entries + Common::File f2; + if (f2.open(Common::String::format("%smirr.ext", files._isDarkCc ? "dark" : "xeen"))) { + while (me.synchronize(f2)) + scripts._mirror.push_back(me); + f2.close(); + } + + for (uint idx = 0; idx < scripts._mirror.size(); ++idx) { + if (!line.compareToIgnoreCase(scripts._mirror[idx]._name)) { + result = idx + 1; + sound.playFX(_vm->_files->_isDarkCc ? 35 : 61); + break; + } + } + } + } + + w.close(); + return result; +} + +/*------------------------------------------------------------------------*/ + +NumericInput::NumericInput(XeenEngine *vm, int window) : Input(vm, &(*vm->_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; +} + +/*------------------------------------------------------------------------*/ + +int Choose123::show(XeenEngine *vm, int numOptions) { + assert(numOptions <= 3); + Choose123 *dlg = new Choose123(vm); + int result = dlg->execute(numOptions); + delete dlg; + + return result; +} + +int Choose123::execute(int numOptions) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + LocationManager &loc = *_vm->_locations; + Windows &windows = *_vm->_windows; + + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_DIALOG_123; + + loadButtons(numOptions); + _iconSprites.draw(0, 7, Common::Point(232, 74)); + drawButtons(&windows[0]); + windows[34].update(); + + int result = -1; + while (result == -1) { + do { + events.updateGameCounter(); + int delay; + if (loc.isActive()) { + loc.drawAnim(true); + delay = 3; + } else { + intf.draw3d(true); + delay = 1; + } + + events.wait(delay); + if (_vm->shouldExit()) + return 0; + } while (!_buttonValue); + + switch (_buttonValue) { + case Common::KEYCODE_ESCAPE: + result = 0; + break; + case Common::KEYCODE_1: + case Common::KEYCODE_2: + case Common::KEYCODE_3: { + int v = _buttonValue - Common::KEYCODE_1 + 1; + if (v <= numOptions) + result = v; + break; + } + default: + break; + } + } + + _vm->_mode = oldMode; + intf.mainIconsPrint(); + + return result; +} + +void Choose123::loadButtons(int numOptions) { + _iconSprites.load("choose.icn"); + + if (numOptions >= 1) + addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_1, &_iconSprites); + if (numOptions >= 2) + addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_2, &_iconSprites); + if (numOptions >= 3) + addButton(Common::Rect(286, 75, 311, 95), Common::KEYCODE_3, &_iconSprites); +} + +/*------------------------------------------------------------------------*/ + +int HowMuch::show(XeenEngine *vm) { + HowMuch *dlg = new HowMuch(vm); + int result = dlg->execute(); + delete dlg; + + return result; +} + +int HowMuch::execute() { + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Common::String num; + + w.open(); + w.writeString(Res.HOW_MUCH); + w.update(); + int lineSize = Input::show(_vm, &w, num, 8, 70, true); + w.close(); + + if (!lineSize) + return -1; + return atoi(num.c_str()); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_input.h b/engines/xeen/dialogs/dialogs_input.h new file mode 100644 index 0000000000..270495ffd5 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_input.h @@ -0,0 +1,105 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_STRING_INPUT_H +#define XEEN_DIALOGS_STRING_INPUT_H + +#include "common/keyboard.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/screen.h" + +namespace Xeen { + +class Input : public ButtonContainer { +private: + /** + * Draws the text input and cursor and waits until the user presses a key + */ + Common::KeyState waitForKey(const Common::String &msg); + + /** + * Animates the box text cursor + */ + void animateCursor(); +protected: + Window *_window; + int _cursorAnimIndex; + + /** + * Allows the user to enter a string + */ + int getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric); + + Input(XeenEngine *vm, Window *window) : ButtonContainer(vm), + _window(window), _cursorAnimIndex(0) {} +public: + static int show(XeenEngine *vm, Window *window, Common::String &line, + uint maxLen, int maxWidth, bool isNumeric = false); +}; + +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 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); +}; + +class Choose123 : public ButtonContainer { +private: + SpriteResource _iconSprites; + + Choose123(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(int numOptions); + + void loadButtons(int numOptions); +public: + static int show(XeenEngine *vm, int numOptions); +}; + +class HowMuch : public ButtonContainer { +private: + SpriteResource _iconSprites; + + HowMuch(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(); +public: + static int show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_STRING_INPUT_H */ diff --git a/engines/xeen/dialogs/dialogs_items.cpp b/engines/xeen/dialogs/dialogs_items.cpp new file mode 100644 index 0000000000..0ca0fd2267 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_items.cpp @@ -0,0 +1,1066 @@ +/* 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/dialogs_items.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/dialogs/dialogs_quests.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +Character *ItemsDialog::show(XeenEngine *vm, Character *c, ItemsMode mode) { + ItemsDialog *dlg = new ItemsDialog(vm); + Character *result = dlg->execute(c, mode); + delete dlg; + + return result; +} + +Character *ItemsDialog::execute(Character *c, ItemsMode mode) { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + + Character *startingChar = c; + ItemCategory category = mode == ITEMMODE_RECHARGE || mode == ITEMMODE_COMBAT ? + CATEGORY_MISC : CATEGORY_WEAPON; + int varA = mode == ITEMMODE_COMBAT ? 1 : 0; + if (varA != 0) + mode = ITEMMODE_CHAR_INFO; + bool updateStock = mode == ITEMMODE_BLACKSMITH; + int itemIndex = -1; + Common::StringArray lines; + uint arr[40]; + int actionIndex = -1; + + events.setCursor(0); + loadButtons(mode, c); + + windows[29].open(); + windows[30].open(); + + enum { REDRAW_NONE, REDRAW_TEXT, REDRAW_FULL } redrawFlag = REDRAW_FULL; + for (;;) { + if (redrawFlag == REDRAW_FULL) { + if ((mode != ITEMMODE_CHAR_INFO || category != CATEGORY_MISC) && mode != ITEMMODE_ENCHANT + && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { + _buttons[4]._bounds.moveTo(148, _buttons[4]._bounds.top); + _buttons[9]._draw = false; + } else if (mode == ITEMMODE_RECHARGE) { + _buttons[4]._value = Common::KEYCODE_r; + } else if (mode == ITEMMODE_ENCHANT) { + _buttons[4]._value = Common::KEYCODE_e; + } else if (mode == ITEMMODE_TO_GOLD) { + _buttons[4]._value = Common::KEYCODE_g; + } else { + _buttons[4]._bounds.moveTo(0, _buttons[4]._bounds.top); + _buttons[9]._draw = true; + _buttons[9]._value = Common::KEYCODE_u; + } + + // Write text for the dialog + Common::String msg; + if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_8 && mode != ITEMMODE_ENCHANT + && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { + msg = Common::String::format(Res.ITEMS_DIALOG_TEXT1, + Res.BTN_BUY, Res.BTN_SELL, Res.BTN_IDENTIFY, Res.BTN_FIX); + } else if (mode != ITEMMODE_ENCHANT && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { + msg = Common::String::format(Res.ITEMS_DIALOG_TEXT1, + category == 3 ? Res.BTN_USE : Res.BTN_EQUIP, + Res.BTN_REMOVE, Res.BTN_DISCARD, Res.BTN_QUEST); + } else if (mode == ITEMMODE_ENCHANT) { + msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_ENCHANT); + } else if (mode == ITEMMODE_RECHARGE) { + msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_RECHARGE); + } else { + msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_GOLD); + } + + windows[29].writeString(msg); + drawButtons(&windows[0]); + + Common::fill(&arr[0], &arr[40], 0); + itemIndex = -1; + } + + if (redrawFlag == REDRAW_TEXT || redrawFlag == REDRAW_FULL) { + lines.clear(); + + if (mode == ITEMMODE_CHAR_INFO || category != 3) { + _iconSprites.draw(0, 8, Common::Point(148, 109)); + } + if (mode != ITEMMODE_ENCHANT && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { + _iconSprites.draw(0, 10, Common::Point(182, 109)); + _iconSprites.draw(0, 12, Common::Point(216, 109)); + _iconSprites.draw(0, 14, Common::Point(250, 109)); + } + + switch (mode) { + case ITEMMODE_CHAR_INFO: + _iconSprites.draw(0, 9, Common::Point(148, 109)); + break; + case ITEMMODE_BLACKSMITH: + _iconSprites.draw(0, 11, Common::Point(182, 109)); + break; + case ITEMMODE_REPAIR: + _iconSprites.draw(0, 15, Common::Point(250, 109)); + break; + case ITEMMODE_IDENTIFY: + _iconSprites.draw(0, 13, Common::Point(216, 109)); + break; + default: + break; + } + + for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { + DrawStruct &ds = _itemsDrawList[idx]; + XeenItem &i = c->_items[category][idx]; + + ds._sprites = nullptr; + ds._x = 8; + ds._y = 18 + idx * 9; + + switch (category) { + case CATEGORY_WEAPON: + case CATEGORY_ARMOR: + case CATEGORY_ACCESSORY: + if (i._id) { + if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 + || mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE) { + lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE1, + arr[idx], idx + 1, + c->_items[category].getFullDescription(idx, arr[idx]).c_str())); + } else { + lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE2, + arr[idx], idx + 1, + c->_items[category].getFullDescription(idx, arr[idx]).c_str(), + calcItemCost(c, idx, mode, + mode == ITEMMODE_TO_GOLD ? 1 : startingChar->_skills[MERCHANT], + category) + )); + } + + ds._sprites = &_equipSprites; + if (c->_weapons.passRestrictions(i._id, true)) + ds._frame = i._frame; + else + ds._frame = 14; + } else if (ds._sprites == nullptr && idx == 0) { + lines.push_back(Res.NO_ITEMS_AVAILABLE); + } + break; + + case CATEGORY_MISC: + if (i._material == 0) { + // No item + if (idx == 0) { + lines.push_back(Res.NO_ITEMS_AVAILABLE); + } + } else { + ItemsMode tempMode = mode; + int skill = startingChar->_skills[MERCHANT]; + + if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 + || mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE) { + tempMode = ITEMMODE_ENCHANT; + } else if (mode == ITEMMODE_TO_GOLD) { + skill = 1; + } + + lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE2, + arr[idx], idx + 1, + c->_items[category].getFullDescription(idx, arr[idx]).c_str(), + calcItemCost(c, idx, tempMode, skill, category) + )); + } + break; + + default: + break; + } + } + while (lines.size() < INV_ITEMS_TOTAL) + lines.push_back(""); + + // Draw out overall text and the list of items + switch (mode) { + case ITEMMODE_CHAR_INFO: + case ITEMMODE_8: + windows[30].writeString(Common::String::format(Res.X_FOR_THE_Y, + category == CATEGORY_MISC ? "\x3l" : "\x3c", + Res.CATEGORY_NAMES[category], c->_name.c_str(), Res.CLASS_NAMES[c->_class], + category == CATEGORY_MISC ? Res.FMT_CHARGES : " ", + lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), + lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), + lines[8].c_str() + )); + break; + + case ITEMMODE_BLACKSMITH: + windows[30].writeString(Common::String::format(Res.AVAILABLE_GOLD_COST, + Res.CATEGORY_NAMES[category], party._gold, + lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), + lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), + lines[8].c_str() + )); + break; + + case ITEMMODE_2: + case ITEMMODE_RECHARGE: + case ITEMMODE_ENCHANT: + case ITEMMODE_REPAIR: + case ITEMMODE_IDENTIFY: + case ITEMMODE_TO_GOLD: + windows[30].writeString(Common::String::format(Res.X_FOR_Y, + Res.CATEGORY_NAMES[category], startingChar->_name.c_str(), + (mode == ITEMMODE_RECHARGE || mode == ITEMMODE_ENCHANT) ? Res.CHARGES : Res.COST, + lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), + lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), + lines[8].c_str() + )); + break; + + case ITEMMODE_3: + case ITEMMODE_5: + windows[30].writeString(Common::String::format(Res.X_FOR_Y_GOLD, + Res.CATEGORY_NAMES[category], c->_name.c_str(), party._gold, Res.CHARGES, + lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), + lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), + lines[8].c_str() + )); + break; + + default: + break; + } + + // Draw the glyphs for the items + windows[0].drawList(_itemsDrawList, INV_ITEMS_TOTAL); + windows[0].update(); + } + + redrawFlag = REDRAW_NONE; + + if (itemIndex != -1) { + switch (mode) { + case ITEMMODE_BLACKSMITH: + actionIndex = 0; + break; + case ITEMMODE_2: + actionIndex = 1; + break; + case ITEMMODE_REPAIR: + actionIndex = 3; + break; + case ITEMMODE_IDENTIFY: + actionIndex = 2; + break; + default: + break; + } + } + + // If it's time to do an item action, take care of it + if (actionIndex >= 0) { + int result = doItemOptions(*c, actionIndex, itemIndex, category, mode); + if (result == 1) { + // Finish dialog with no selected character + c = nullptr; + break; + } else if (result == 2) { + // Close dialogs and finish dialog with original starting character + windows[30].close(); + windows[29].close(); + c = startingChar; + break; + } + + // Otherwise, result and continue showing dialog + actionIndex = -1; + } + + // Wait for a selection + _buttonValue = 0; + while (!_vm->shouldExit() && !_buttonValue) { + events.pollEventsAndWait(); + checkEvents(_vm); + } + if (_vm->shouldExit()) + return nullptr; + + // Handle escaping out of dialog + if (_buttonValue == Common::KEYCODE_ESCAPE) { + if (mode == ITEMMODE_8) + continue; + c = startingChar; + break; + } + + // Handle other selections + 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: + if (!varA && mode != ITEMMODE_3 && mode != ITEMMODE_ENCHANT + && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD + && party._mazeId != 0) { + _buttonValue -= Common::KEYCODE_F1; + + if (_buttonValue < (int)(_vm->_mode == MODE_COMBAT ? + combat._combatParty.size() : party._activeParty.size())) { + // Character number is valid + redrawFlag = REDRAW_TEXT; + Character *newChar = _vm->_mode == MODE_COMBAT ? + combat._combatParty[_buttonValue] : &party._activeParty[_buttonValue]; + + if (mode == ITEMMODE_BLACKSMITH) { + _oldCharacter = newChar; + startingChar = newChar; + c = &_itemsCharacter; + } else if (mode != ITEMMODE_2 && mode != ITEMMODE_REPAIR + && mode != ITEMMODE_IDENTIFY && itemIndex != -1) { + InventoryItems &destItems = newChar->_items[category]; + XeenItem &destItem = destItems[INV_ITEMS_TOTAL - 1]; + InventoryItems &srcItems = c->_items[category]; + XeenItem &srcItem = srcItems[itemIndex]; + + if (srcItem._bonusFlags & ITEMFLAG_CURSED) + ErrorScroll::show(_vm, Res.CANNOT_REMOVE_CURSED_ITEM); + else if (destItems[INV_ITEMS_TOTAL - 1]._id) + ErrorScroll::show(_vm, Common::String::format( + Res.CATEGORY_BACKPACK_IS_FULL[category], c->_name.c_str())); + else { + destItem = srcItem; + srcItem.clear(); + destItem._frame = 0; + + srcItems.sort(); + destItems.sort(); + } + + continue; + } + + c = newChar; + startingChar = newChar; + intf.highlightChar(_buttonValue); + } + } + break; + + case Common::KEYCODE_1: + case Common::KEYCODE_2: + case Common::KEYCODE_3: + case Common::KEYCODE_4: + case Common::KEYCODE_5: + case Common::KEYCODE_6: + case Common::KEYCODE_7: + case Common::KEYCODE_8: + case Common::KEYCODE_9: + // Select an item + if (mode == ITEMMODE_3) + break; + + _buttonValue -= Common::KEYCODE_1; + if (_buttonValue != itemIndex) { + // Check whether the new selection has an associated item + if (!c->_items[category][_buttonValue].empty()) { + itemIndex = _buttonValue; + Common::fill(&arr[0], &arr[40], 0); + arr[itemIndex] = 15; + } + + redrawFlag = REDRAW_TEXT; + } + break; + + case Common::KEYCODE_a: + // Armor category + category = CATEGORY_ARMOR; + redrawFlag = REDRAW_FULL; + break; + + case Common::KEYCODE_b: + // Buy + if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && + mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { + mode = ITEMMODE_BLACKSMITH; + c = &_itemsCharacter; + redrawFlag = REDRAW_FULL; + } + break; + + case Common::KEYCODE_c: + // Accessories category + category = CATEGORY_ACCESSORY; + redrawFlag = REDRAW_FULL; + break; + + case Common::KEYCODE_d: + if (mode == ITEMMODE_CHAR_INFO) + actionIndex = 3; + break; + + case Common::KEYCODE_e: + if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_ENCHANT || + mode == ITEMMODE_TO_GOLD) { + if (category != CATEGORY_MISC) { + actionIndex = mode == ITEMMODE_ENCHANT ? 4 : 0; + } + } + break; + + case Common::KEYCODE_f: + if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && + mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { + mode = ITEMMODE_REPAIR; + c = startingChar; + redrawFlag = REDRAW_TEXT; + } + break; + + case Common::KEYCODE_g: + if (mode == ITEMMODE_TO_GOLD) + actionIndex = 6; + break; + + case Common::KEYCODE_i: + if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && + mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { + mode = ITEMMODE_IDENTIFY; + c = startingChar; + redrawFlag = REDRAW_TEXT; + } + break; + + case Common::KEYCODE_m: + // Misc + category = CATEGORY_MISC; + redrawFlag = REDRAW_TEXT; + break; + + case Common::KEYCODE_q: + // Quests + if (mode == ITEMMODE_CHAR_INFO) { + Quests::show(_vm); + redrawFlag = REDRAW_FULL; + } + break; + + case Common::KEYCODE_r: + if (mode == ITEMMODE_CHAR_INFO) + actionIndex = 1; + else if (mode == ITEMMODE_RECHARGE) + actionIndex = 5; + break; + + case Common::KEYCODE_s: + if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && + mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { + mode = ITEMMODE_2; + c = startingChar; + redrawFlag = REDRAW_TEXT; + } + break; + + case Common::KEYCODE_u: + if (mode == ITEMMODE_CHAR_INFO && category == CATEGORY_MISC) + actionIndex = 2; + break; + + case Common::KEYCODE_w: + // Weapons category + category = CATEGORY_WEAPON; + redrawFlag = REDRAW_TEXT; + break; + } + } + + windows[30].close(); + windows[29].close(); + + intf.drawParty(true); + if (updateStock) + charData2BlackData(); + + return c; +} + +void ItemsDialog::loadButtons(ItemsMode mode, Character *&c) { + _iconSprites.load(Common::String::format("%s.icn", + (mode == ITEMMODE_CHAR_INFO) ? "items" : "buy")); + _equipSprites.load("equip.icn"); + + if (mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE || mode == ITEMMODE_TO_GOLD) { + // Enchant button list + addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_w, &_iconSprites); + addButton(Common::Rect(46, 109, 70, 129), Common::KEYCODE_a, &_iconSprites); + addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_c, &_iconSprites); + addButton(Common::Rect(114, 109, 138, 129), Common::KEYCODE_m, &_iconSprites); + addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_e, &_iconSprites); + addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); + addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_u, &_iconSprites); + addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); + addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); + addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); + addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); + addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); + addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); + addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); + addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); + addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); + } else { + addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_w, &_iconSprites); + addButton(Common::Rect(46, 109, 70, 129), Common::KEYCODE_a, &_iconSprites); + addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_c, &_iconSprites); + addButton(Common::Rect(114, 109, 138, 129), Common::KEYCODE_m, &_iconSprites); + addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_e, &_iconSprites); + addButton(Common::Rect(182, 109, 206, 129), Common::KEYCODE_r, &_iconSprites); + addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_d, &_iconSprites); + addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_q, &_iconSprites); + addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); + addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); + addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); + addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); + addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); + addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); + addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); + addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); + addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); + addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); + addPartyButtons(_vm); + } + + if (mode == ITEMMODE_BLACKSMITH) { + _oldCharacter = c; + c = &_itemsCharacter; + blackData2CharData(); + + _buttons[4]._value = Common::KEYCODE_b; + _buttons[5]._value = Common::KEYCODE_s; + _buttons[6]._value = Common::KEYCODE_i; + _buttons[7]._value = Common::KEYCODE_f; + + setEquipmentIcons(); + } else { + _buttons[4]._value = Common::KEYCODE_e; + _buttons[5]._value = Common::KEYCODE_r; + _buttons[6]._value = Common::KEYCODE_d; + _buttons[7]._value = Common::KEYCODE_q; + } +} + +void ItemsDialog::blackData2CharData() { + Party &party = *_vm->_party; + bool isDarkCc = _vm->_files->_isDarkCc; + int slotIndex = 0; + while (slotIndex < 4 && party._mazeId != (int)Res.BLACKSMITH_MAP_IDS[isDarkCc][slotIndex]) + ++slotIndex; + if (slotIndex == 4) + slotIndex = 0; + + for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { + _itemsCharacter._weapons[idx] = party._blacksmithWeapons[isDarkCc][idx]; + _itemsCharacter._armor[idx] = party._blacksmithArmor[isDarkCc][idx]; + _itemsCharacter._accessories[idx] = party._blacksmithAccessories[isDarkCc][idx]; + _itemsCharacter._misc[idx] = party._blacksmithMisc[isDarkCc][idx]; + } +} + +void ItemsDialog::charData2BlackData() { + Party &party = *_vm->_party; + bool isDarkCc = _vm->_files->_isDarkCc; + int slotIndex = 0; + while (slotIndex < 4 && party._mazeId != (int)Res.BLACKSMITH_MAP_IDS[isDarkCc][slotIndex]) + ++slotIndex; + if (slotIndex == 4) + slotIndex = 0; + + for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { + party._blacksmithWeapons[isDarkCc][idx] = _itemsCharacter._weapons[idx]; + party._blacksmithArmor[isDarkCc][idx] = _itemsCharacter._armor[idx]; + party._blacksmithAccessories[isDarkCc][idx] = _itemsCharacter._accessories[idx]; + party._blacksmithMisc[isDarkCc][idx] = _itemsCharacter._misc[idx]; + } +} + +void ItemsDialog::setEquipmentIcons() { + for (int typeIndex = 0; typeIndex < 4; ++typeIndex) { + for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { + switch (typeIndex) { + case CATEGORY_WEAPON: { + XeenItem &i = _itemsCharacter._weapons[idx]; + if (i._id <= 17) + i._frame = 1; + else if (i._id <= 29 || i._id > 33) + i._frame = 13; + else + i._frame = 4; + break; + } + + case CATEGORY_ARMOR: { + XeenItem &i = _itemsCharacter._armor[idx]; + if (i._id <= 7) + i._frame = 3; + else if (i._id == 9) + i._frame = 5; + else if (i._id == 10) + i._frame = 9; + else if (i._id <= 12) + i._frame = 10; + else + i._frame = 6; + break; + } + + case CATEGORY_ACCESSORY: { + XeenItem &i = _itemsCharacter._accessories[idx]; + if (i._id == 1) + i._id = 8; + else if (i._id == 2) + i._frame = 12; + else if (i._id <= 7) + i._frame = 7; + else + i._frame = 11; + break; + } + + default: + break; + } + } + } +} + +int ItemsDialog::calcItemCost(Character *c, int itemIndex, ItemsMode mode, + int skillLevel, ItemCategory category) { + int amount1 = 0, amount2 = 0, amount3 = 0, amount4 = 0; + int result = 0; + int level = skillLevel & 0x7f; + + InventoryItems *invGroups[4] = { + &c->_weapons, &c->_armor, &c->_accessories, &c->_misc + }; + const int *BASE_COSTS[4] = { + Res.WEAPON_BASE_COSTS, Res.ARMOR_BASE_COSTS, Res.ACCESSORY_BASE_COSTS, Res.MISC_BASE_COSTS + }; + + switch (mode) { + case ITEMMODE_BLACKSMITH: + level = 0; + break; + case ITEMMODE_2: + case ITEMMODE_TO_GOLD: + level = level == 0 ? 1 : 0; + break; + case ITEMMODE_IDENTIFY: + level = 2; + break; + case ITEMMODE_REPAIR: + level = 3; + break; + default: + break; + } + + switch (category) { + case CATEGORY_WEAPON: + case CATEGORY_ARMOR: + case CATEGORY_ACCESSORY: { + XeenItem &i = (*invGroups[category])[itemIndex]; + amount1 = (BASE_COSTS[category])[i._id]; + + if (i._material > 36 && i._material < 59) { + switch (i._material) { + case 37: + amount1 /= 10; + break; + case 38: + amount1 /= 4; + break; + case 39: + amount1 /= 2; + break; + case 40: + amount1 /= 4; + break; + default: + amount1 *= Res.METAL_BASE_MULTIPLIERS[i._material - 37]; + break; + } + } + + if (i._material < 37) + amount2 = Res.ELEMENTAL_DAMAGE[i._material] * 100; + else if (i._material > 58) + amount3 = Res.ELEMENTAL_DAMAGE[i._material - 59 + 7] * 100; + + switch (mode) { + case ITEMMODE_BLACKSMITH: + case ITEMMODE_2: + case ITEMMODE_REPAIR: + case ITEMMODE_IDENTIFY: + case ITEMMODE_TO_GOLD: + result = (amount1 + amount2 + amount3 + amount4) / Res.ITEM_SKILL_DIVISORS[level]; + if (!result) + result = 1; + break; + default: + break; + } + break; + } + + case CATEGORY_MISC: { + // Misc + XeenItem &i = c->_misc[itemIndex]; + amount1 = Res.MISC_MATERIAL_COSTS[i._material]; + amount4 = Res.MISC_BASE_COSTS[i._id]; + + switch (mode) { + case ITEMMODE_BLACKSMITH: + case ITEMMODE_2: + case ITEMMODE_REPAIR: + case ITEMMODE_IDENTIFY: + case ITEMMODE_TO_GOLD: + result = (amount1 + amount2 + amount3 + amount4) / Res.ITEM_SKILL_DIVISORS[level]; + if (!result) + result = 1; + break; + default: + break; + } + break; + } + + default: + break; + } + + return (mode == ITEMMODE_CHAR_INFO) ? 0 : result; +} + +int ItemsDialog::doItemOptions(Character &c, int actionIndex, int itemIndex, ItemCategory category, + ItemsMode mode) { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Sound &sound = *_vm->_sound; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + bool isDarkCc = _vm->_files->_isDarkCc; + + XeenItem *itemCategories[4] = { &c._weapons[0], &c._armor[0], &c._accessories[0], &c._misc[0] }; + XeenItem *items = itemCategories[category]; + if (!items[0]._id) + // Inventory is empty + return category == CATEGORY_MISC ? 0 : 2; + + Window &w = windows[11]; + SpriteResource escSprites; + if (itemIndex < 0 || itemIndex > 8) { + saveButtons(); + + escSprites.load("esc.icn"); + addButton(Common::Rect(235, 111, 259, 131), Common::KEYCODE_ESCAPE, &escSprites); + addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); + addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); + addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); + addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); + addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); + addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); + addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); + addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); + addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); + + w.open(); + w.writeString(Common::String::format(Res.WHICH_ITEM, Res.ITEM_ACTIONS[actionIndex])); + _iconSprites.draw(0, 0, Common::Point(235, 111)); + w.update(); + + while (!_vm->shouldExit()) { + while (!_buttonValue) { + events.pollEventsAndWait(); + checkEvents(_vm); + if (_vm->shouldExit()) + return false; + } + + if (_buttonValue == Common::KEYCODE_ESCAPE) { + itemIndex = -1; + break; + } else if (_buttonValue >= Common::KEYCODE_1 && _buttonValue <= Common::KEYCODE_9) { + // Check whether there's an item at the selected index + int selectedIndex = _buttonValue - Common::KEYCODE_1; + if (!items[selectedIndex]._id) + continue; + + itemIndex = selectedIndex; + break; + } + } + + w.close(); + restoreButtons(); + } + + if (itemIndex != -1) { + XeenItem &item = c._items[category][itemIndex]; + + switch (mode) { + case ITEMMODE_CHAR_INFO: + case ITEMMODE_8: + switch (actionIndex) { + case 0: + c._items[category].equipItem(itemIndex); + break; + case 1: + c._items[category].removeItem(itemIndex); + break; + case 2: + if (!party._mazeId) { + ErrorScroll::show(_vm, Res.WHATS_YOUR_HURRY); + } else { + XeenItem &i = c._misc[itemIndex]; + + Condition condition = c.worstCondition(); + switch (condition) { + case ASLEEP: + case PARALYZED: + case UNCONSCIOUS: + case DEAD: + case STONED: + case ERADICATED: + ErrorScroll::show(_vm, Common::String::format(Res.IN_NO_CONDITION, c._name.c_str())); + break; + default: + if (combat._itemFlag) { + ErrorScroll::show(_vm, Res.USE_ITEM_IN_COMBAT); + } else if (i._id && (i._bonusFlags & ITEMFLAG_BONUS_MASK) + && !(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED))) { + int charges = (i._bonusFlags & ITEMFLAG_BONUS_MASK) - 1; + i._bonusFlags = charges; + _oldCharacter = &c; + + windows[30].close(); + windows[29].close(); + windows[24].close(); + spells.castItemSpell(i._id); + + if (!charges) { + // Ran out of charges, so make item disappear + c._items[category][itemIndex].clear(); + c._items[category].sort(); + } + } else { + ErrorScroll::show(_vm, Common::String::format(Res.NO_SPECIAL_ABILITIES, + c._items[category].getFullDescription(itemIndex).c_str() + )); + } + } + } + break; + case 3: + c._items[category].discardItem(itemIndex); + break; + default: + break; + } + break; + + case ITEMMODE_BLACKSMITH: { + InventoryItems &invItems = _oldCharacter->_items[category]; + if (invItems[INV_ITEMS_TOTAL - 1]._id) { + // If the last slot is in use, it means the list is full + ErrorScroll::show(_vm, Common::String::format(Res.BACKPACK_IS_FULL, + _oldCharacter->_name.c_str())); + } else { + int cost = calcItemCost(_oldCharacter, itemIndex, mode, 0, category); + Common::String desc = c._items[category].getFullDescription(itemIndex); + if (Confirm::show(_vm, Common::String::format(Res.BUY_X_FOR_Y_GOLD, + desc.c_str(), cost))) { + if (party.subtract(CONS_GOLD, cost, WHERE_PARTY, WT_FREEZE_WAIT)) { + if (isDarkCc) { + sound.stopSound(); + sound.playSound("choice2.voc"); + } + + // Add entry to the end of the list + _oldCharacter->_items[category][8] = c._items[category][itemIndex]; + _oldCharacter->_items[category][8]._frame = 0; + c._items[category].clear(); + c._items[category].sort(); + _oldCharacter->_items[category].sort(); + } + } + } + return 0; + } + + case ITEMMODE_2: { + bool noNeed; + switch (category) { + case CATEGORY_WEAPON: + noNeed = (item._bonusFlags & ITEMFLAG_CURSED) || item._id == 34; + break; + default: + noNeed = item._bonusFlags & ITEMFLAG_CURSED; + break; + } + + if (noNeed) { + ErrorScroll::show(_vm, Common::String::format(Res.NO_NEED_OF_THIS, + c._items[category].getFullDescription(itemIndex).c_str())); + } else { + int cost = calcItemCost(&c, itemIndex, mode, c._skills[MERCHANT], category); + Common::String desc = c._items[category].getFullDescription(itemIndex); + Common::String msg = Common::String::format(Res.SELL_X_FOR_Y_GOLD, + desc.c_str(), cost); + + if (Confirm::show(_vm, msg)) { + // Remove the sold item and add gold to the party's total + item.clear(); + c._items[category].sort(); + + party._gold += cost; + } + } + return 0; + } + + case ITEMMODE_RECHARGE: + if (category != CATEGORY_MISC || c._misc[itemIndex]._material > 9 + || c._misc[itemIndex]._id == 53 || c._misc[itemIndex]._id == 0) { + sound.playFX(21); + ErrorScroll::show(_vm, Common::String::format(Res.NOT_RECHARGABLE, Res.SPELL_FAILED)); + } else { + int charges = MIN(63, _vm->getRandomNumber(1, 6) + + (c._misc[itemIndex]._bonusFlags & ITEMFLAG_BONUS_MASK)); + sound.playFX(20); + + c._misc[itemIndex]._bonusFlags = (c._misc[itemIndex]._bonusFlags + & ~ITEMFLAG_BONUS_MASK) | charges; + } + return 2; + + case ITEMMODE_ENCHANT: { + int amount = _vm->getRandomNumber(1, _oldCharacter->getCurrentLevel() / 5 + 1); + amount = MIN(amount, 5); + _oldCharacter->_items[category].enchantItem(itemIndex, amount); + break; + } + + case ITEMMODE_REPAIR: + if (!(item._bonusFlags & ITEMFLAG_BROKEN)) { + ErrorScroll::show(_vm, Res.ITEM_NOT_BROKEN); + } else { + int cost = calcItemCost(&c, itemIndex, mode, actionIndex, category); + Common::String msg = Common::String::format(Res.FIX_IDENTIFY_GOLD, + Res.FIX_IDENTIFY[0], + c._items[category].getFullDescription(itemIndex).c_str(), + cost); + + if (Confirm::show(_vm, msg) && party.subtract(CONS_GOLD, cost, WHERE_PARTY)) { + item._bonusFlags &= ~ITEMFLAG_BROKEN; + } + } + break; + + case ITEMMODE_IDENTIFY: { + int cost = calcItemCost(&c, itemIndex, mode, actionIndex, category); + Common::String msg = Common::String::format(Res.FIX_IDENTIFY_GOLD, + Res.FIX_IDENTIFY[1], + c._items[category].getFullDescription(itemIndex).c_str(), + cost); + + if (Confirm::show(_vm, msg) && party.subtract(CONS_GOLD, cost, WHERE_PARTY)) { + Common::String details = c._items[category].getIdentifiedDetails(itemIndex); + Common::String desc = c._items[category].getFullDescription(itemIndex); + Common::String str = Common::String::format(Res.IDENTIFY_ITEM_MSG, + desc.c_str(), details.c_str()); + + Window &win = windows[14]; + win.open(); + win.writeString(str); + win.update(); + + saveButtons(); + clearButtons(); + + while (!_vm->shouldExit() && !events.isKeyMousePressed()) + events.pollEventsAndWait(); + events.clearEvents(); + + restoreButtons(); + win.close(); + } + break; + } + + case ITEMMODE_TO_GOLD: + // Convert item in inventory to gold + itemToGold(c, itemIndex, category, mode); + return 2; + + default: + break; + } + } + + intf._charsShooting = false; + combat.moveMonsters(); + combat._whosTurn = -1; + return true; +} + +void ItemsDialog::itemToGold(Character &c, int itemIndex, ItemCategory category, + ItemsMode mode) { + XeenItem &item = c._items[category][itemIndex]; + Party &party = *_vm->_party; + Sound &sound = *_vm->_sound; + + if (category == CATEGORY_WEAPON && item._id == 34) { + sound.playFX(21); + ErrorScroll::show(_vm, Common::String::format("\v012\t000\x03""c%s", + Res.SPELL_FAILED)); + } else if (item._id != 0) { + // There is a valid item present + // Calculate cost of item and add it to the party's total + int cost = calcItemCost(&c, itemIndex, mode, 1, category); + party._gold += cost; + + // Remove the item from the inventory + item.clear(); + c._items[category].sort(); + } +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_items.h b/engines/xeen/dialogs/dialogs_items.h new file mode 100644 index 0000000000..b9af06eb74 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_items.h @@ -0,0 +1,89 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_ITEMS_H +#define XEEN_DIALOGS_ITEMS_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" +#include "xeen/window.h" + +namespace Xeen { + +enum ItemsMode { + ITEMMODE_CHAR_INFO = 0, ITEMMODE_BLACKSMITH = 1, ITEMMODE_2 = 2, ITEMMODE_3 = 3, + ITEMMODE_RECHARGE = 4, ITEMMODE_5 = 5, ITEMMODE_ENCHANT = 6, ITEMMODE_COMBAT = 7, ITEMMODE_8 = 8, + ITEMMODE_REPAIR = 9, ITEMMODE_IDENTIFY = 10, ITEMMODE_TO_GOLD = 11 +}; + +class ItemsDialog : public ButtonContainer { +private: + SpriteResource _iconSprites; + SpriteResource _equipSprites; + Character _itemsCharacter; + Character *_oldCharacter; + DrawStruct _itemsDrawList[INV_ITEMS_TOTAL]; + + ItemsDialog(XeenEngine *vm) : ButtonContainer(vm), _oldCharacter(nullptr) {} + + Character *execute(Character *c, ItemsMode mode); + + /** + * Load the buttons for the dialog + */ + void loadButtons(ItemsMode mode, Character *&c); + + /** + * Loads the temporary _itemsCharacter character with the item set + * the given blacksmith has available, so the user can "view" the + * set as if it were a standard character's inventory + */ + void blackData2CharData(); + + /** + * Saves the inventory from the temporary _itemsCharacter character back into the + * blacksmith storage, so changes in blacksmith inventory remain persistent + */ + void charData2BlackData(); + + /** + * Sets the equipment icon to use for each item for display + */ + void setEquipmentIcons(); + + /** + * Calculate the cost of an item + */ + int calcItemCost(Character *c, int itemIndex, ItemsMode mode, int skillLevel, + ItemCategory category); + + int doItemOptions(Character &c, int actionIndex, int itemIndex, + ItemCategory category, ItemsMode mode); + + void itemToGold(Character &c, int itemIndex, ItemCategory category, ItemsMode mode); +public: + static Character *show(XeenEngine *vm, Character *c, ItemsMode mode); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_ITEMS_H */ diff --git a/engines/xeen/dialogs/dialogs_map.cpp b/engines/xeen/dialogs/dialogs_map.cpp new file mode 100644 index 0000000000..b822c71472 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_map.cpp @@ -0,0 +1,461 @@ +/* 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/dialogs_map.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +#define MAP_SIZE 16 +#define MAP_DIFF (MAP_SIZE / 2) +#define MAP_XSTART 80 +#define MAP_YSTART 38 +#define TILE_WIDTH 10 +#define TILE_HEIGHT 8 + +void MapDialog::show(XeenEngine *vm) { + MapDialog *dlg = new MapDialog(vm); + dlg->execute(); + delete dlg; +} + +void MapDialog::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + + _pt = party._mazePosition; + _globalSprites.load("global.icn"); + + if (_pt.x < 8 && map.mazeData()._surroundingMazes._west == 0) { + _arrowPt.x = _pt.x * 10 + 4; + _pt.x = 7; + } else if (_pt.x > 23) { + _arrowPt.x = (byte)(_pt.x * 10 + 100); + _pt.x = 23; + } else if (_pt.x > 8 && map.mazeData()._surroundingMazes._east == 0) { + _arrowPt.x = (byte)(_pt.x * 10 + 4); + _pt.x = 7; + } else { + _arrowPt.x = 74; + } + + if (_pt.y < 8 && map.mazeData()._surroundingMazes._south == 0) { + _arrowPt.y = ((15 - _pt.y) << 3) + 13; + _pt.y = 8; + } else if (_pt.y > 24) { + _arrowPt.y = ((15 - (_pt.y - 16)) << 3) + 13; + _pt.y = 24; + } else if (_pt.y >= 8 && map.mazeData()._surroundingMazes._north == 0) { + _arrowPt.y = ((15 - _pt.y) << 3) + 13; + _pt.y = 8; + } else { + _arrowPt.y = 69; + } + + windows[5].open(); + bool drawFlag = true; + + events.updateGameCounter(); + do { + if (drawFlag) + intf.draw3d(false, false); + windows[5].writeString("\r"); + + if (map._isOutdoors) + drawOutdoors(); + else + drawIndoors(); + + windows[5].frame(); + if (!map._isOutdoors) { + map._tileSprites.draw(0, 52, Common::Point(76, 30)); + } else if (_frameEndFlag) { + _globalSprites.draw(0, party._mazeDirection + 1, + Common::Point(_arrowPt.x + 76, _arrowPt.y + 25)); + } + + if (events.timeElapsed() > 5) { + // Set the flag to make the basic arrow blinking effect + _frameEndFlag = !_frameEndFlag; + events.updateGameCounter(); + } + + windows[5].writeString(Common::String::format(Res.MAP_TEXT, + map._mazeName.c_str(), party._mazePosition.x, + party._mazePosition.y, Res.DIRECTION_TEXT[party._mazeDirection])); + windows[5].update(); + windows[3].update(); + + events.ipause5(2); + drawFlag = false; + } while (!_vm->shouldExit() && !events.isKeyMousePressed()); + + events.clearEvents(); + windows[5].close(); +} + +void MapDialog::drawOutdoors() { + Map &map = *g_vm->_map; + int v, frame; + + // Draw outdoors map + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); + assert(v != INVALID_CELL); + frame = map.mazeDataCurrent()._surfaceTypes[v]; + + if (map._currentSteppedOn) { + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + } + } + } + + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 4); + assert(v != INVALID_CELL); + frame = map.mazeDataCurrent()._wallTypes[v]; + + if (frame && map._currentSteppedOn) + map._tileSprites.draw(0, frame + 16, Common::Point(xp, yp)); + } + } + + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + --mazeY, yp += TILE_HEIGHT) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + frame = map.mazeLookup(Common::Point(mazeX, mazeY), 8, 0xff); + + if (frame && map._currentSteppedOn) + map._tileSprites.draw(0, frame + 32, Common::Point(xp, yp)); + } + } +} + +void MapDialog::drawIndoors() { + Map &map = *g_vm->_map; + Party &party = *g_vm->_party; + int v, frame; + int frame2 = _animFrame; + _animFrame = (_animFrame + 2) % 8; + + // Draw indoors map + frame2 = (frame2 + 2) % 8; + + // Draw default ground for all the valid explored areas + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSteppedOn) + map._tileSprites.draw(0, 0, Common::Point(xp, yp)); + } + } + + // Draw thinner ground tiles on the left edge of the map + for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(75, yp)); + } + + // Draw thin tile portion on top-left corner of map + v = map.mazeLookup(Common::Point(_pt.x - 8, _pt.y + 8), 0, 0xffff); + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(75, 35)); + + // Draw any thin tiles at the very top of the map + for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(xp, 35)); + } + + // Draw the default ground tiles + for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v != INVALID_CELL && map._currentSurfaceId && map._currentSteppedOn) + map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ + map._currentSurfaceId], Common::Point(xp, yp)); + } + } + + // Draw walls on left and top edges of map + for (int xp = MAP_XSTART, yp = MAP_YSTART + (MAP_SIZE - 1) * TILE_HEIGHT, + mazeX = _pt.x - (MAP_DIFF - 1), mazeY = _pt.y - MAP_DIFF; + mazeX < (_pt.x + MAP_DIFF); xp += TILE_WIDTH, yp -= TILE_HEIGHT, ++mazeX, ++mazeY) { + // Draw walls on left edge of map + v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 12); + + switch (v) { + case SURFTYPE_DIRT: + frame = 18; + break; + case SURFTYPE_SNOW: + frame = 22; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_CLOUD: + frame = 16; + break; + case SURFTYPE_LAVA: + case SURFTYPE_DWATER: + frame = 2; + break; + case SURFTYPE_DESERT: + frame = 30; + break; + case SURFTYPE_ROAD: + frame = 32; + break; + case SURFTYPE_TFLR: + frame = 20; + break; + case SURFTYPE_SKY: + frame = 28; + break; + case SURFTYPE_CROAD: + frame = 14; + break; + case SURFTYPE_SEWER: + frame = frame2 + 4; + break; + case SURFTYPE_SCORCH: + frame = 24; + break; + case SURFTYPE_SPACE: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(70, yp)); + + // Draw walls on top edge of map + v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0); + + switch (v) { + case SURFTYPE_DIRT: + frame = 19; + break; + case SURFTYPE_GRASS: + frame = 35; + break; + case SURFTYPE_SNOW: + frame = 23; + break; + case SURFTYPE_SWAMP: + case SURFTYPE_CLOUD: + frame = 17; + break; + case SURFTYPE_LAVA: + case SURFTYPE_DWATER: + frame = 3; + break; + case SURFTYPE_DESERT: + frame = 31; + break; + case SURFTYPE_ROAD: + frame = 33; + break; + case SURFTYPE_TFLR: + frame = 21; + break; + case SURFTYPE_SKY: + frame = 29; + break; + case SURFTYPE_CROAD: + frame = 15; + break; + case SURFTYPE_SEWER: + frame = frame2 + 5; + break; + case SURFTYPE_SCORCH: + frame = 25; + break; + case SURFTYPE_SPACE: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(xp, 30)); + } + + // Draw the walls for the remaining cells of the minimap + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1, yCtr = 0; yCtr < MAP_SIZE; + yp += TILE_HEIGHT, --mazeY, ++yCtr) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1), xCtr = 0; xCtr < MAP_SIZE; + xp += TILE_WIDTH, ++mazeX, ++xCtr) { + // Draw the arrow if at the correct position + if ((_arrowPt.x / 10) == xCtr && (14 - (_arrowPt.y / 10)) == yCtr && _frameEndFlag) { + _globalSprites.draw(0, party._mazeDirection + 1, + Common::Point(_arrowPt.x + 81, _arrowPt.y + 29)); + } + + v = map.mazeLookup(Common::Point(mazeX, mazeY), 12); + switch (v) { + case 1: + frame = 18; + break; + case 2: + frame = 34; + break; + case 3: + frame = 22; + break; + case 4: + case 13: + frame = 16; + break; + case 5: + case 8: + frame = 2; + break; + case 6: + frame = 30; + break; + case 7: + frame = 32; + break; + case 9: + frame = 20; + break; + case 10: + frame = 28; + break; + case 11: + frame = 14; + break; + case 12: + frame = frame2 + 4; + break; + case 14: + frame = 24; + break; + case 15: + frame = 26; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); + switch (v) { + case 1: + frame = 19; + break; + case 2: + frame = 35; + break; + case 3: + frame = 23; + break; + case 4: + case 13: + frame = 17; + break; + case 5: + case 8: + frame = 3; + break; + case 6: + frame = 31; + break; + case 7: + frame = 33; + break; + case 9: + frame = 21; + break; + case 10: + frame = 29; + break; + case 11: + frame = 15; + break; + case 12: + frame = frame2 + 5; + break; + case 14: + frame = 25; + break; + case 15: + frame = 27; + break; + default: + frame = -1; + break; + } + + if (frame != -1 && map._currentSteppedOn) + map._tileSprites.draw(0, frame, Common::Point(xp, yp)); + } + } + + // Draw overlay on cells that haven't been stepped on yet + for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); + yp += TILE_HEIGHT, --mazeY) { + for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); + xp += TILE_WIDTH, ++mazeX) { + v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); + + if (v == INVALID_CELL || !map._currentSteppedOn) + map._tileSprites.draw(0, 1, Common::Point(xp, yp)); + } + } +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_map.h b/engines/xeen/dialogs/dialogs_map.h new file mode 100644 index 0000000000..5e22e5268d --- /dev/null +++ b/engines/xeen/dialogs/dialogs_map.h @@ -0,0 +1,62 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_MAP_H +#define XEEN_DIALOGS_MAP_H + +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class XeenEngine; + +class MapDialog: public ButtonContainer { +private: + int _animFrame; + SpriteResource _globalSprites; + Common::Point _pt, _arrowPt; + bool _frameEndFlag; +private: + MapDialog(XeenEngine *vm) : ButtonContainer(vm), + _animFrame(0), _frameEndFlag(false) {} + + /** + * Draws the map contents when outdoors + */ + void drawOutdoors(); + + /** + * Draws the map contents when indoors + */ + void drawIndoors(); + + /** + * Handles the display of the dialog + */ + void execute(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_AUTOMAP_H */ diff --git a/engines/xeen/dialogs/dialogs_message.cpp b/engines/xeen/dialogs/dialogs_message.cpp new file mode 100644 index 0000000000..df8afea34c --- /dev/null +++ b/engines/xeen/dialogs/dialogs_message.cpp @@ -0,0 +1,123 @@ +/* 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 "common/scummsys.h" +#include "xeen/dialogs/dialogs_message.h" +#include "xeen/events.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void MessageDialog::show(XeenEngine *vm, const Common::String &msg, MessageWaitType waitType) { + MessageDialog *dlg = new MessageDialog(vm); + dlg->execute(msg, waitType); + delete dlg; +} + +void MessageDialog::execute(const Common::String &msg, MessageWaitType waitType) { + EventsManager &events = *_vm->_events; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + + w.open(); + w.writeString(msg); + w.update(); + + switch (waitType) { + case WT_FREEZE_WAIT: + while (!_vm->shouldExit() && !events.isKeyMousePressed()) + events.pollEventsAndWait(); + + events.clearEvents(); + break; + + case WT_ANIMATED_WAIT: + if (windows[11]._enabled || _vm->_mode == MODE_17) { + g_vm->_locations->wait(); + break; + } + // fall through + + case WT_NONFREEZED_WAIT: + do { + events.updateGameCounter(); + _vm->_interface->draw3d(true); + + events.wait(1); + if (checkEvents(_vm)) + break; + } while (!_vm->shouldExit() && !_buttonValue); + break; + + case WT_LOC_WAIT: + g_vm->_locations->wait(); + break; + + default: + break; + } + + w.close(); +} + +/*------------------------------------------------------------------------*/ + +void ErrorScroll::show(XeenEngine *vm, const Common::String &msg, MessageWaitType waitType) { + Common::String s = Common::String::format("\x3""c\v010\t000%s", msg.c_str()); + MessageDialog::show(vm, s, waitType); +} + +/*------------------------------------------------------------------------*/ + +void CantCast::show(XeenEngine *vm, int spellId, int componentNum) { + CantCast *dlg = new CantCast(vm); + dlg->execute(spellId, componentNum); + delete dlg; +} + +void CantCast::execute(int spellId, int componentNum) { + EventsManager &events = *_vm->_events; + Sound &sound = *_vm->_sound; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_FF; + + sound.playFX(21); + w.open(); + w.writeString(Common::String::format(Res.NOT_ENOUGH_TO_CAST, + Res.SPELL_CAST_COMPONENTS[componentNum - 1], + spells._spellNames[spellId].c_str() + )); + w.update(); + + do { + events.pollEventsAndWait(); + } while (!_vm->shouldExit() && !events.isKeyMousePressed()); + events.clearEvents(); + + w.close(); + _vm->_mode = oldMode; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_message.h b/engines/xeen/dialogs/dialogs_message.h new file mode 100644 index 0000000000..95d942858c --- /dev/null +++ b/engines/xeen/dialogs/dialogs_message.h @@ -0,0 +1,61 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_dialogs_message_H +#define XEEN_dialogs_message_H + +#include "xeen/dialogs/dialogs.h" +#include "xeen/character.h" + +namespace Xeen { + +enum MessageWaitType { WT_FREEZE_WAIT = 0, WT_NONFREEZED_WAIT = 1, + WT_LOC_WAIT = 2, WT_ANIMATED_WAIT = 3 }; + +class MessageDialog : public ButtonContainer { +private: + MessageDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(const Common::String &msg, MessageWaitType waitType); +public: + static void show(XeenEngine *vm, const Common::String &msg, + MessageWaitType waitType = WT_FREEZE_WAIT); +}; + +class ErrorScroll { +public: + static void show(XeenEngine *vm, const Common::String &msg, + MessageWaitType waitType = WT_FREEZE_WAIT); +}; + +class CantCast: public ButtonContainer { +private: + CantCast(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(int spellId, int componentNum); +public: + static void show(XeenEngine *vm, int spellId, int componentNum); +}; + +} // End of namespace Xeen + +#endif /* XEEN_dialogs_message_H */ diff --git a/engines/xeen/dialogs/dialogs_party.cpp b/engines/xeen/dialogs/dialogs_party.cpp new file mode 100644 index 0000000000..33e138b6ac --- /dev/null +++ b/engines/xeen/dialogs/dialogs_party.cpp @@ -0,0 +1,451 @@ +/* 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/dialogs_char_info.h" +#include "xeen/dialogs/dialogs_create_char.h" +#include "xeen/dialogs/dialogs_party.h" +#include "xeen/dialogs/dialogs_input.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/character.h" +#include "xeen/events.h" +#include "xeen/party.h" +#include "xeen/xeen.h" + +namespace Xeen { + +PartyDialog::PartyDialog(XeenEngine *vm) : ButtonContainer(vm), + PartyDrawer(vm), _vm(vm) { + initDrawStructs(); +} + +void PartyDialog::show(XeenEngine *vm) { + PartyDialog *dlg = new PartyDialog(vm); + dlg->execute(); + delete dlg; +} + +void PartyDialog::execute() { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Screen &screen = *_vm->_screen; + Sound &sound = *_vm->_sound; + Windows &windows = *_vm->_windows; + bool modeFlag = false; + int startingChar = 0; + + loadButtons(); + setupBackground(); + + while (!_vm->shouldExit()) { + _vm->_mode = MODE_1; + + // Build up a list of available characters in the Roster that are on the + // same side of Xeen as the player is currently on + _charList.clear(); + for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) { + Character &player = party._roster[i]; + if (player._name.empty() || player._xeenSide != (map._loadDarkSide ? 1 : 0)) + continue; + + _charList.push_back(i); + } + + Window &w = windows[11]; + w.open(); + setupFaces(startingChar, false); + w.writeString(Common::String::format(Res.PARTY_DIALOG_TEXT, _partyDetails.c_str())); + w.drawList(&_faceDrawStructs[0], 4); + + _uiSprites.draw(w, 0, Common::Point(16, 100)); + _uiSprites.draw(w, 2, Common::Point(52, 100)); + _uiSprites.draw(w, 4, Common::Point(87, 100)); + _uiSprites.draw(w, 6, Common::Point(122, 100)); + _uiSprites.draw(w, 8, Common::Point(157, 100)); + _uiSprites.draw(w, 10, Common::Point(192, 100)); + if (g_vm->getGameID() == GType_Swords) + Res._logoSprites.draw(1, 0, Common::Point(232, 9)); + + screen.loadPalette("mm4.pal"); + + if (modeFlag) { + windows[0].update(); + events.setCursor(0); + screen.fadeIn(); + } else { + if (_vm->getGameID() == GType_DarkSide) { + screen.fadeOut(); + windows[0].update(); + } + + doScroll(false, false); + events.setCursor(0); + + if (_vm->getGameID() == GType_DarkSide) { + screen.fadeIn(); + } + } + + bool breakFlag = false; + while (!_vm->shouldExit() && !breakFlag) { + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_vm->shouldExit() && !_buttonValue); + + switch (_buttonValue) { + case Common::KEYCODE_ESCAPE: + case Common::KEYCODE_SPACE: + case Common::KEYCODE_e: + case Common::KEYCODE_x: + if (party._activeParty.size() == 0) { + ErrorScroll::show(_vm, Res.NO_ONE_TO_ADVENTURE_WITH); + } else { + if (_vm->_mode != MODE_0) { + for (int idx = OBSCURITY_NONE; idx >= OBSCURITY_BLACK; --idx) { + events.updateGameCounter(); + intf.obscureScene((Obscurity)idx); + w.update(); + + while (events.timeElapsed() < 1) + events.pollEventsAndWait(); + } + } + + w.close(); + party._mazeId = party._priorMazeId; + + party.copyPartyToRoster(); + //_vm->_saves->writeCharFile(); + return; + } + break; + + case Common::KEYCODE_F1: + case Common::KEYCODE_F2: + case Common::KEYCODE_F3: + case Common::KEYCODE_F4: + case Common::KEYCODE_F5: + case Common::KEYCODE_F6: + // Show character info + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)party._activeParty.size()) + CharacterInfo::show(_vm, _buttonValue); + break; + + case Common::KEYCODE_1: + case Common::KEYCODE_2: + case Common::KEYCODE_3: + case Common::KEYCODE_4: + _buttonValue -= Common::KEYCODE_1 - 7; + if ((_buttonValue - 7 + startingChar) < (int)_charList.size()) { + // Check if the selected character is already in the party + uint idx = 0; + for (; idx < party._activeParty.size(); ++idx) { + if (_charList[_buttonValue - 7 + startingChar] == + party._activeParty[idx]._rosterId) + break; + } + + // Only add the character if they're not already in the party + if (idx == party._activeParty.size()) { + if (party._activeParty.size() == MAX_ACTIVE_PARTY) { + sound.playFX(21); + ErrorScroll::show(_vm, Res.YOUR_PARTY_IS_FULL); + } else { + // Add the character to the active party + party._activeParty.push_back(party._roster[ + _charList[_buttonValue - 7 + startingChar]]); + startingCharChanged(startingChar); + } + } + } + break; + + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + // Up arrow + if (startingChar > 0) { + startingChar -= 4; + startingCharChanged(startingChar); + } + break; + + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + // Down arrow + if (startingChar < ((int)_charList.size() - 4)) { + startingChar += 4; + startingCharChanged(startingChar); + } + break; + + case Common::KEYCODE_c: + // Create + if (_charList.size() == XEEN_TOTAL_CHARACTERS) { + ErrorScroll::show(_vm, Res.YOUR_ROSTER_IS_FULL); + } else { + screen.fadeOut(); + w.close(); + + // Show the create character dialog + CreateCharacterDialog::show(_vm); + + party.copyPartyToRoster(); + //_vm->_saves->writeCharFile(); + screen.fadeOut(); + modeFlag = true; + breakFlag = true; + } + break; + + case Common::KEYCODE_d: + // Delete character + if (_charList.size() > 0) { + int charButtonValue = selectCharacter(true, startingChar); + if (charButtonValue != 0) { + int charIndex = charButtonValue - Common::KEYCODE_1 + startingChar; + Character &c = party._roster[_charList[charIndex]]; + if (c.hasSlayerSword()) { + ErrorScroll::show(_vm, Res.HAS_SLAYER_SWORD); + } else { + Common::String msg = Common::String::format(Res.SURE_TO_DELETE_CHAR, + c._name.c_str(), Res.CLASS_NAMES[c._class]); + if (Confirm::show(_vm, msg)) { + // If the character is in the party, remove it + for (uint idx = 0; idx < party._activeParty.size(); ++idx) { + if (party._activeParty[idx]._rosterId == c._rosterId) { + party._activeParty.remove_at(idx); + break; + } + } + + // Empty the character in the roster + c.clear(); + + // Rebuild the character list + _charList.clear(); + for (int idx = 0; idx < XEEN_TOTAL_CHARACTERS; ++idx) { + Character &ch = party._roster[idx]; + if (!ch._name.empty() && ch._savedMazeId == party._priorMazeId) { + _charList.push_back(idx); + } + } + + startingCharChanged(startingChar); + } + } + } + } + break; + + case Common::KEYCODE_r: + // Remove character + if (party._activeParty.size() > 0) { + int charButtonValue = selectCharacter(false, startingChar); + if (charButtonValue != 0) { + party.copyPartyToRoster(); + party._activeParty.remove_at(charButtonValue - Common::KEYCODE_F1); + } + startingCharChanged(startingChar); + } + break; + + default: + break; + } + } + } +} + +void PartyDialog::loadButtons() { + _uiSprites.load("inn.icn"); + addButton(Common::Rect(16, 100, 40, 120), Common::KEYCODE_UP, &_uiSprites); + addButton(Common::Rect(52, 100, 76, 120), Common::KEYCODE_DOWN, &_uiSprites); + addButton(Common::Rect(87, 100, 111, 120), Common::KEYCODE_d, &_uiSprites); + addButton(Common::Rect(122, 100, 146, 120), Common::KEYCODE_r, &_uiSprites); + addButton(Common::Rect(157, 100, 181, 120), Common::KEYCODE_c, &_uiSprites); + addButton(Common::Rect(192, 100, 216, 120), Common::KEYCODE_x, &_uiSprites); + addButton(Common::Rect(0, 0, 0, 0), Common::KEYCODE_ESCAPE); +} + +void PartyDialog::initDrawStructs() { + _faceDrawStructs[0] = DrawStruct(0, 0, 0); + _faceDrawStructs[1] = DrawStruct(0, 101, 0); + _faceDrawStructs[2] = DrawStruct(0, 0, 43); + _faceDrawStructs[3] = DrawStruct(0, 101, 43); +} + +void PartyDialog::setupBackground() { + _vm->_screen->loadBackground("back.raw"); + _vm->_interface->assembleBorder(); +} + +void PartyDialog::setupFaces(int firstDisplayChar, bool updateFlag) { + Party &party = *_vm->_party; + Common::String charNames[4]; + Common::String charRaces[4]; + Common::String charSex[4]; + Common::String charClasses[4]; + int posIndex; + int charId; + + // Reset the button areas for the display character images + while (_buttons.size() > 7) + _buttons.remove_at(7); + addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); + addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); + addButton(Common::Rect(59, 59, 91, 91), Common::KEYCODE_3); + addButton(Common::Rect(117, 59, 151, 91), Common::KEYCODE_4); + + + for (posIndex = 0; posIndex < 4; ++posIndex) { + charId = (firstDisplayChar + posIndex) >= (int)_charList.size() ? -1 : + _charList[firstDisplayChar + posIndex]; + bool isInParty = party.isInParty(charId); + + if (charId == -1) { + while ((int)_buttons.size() >(7 + posIndex)) + _buttons.remove_at(_buttons.size() - 1); + break; + } + + Common::Rect &b = _buttons[7 + posIndex]._bounds; + b.moveTo((posIndex & 1) ? 117 : 16, b.top); + Character &ps = party._roster[_charList[firstDisplayChar + posIndex]]; + charNames[posIndex] = isInParty ? Res.IN_PARTY : ps._name; + charRaces[posIndex] = Res.RACE_NAMES[ps._race]; + charSex[posIndex] = Res.SEX_NAMES[ps._sex]; + charClasses[posIndex] = Res.CLASS_NAMES[ps._class]; + } + + drawParty(updateFlag); + + // Set up the sprite set to use for each face + for (posIndex = 0; posIndex < 4; ++posIndex) { + if ((firstDisplayChar + posIndex) >= (int)_charList.size()) + _faceDrawStructs[posIndex]._sprites = nullptr; + else + _faceDrawStructs[posIndex]._sprites = party._roster[ + _charList[firstDisplayChar + posIndex]]._faceSprites; + } + + _partyDetails = Common::String::format(Res.PARTY_DETAILS, + charNames[0].c_str(), charRaces[0].c_str(), charSex[0].c_str(), charClasses[0].c_str(), + charNames[1].c_str(), charRaces[1].c_str(), charSex[1].c_str(), charClasses[1].c_str(), + charNames[2].c_str(), charRaces[2].c_str(), charSex[2].c_str(), charClasses[2].c_str(), + charNames[3].c_str(), charRaces[3].c_str(), charSex[3].c_str(), charClasses[3].c_str() + ); +} + +void PartyDialog::startingCharChanged(int firstDisplayChar) { + Windows &windows = *_vm->_windows; + Window &w = windows[11]; + + setupFaces(firstDisplayChar, true); + w.writeString(Common::String::format(Res.PARTY_DIALOG_TEXT, _partyDetails.c_str())); + w.drawList(_faceDrawStructs, 4); + + _uiSprites.draw(w, 0, Common::Point(16, 100)); + _uiSprites.draw(w, 2, Common::Point(52, 100)); + _uiSprites.draw(w, 4, Common::Point(87, 100)); + _uiSprites.draw(w, 6, Common::Point(122, 100)); + _uiSprites.draw(w, 8, Common::Point(157, 100)); + _uiSprites.draw(w, 10, Common::Point(192, 100)); + + w.update(); +} + +int PartyDialog::selectCharacter(bool isDelete, int firstDisplayChar) { + EventsManager &events = *_vm->_events; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Window &w = windows[28]; + + SpriteResource iconSprites; + iconSprites.load("esc.icn"); + + w.setBounds(Common::Rect(50, isDelete ? 112 : 76, 266, isDelete ? 148 : 112)); + w.open(); + w.writeString(Common::String::format(Res.REMOVE_OR_DELETE_WHICH, + Res.REMOVE_DELETE[isDelete ? 1 : 0])); + iconSprites.draw(w, 0, Common::Point(225, isDelete ? 120 : 84)); + w.update(); + + saveButtons(); + addButton(Common::Rect(225, isDelete ? 120 : 84, 249, isDelete ? 140 : 104), + Common::KEYCODE_ESCAPE, &iconSprites); + addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); + addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); + addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); + addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); + addPartyButtons(_vm); + + int result = -1, v; + while (!_vm->shouldExit() && result == -1) { + _buttonValue = 0; + while (!_vm->shouldExit() && !_buttonValue) { + events.pollEventsAndWait(); + checkEvents(_vm); + } + + switch (_buttonValue) { + case Common::KEYCODE_ESCAPE: + result = 0; + break; + + case Common::KEYCODE_F1: + case Common::KEYCODE_F2: + case Common::KEYCODE_F3: + case Common::KEYCODE_F4: + case Common::KEYCODE_F5: + case Common::KEYCODE_F6: + if (!isDelete) { + v = _buttonValue - Common::KEYCODE_F1; + if (v < (int)party._activeParty.size()) + result = _buttonValue; + } + break; + + case Common::KEYCODE_1: + case Common::KEYCODE_2: + case Common::KEYCODE_3: + case Common::KEYCODE_4: + if (isDelete) { + v = _buttonValue - Common::KEYCODE_1; + if ((firstDisplayChar + v) < (int)_charList.size()) + result = _buttonValue; + } + break; + + default: + break; + } + } + + w.close(); + restoreButtons(); + return result == -1 ? 0 : result; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_party.h b/engines/xeen/dialogs/dialogs_party.h new file mode 100644 index 0000000000..8f87ca3aa6 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_party.h @@ -0,0 +1,87 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_PARTY_H +#define XEEN_DIALOGS_PARTY_H + +#include "common/array.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/interface.h" +#include "xeen/screen.h" +#include "xeen/sprites.h" + +namespace Xeen { + +/** + * Shows the Party dialog that's shown when signing into an inn + */ +class PartyDialog : public ButtonContainer, public PartyDrawer { +private: + XeenEngine *_vm; + SpriteResource _uiSprites; + DrawStruct _faceDrawStructs[4]; + Common::String _partyDetails; + Common::Array _charList; + + /** + * Constructor + */ + PartyDialog(XeenEngine *vm); + + /** + * Executes the dialog + */ + void execute(); + + /** + * Loads buttons for the dialog + */ + void loadButtons(); + + /** + * Initialises a list of elements to draw + */ + void initDrawStructs(); + + /** + * Sets up the background + */ + void setupBackground(); + + /** + * Sets up the faces from the avaialble roster for display in the party dialog + */ + void setupFaces(int firstDisplayChar, bool updateFlag); + + void startingCharChanged(int firstDisplayChar); + + int selectCharacter(bool isDelete, int firstDisplayChar); +public: + /** + * Show the Party dialog + */ + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_PARTY_H */ diff --git a/engines/xeen/dialogs/dialogs_query.cpp b/engines/xeen/dialogs/dialogs_query.cpp new file mode 100644 index 0000000000..79f46826cd --- /dev/null +++ b/engines/xeen/dialogs/dialogs_query.cpp @@ -0,0 +1,158 @@ +/* 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/dialogs_query.h" +#include "xeen/xeen.h" + +namespace Xeen { + +bool Confirm::show(XeenEngine *vm, const Common::String &msg, int mode) { + Confirm *dlg = new Confirm(vm); + bool result = dlg->execute(msg, mode); + delete dlg; + + return result; +} + +bool Confirm::execute(const Common::String &msg, int mode) { + EventsManager &events = *_vm->_events; + Windows &windows = *_vm->_windows; + SpriteResource confirmSprites; + + confirmSprites.load("confirm.icn"); + addButton(Common::Rect(129, 112, 153, 122), Common::KEYCODE_y, &confirmSprites); + addButton(Common::Rect(185, 112, 209, 122), Common::KEYCODE_n, &confirmSprites); + + Window &w = windows[mode ? 22 : 21]; + w.open(); + + if (!mode) { + confirmSprites.draw(w, 0, Common::Point(129, 112)); + confirmSprites.draw(w, 2, Common::Point(185, 112)); + _buttons[0]._bounds.moveTo(129, 112); + _buttons[1]._bounds.moveTo(185, 112); + } else { + if (mode & 0x80) { + clearButtons(); + } else { + confirmSprites.draw(w, 0, Common::Point(120, 133)); + confirmSprites.draw(w, 2, Common::Point(176, 133)); + _buttons[0]._bounds.moveTo(120, 133); + _buttons[1]._bounds.moveTo(176, 133); + } + } + + w.writeString(msg); + w.update(); + + events.clearEvents(); + bool result = false; + + while (!_vm->shouldExit()) { + events.pollEvents(); + checkEvents(_vm); + + if ((mode & 0x80) || _buttonValue == Common::KEYCODE_ESCAPE + || _buttonValue == Common::KEYCODE_n) + break; + + if (_buttonValue == Common::KEYCODE_y) { + result = true; + break; + } + } + + w.close(); + return result; +} + +/*------------------------------------------------------------------------*/ + +bool YesNo::show(XeenEngine *vm, bool type, bool townFlag) { + YesNo *dlg = new YesNo(vm); + bool result = dlg->execute(type, townFlag); + delete dlg; + + return result; +} + +bool YesNo::execute(bool type, bool townFlag) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Resources &res = *_vm->_resources; + LocationManager &loc = *_vm->_locations; + Windows &windows = *_vm->_windows; + SpriteResource confirmSprites; + bool result = false; + + Mode oldMode = _vm->_mode; + _vm->_mode = oldMode == MODE_7 ? MODE_8 : MODE_7; + + if (!type) { + confirmSprites.load("confirm.icn"); + res._globalSprites.draw(0, 7, Common::Point(232, 74)); + confirmSprites.draw(0, 0, Common::Point(235, 75)); + confirmSprites.draw(0, 2, Common::Point(260, 75)); + windows[34].update(); + + addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_y, &confirmSprites); + addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_n, &confirmSprites); + + intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; + intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; + } + + while (!_vm->shouldExit()) { + events.updateGameCounter(); + + if (loc.isActive()) { + loc.drawAnim(townFlag); + //numFrames = 3; + } else { + intf.draw3d(true); + //numFrames = 1; + } + + events.wait(3); + checkEvents(_vm); + if (!_buttonValue) + continue; + + if (type || _buttonValue == Common::KEYCODE_y) { + result = true; + break; + } else if (_buttonValue == Common::KEYCODE_n || _buttonValue == Common::KEYCODE_ESCAPE) + break; + } + + intf._face1State = intf._face2State = 2; + _vm->_mode = oldMode; + + if (!type) + intf.mainIconsPrint(); + + return result; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_query.h b/engines/xeen/dialogs/dialogs_query.h new file mode 100644 index 0000000000..911de3d79d --- /dev/null +++ b/engines/xeen/dialogs/dialogs_query.h @@ -0,0 +1,50 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_QUERY_H +#define XEEN_DIALOGS_QUERY_H + +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class Confirm : public ButtonContainer { +private: + Confirm(XeenEngine *vm) : ButtonContainer(vm) {} + + bool execute(const Common::String &msg, int mode); +public: + static bool show(XeenEngine *vm, const Common::String &msg, int mode = 0); +}; + +class YesNo : public ButtonContainer { +private: + YesNo(XeenEngine *vm) : ButtonContainer(vm) {} + + bool execute(bool type, bool townFlag); +public: + static bool show(XeenEngine *vm, bool type, bool townFlag = false); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_QUERY_H */ diff --git a/engines/xeen/dialogs/dialogs_quests.cpp b/engines/xeen/dialogs/dialogs_quests.cpp new file mode 100644 index 0000000000..e4f62270ef --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quests.cpp @@ -0,0 +1,254 @@ +/* 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 "common/scummsys.h" +#include "xeen/dialogs/dialogs_quests.h" +#include "xeen/events.h" +#include "xeen/party.h" +#include "xeen/xeen.h" + +namespace Xeen { + +#define MAX_DIALOG_LINES 128 + +void Quests::show(XeenEngine *vm) { + Quests *dlg = new Quests(vm); + dlg->execute(); + delete dlg; +} + +void Quests::execute() { + EventsManager &events = *_vm->_events; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Mode oldMode = _vm->_mode; + int count = 0; + bool headerShown = false; + int topRow = 0; + + addButtons(); + loadQuestNotes(); + + enum { QUEST_ITEMS, CURRENT_QUESTS, AUTO_NOTES } mode = QUEST_ITEMS; + bool windowFlag; + if (windows[29]._enabled) { + windowFlag = false; + } else { + windows[29].open(); + windows[30].open(); + windowFlag = true; + } + + windows[29].writeString(Res.QUESTS_DIALOG_TEXT); + drawButtons(&windows[0]); + + while (!_vm->shouldExit()) { + Common::String lines[MAX_DIALOG_LINES]; + + switch (mode) { + case QUEST_ITEMS: + for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) + lines[idx] = "\b \b*"; + + count = 0; + headerShown = false; + for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) { + if (party._questItems[idx]) { + if (!count && !headerShown && idx < 35) { + lines[count++] = Res.CLOUDS_OF_XEEN_LINE; + } + if (idx >= 35 && !headerShown) { + lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; + headerShown = true; + } + + switch (idx) { + case 17: + case 26: + case 79: + case 80: + case 81: + case 82: + case 83: + case 84: + lines[count++] = Common::String::format("%d %s%c", + party._questItems[idx], Res.QUEST_ITEM_NAMES[idx], + party._questItems[idx] == 1 ? ' ' : 's'); + break; + default: + lines[count++] = Res.QUEST_ITEM_NAMES[idx]; + break; + } + } + } + + if (count == 0) { + windows[30].writeString(Res.NO_QUEST_ITEMS); + } else { + windows[30].writeString(Common::String::format(Res.QUEST_ITEMS_DATA, + lines[topRow].c_str(), lines[topRow + 1].c_str(), + lines[topRow + 2].c_str(), lines[topRow + 3].c_str(), + lines[topRow + 4].c_str(), lines[topRow + 5].c_str(), + lines[topRow + 6].c_str(), lines[topRow + 7].c_str(), + lines[topRow + 8].c_str() + )); + } + break; + + case CURRENT_QUESTS: + for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) + lines[idx] = ""; + + count = 0; + headerShown = false; + for (int idx = 0; idx < TOTAL_QUEST_FLAGS; ++idx) { + if (party._questFlags[(idx + 1) / 30][(idx + 1) % 30]) { + if (!count && !headerShown && idx < 29) { + lines[count++] = Res.CLOUDS_OF_XEEN_LINE; + } + if (idx > 28 && !headerShown) { + lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; + headerShown = true; + } + + lines[count++] = _questNotes[idx]; + } + } + + if (count == 0) + lines[1] = Res.NO_CURRENT_QUESTS; + + windows[30].writeString(Common::String::format(Res.CURRENT_QUESTS_DATA, + lines[topRow].c_str(), lines[topRow + 1].c_str(), lines[topRow + 2].c_str())); + break; + + case AUTO_NOTES: + for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) + lines[idx] = ""; + + count = 0; + headerShown = false; + for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) { + if (party._worldFlags[idx]) { + if (!count && !headerShown && idx < 72) { + lines[count++] = Res.CLOUDS_OF_XEEN_LINE; + } + if (idx >= 72 && !headerShown) { + lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; + headerShown = true; + } + + lines[count++] = _questNotes[idx + 56]; + } + } + + if (count == 0) + lines[1] = Res.NO_AUTO_NOTES; + + windows[30].writeString(Common::String::format(Res.AUTO_NOTES_DATA, + lines[topRow].c_str(), lines[topRow + 1].c_str(), + lines[topRow + 2].c_str(), lines[topRow + 3].c_str(), + lines[topRow + 4].c_str(), lines[topRow + 5].c_str(), + lines[topRow + 6].c_str(), lines[topRow + 7].c_str(), + lines[topRow + 8].c_str() + )); + break; + } + + windows[30].writeString("\v000\t000"); + windows[24].update(); + + // Key handling + _buttonValue = 0; + while (!_vm->shouldExit() && !_buttonValue) { + events.pollEventsAndWait(); + checkEvents(_vm); + } + + if (_buttonValue == Common::KEYCODE_ESCAPE) + break; + + switch (_buttonValue) { + case Common::KEYCODE_a: + mode = AUTO_NOTES; + topRow = 0; + break; + case Common::KEYCODE_i: + mode = QUEST_ITEMS; + topRow = 0; + break; + case Common::KEYCODE_q: + mode = CURRENT_QUESTS; + topRow = 0; + break; + case Common::KEYCODE_HOME: + topRow = 0; + break; + case Common::KEYCODE_END: + topRow = MAX(count - 1, 0); + break; + case Common::KEYCODE_PAGEUP: + topRow = MAX(topRow - 3, 0); + break; + case Common::KEYCODE_PAGEDOWN: + topRow = CLIP(topRow + 3, 0, MAX(count - 1, 0)); + break; + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + topRow = MAX(topRow - 1, 0); + break; + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + topRow = CLIP(topRow + 1, 0, MAX(count - 1, 0)); + break; + default: + break; + } + } + + if (windowFlag) { + windows[30].close(); + windows[29].close(); + } + _vm->_mode = oldMode; +} + +void Quests::addButtons() { + _iconSprites.load("quest.icn"); + + + addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_i, &_iconSprites); + addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_q, &_iconSprites); + addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_a, &_iconSprites); + addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_UP, &_iconSprites); + addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_DOWN, &_iconSprites); + addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); +} + +void Quests::loadQuestNotes() { + File f("qnotes.bin"); + while (f.pos() < f.size()) + _questNotes.push_back(f.readString()); + f.close(); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_quests.h b/engines/xeen/dialogs/dialogs_quests.h new file mode 100644 index 0000000000..a3f1980c67 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quests.h @@ -0,0 +1,49 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_QUESTS_H +#define XEEN_DIALOGS_QUESTS_H + +#include "common/str-array.h" +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class Quests : public ButtonContainer { +private: + SpriteResource _iconSprites; + Common::StringArray _questNotes; + + Quests(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(); + + void addButtons(); + + void loadQuestNotes(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_QUESTS_H */ diff --git a/engines/xeen/dialogs/dialogs_quick_fight.cpp b/engines/xeen/dialogs/dialogs_quick_fight.cpp new file mode 100644 index 0000000000..63acf55655 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quick_fight.cpp @@ -0,0 +1,105 @@ +/* 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/dialogs_quick_fight.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void QuickFight::show(XeenEngine *vm, Character *currentChar) { + QuickFight *dlg = new QuickFight(vm, currentChar); + dlg->execute(); + delete dlg; +} + +QuickFight::QuickFight(XeenEngine *vm, Character *currentChar) : ButtonContainer(vm), + _currentChar(currentChar) { + loadButtons(); +} + +void QuickFight::execute() { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Window &w = windows[10]; + w.open(); + + do { + // Draw the dialog text and buttons + Common::String msg = Common::String::format(Res.QUICK_FIGHT_TEXT, + _currentChar->_name.c_str(), + Res.QUICK_FIGHT_OPTIONS[_currentChar->_quickOption]); + w.writeString(msg); + drawButtons(&w); + + // Wait for selection + _buttonValue = 0; + events.updateGameCounter(); + do { + intf.draw3d(false, false); + + events.pollEventsAndWait(); + checkEvents(_vm); + if (_vm->shouldExit()) + return; + } while (!_buttonValue && !events.timeElapsed()); + + switch (_buttonValue) { + case Common::KEYCODE_n: + case Common::KEYCODE_t: + _currentChar->_quickOption = (QuickAction)(((int)_currentChar->_quickOption + 1) % 4); + break; + + case Common::KEYCODE_F1: + case Common::KEYCODE_F2: + case Common::KEYCODE_F3: + case Common::KEYCODE_F4: + case Common::KEYCODE_F5: + case Common::KEYCODE_F6: { + int charIdx = _buttonValue - Common::KEYCODE_F1; + if (charIdx < (int)combat._combatParty.size()) { + // Highlight new character + _currentChar = &party._activeParty[charIdx]; + intf.highlightChar(charIdx); + } + break; + } + + default: + break; + } + } while (_buttonValue != Common::KEYCODE_RETURN && _buttonValue != Common::KEYCODE_ESCAPE); + + w.close(); + events.clearEvents(); +} + +void QuickFight::loadButtons() { + _icons.load("train.icn"); + addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons); + addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_icons); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_quick_fight.h b/engines/xeen/dialogs/dialogs_quick_fight.h new file mode 100644 index 0000000000..e3662c930a --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quick_fight.h @@ -0,0 +1,60 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_QUICK_FIGHT_H +#define XEEN_DIALOGS_QUICK_FIGHT_H + +#include "xeen/character.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/sprites.h" + +namespace Xeen { + +class QuickFight : public ButtonContainer { +private: + SpriteResource _icons; + Character *_currentChar; +private: + /** + * Constructor + */ + QuickFight(XeenEngine *vm, Character *currentChar); + + /** + * Executes the display of the dialog + */ + void execute(); + + /** + * Load butons for the dialog + */ + void loadButtons(); +public: + /** + * Show the dialog + */ + static void show(XeenEngine *vm, Character *currentChar); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_QUICK_FIGHT_H */ diff --git a/engines/xeen/dialogs/dialogs_quick_ref.cpp b/engines/xeen/dialogs/dialogs_quick_ref.cpp new file mode 100644 index 0000000000..0c8a63b43a --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quick_ref.cpp @@ -0,0 +1,88 @@ +/* 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/dialogs_quick_ref.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +void QuickReferenceDialog::show(XeenEngine *vm) { + QuickReferenceDialog *dlg = new QuickReferenceDialog(vm); + dlg->execute(); + delete dlg; +} + +void QuickReferenceDialog::execute() { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Common::String lines[8]; + + events.setCursor(0); + + for (uint idx = 0; idx < (combat._globalCombat == 2 ? combat._combatParty.size() : + party._activeParty.size()); ++idx) { + Character &c = combat._globalCombat == 2 ? *combat._combatParty[idx] : + party._activeParty[idx]; + Condition condition = c.worstCondition(); + lines[idx] = Common::String::format(Res.QUICK_REF_LINE, + idx * 10 + 24, idx + 1, c._name.c_str(), + Res.CLASS_NAMES[c._class][0], Res.CLASS_NAMES[c._class][1], Res.CLASS_NAMES[c._class][2], + c.statColor(c.getCurrentLevel(), c._level._permanent), c._level._permanent, + c.statColor(c._currentHp, c.getMaxHP()), c._currentHp, + c.statColor(c._currentSp, c.getMaxSP()), c._currentSp, + c.statColor(c.getArmorClass(), c.getArmorClass(true)), c.getArmorClass(), + Res.CONDITION_COLORS[condition], + Res.CONDITION_NAMES[condition][0], Res.CONDITION_NAMES[condition][1], + Res.CONDITION_NAMES[condition][2], Res.CONDITION_NAMES[condition][3] + ); + } + + int food = (party._food / party._activeParty.size()) / 3; + Common::String msg = Common::String::format(Res.QUICK_REFERENCE, + lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), + lines[3].c_str(), lines[4].c_str(), lines[5].c_str(), + lines[6].c_str(), lines[7].c_str(), + party._gold, party._gems, + food, food == 1 ? "" : "s" + ); + + Window &w = windows[24]; + bool windowOpen = w._enabled; + if (!windowOpen) + w.open(); + w.writeString(msg); + w.update(); + + // Wait for a key/mouse press + events.clearEvents(); + while (!_vm->shouldExit() && !events.isKeyMousePressed()) + events.pollEventsAndWait(); + events.clearEvents(); + + if (!windowOpen) + w.close(); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_quick_ref.h b/engines/xeen/dialogs/dialogs_quick_ref.h new file mode 100644 index 0000000000..4630043c3f --- /dev/null +++ b/engines/xeen/dialogs/dialogs_quick_ref.h @@ -0,0 +1,41 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_QUICK_REF_H +#define XEEN_DIALOGS_QUICK_REF_H + +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class QuickReferenceDialog : public ButtonContainer { +private: + QuickReferenceDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_QUICK_REF_H */ diff --git a/engines/xeen/dialogs/dialogs_spells.cpp b/engines/xeen/dialogs/dialogs_spells.cpp new file mode 100644 index 0000000000..3da5a5149e --- /dev/null +++ b/engines/xeen/dialogs/dialogs_spells.cpp @@ -0,0 +1,1045 @@ +/* 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/dialogs_spells.h" +#include "xeen/dialogs/dialogs_input.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/resources.h" +#include "xeen/spells.h" +#include "xeen/sprites.h" +#include "xeen/xeen.h" + +namespace Xeen { + +Character *SpellsDialog::show(XeenEngine *vm, ButtonContainer *priorDialog, + Character *c, int isCasting) { + SpellsDialog *dlg = new SpellsDialog(vm); + Character *result = dlg->execute(priorDialog, c, isCasting); + delete dlg; + + return result; +} + +Character *SpellsDialog::execute(ButtonContainer *priorDialog, Character *c, int isCasting) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Sound &sound = *_vm->_sound; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + bool isDarkCc = _vm->_files->_isDarkCc; + loadButtons(); + + int castingCopy = isCasting; + isCasting &= 0x7f; + int selection = -1; + int topIndex = 0; + int newSelection; + windows[25].open(); + + do { + if (!isCasting) { + if (!c->guildMember()) { + sound.stopSound(); + intf._overallFrame = 5; + sound.playSound(isDarkCc ? "skull1.voc" : "guild11.voc", 1); + break; + } + + Common::String title = Common::String::format(Res.BUY_SPELLS, c->_name.c_str()); + Common::String msg = Common::String::format(Res.GUILD_OPTIONS, + title.c_str(), XeenEngine::printMil(party._gold).c_str()); + windows[10].writeString(msg); + + warning("TODO: Sprite draw using previously used button sprites"); + } + + _spells.clear(); + const char *errorMsg = setSpellText(c, castingCopy); + windows[25].writeString(Common::String::format(Res.SPELLS_FOR, + errorMsg == nullptr ? Res.SPELL_LINES_0_TO_9 : "", + c->_name.c_str())); + + // Setup and write out spell list + const char *names[10]; + int colors[10]; + Common::String emptyStr = ""; + Common::fill(&names[0], &names[10], emptyStr.c_str()); + Common::fill(&colors[0], &colors[10], 9); + + for (int idx = 0; idx < 10; ++idx) { + if ((topIndex + idx) < (int)_spells.size()) { + names[idx] = _spells[topIndex + idx]._name.c_str(); + colors[idx] = _spells[topIndex + idx]._color; + } + } + + if (selection >= topIndex && selection < (topIndex + 10)) + colors[selection - topIndex] = 15; + if (_spells.size() == 0) + names[0] = errorMsg; + + windows[37].writeString(Common::String::format(Res.SPELLS_DIALOG_SPELLS, + colors[0], names[0], colors[1], names[1], colors[2], names[2], + colors[3], names[3], colors[4], names[4], colors[5], names[5], + colors[6], names[6], colors[7], names[7], colors[8], names[8], + colors[9], names[9], + isCasting ? Res.SPELL_PTS : Res.GOLD, + isCasting ? c->_currentSp : party._gold + )); + + _scrollSprites.draw(0, 4, Common::Point(39, 26)); + _scrollSprites.draw(0, 0, Common::Point(187, 26)); + _scrollSprites.draw(0, 2, Common::Point(187, 111)); + if (isCasting) + _scrollSprites.draw(windows[25], 5, Common::Point(132, 123)); + + windows[25].update(); + + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_vm->shouldExit() && !_buttonValue); + + 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: + if (_vm->_mode != MODE_COMBAT) { + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + spells._lastCaster = _buttonValue; + intf.highlightChar(_buttonValue); + + if (_vm->_mode == MODE_17) { + windows[10].writeString(Common::String::format(Res.GUILD_OPTIONS, + XeenEngine::printMil(party._gold).c_str(), Res.GUILD_TEXT, c->_name.c_str())); + } else { + int category; + switch (c->_class) { + case CLASS_ARCHER: + case CLASS_SORCERER: + category = 1; + break; + case CLASS_DRUID: + case CLASS_RANGER: + category = 2; + break; + default: + category = 0; + break; + } + + int spellIndex = (c->_currentSpell == -1) ? 39 : c->_currentSpell; + int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; + windows[10].writeString(Common::String::format(Res.CAST_SPELL_DETAILS, + c->_name.c_str(), spells._spellNames[spellId].c_str(), + spells.calcSpellPoints(spellId, c->getCurrentLevel()), + Res.SPELL_GEM_COST[spellId], c->_currentSp)); + } + + if (priorDialog != nullptr) + priorDialog->drawButtons(&windows[0]); + windows[10].update(); + } + } + break; + + case Common::KEYCODE_RETURN: + case Common::KEYCODE_KP_ENTER: + case Common::KEYCODE_s: + if (selection != -1) + _buttonValue = Common::KEYCODE_ESCAPE; + break; + + case Common::KEYCODE_ESCAPE: + selection = -1; + _buttonValue = Common::KEYCODE_ESCAPE; + break; + + case Common::KEYCODE_0: + case Common::KEYCODE_1: + case Common::KEYCODE_2: + case Common::KEYCODE_3: + case Common::KEYCODE_4: + case Common::KEYCODE_5: + case Common::KEYCODE_6: + case Common::KEYCODE_7: + case Common::KEYCODE_8: + case Common::KEYCODE_9: + newSelection = topIndex + ((_buttonValue == Common::KEYCODE_0) ? 9 : + (_buttonValue - Common::KEYCODE_1)); + + if (newSelection < (int)_spells.size()) { + int expenseFactor = 0; + int category = 0; + + switch (c->_class) { + case CLASS_PALADIN: + expenseFactor = 1; + category = 0; + break; + case CLASS_ARCHER: + expenseFactor = 1; + category = 1; + break; + case CLASS_CLERIC: + category = 0; + break; + case CLASS_SORCERER: + category = 1; + break; + case CLASS_DRUID: + category = 2; + break; + case CLASS_RANGER: + expenseFactor = 1; + category = 2; + break; + default: + break; + } + + int spellIndex = _spells[newSelection]._spellIndex; + int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; + int spellCost = spells.calcSpellCost(spellId, expenseFactor); + + if (isCasting) { + selection = newSelection; + } else { + Common::String spellName = _spells[newSelection]._name; + Common::String msg = (castingCopy & 0x80) ? + Common::String::format(Res.SPELLS_PRESS_A_KEY, spellName.c_str()) : + Common::String::format(Res.SPELLS_PURCHASE, spellName.c_str(), spellCost); + + if (Confirm::show(_vm, msg, castingCopy + 1)) { + if (party.subtract(CONS_GOLD, spellCost, WHERE_PARTY, WT_FREEZE_WAIT)) { + c->_spells[spellIndex] = true; + sound.stopSound(); + intf._overallFrame = 0; + sound.playSound(isDarkCc ? "guild12.voc" : "parrot2.voc", 1); + } else { + sound.playFX(21); + } + } + } + } + break; + + case Common::KEYCODE_PAGEUP: + case Common::KEYCODE_KP9: + topIndex = MAX((int)topIndex - 10, 0); + break; + + case Common::KEYCODE_PAGEDOWN: + case Common::KEYCODE_KP3: + topIndex = MIN(topIndex + 10, (((int)_spells.size() - 1) / 10) * 10); + break; + + case Common::KEYCODE_UP: + case Common::KEYCODE_KP8: + if (topIndex > 0) + --topIndex; + break; + + case Common::KEYCODE_DOWN: + case Common::KEYCODE_KP2: + if (topIndex < ((int)_spells.size() - 10)) + ++topIndex; + break; + } + } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); + + windows[25].close(); + + if (_vm->shouldExit()) + selection = -1; + if (isCasting && selection != -1) + c->_currentSpell = _spells[selection]._spellIndex; + + return c; +} + +void SpellsDialog::loadButtons() { + _iconSprites.load("main.icn"); + _scrollSprites.load("scroll.icn"); + addButton(Common::Rect(187, 26, 198, 36), Common::KEYCODE_UP, &_scrollSprites); + addButton(Common::Rect(187, 111, 198, 121), Common::KEYCODE_DOWN, &_scrollSprites); + addButton(Common::Rect(40, 28, 187, 36), Common::KEYCODE_1); + addButton(Common::Rect(40, 37, 187, 45), Common::KEYCODE_2); + addButton(Common::Rect(40, 46, 187, 54), Common::KEYCODE_3); + addButton(Common::Rect(40, 55, 187, 63), Common::KEYCODE_4); + addButton(Common::Rect(40, 64, 187, 72), Common::KEYCODE_5); + addButton(Common::Rect(40, 73, 187, 81), Common::KEYCODE_6); + addButton(Common::Rect(40, 82, 187, 90), Common::KEYCODE_7); + addButton(Common::Rect(40, 91, 187, 99), Common::KEYCODE_8); + addButton(Common::Rect(40, 100, 187, 108), Common::KEYCODE_9); + addButton(Common::Rect(40, 109, 187, 117), Common::KEYCODE_0); + addButton(Common::Rect(174, 123, 198, 133), Common::KEYCODE_ESCAPE); + addButton(Common::Rect(187, 35, 198, 73), Common::KEYCODE_PAGEUP); + addButton(Common::Rect(187, 74, 198, 112), Common::KEYCODE_PAGEDOWN); + addButton(Common::Rect(132, 123, 168, 133), Common::KEYCODE_s); + addPartyButtons(_vm); +} + +const char *SpellsDialog::setSpellText(Character *c, int isCasting) { + Party &party = *_vm->_party; + Spells &spells = *_vm->_spells; + bool isDarkCc = _vm->_files->_isDarkCc; + int expenseFactor = 0; + int currLevel = c->getCurrentLevel(); + int category; + + if ((isCasting & 0x7f) == 0) { + switch (c->_class) { + case CLASS_PALADIN: + expenseFactor = 1; + category = 0; + break; + case CLASS_ARCHER: + expenseFactor = 1; + category = 1; + break; + case CLASS_CLERIC: + category = 0; + break; + case CLASS_SORCERER: + category = 1; + break; + case CLASS_DRUID: + category = 2; + break; + case CLASS_RANGER: + expenseFactor = 1; + category = 2; + break; + default: + category = -1; + break; + } + + if (category != -1) { + if (party._mazeId == 49 || party._mazeId == 37) { + for (uint spellId = 0; spellId < 76; ++spellId) { + int idx = 0; + while (idx < MAX_SPELLS_PER_CLASS && Res.SPELLS_ALLOWED[category][idx] != (int)spellId) + ++idx; + + // Handling if the spell is appropriate for the character's class + if (idx < MAX_SPELLS_PER_CLASS) { + if (!c->_spells[idx] || (isCasting & 0x80)) { + int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); + _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", + spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), + idx, spellId)); + } + } + } + } else if (isDarkCc) { + int groupIndex = (party._mazeId - 29) / 2; + for (int spellId = Res.DARK_SPELL_RANGES[groupIndex][0]; + spellId < Res.DARK_SPELL_RANGES[groupIndex][1]; ++spellId) { + int idx = 0; + while (idx < 40 && Res.SPELLS_ALLOWED[category][idx] == + Res.DARK_SPELL_OFFSETS[category][spellId]); + + if (idx < 40) { + if (!c->_spells[idx] || (isCasting & 0x80)) { + int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); + _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", + spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), + idx, spellId)); + } + } + } + } else { + for (int spellId = 0; spellId < 20; ++spellId) { + int idx = 0; + while (Res.CLOUDS_SPELL_OFFSETS[party._mazeId - 29][spellId] != + (int)Res.SPELLS_ALLOWED[category][idx] && idx < 40) ; + + if (idx < 40) { + if (!c->_spells[idx] || (isCasting & 0x80)) { + int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); + _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", + spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), + idx, spellId)); + } + } + } + } + } + + if (c->getMaxSP() == 0) + return Res.NOT_A_SPELL_CASTER; + + } else if ((isCasting & 0x7f) == 1) { + switch (c->_class) { + case CLASS_ARCHER: + case CLASS_SORCERER: + category = 1; + break; + case CLASS_DRUID: + case CLASS_RANGER: + category = 2; + break; + case CLASS_PALADIN: + case CLASS_CLERIC: + default: + category = 0; + break; + } + + if (c->getMaxSP() == 0) { + return Res.NOT_A_SPELL_CASTER; + } else { + for (int spellIndex = 0; spellIndex < MAX_SPELLS_PER_CLASS; ++spellIndex) { + if (c->_spells[spellIndex]) { + int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; + int gemCost = Res.SPELL_GEM_COST[spellId]; + int spCost = spells.calcSpellPoints(spellId, currLevel); + + Common::String msg = Common::String::format("\x3l%s\x3r\x9""000%u/%u", + spells._spellNames[spellId].c_str(), spCost, gemCost); + _spells.push_back(SpellEntry(msg, spellIndex, spellId)); + } + } + } + } + + return nullptr; +} + +/*------------------------------------------------------------------------*/ + +CastSpell::CastSpell(XeenEngine *vm) : ButtonContainer(vm) { + Windows &windows = *_vm->_windows; + _oldMode = _vm->_mode; + _vm->_mode = MODE_3; + + windows[10].open(); + loadButtons(); +} + +CastSpell::~CastSpell() { + Interface &intf = *_vm->_interface; + Windows &windows = *_vm->_windows; + + windows[10].close(); + intf.unhighlightChar(); + + _vm->_mode = (Mode)_oldMode; +} + + +int CastSpell::show(XeenEngine *vm) { + Combat &combat = *vm->_combat; + Interface &intf = *vm->_interface; + Party &party = *vm->_party; + Spells &spells = *vm->_spells; + int charNum; + + // Get which character is doing the casting + if (vm->_mode == MODE_COMBAT) { + charNum = combat._whosTurn; + } else if (spells._lastCaster >= 0 && spells._lastCaster < (int)party._activeParty.size()) { + charNum = spells._lastCaster; + } else { + for (charNum = (int)party._activeParty.size() - 1; charNum >= 0; --charNum) { + if (party._activeParty[charNum]._hasSpells) { + spells._lastCaster = charNum; + break; + } + } + } + + Character *c = &party._activeParty[charNum]; + intf.highlightChar(charNum); + + return show(vm, c); +} + +int CastSpell::show(XeenEngine *vm, Character *&c) { + Spells &spells = *vm->_spells; + CastSpell *dlg = new CastSpell(vm); + int spellId; + int result = -1; + + do { + spellId = dlg->execute(c); + + if (g_vm->shouldExit() || spellId == -1) { + result = 0; + } else { + result = spells.castSpell(c, (MagicSpell)spellId); + } + } while (result == -1); + + delete dlg; + return result; +} + +int CastSpell::execute(Character *&c) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + Window &w = windows[10]; + + int spellId = -1; + bool redrawFlag = true; + do { + if (redrawFlag) { + int category = c->getClassCategory(); + int spellIndex = c->_currentSpell != -1 ? c->_currentSpell : 39; + spellId = Res.SPELLS_ALLOWED[category][spellIndex]; + int gemCost = Res.SPELL_GEM_COST[spellId]; + int spCost = spells.calcSpellPoints(spellId, c->getCurrentLevel()); + + w.writeString(Common::String::format(Res.CAST_SPELL_DETAILS, + c->_name.c_str(), spells._spellNames[spellId].c_str(), + spCost, gemCost, c->_currentSp)); + drawButtons(&windows[0]); + w.update(); + + redrawFlag = false; + } + + events.updateGameCounter(); + intf.draw3d(true); + + // Wait for event or time expiry + do { + events.pollEventsAndWait(); + checkEvents(_vm); + } while (!_vm->shouldExit() && events.timeElapsed() < 1 && !_buttonValue); + + 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: + // Only allow changing character if the party is not in combat + if (_oldMode != MODE_COMBAT) { + _vm->_mode = (Mode)_oldMode; + _buttonValue -= Common::KEYCODE_F1; + + if (_buttonValue < (int)party._activeParty.size()) { + c = &party._activeParty[_buttonValue]; + intf.highlightChar(_buttonValue); + redrawFlag = true; + break; + } + } + break; + + case Common::KEYCODE_ESCAPE: + spellId = -1; + break; + + case Common::KEYCODE_c: + // Cast spell - return the selected spell Id to be cast + if (c->_currentSpell != -1 && !c->noActions()) + _buttonValue = Common::KEYCODE_ESCAPE; + break; + + case Common::KEYCODE_n: + // Select new spell + _vm->_mode = (Mode)_oldMode; + c = SpellsDialog::show(_vm, this, c, 1); + redrawFlag = true; + break; + + default: + break; + } + } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); + + if (_vm->shouldExit()) + spellId = -1; + return spellId; +} + +void CastSpell::loadButtons() { + _iconSprites.load("cast.icn"); + addButton(Common::Rect(234, 108, 259, 128), Common::KEYCODE_c, &_iconSprites); + addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_n, &_iconSprites); + addButton(Common::Rect(288, 108, 312, 128), Common::KEYCODE_ESCAPE, &_iconSprites); + addPartyButtons(_vm); +} + +/*------------------------------------------------------------------------*/ + +Character *SpellOnWho::show(XeenEngine *vm, int spellId) { + SpellOnWho *dlg = new SpellOnWho(vm); + int result = dlg->execute(spellId); + delete dlg; + + if (result == -1) + return nullptr; + + Combat &combat = *vm->_combat; + Party &party = *vm->_party; + return combat._combatMode == 2 ? combat._combatParty[result] : + &party._activeParty[result]; +} + +int SpellOnWho::execute(int spellId) { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Party &party = *_vm->_party; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + Window &w = windows[16]; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_3; + int result = 999; + + w.open(); + w.writeString(Res.ON_WHO); + w.update(); + addPartyButtons(_vm); + + while (result == 999) { + do { + events.updateGameCounter(); + intf.draw3d(true); + + do { + events.pollEventsAndWait(); + if (_vm->shouldExit()) + return -1; + + checkEvents(_vm); + } while (!_buttonValue && events.timeElapsed() < 1); + } while (!_buttonValue); + + switch (_buttonValue) { + case Common::KEYCODE_ESCAPE: + result = -1; + spells.addSpellCost(*combat._oldCharacter, spellId); + break; + + case Common::KEYCODE_F1: + case Common::KEYCODE_F2: + case Common::KEYCODE_F3: + case Common::KEYCODE_F4: + case Common::KEYCODE_F5: + case Common::KEYCODE_F6: + _buttonValue -= Common::KEYCODE_F1; + if (_buttonValue < (int)(combat._combatMode == 2 ? combat._combatParty.size() : + party._activeParty.size())) { + result = _buttonValue; + } + break; + } + } + + w.close(); + _vm->_mode = oldMode; + return result; +} + +/*------------------------------------------------------------------------*/ + +int SelectElement::show(XeenEngine *vm, int spellId) { + SelectElement *dlg = new SelectElement(vm); + int result = dlg->execute(spellId); + delete dlg; + + return result; +} + +int SelectElement::execute(int spellId) { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + Window &w = windows[15]; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_3; + int result = 999; + + loadButtons(); + + w.open(); + w.writeString(Res.WHICH_ELEMENT1); + drawButtons(&windows[0]); + w.update(); + + while (result == 999) { + do { + events.updateGameCounter(); + intf.draw3d(true); + w.frame(); + w.writeString(Res.WHICH_ELEMENT2); + drawButtons(&windows[0]); + w.update(); + + do { + events.pollEventsAndWait(); + if (_vm->shouldExit()) + return -1; + + checkEvents(_vm); + } while (!_buttonValue && events.timeElapsed() < 1); + } while (!_buttonValue); + + switch (_buttonValue) { + case Common::KEYCODE_ESCAPE: + result = -1; + spells.addSpellCost(*combat._oldCharacter, spellId); + break; + + case Common::KEYCODE_a: + result = DT_POISON; + break; + case Common::KEYCODE_c: + result = DT_COLD; + break; + case Common::KEYCODE_e: + result = DT_ELECTRICAL; + break; + case Common::KEYCODE_f: + result = DT_FIRE; + break; + default: + break; + } + } + + w.close(); + _vm->_mode = oldMode; + return result; +} + +void SelectElement::loadButtons() { + _iconSprites.load("element.icn"); + addButton(Common::Rect(60, 92, 84, 112), Common::KEYCODE_f, &_iconSprites); + addButton(Common::Rect(90, 92, 114, 112), Common::KEYCODE_e, &_iconSprites); + addButton(Common::Rect(120, 92, 144, 112), Common::KEYCODE_c, &_iconSprites); + addButton(Common::Rect(150, 92, 174, 112), Common::KEYCODE_a, &_iconSprites); +} + +/*------------------------------------------------------------------------*/ + +void NotWhileEngaged::show(XeenEngine *vm, int spellId) { + NotWhileEngaged *dlg = new NotWhileEngaged(vm); + dlg->execute(spellId); + delete dlg; +} + +void NotWhileEngaged::execute(int spellId) { + EventsManager &events = *_vm->_events; + Spells &spells = *_vm->_spells; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_3; + + w.open(); + w.writeString(Common::String::format(Res.CANT_CAST_WHILE_ENGAGED, + spells._spellNames[spellId].c_str())); + w.update(); + + while (!_vm->shouldExit() && !events.isKeyMousePressed()) + events.pollEventsAndWait(); + events.clearEvents(); + + w.close(); + _vm->_mode = oldMode; +} + +/*------------------------------------------------------------------------*/ + +bool LloydsBeacon::show(XeenEngine *vm) { + LloydsBeacon *dlg = new LloydsBeacon(vm); + bool result = dlg->execute(); + delete dlg; + + return result; +} + +bool LloydsBeacon::execute() { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Sound &sound = *_vm->_sound; + Windows &windows = *_vm->_windows; + Window &w = windows[10]; + bool isDarkCc = _vm->_files->_isDarkCc; + Character &c = *combat._oldCharacter; + + loadButtons(); + + if (!c._lloydMap) { + // No destination previously set, so have a default ready + if (isDarkCc) { + c._lloydSide = 1; + c._lloydPosition = Common::Point(25, 21); + c._lloydMap = 29; + } else { + c._lloydSide = 0; + c._lloydPosition = Common::Point(18, 4); + c._lloydMap = 28; + } + } + + // Open up the text file for the destination map and read in it's name + File textFile(Common::String::format("%s%c%03d.txt", + c._lloydSide == 0 ? "xeen" : "dark", + c._lloydMap >= 100 ? 'x' : '0', + c._lloydMap)); + Common::String mapName = textFile.readString(); + textFile.close(); + + // Display the dialog + w.open(); + w.writeString(Common::String::format(Res.LLOYDS_BEACON, + mapName.c_str(), c._lloydPosition.x, c._lloydPosition.y)); + drawButtons(&windows[0]); + w.update(); + + bool result = true; + do { + do { + events.updateGameCounter(); + intf.draw3d(true); + + do { + events.pollEventsAndWait(); + if (_vm->shouldExit()) + return true; + + checkEvents(_vm); + } while (!_buttonValue && events.timeElapsed() < 1); + } while (!_buttonValue); + + switch (_buttonValue) { + case Common::KEYCODE_r: + if (!isDarkCc && c._lloydMap >= 75 && c._lloydMap <= 78 && !party._cloudsEnd) { + result = false; + } else { + sound.playFX(51); + map._loadDarkSide = isDarkCc; + if (c._lloydMap != party._mazeId || c._lloydSide != (isDarkCc ? 1 : 0)) { + map.load(c._lloydMap); + } + + party._mazePosition = c._lloydPosition; + } + + _buttonValue = Common::KEYCODE_ESCAPE; + break; + + case Common::KEYCODE_s: + case Common::KEYCODE_t: + sound.playFX(20); + c._lloydMap = party._mazeId; + c._lloydPosition = party._mazePosition; + c._lloydSide = isDarkCc ? 1 : 0; + + _buttonValue = Common::KEYCODE_ESCAPE; + break; + } + } while (_buttonValue != Common::KEYCODE_ESCAPE); + + w.close(); + return result; +} + +void LloydsBeacon::loadButtons() { + _iconSprites.load("lloyds.icn"); + + addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_r, &_iconSprites); + addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_iconSprites); +} + +/*------------------------------------------------------------------------*/ + +int Teleport::show(XeenEngine *vm) { + Teleport *dlg = new Teleport(vm); + int result = dlg->execute(); + delete dlg; + + return result; +} + +int Teleport::execute() { + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Windows &windows = *_vm->_windows; + Window &w = windows[6]; + Common::String num; + + w.open(); + w.writeString(Common::String::format(Res.HOW_MANY_SQUARES, + Res.DIRECTION_TEXT[party._mazeDirection])); + w.update(); + int lineSize = Input::show(_vm, &w, num, 1, 200, true); + w.close(); + + if (!lineSize) + return -1; + int numSquares = atoi(num.c_str()); + Common::Point pt = party._mazePosition; + int v; + + switch (party._mazeDirection) { + case DIR_NORTH: + pt.y += numSquares; + break; + case DIR_EAST: + pt.x += numSquares; + break; + case DIR_SOUTH: + pt.y -= numSquares; + break; + case DIR_WEST: + pt.x -= numSquares; + break; + default: + break; + } + + v = map.mazeLookup(pt, map._isOutdoors ? 0xF : 0xFFFF, 0); + + if ((v != (map._isOutdoors ? 0 : INVALID_CELL)) && + (!map._isOutdoors || v == SURFTYPE_DWATER)) { + party._mazePosition = pt; + return 1; + } else { + return 0; + } +} + +/*------------------------------------------------------------------------*/ + +int TownPortal::show(XeenEngine *vm) { + TownPortal *dlg = new TownPortal(vm); + int townNumber = dlg->execute(); + delete dlg; + + return townNumber; +} + +int TownPortal::execute() { + Map &map = *_vm->_map; + Windows &windows = *_vm->_windows; + Window &w = windows[20]; + Common::String townNames[5]; + Mode oldMode = _vm->_mode; + _vm->_mode = MODE_FF; + + // Build up a lsit of the names of the towns on the current side of Xeen + for (int idx = 0; idx < 5; ++idx) { + File f(Common::String::format("%s%04d.txt", + map._sideTownPortal ? "dark" : "xeen", + Res.TOWN_MAP_NUMBERS[map._sideTownPortal][idx])); + townNames[idx] = f.readString(); + f.close(); + } + + w.open(); + w.writeString(Common::String::format(Res.TOWN_PORTAL, + townNames[0].c_str(), townNames[1].c_str(), townNames[2].c_str(), + townNames[3].c_str(), townNames[4].c_str() + )); + w.update(); + + // Get the town number + int townNumber; + Common::String num; + do { + int result = Input::show(_vm, &w, num, 1, 160, true); + townNumber = !result ? 0 : atoi(num.c_str()); + } while (townNumber > 5); + + w.close(); + _vm->_mode = oldMode; + + return townNumber; +} + +/*------------------------------------------------------------------------*/ + +void IdentifyMonster::show(XeenEngine *vm) { + IdentifyMonster *dlg = new IdentifyMonster(vm); + dlg->execute(); + delete dlg; +} + +void IdentifyMonster::execute() { + Combat &combat = *_vm->_combat; + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Sound &sound = *_vm->_sound; + Windows &windows = *_vm->_windows; + Window &w = windows[17]; + Common::String monsterDesc[3]; + + for (int monIndex = 0; monIndex < 3; ++monIndex) { + if (combat._attackMonsters[monIndex] == -1) + continue; + + MazeMonster &monster = map._mobData._monsters[combat._attackMonsters[monIndex]]; + MonsterStruct &monsterData = *monster._monsterData; + + monsterDesc[monIndex] = Common::String::format(Res.MONSTER_DETAILS, + monsterData._name.c_str(), + _vm->printK2(monster._hp).c_str(), + monsterData._armorClass, monsterData._numberOfAttacks, + Res.MONSTER_SPECIAL_ATTACKS[monsterData._specialAttack] + ); + } + + sound.playFX(20); + w.open(); + w.writeString(Common::String::format(Res.IDENTIFY_MONSTERS, + monsterDesc[0].c_str(), monsterDesc[1].c_str(), monsterDesc[2].c_str())); + w.update(); + + do { + events.updateGameCounter(); + intf.draw3d(false); + w.frame(); + windows[3].update(); + + events.wait(1, false); + } while (!events.isKeyMousePressed()); + + w.close(); +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_spells.h b/engines/xeen/dialogs/dialogs_spells.h new file mode 100644 index 0000000000..2bcaef43e5 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_spells.h @@ -0,0 +1,151 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_SPELLS_H +#define XEEN_DIALOGS_SPELLS_H + +#include "common/array.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/party.h" + +namespace Xeen { + +struct SpellEntry { + Common::String _name; + int _spellIndex; + int _spellId; + int _color; + + SpellEntry(const Common::String &name, int spellIndex, int spellId) : + _name(name), _spellIndex(spellIndex), _spellId(spellId), _color(9) {} +}; + +class SpellsDialog : public ButtonContainer { +private: + SpriteResource _iconSprites; + SpriteResource _scrollSprites; + Common::Array _spells; + + SpellsDialog(XeenEngine *vm) : ButtonContainer(vm) {} + + Character *execute(ButtonContainer *priorDialog, Character *c, int isCasting); + + void loadButtons(); + + const char *setSpellText(Character *c, int isCasting); +public: + static Character *show(XeenEngine *vm, ButtonContainer *priorDialog, + Character *c, int isCasting); +}; + +class CastSpell : public ButtonContainer { +private: + SpriteResource _iconSprites; + int _oldMode; +private: + CastSpell(XeenEngine *vm); + ~CastSpell(); + + int execute(Character *&c); + + void loadButtons(); +public: + static int show(XeenEngine *vm); + static int show(XeenEngine *vm, Character *&c); +}; + +class SpellOnWho : public ButtonContainer { +private: + SpellOnWho(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(int spellId); +public: + static Character *show(XeenEngine *vm, int spellId); +}; + +class SelectElement : public ButtonContainer { +private: + SpriteResource _iconSprites; + + SelectElement(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(int spellId); + + void loadButtons(); +public: + static int show(XeenEngine *vm, int spellId); +}; + +class NotWhileEngaged : public ButtonContainer { +private: + NotWhileEngaged(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(int spellId); +public: + static void show(XeenEngine *vm, int spellId); +}; + +class LloydsBeacon : public ButtonContainer { +private: + SpriteResource _iconSprites; + + LloydsBeacon(XeenEngine *vm) : ButtonContainer(vm) {} + + bool execute(); + + void loadButtons(); +public: + static bool show(XeenEngine *vm); +}; + +class Teleport : public ButtonContainer { +private: + SpriteResource _iconSprites; + + Teleport(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(); +public: + static int show(XeenEngine *vm); +}; + +class TownPortal : public ButtonContainer { +private: + TownPortal(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(); +public: + static int show(XeenEngine *vm); +}; + +class IdentifyMonster : public ButtonContainer { +private: + IdentifyMonster(XeenEngine *vm) : ButtonContainer(vm) {} + + void execute(); +public: + static void show(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_SPELLS_H */ diff --git a/engines/xeen/dialogs/dialogs_whowill.cpp b/engines/xeen/dialogs/dialogs_whowill.cpp new file mode 100644 index 0000000000..842804219b --- /dev/null +++ b/engines/xeen/dialogs/dialogs_whowill.cpp @@ -0,0 +1,105 @@ +/* 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/dialogs_whowill.h" +#include "xeen/resources.h" +#include "xeen/xeen.h" + +namespace Xeen { + +int WhoWill::show(XeenEngine *vm, int message, int action, bool type) { + WhoWill *dlg = new WhoWill(vm); + int result = dlg->execute(message, action, type); + delete dlg; + + return result; +} + +int WhoWill::execute(int message, int action, bool type) { + EventsManager &events = *_vm->_events; + Interface &intf = *_vm->_interface; + Map &map = *_vm->_map; + Party &party = *_vm->_party; + Scripts &scripts = *_vm->_scripts; + LocationManager &loc = *_vm->_locations; + Windows &windows = *_vm->_windows; + int numFrames; + + if (party._activeParty.size() <= 1) + // Unless there's at least two characters, just return the first one + return 1; + + windows[38].close(); + windows[12].close(); + + Common::String actionStr = type ? map._events._text[action] : Res.WHO_WILL_ACTIONS[action]; + Common::String msg = Common::String::format(Res.WHO_WILL, actionStr.c_str(), + Res.WHO_ACTIONS[message], party._activeParty.size()); + + windows[36].open(); + windows[36].writeString(msg); + windows[36].update(); + + intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; + intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; + + while (!_vm->shouldExit()) { + events.updateGameCounter(); + + if (windows[11]._enabled) { + loc.drawAnim(false); + windows[36].frame(); + numFrames = 3; + } else { + intf.draw3d(false); + windows[36].frame(); + windows[3].update(); + numFrames = 1; + } + + events.wait(numFrames); + checkEvents(_vm); + if (!_buttonValue) + continue; + + if (_buttonValue == 27) { + _buttonValue = 0; + break; + } else if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { + _buttonValue -= Common::KEYCODE_F1 - 1; + if (_buttonValue > (int)party._activeParty.size()) + continue; + + if (party._activeParty[_buttonValue - 1].noActions()) + continue; + + scripts._whoWill = _buttonValue; + break; + } + } + + intf._face1State = intf._face2State = 2; + windows[36].close(); + return _buttonValue; +} + +} // End of namespace Xeen diff --git a/engines/xeen/dialogs/dialogs_whowill.h b/engines/xeen/dialogs/dialogs_whowill.h new file mode 100644 index 0000000000..5303bdbea3 --- /dev/null +++ b/engines/xeen/dialogs/dialogs_whowill.h @@ -0,0 +1,41 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DIALOGS_WHOWHILL_H +#define XEEN_DIALOGS_WHOWHILL_H + +#include "xeen/dialogs/dialogs.h" + +namespace Xeen { + +class WhoWill : public ButtonContainer { +private: + WhoWill(XeenEngine *vm) : ButtonContainer(vm) {} + + int execute(int message, int action, bool type); +public: + static int show(XeenEngine *vm, int message, int action, bool type); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DIALOGS_WHOWHILL_H */ diff --git a/engines/xeen/dialogs_awards.cpp b/engines/xeen/dialogs_awards.cpp deleted file mode 100644 index 242539c20b..0000000000 --- a/engines/xeen/dialogs_awards.cpp +++ /dev/null @@ -1,131 +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_awards.h" -#include "xeen/party.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void Awards::show(XeenEngine *vm, const Character *ch) { - Awards *dlg = new Awards(vm); - dlg->execute(ch); - delete dlg; -} - -void Awards::execute(const Character *ch) { - EventsManager &events = *g_vm->_events; - Windows &windows = *g_vm->_windows; - Common::StringArray awards; - int numAwards; - Mode oldMode = g_vm->_mode; - int topIndex = 0; - - loadStrings("award.bin", 1); - addButtons(); - - // Open the window and draw contents - bool win29Open = windows[29]._enabled; - if (!win29Open) { - windows[29].open(); - windows[30].open(); - } - - windows[29].writeString(Res.AWARDS_TEXT); - drawButtons(&windows[0]); - - while (!_vm->shouldExit()) { - // Build up a list of awards the character has - awards.clear(); - awards.resize(AWARDS_TOTAL); - numAwards = 0; - - for (int awardNum = 0; awardNum < AWARDS_TOTAL; ++awardNum) { - if (ch->hasAward(awardNum)) { - if (awardNum == 9) { - // # Warzone Wins - awards[numAwards] = Common::String::format(_textStrings[9].c_str(), 28); - } else if (awardNum == 17) { - // Legendary Race - awards[numAwards] = Common::String::format(_textStrings[17].c_str(), - Res.RACE_NAMES[ch->_race]); - } else { - awards[numAwards] = _textStrings[awardNum]; - } - ++numAwards; - } - } - - // If no awards, add in a message indicating so - if (numAwards == 0) { - awards[1] = Res.NO_AWARDS; - } - - Common::String msg = Common::String::format(Res.AWARDS_FOR, - ch->_name.c_str(), Res.CLASS_NAMES[ch->_class], - awards[topIndex].c_str(), - awards[topIndex + 1].c_str(), - awards[topIndex + 2].c_str(), - awards[topIndex + 3].c_str(), - awards[topIndex + 4].c_str(), - awards[topIndex + 5].c_str(), - awards[topIndex + 6].c_str(), - awards[topIndex + 7].c_str(), - awards[topIndex + 8].c_str() - ); - windows[30].writeString(msg); - windows[24].update(); - - // Wait for keypress - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!g_vm->shouldExit() && !_buttonValue); - - if (_buttonValue == Common::KEYCODE_ESCAPE) { - break; - } else if (_buttonValue == Common::KEYCODE_u) { - topIndex = MAX(topIndex - 1, 0); - } else if (_buttonValue == Common::KEYCODE_d) { - if ((++topIndex + 9) > numAwards) - --topIndex; - } - } - - // Close the window - if (win29Open) { - windows[30].close(); - windows[29].close(); - } - - g_vm->_mode = oldMode; -} - -void Awards::addButtons() { - _iconSprites.load("award.icn"); - addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_u, &_iconSprites); - addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_d, &_iconSprites); - addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_awards.h b/engines/xeen/dialogs_awards.h deleted file mode 100644 index 6ce3a05f59..0000000000 --- a/engines/xeen/dialogs_awards.h +++ /dev/null @@ -1,52 +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_DIALOGS_AWARDS_H -#define XEEN_DIALOGS_AWARDS_H - -#include "xeen/dialogs.h" -#include "xeen/character.h" - -namespace Xeen { - -class Awards : public ButtonContainer { -private: - SpriteResource _iconSprites; -private: - Awards(XeenEngine *vm) : ButtonContainer(vm) {} - - /** - * Executes the dialog - */ - void execute(const Character *ch); - - /** - * Add buttons for the dialog - */ - void addButtons(); -public: - static void show(XeenEngine *vm, const Character *ch); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_AWARDS_H */ diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp deleted file mode 100644 index 3d9ebfb2e0..0000000000 --- a/engines/xeen/dialogs_char_info.cpp +++ /dev/null @@ -1,571 +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_awards.h" -#include "xeen/dialogs_char_info.h" -#include "xeen/dialogs_exchange.h" -#include "xeen/dialogs_items.h" -#include "xeen/dialogs_quick_ref.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void CharacterInfo::show(XeenEngine *vm, int charIndex) { - CharacterInfo *dlg = new CharacterInfo(vm); - dlg->execute(charIndex); - delete dlg; -} - -void CharacterInfo::execute(int charIndex) { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - - bool redrawFlag = true; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_CHARACTER_INFO; - loadDrawStructs(); - addButtons(); - - Character *c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : combat._combatParty[charIndex]; - intf.highlightChar(charIndex); - Window &w = windows[24]; - w.open(); - - do { - if (redrawFlag) { - Common::String charDetails = loadCharacterDetails(*c); - w.writeString(Common::String::format(Res.CHARACTER_TEMPLATE, charDetails.c_str())); - w.drawList(_drawList, 24); - w.update(); - redrawFlag = false; - } - - // Wait for keypress, showing a blinking cursor - events.updateGameCounter(); - bool cursorFlag = false; - _buttonValue = 0; - while (!_vm->shouldExit() && !_buttonValue) { - events.pollEventsAndWait(); - if (events.timeElapsed() > 4) { - cursorFlag = !cursorFlag; - events.updateGameCounter(); - } - - showCursor(cursorFlag); - w.update(); - checkEvents(_vm); - } - events.clearEvents(); - - switch (_buttonValue) { - case Common::KEYCODE_F1: - case Common::KEYCODE_F2: - case Common::KEYCODE_F3: - case Common::KEYCODE_F4: - case Common::KEYCODE_F5: - case Common::KEYCODE_F6: - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)(oldMode == MODE_COMBAT ? combat._combatParty.size() : party._activeParty.size())) { - charIndex = _buttonValue; - c = (oldMode != MODE_COMBAT) ? &party._activeParty[charIndex] : combat._combatParty[charIndex]; - } else { - _vm->_mode = MODE_CHARACTER_INFO; - } - - intf.highlightChar(_buttonValue); - redrawFlag = true; - break; - - case Common::KEYCODE_UP: - case Common::KEYCODE_KP8: - if (_cursorCell > 0) { - showCursor(false); - --_cursorCell; - showCursor(true); - } - w.update(); - break; - - case Common::KEYCODE_DOWN: - case Common::KEYCODE_KP2: - if (_cursorCell < 20) { - showCursor(false); - ++_cursorCell; - showCursor(true); - } - w.update(); - break; - - case Common::KEYCODE_LEFT: - case Common::KEYCODE_KP4: - if (_cursorCell >= 5) { - showCursor(false); - _cursorCell -= 5; - showCursor(true); - } - w.update(); - break; - - case Common::KEYCODE_RIGHT: - case Common::KEYCODE_KP6: - if (_cursorCell <= 15) { - showCursor(false); - _cursorCell += 5; - showCursor(true); - } - w.update(); - break; - - case Common::KEYCODE_RETURN: - case Common::KEYCODE_KP_ENTER: - _buttonValue = _cursorCell + Common::KEYCODE_a; - // Deliberate fall-through - - case 1001: - case 1002: - case 1003: - case 1004: - case 1005: - case 1006: - case 1007: - case 1008: - case 1009: - case 1010: - case 1011: - case 1012: - case 1013: - case 1014: - case 1015: - case 1016: - case 1017: - case 1018: - case 1019: - case 1020: { - showCursor(false); - _cursorCell = _buttonValue - 1001; - showCursor(true); - w.update(); - - bool result = expandStat(_cursorCell, *c); - _vm->_mode = MODE_COMBAT; - if (result) - redrawFlag = true; - break; - } - - case Common::KEYCODE_e: - if (oldMode == MODE_COMBAT) { - ErrorScroll::show(_vm, Res.EXCHANGING_IN_COMBAT, WT_FREEZE_WAIT); - } else { - _vm->_mode = oldMode; - ExchangeDialog::show(_vm, c, charIndex); - _vm->_mode = MODE_CHARACTER_INFO; - redrawFlag = true; - } - break; - - case Common::KEYCODE_i: - _vm->_mode = oldMode; - _vm->_combat->_itemFlag = _vm->_mode == MODE_COMBAT; - c = ItemsDialog::show(_vm, c, ITEMMODE_CHAR_INFO); - - if (!c) { - party._stepped = true; - goto exit; - } - - _vm->_mode = MODE_CHARACTER_INFO; - break; - - case Common::KEYCODE_q: - QuickReferenceDialog::show(_vm); - redrawFlag = true; - break; - - case Common::KEYCODE_ESCAPE: - goto exit; - } - } while (!_vm->shouldExit()); -exit: - w.close(); - intf.unhighlightChar(); - _vm->_mode = oldMode; - _vm->_combat->_itemFlag = false; -} - -void CharacterInfo::loadDrawStructs() { - _drawList[0] = DrawStruct(0, 2, 16); - _drawList[1] = DrawStruct(2, 2, 39); - _drawList[2] = DrawStruct(4, 2, 62); - _drawList[3] = DrawStruct(6, 2, 85); - _drawList[4] = DrawStruct(8, 2, 108); - _drawList[5] = DrawStruct(10, 53, 16); - _drawList[6] = DrawStruct(12, 53, 39); - _drawList[7] = DrawStruct(14, 53, 62); - _drawList[8] = DrawStruct(16, 53, 85); - _drawList[9] = DrawStruct(18, 53, 108); - _drawList[10] = DrawStruct(20, 104, 16); - _drawList[11] = DrawStruct(22, 104, 39); - _drawList[12] = DrawStruct(24, 104, 62); - _drawList[13] = DrawStruct(26, 104, 85); - _drawList[14] = DrawStruct(28, 104, 108); - _drawList[15] = DrawStruct(30, 169, 16); - _drawList[16] = DrawStruct(32, 169, 39); - _drawList[17] = DrawStruct(34, 169, 62); - _drawList[18] = DrawStruct(36, 169, 85); - _drawList[19] = DrawStruct(38, 169, 108); - _drawList[20] = DrawStruct(40, 277, 3); - _drawList[21] = DrawStruct(42, 277, 35); - _drawList[22] = DrawStruct(44, 277, 67); - _drawList[23] = DrawStruct(46, 277, 99); - - _iconSprites.load("view.icn"); - for (int idx = 0; idx < 24; ++idx) - _drawList[idx]._sprites = &_iconSprites; -} - -void CharacterInfo::addButtons() { - addButton(Common::Rect(10, 24, 34, 44), 1001, &_iconSprites); - addButton(Common::Rect(10, 47, 34, 67), 1002, &_iconSprites); - addButton(Common::Rect(10, 70, 34, 90), 1003, &_iconSprites); - addButton(Common::Rect(10, 93, 34, 113), 1004, &_iconSprites); - addButton(Common::Rect(10, 116, 34, 136), 1005, &_iconSprites); - addButton(Common::Rect(61, 24, 85, 44), 1006, &_iconSprites); - addButton(Common::Rect(61, 47, 85, 67), 1007, &_iconSprites); - addButton(Common::Rect(61, 70, 85, 90), 1008, &_iconSprites); - addButton(Common::Rect(61, 93, 85, 113), 1009, &_iconSprites); - addButton(Common::Rect(61, 116, 85, 136), 1010, &_iconSprites); - addButton(Common::Rect(112, 24, 136, 44), 1011, &_iconSprites); - addButton(Common::Rect(112, 47, 136, 67), 1012, &_iconSprites); - addButton(Common::Rect(112, 70, 136, 90), 1013, &_iconSprites); - addButton(Common::Rect(112, 93, 136, 113), 1014, &_iconSprites); - addButton(Common::Rect(112, 116, 136, 136), 1015, &_iconSprites); - addButton(Common::Rect(177, 24, 201, 44), 1016, &_iconSprites); - addButton(Common::Rect(177, 47, 201, 67), 1017, &_iconSprites); - addButton(Common::Rect(177, 70, 201, 90), 1018, &_iconSprites); - addButton(Common::Rect(177, 93, 201, 113), 1019, &_iconSprites); - addButton(Common::Rect(177, 116, 201, 136), 1020, &_iconSprites); - addButton(Common::Rect(285, 11, 309, 31), Common::KEYCODE_i, &_iconSprites); - addButton(Common::Rect(285, 43, 309, 63), Common::KEYCODE_q, &_iconSprites); - addButton(Common::Rect(285, 75, 309, 95), Common::KEYCODE_e, &_iconSprites); - addButton(Common::Rect(285, 107, 309, 127), Common::KEYCODE_ESCAPE, &_iconSprites); - addPartyButtons(_vm); -} - -Common::String CharacterInfo::loadCharacterDetails(const Character &c) { - Condition condition = c.worstCondition(); - Party &party = *_vm->_party; - int foodVal = party._food / party._activeParty.size() / 3; - - int totalResist = - c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary + - c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary + - c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary + - c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary + - c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary + - c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary; - - return Common::String::format(Res.CHARACTER_DETAILS, - Res.PARTY_GOLD, c._name.c_str(), Res.SEX_NAMES[c._sex], - Res.RACE_NAMES[c._race], Res.CLASS_NAMES[c._class], - c.statColor(c.getStat(MIGHT), c.getStat(MIGHT, true)), c.getStat(MIGHT), - c.statColor(c.getStat(ACCURACY), c.getStat(ACCURACY, true)), c.getStat(ACCURACY), - c.statColor(c._currentHp, c.getMaxHP()), c._currentHp, - c.getCurrentExperience(), - c.statColor(c.getStat(INTELLECT), c.getStat(INTELLECT, true)), c.getStat(INTELLECT), - c.statColor(c.getStat(LUCK), c.getStat(LUCK, true)), c.getStat(LUCK), - c.statColor(c._currentSp, c.getMaxSP()), c._currentSp, - party._gold, - c.statColor(c.getStat(PERSONALITY), c.getStat(PERSONALITY, true)), c.getStat(PERSONALITY), - c.statColor(c.getAge(), c.getAge(true)), c.getAge(), - totalResist, - party._gems, - c.statColor(c.getStat(ENDURANCE), c.getStat(ENDURANCE, true)), c.getStat(ENDURANCE), - c.statColor(c.getCurrentLevel(), c._level._permanent), c.getCurrentLevel(), - c.getNumSkills(), - foodVal, (foodVal == 1) ? ' ' : 's', - c.statColor(c.getStat(SPEED), c.getStat(SPEED, true)), c.getStat(SPEED), - c.statColor(c.getArmorClass(), c.getArmorClass(true)), c.getArmorClass(), - c.getNumAwards(), - Res.CONDITION_COLORS[condition], Res.CONDITION_NAMES[condition], - condition == NO_CONDITION && party._blessed ? Res.PLUS_14 : "", - condition == NO_CONDITION && party._powerShield ? Res.PLUS_14 : "", - condition == NO_CONDITION && party._holyBonus ? Res.PLUS_14 : "", - condition == NO_CONDITION && party._heroism ? Res.PLUS_14 : "" - ); -} - -void CharacterInfo::showCursor(bool flag) { - const int CURSOR_X[5] = { 9, 60, 111, 176, 0 }; - const int CURSOR_Y[5] = { 23, 46, 69, 92, 115 }; - - if (_cursorCell < 20) { - _iconSprites.draw(0, flag ? 49 : 48, - Common::Point(CURSOR_X[_cursorCell / 5], CURSOR_Y[_cursorCell % 5])); - } -} - -bool CharacterInfo::expandStat(int attrib, const Character &c) { - const int STAT_POS[2][20] = { - { - 61, 61, 61, 61, 61, 112, 112, 112, 112, 112, - 177, 177, 177, 177, 177, 34, 34, 34, 34, 34 - }, { - 24, 47, 70, 93, 116, 24, 47, 70, 93, 116, - 24, 47, 70, 93, 116, 24, 47, 70, 93, 116 - } - }; - assert(attrib < 20); - Common::Rect bounds(STAT_POS[0][attrib], STAT_POS[1][attrib], - STAT_POS[0][attrib] + 143, STAT_POS[1][attrib] + 52); - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - uint stat1, stat2; - uint idx; - Common::String msg; - - switch (attrib) { - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - case 6: - // Basic attributes - stat1 = c.getStat((Attribute)attrib, false); - stat2 = c.getStat((Attribute)attrib, true); - idx = 0; - while (Res.STAT_VALUES[idx] <= (int)stat1) - ++idx; - - msg = Common::String::format(Res.CURRENT_MAXIMUM_RATING_TEXT, Res.STAT_NAMES[attrib], - stat1, stat2, Res.RATING_TEXT[idx]); - break; - - case 7: - // Age - stat1 = c.getAge(false); - stat2 = c.getAge(true); - msg = Common::String::format(Res.AGE_TEXT, Res.STAT_NAMES[attrib], - stat1, stat2, c._birthDay, c._birthYear); - break; - - case 8: { - // Level - const int CLASS_ATTACK_GAINS[10] = { 5, 6, 6, 7, 8, 6, 5, 4, 7, 6 }; - idx = c.getCurrentLevel() / CLASS_ATTACK_GAINS[c._class] + 1; - - msg = Common::String::format(Res.LEVEL_TEXT, Res.STAT_NAMES[attrib], - c.getCurrentLevel(), c._level._permanent, - idx, idx > 1 ? "s" : "", - c._level._permanent); - break; - } - - case 9: - // Armor Class - stat1 = c.getArmorClass(false); - stat2 = c.getArmorClass(true); - msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], - stat1, stat2); - bounds.setHeight(42); - break; - - case 10: - // Hit Points - stat1 = c._currentHp; - stat2 = c.getMaxHP(); - msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], - stat1, stat2); - bounds.setHeight(42); - break; - - case 11: - // Spell Points - stat1 = c._currentSp; - stat2 = c.getMaxSP(); - msg = Common::String::format(Res.CURRENT_MAXIMUM_TEXT, Res.STAT_NAMES[attrib], - stat1, stat2); - bounds.setHeight(42); - break; - - case 12: - // Resistences - msg = Common::String::format(Res.RESISTENCES_TEXT, Res.STAT_NAMES[attrib], - c._fireResistence._permanent + c.itemScan(11) + c._fireResistence._temporary, - c._coldResistence._permanent + c.itemScan(13) + c._coldResistence._temporary, - c._electricityResistence._permanent + c.itemScan(12) + c._electricityResistence._temporary, - c._poisonResistence._permanent + c.itemScan(14) + c._poisonResistence._temporary, - c._energyResistence._permanent + c.itemScan(15) + c._energyResistence._temporary, - c._magicResistence._permanent + c.itemScan(16) + c._magicResistence._temporary); - bounds.setHeight(80); - break; - - case 13: { - // Skills - Common::String lines[20]; - int numLines = c.getNumSkills(); - if (numLines > 0) { - for (int skill = THIEVERY; skill <= DANGER_SENSE; ++skill) { - if (c._skills[skill]) { - if (skill == THIEVERY) { - lines[0] = Common::String::format("\n\t020%s%u", - Res.SKILL_NAMES[THIEVERY], c.getThievery()); - } else { - lines[skill] = Common::String::format("\n\t020%s", Res.SKILL_NAMES[skill]); - } - } - } - } else { - lines[0] = Res.NONE; - numLines = 1; - } - - msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - Res.STAT_NAMES[attrib], lines[0].c_str(), lines[1].c_str(), - lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), lines[5].c_str(), - lines[17].c_str(), lines[6].c_str(), lines[7].c_str(), lines[8].c_str(), - lines[9].c_str(), lines[10].c_str(), lines[11].c_str(), lines[12].c_str(), - lines[13].c_str(), lines[16].c_str(), lines[14].c_str(), lines[15].c_str()); - - bounds.top -= (numLines / 2) * 8; - bounds.setHeight(numLines * 9 + 26); - if (bounds.bottom >= SCREEN_HEIGHT) - bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1); - break; - } - - case 14: - // Awards - Awards::show(_vm, &c); - return false; - - case 15: - // Experience - stat1 = c.getCurrentExperience(); - stat2 = c.experienceToNextLevel(); - msg = Common::String::format(Res.EXPERIENCE_TEXT, - Res.STAT_NAMES[attrib], stat1, - stat2 == 0 ? Res.ELIGIBLE : Common::String::format("%d", stat2).c_str() - ); - bounds.setHeight(43); - break; - - case 16: - // Gold - msg = Common::String::format(Res.IN_PARTY_IN_BANK, Res.CONSUMABLE_NAMES[0], - party._gold, party._bankGold); - bounds.setHeight(43); - break; - - case 17: - // Gems - msg = Common::String::format(Res.IN_PARTY_IN_BANK, Res.CONSUMABLE_NAMES[1], - party._gems, party._bankGems); - bounds.setHeight(43); - break; - - case 18: { - // Food - int food = (party._food / party._activeParty.size()) / 3; - msg = Common::String::format(Res.FOOD_TEXT, Res.CONSUMABLE_NAMES[2], - party._food, food, food != 1 ? "s" : ""); - break; - } - - case 19: { - // Conditions - Common::String lines[20]; - int total = 0; - for (int condition = CURSED; condition <= ERADICATED; ++condition) { - if (c._conditions[condition]) { - if (condition >= UNCONSCIOUS) { - lines[condition] = Common::String::format("\n\t020%s", - Res.CONDITION_NAMES[condition]); - } else { - lines[condition] = Common::String::format("\n\t020%s\t095-%d", - Res.CONDITION_NAMES[condition], c._conditions[condition]); - } - - ++total; - } - } - - Condition condition = c.worstCondition(); - if (condition == NO_CONDITION) { - lines[0] = Common::String::format("\n\t020%s", Res.GOOD); - ++total; - } - - if (party._blessed) - lines[16] = Common::String::format(Res.BLESSED, party._blessed); - if (party._powerShield) - lines[17] = Common::String::format(Res.POWER_SHIELD, party._powerShield); - if (party._holyBonus) - lines[18] = Common::String::format(Res.HOLY_BONUS, party._holyBonus); - if (party._heroism) - lines[19] = Common::String::format(Res.HEROISM, party._heroism); - - msg = Common::String::format("\x2\x3""c%s\x3l%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\x1", - Res.CONSUMABLE_NAMES[3], lines[0].c_str(), lines[1].c_str(), - lines[2].c_str(), lines[3].c_str(), lines[4].c_str(), - lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), - lines[8].c_str(), lines[9].c_str(), lines[10].c_str(), - lines[11].c_str(), lines[12].c_str(), lines[13].c_str(), - lines[14].c_str(), lines[15].c_str(), lines[16].c_str(), - lines[17].c_str(), lines[18].c_str(), lines[19].c_str() - ); - - bounds.top -= ((total - 1) / 2) * 8; - bounds.setHeight(total * 9 + 26); - if (bounds.bottom >= SCREEN_HEIGHT) - bounds.moveTo(bounds.left, SCREEN_HEIGHT - bounds.height() - 1); - break; - } - - default: - break; - } - - // Write the data for the stat display - Window &w = windows[28]; - w.setBounds(bounds); - w.open(); - w.writeString(msg); - w.update(); - - // Wait for a user key/click - EventsManager &events = *_vm->_events; - while (!_vm->shouldExit() && !events.isKeyMousePressed()) - events.pollEventsAndWait(); - events.clearEvents(); - - w.close(); - return false; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_char_info.h b/engines/xeen/dialogs_char_info.h deleted file mode 100644 index 5f538700f9..0000000000 --- a/engines/xeen/dialogs_char_info.h +++ /dev/null @@ -1,69 +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_DIALOGS_CHAR_INFO_H -#define XEEN_DIALOGS_CHAR_INFO_H - -#include "xeen/dialogs.h" -#include "xeen/party.h" -#include "xeen/window.h" - -namespace Xeen { - -class CharacterInfo : public ButtonContainer { -private: - SpriteResource _iconSprites; - DrawStruct _drawList[24]; - int _cursorCell; - - CharacterInfo(XeenEngine *vm) : ButtonContainer(vm), _cursorCell(0) {} - - void execute(int charIndex); - - /** - * Load the draw structure list with frame numbers and positions - */ - void loadDrawStructs(); - - /** - * Set up the button list for the dialog - */ - void addButtons(); - - /** - * Return a string containing the details of the character - */ - Common::String loadCharacterDetails(const Character &c); - - /** - * Cursor display handling - */ - void showCursor(bool flag); - - bool expandStat(int attrib, const Character &c); -public: - static void show(XeenEngine *vm, int charIndex); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_CHAR_INFO_H */ diff --git a/engines/xeen/dialogs_control_panel.cpp b/engines/xeen/dialogs_control_panel.cpp deleted file mode 100644 index d2129e46c2..0000000000 --- a/engines/xeen/dialogs_control_panel.cpp +++ /dev/null @@ -1,220 +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_control_panel.h" -#include "xeen/dialogs_query.h" -#include "xeen/party.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -int ControlPanel::show(XeenEngine *vm) { - ControlPanel *dlg = new ControlPanel(vm); - int result = dlg->execute(); - delete dlg; - - return result; -} - -int ControlPanel::execute() { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - SavesManager &saves = *_vm->_saves; - Sound &sound = *_vm->_sound; - Windows &windows = *_vm->_windows; - Window &w = windows[23]; - Window &w3 = windows[3]; - - loadButtons(); - - int result = 0, debugCtr = 0; - w.open(); - - do { - Common::String btnText = getButtonText(); - Common::String text = Common::String::format(Res.CONTROL_PANEL_TEXT, btnText.c_str()); - - drawButtons(&w); - w.writeString(text); - w.writeString("\xB""000\t000\x1"); - w.update(); - - do { - events.updateGameCounter(); - intf.draw3d(false, false); - w.writeString("\r"); - drawButtons(&w); - w.writeString(text); - w.writeString("\v000\t000"); - w.frame(); - - if (_debugFlag) - w.writeString(getTimeText()); - - w3.update(); - w.update(); - - events.pollEventsAndWait(); - checkEvents(_vm); - if (_vm->shouldExit()) - return 0; - } while (!_buttonValue && !events.timeElapsed()); - - switch (_buttonValue) { - case Common::KEYCODE_q: - if (Confirm::show(g_vm, Res.CONFIRM_QUIT)) { - g_vm->_gameMode = GMODE_QUIT; - result = 1; - } - break; - - case Common::KEYCODE_w: - if (Confirm::show(g_vm, Res.MR_WIZARD)) { - w.close(); - if (!windows[2]._enabled) { - sound.playFX(51); - - if (g_vm->getGameID() == GType_WorldOfXeen) { - map._loadDarkSide = false; - map.load(28); - party._mazeDirection = DIR_EAST; - } else { - map._loadDarkSide = true; - map.load(29); - party._mazeDirection = DIR_SOUTH; - } - party.moveToRunLocation(); - } - - party._gems = 0; - result = 2; - } - break; - - case Common::KEYCODE_l: - if (_vm->_mode == MODE_COMBAT) { - ErrorScroll::show(_vm, Res.NO_LOADING_IN_COMBAT); - } else { - // Close dialog and show loading dialog - result = 3; - } - break; - - case Common::KEYCODE_s: - if (_vm->_mode == MODE_COMBAT) { - ErrorScroll::show(_vm, Res.NO_SAVING_IN_COMBAT); - } else { - // Close dialog and show saving dialog - result = 4; - } - break; - - case Common::KEYCODE_e: - sound.setEffectsOn(!sound._soundOn); - break; - - case Common::KEYCODE_m: - sound.setMusicOn(!sound._musicOn); - break; - - case Common::KEYCODE_ESCAPE: - result = 1; - break; - - // Goober cheat sequence - case Common::KEYCODE_g: - debugCtr = 1; - break; - case Common::KEYCODE_o: - debugCtr = (debugCtr == 1 || debugCtr == 2) ? 2 : 0; - break; - case Common::KEYCODE_b: - debugCtr = (debugCtr == 2) ? 3 : 0; - break; - case Common::KEYCODE_r: - if (debugCtr == 3) - _debugFlag = true; - else - debugCtr = 0; - break; - - default: - break; - } - } while (!result); - - w.close(); - intf.drawParty(true); - - if (result == 3) { - saves.loadGame(); - } else if (result == 4) { - saves.saveGame(); - } - - return result; -} - -void ControlPanel::loadButtons() { - _iconSprites.load("cpanel.icn"); - - addButton(Common::Rect(214, 56, 244, 69), Common::KEYCODE_e, 0, &_iconSprites); - addButton(Common::Rect(214, 75, 244, 88), Common::KEYCODE_m, 0, &_iconSprites); - addButton(Common::Rect(135, 56, 165, 69), Common::KEYCODE_l, 0, &_iconSprites); - addButton(Common::Rect(135, 75, 165, 88), Common::KEYCODE_s, 0, &_iconSprites); - - // For ScummVM we've merged both Save and Save As into a single - // save item, so we don't need this one - addButton(Common::Rect(), 0); - - addButton(Common::Rect(135, 94, 165, 107), Common::KEYCODE_q, 0, &_iconSprites); - addButton(Common::Rect(175, 113, 205, 126), Common::KEYCODE_w, 0, &_iconSprites); -} - -Common::String ControlPanel::getButtonText() { - Sound &sound = *g_vm->_sound; - _btnSoundText = sound._soundOn ? Res.ON : Res.OFF; - _btnMusicText = sound._musicOn ? Res.ON : Res.OFF; - - return Common::String::format(Res.CONTROL_PANEL_BUTTONS, - _btnSoundText.c_str(), _btnMusicText.c_str()); -} - -Common::String ControlPanel::getTimeText() const { - TimeDate td; - g_system->getTimeAndDate(td); - Common::String timeStr = Common::String::format("%d:%.2d:%.2d%c", - td.tm_hour == 0 || td.tm_hour == 12 ? 12 : (td.tm_hour % 12), - td.tm_min, td.tm_sec, (td.tm_hour >= 12) ? 'p' : 'c'); - - uint32 playtime = g_vm->_events->playTime() / GAME_FRAME_RATE; - Common::String playtimeStr = Common::String::format("%d:%.2d:%.2d", - playtime / 3600, (playtime / 60) % 60, playtime % 60); - return Common::String::format( - "\x2\x3l\xB""000\t000\x4""160%s\x3r\xB""000\t000%s\x1", - timeStr.c_str(), playtimeStr.c_str()); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_control_panel.h b/engines/xeen/dialogs_control_panel.h deleted file mode 100644 index b87e78dd14..0000000000 --- a/engines/xeen/dialogs_control_panel.h +++ /dev/null @@ -1,66 +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_DIALOGS_CONTROL_PANEL_H -#define XEEN_DIALOGS_CONTROL_PANEL_H - -#include "xeen/dialogs.h" - -namespace Xeen { - -class ControlPanel : public ButtonContainer { -private: - SpriteResource _iconSprites; - Common::String _btnSoundText, _btnMusicText; - bool _debugFlag; -private: - ControlPanel(XeenEngine *vm) : ButtonContainer(vm), _debugFlag(false) {} - - /** - * Inner handler for showing the dialog - */ - int execute(); - - /** - * Loads the buttons for the dialog - */ - void loadButtons(); - - /** - * Gets the text for the dialog buttons - */ - Common::String getButtonText(); - - /** - * Gets the current time - */ - Common::String getTimeText() const; -public: - /** - * Show the control panel - */ - static int show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_CONTROL_PANEL_H */ diff --git a/engines/xeen/dialogs_create_char.cpp b/engines/xeen/dialogs_create_char.cpp deleted file mode 100644 index 73aa4b3f02..0000000000 --- a/engines/xeen/dialogs_create_char.cpp +++ /dev/null @@ -1,648 +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_create_char.h" -#include "xeen/dialogs_input.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void CreateCharacterDialog::show(XeenEngine *vm) { - CreateCharacterDialog *dlg = new CreateCharacterDialog(vm); - dlg->execute(); - delete dlg; -} - -CreateCharacterDialog::CreateCharacterDialog(XeenEngine *vm) : ButtonContainer(vm) { - Common::fill(&_attribs[0], &_attribs[TOTAL_ATTRIBUTES], 0); - Common::fill(&_allowedClasses[0], &_allowedClasses[TOTAL_CLASSES], false); - _dicePos[0] = Common::Point(20, 17); - _dicePos[1] = Common::Point(112, 35); - _dicePos[2] = Common::Point(61, 50); - _diceFrame[0] = 0; - _diceFrame[1] = 2; - _diceFrame[2] = 4; - _diceInc[0] = Common::Point(10, -10); - _diceInc[1] = Common::Point(-10, -10); - _diceInc[2] = Common::Point(-10, 10); - - _dice.load("dice.vga"); - _diceSize = _dice.getFrameSize(0); - - loadButtons(); -} - -void CreateCharacterDialog::execute() { - EventsManager &events = *_vm->_events; - Party &party = *_vm->_party; - Screen &screen = *_vm->_screen; - Windows &windows = *_vm->_windows; - Window &w = windows[0]; - Common::Array freeCharList; - int classId = -1; - int selectedClass = 0; - bool hasFadedIn = false; - bool restartFlag = true; - Race race = HUMAN; - Sex sex = MALE; - Common::String msg, details; - int charIndex = 0; - - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_4; - - // Load the background - screen.loadBackground("create.raw"); - events.setCursor(0); - - while (!_vm->shouldExit()) { - if (restartFlag) { - // Build up list of roster slot indexes that are free - freeCharList.clear(); - for (uint idx = 0; idx < XEEN_TOTAL_CHARACTERS; ++idx) { - if (party._roster[idx]._name.empty()) - freeCharList.push_back(idx); - } - charIndex = 0; - - if (freeCharList.size() == XEEN_TOTAL_CHARACTERS) - break; - - // Get and race and sex for the given character - race = (Race)((freeCharList[charIndex] / 4) % 5); - sex = (Sex)(freeCharList[charIndex] & 1); - - // Randomly determine attributes, and which classes they allow - rollAttributes(); - - // Get the display of the rolled character details - selectedClass = newCharDetails(race, sex, classId, selectedClass, details); - msg = Common::String::format(Res.CREATE_CHAR_DETAILS, - details.c_str()); - - // Draw the icons and the currently selected headshot - drawIcons(); - party._roster[freeCharList[charIndex]]._faceSprites->draw( - w, 0, Common::Point(27, 102)); - - // Render all on-screen text - w.writeString(msg); - w.update(); - - // Draw the arrow for the selected class, if applicable - if (selectedClass != -1) - printSelectionArrow(selectedClass); - - // Draw the dice - drawDice(); - if (!hasFadedIn) { - screen.fadeIn(); - hasFadedIn = true; - } - - restartFlag = false; - } - - // Animate the dice until a user action occurs - _buttonValue = 0; - while (!_vm->shouldExit() && !_buttonValue) - drawDice(); - - // Handling for different actions - if (_buttonValue == Common::KEYCODE_ESCAPE) - break; - - switch (_buttonValue) { - case Common::KEYCODE_UP: - if (charIndex == 0) - continue; - - --charIndex; - race = (Race)((freeCharList[charIndex] / 4) % 5); - sex = (Sex)(freeCharList[charIndex] & 1); - break; - - case Common::KEYCODE_DOWN: - if (++charIndex == (int)freeCharList.size()) { - --charIndex; - continue; - } else { - race = (Race)((freeCharList[charIndex] / 4) % 5); - sex = (Sex)(freeCharList[charIndex] & 1); - } - break; - - case Common::KEYCODE_PAGEUP: - for (int tempClass = selectedClass - 1; tempClass >= 0; --tempClass) { - if (_allowedClasses[tempClass]) { - selectedClass = tempClass; - break; - } - } - - printSelectionArrow(selectedClass); - continue; - - case Common::KEYCODE_PAGEDOWN: - break; - - case Common::KEYCODE_m: - case Common::KEYCODE_i: - case Common::KEYCODE_p: - case Common::KEYCODE_e: - case Common::KEYCODE_s: - case Common::KEYCODE_a: - case Common::KEYCODE_l: - if (swapAttributes(_buttonValue)) { - checkClass(); - classId = -1; - selectedClass = newCharDetails(race, sex, classId, selectedClass, msg); - } - break; - - case 1000: - case 1001: - case 1002: - case 1003: - case 1004: - case 1005: - case 1006: - case 1007: - case 1008: - case 1009: - if (_allowedClasses[_buttonValue - 1000]) { - selectedClass = classId = _buttonValue - 1000; - } - break; - - case Common::KEYCODE_c: { - _vm->_mode = MODE_FF; - bool result = saveCharacter(party._roster[freeCharList[charIndex]], - classId, race, sex); - _vm->_mode = MODE_4; - - if (result) - restartFlag = true; - continue; - } - - case Common::KEYCODE_RETURN: - classId = selectedClass; - break; - - case Common::KEYCODE_SPACE: - case Common::KEYCODE_r: - // Re-roll the attributes - rollAttributes(); - classId = -1; - break; - - default: - // For all other keypresses, skip the code below the switch - // statement, and go to wait for the next key - continue; - } - - if (_buttonValue != Common::KEYCODE_PAGEDOWN) { - selectedClass = newCharDetails(race, sex, classId, selectedClass, msg); - - drawIcons2(); - party._roster[freeCharList[charIndex]]._faceSprites->draw(w, 0, - Common::Point(27, 102)); - - w.writeString(msg); - w.update(); - - if (selectedClass != -1) { - printSelectionArrow(selectedClass); - continue; - } - } - - // Move to next available class, or if the code block above resulted in - // selectedClass being -1, move to select the first available class - for (int tempClass = selectedClass + 1; tempClass <= CLASS_RANGER; ++tempClass) { - if (_allowedClasses[tempClass]) { - selectedClass = tempClass; - break; - } - } - - printSelectionArrow(selectedClass); - } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); - - _vm->_mode = oldMode; -} - -void CreateCharacterDialog::loadButtons() { - _icons.load("create.icn"); - - // Add buttons - addButton(Common::Rect(132, 98, 156, 118), Common::KEYCODE_r, &_icons); - addButton(Common::Rect(132, 128, 156, 148), Common::KEYCODE_c, &_icons); - addButton(Common::Rect(132, 158, 156, 178), Common::KEYCODE_ESCAPE, &_icons); - addButton(Common::Rect(86, 98, 110, 118), Common::KEYCODE_UP, &_icons); - addButton(Common::Rect(86, 120, 110, 140), Common::KEYCODE_DOWN, &_icons); - addButton(Common::Rect(168, 19, 192, 39), Common::KEYCODE_n, nullptr); - addButton(Common::Rect(168, 43, 192, 63), Common::KEYCODE_i, nullptr); - addButton(Common::Rect(168, 67, 192, 87), Common::KEYCODE_p, nullptr); - addButton(Common::Rect(168, 91, 192, 111), Common::KEYCODE_e, nullptr); - addButton(Common::Rect(168, 115, 192, 135), Common::KEYCODE_s, nullptr); - addButton(Common::Rect(168, 139, 192, 159), Common::KEYCODE_a, nullptr); - addButton(Common::Rect(168, 163, 192, 183), Common::KEYCODE_l, nullptr); - addButton(Common::Rect(227, 19, 239, 29), 1000, nullptr); - addButton(Common::Rect(227, 30, 239, 40), 1001, nullptr); - addButton(Common::Rect(227, 41, 239, 51), 1002, nullptr); - addButton(Common::Rect(227, 52, 239, 62), 1003, nullptr); - addButton(Common::Rect(227, 63, 239, 73), 1004, nullptr); - addButton(Common::Rect(227, 74, 239, 84), 1005, nullptr); - addButton(Common::Rect(227, 85, 239, 95), 1006, nullptr); - addButton(Common::Rect(227, 96, 239, 106), 1007, nullptr); - addButton(Common::Rect(227, 107, 239, 117), 1008, nullptr); - addButton(Common::Rect(227, 118, 239, 128), 1009, nullptr); -} - -void CreateCharacterDialog::drawIcons() { - // Draw the screen - _icons.draw(0, 10, Common::Point(168, 19)); - _icons.draw(0, 12, Common::Point(168, 43)); - _icons.draw(0, 14, Common::Point(168, 67)); - _icons.draw(0, 16, Common::Point(168, 91)); - _icons.draw(0, 18, Common::Point(168, 115)); - _icons.draw(0, 20, Common::Point(168, 139)); - _icons.draw(0, 22, Common::Point(168, 163)); - for (int idx = 0; idx < 9; ++idx) - _icons.draw(0, 24 + idx * 2, Common::Point(227, 19 + 11 * idx)); - - for (int idx = 0; idx < 7; ++idx) - _icons.draw(0, 50 + idx, Common::Point(195, 31 + 24 * idx)); - - _icons.draw(0, 57, Common::Point(62, 148)); - _icons.draw(0, 58, Common::Point(62, 158)); - _icons.draw(0, 59, Common::Point(62, 168)); - _icons.draw(0, 61, Common::Point(220, 19)); - _icons.draw(0, 64, Common::Point(220, 155)); - _icons.draw(0, 65, Common::Point(220, 170)); - - _icons.draw(0, 0, Common::Point(132, 98)); - _icons.draw(0, 2, Common::Point(132, 128)); - _icons.draw(0, 4, Common::Point(132, 158)); - _icons.draw(0, 6, Common::Point(86, 98)); - _icons.draw(0, 8, Common::Point(86, 120)); -} - -void CreateCharacterDialog::drawIcons2() { - for (int idx = 0; idx < 7; ++idx) - _icons.draw(0, 10 + idx * 2, Common::Point(168, 19 + idx * 24)); - for (int idx = 0; idx < 10; ++idx) - _icons.draw(0, 24 + idx * 2, Common::Point(227, 19 + idx * 11)); - for (int idx = 0; idx < 8; ++idx) - _icons.draw(0, 50 + idx, Common::Point(195, 31 + idx * 24)); - - _icons.draw(0, 57, Common::Point(62, 148)); - _icons.draw(0, 58, Common::Point(62, 158)); - _icons.draw(0, 59, Common::Point(62, 168)); - _icons.draw(0, 61, Common::Point(220, 19)); - _icons.draw(0, 64, Common::Point(220, 155)); - _icons.draw(0, 65, Common::Point(220, 170)); - - _icons.draw(0, 0, Common::Point(132, 98)); - _icons.draw(0, 2, Common::Point(132, 128)); - _icons.draw(0, 4, Common::Point(132, 158)); - _icons.draw(0, 6, Common::Point(86, 98)); - _icons.draw(0, 8, Common::Point(86, 120)); -} - -void CreateCharacterDialog::rollAttributes() { - bool repeat = true; - do { - // Default all the attributes to zero - Common::fill(&_attribs[0], &_attribs[TOTAL_ATTRIBUTES], 0); - - // Assign random amounts to each attribute - for (int idx1 = 0; idx1 < 3; ++idx1) { - for (int idx2 = 0; idx2 < TOTAL_ATTRIBUTES; ++idx2) { - _attribs[idx2] += _vm->getRandomNumber(10, 79) / 10; - } - } - - // Check which classes are allowed based on the rolled attributes - checkClass(); - - // Only exit if the attributes allow for at least one class - for (int idx = 0; idx < TOTAL_CLASSES; ++idx) { - if (_allowedClasses[idx]) - repeat = false; - } - } while (repeat); -} - -void CreateCharacterDialog::checkClass() { - _allowedClasses[CLASS_KNIGHT] = _attribs[MIGHT] >= 15; - _allowedClasses[CLASS_PALADIN] = _attribs[MIGHT] >= 13 - && _attribs[PERSONALITY] >= 13 && _attribs[ENDURANCE] >= 13; - _allowedClasses[CLASS_ARCHER] = _attribs[INTELLECT] >= 13 && _attribs[ACCURACY] >= 13; - _allowedClasses[CLASS_CLERIC] = _attribs[PERSONALITY] >= 13; - _allowedClasses[CLASS_SORCERER] = _attribs[INTELLECT] >= 13; - _allowedClasses[CLASS_ROBBER] = _attribs[LUCK] >= 13; - _allowedClasses[CLASS_NINJA] = _attribs[SPEED] >= 13 && _attribs[ACCURACY] >= 13; - _allowedClasses[CLASS_BARBARIAN] = _attribs[ENDURANCE] >= 15; - _allowedClasses[CLASS_DRUID] = _attribs[INTELLECT] >= 15 && _attribs[PERSONALITY] >= 15; - _allowedClasses[CLASS_RANGER] = _attribs[INTELLECT] >= 12 && _attribs[PERSONALITY] >= 12 - && _attribs[ENDURANCE] >= 12 && _attribs[SPEED] >= 12; -} - -int CreateCharacterDialog::newCharDetails(Race race, Sex sex, int classId, - int selectedClass, Common::String &msg) { - int foundClass = -1; - Common::String skillStr, classStr, raceSkillStr; - - // If a selected class is provided, set the default skill for that class - if (classId != -1 && Res.NEW_CHAR_SKILLS[classId] != -1) { - const char *skillP = Res.SKILL_NAMES[Res.NEW_CHAR_SKILLS[classId]]; - skillStr = Common::String(skillP, skillP + Res.NEW_CHAR_SKILLS_LEN[classId]); - } - - // If a class is provided, set the class name - if (classId != -1) { - classStr = Common::String::format("\t062\v168%s", Res.CLASS_NAMES[classId]); - } - - // Set up default skill for the race, if any - if (Res.NEW_CHAR_RACE_SKILLS[race] != -1) { - raceSkillStr = Res.SKILL_NAMES[Res.NEW_CHAR_RACE_SKILLS[race]]; - } - - // Set up color to use for each skill string to be displayed, based - // on whether each class is allowed or not for the given attributes - int classColors[TOTAL_CLASSES]; - Common::fill(&classColors[0], &classColors[TOTAL_CLASSES], 0); - for (int classNum = CLASS_KNIGHT; classNum <= CLASS_RANGER; ++classNum) { - if (_allowedClasses[classNum]) { - if (classId == -1 && (foundClass == -1 || foundClass < classNum)) - foundClass = classNum; - classColors[classNum] = 4; - } - } - if (classId != -1) - classColors[selectedClass] = 12; - - // Return stats details and character class - msg = Common::String::format(Res.NEW_CHAR_STATS, Res.RACE_NAMES[race], Res.SEX_NAMES[sex], - _attribs[MIGHT], _attribs[INTELLECT], _attribs[PERSONALITY], - _attribs[ENDURANCE], _attribs[SPEED], _attribs[ACCURACY], _attribs[LUCK], - classColors[CLASS_KNIGHT], classColors[CLASS_PALADIN], - classColors[CLASS_ARCHER], classColors[CLASS_CLERIC], - classColors[CLASS_SORCERER], classColors[CLASS_ROBBER], - classColors[CLASS_NINJA], classColors[CLASS_BARBARIAN], - classColors[CLASS_DRUID], classColors[CLASS_RANGER], - skillStr.c_str(), raceSkillStr.c_str(), classStr.c_str() - ); - return classId == -1 ? foundClass : selectedClass; -} - -void CreateCharacterDialog::printSelectionArrow(int selectedClass) { - Windows &windows = *_vm->_windows; - Window &w = windows[0]; - - _icons.draw(0, 61, Common::Point(220, 19)); - _icons.draw(0, 63, Common::Point(220, selectedClass * 11 + 21)); - w.update(); -} - -void CreateCharacterDialog::drawDice() { - EventsManager &events = *_vm->_events; - Windows &windows = *_vm->_windows; - Window &w = windows[32]; - - // Draw the dice area background - events.updateGameCounter(); - _dice.draw(w, 7, Common::Point(12, 11)); - - // Iterate through each of the three dice - for (int diceNum = 0; diceNum < 3; ++diceNum) { - _diceFrame[diceNum] = (_diceFrame[diceNum] + 1) % 7; - _dicePos[diceNum] += _diceInc[diceNum]; - - if (_dicePos[diceNum].x < 13) { - _dicePos[diceNum].x = 13; - _diceInc[diceNum].x *= -1; - } else if (_dicePos[diceNum].x >= (163 - _diceSize.x)) { - _dicePos[diceNum].x = 163 - _diceSize.x; - _diceInc[diceNum].x *= -1; - } - - if (_dicePos[diceNum].y < 12) { - _dicePos[diceNum].y = 12; - _diceInc[diceNum].y *= -1; - } else if (_dicePos[diceNum].y >= (93 - _diceSize.y)) { - _dicePos[diceNum].y = 93 - _diceSize.y; - _diceInc[diceNum].y *= -1; - } - - _dice.draw(w, _diceFrame[diceNum], _dicePos[diceNum]); - } - - // Wait for a single frame, checking for any events - w.update(); - events.wait(1); - checkEvents(_vm); -} - -int CreateCharacterDialog::getAttribFromKeycode(int keycode) const { - switch (keycode) { - case Common::KEYCODE_m: - return MIGHT; - case Common::KEYCODE_i: - return INTELLECT; - case Common::KEYCODE_p: - return PERSONALITY; - case Common::KEYCODE_e: - return ENDURANCE; - case Common::KEYCODE_s: - return SPEED; - case Common::KEYCODE_a: - return ACCURACY; - case Common::KEYCODE_l: - return LUCK; - default: - return -1; - } -} - -bool CreateCharacterDialog::swapAttributes(int keycode) { - Windows &windows = *_vm->_windows; - Window &w = windows[0]; - - int srcAttrib = getAttribFromKeycode(keycode); - assert(srcAttrib >= 0); - - _vm->_mode = MODE_86; - _icons.draw(w, srcAttrib * 2 + 11, Common::Point( - _buttons[srcAttrib + 5]._bounds.left, _buttons[srcAttrib + 5]._bounds.top)); - w.update(); - - int destAttrib = exchangeAttribute(srcAttrib); - if (destAttrib != -1) { - _icons.draw(w, destAttrib * 2 + 11, Common::Point( - _buttons[destAttrib + 5]._bounds.left, - _buttons[destAttrib + 5]._bounds.top)); - - SWAP(_attribs[srcAttrib], _attribs[destAttrib]); - return true; - - } else { - _icons.draw(w, srcAttrib * 2 + 10, Common::Point( - _buttons[srcAttrib + 5]._bounds.left, - _buttons[srcAttrib + 5]._bounds.top)); - w.update(); - _vm->_mode = MODE_SLEEPING; - return false; - } -} - -int CreateCharacterDialog::exchangeAttribute(int srcAttr) { - EventsManager &events = *_vm->_events; - Windows &windows = *_vm->_windows; - SpriteResource icons; - icons.load("create2.icn"); - - saveButtons(); - addButton(Common::Rect(118, 58, 142, 78), Common::KEYCODE_ESCAPE, &_icons); - addButton(Common::Rect(168, 19, 192, 39), Common::KEYCODE_m); - addButton(Common::Rect(168, 43, 192, 63), Common::KEYCODE_i); - addButton(Common::Rect(168, 67, 192, 87), Common::KEYCODE_p); - addButton(Common::Rect(168, 91, 192, 111), Common::KEYCODE_e); - addButton(Common::Rect(168, 115, 192, 135), Common::KEYCODE_s); - addButton(Common::Rect(168, 139, 192, 159), Common::KEYCODE_a); - addButton(Common::Rect(168, 163, 192, 183), Common::KEYCODE_l); - - Window &w = windows[26]; - w.open(); - w.writeString(Common::String::format(Res.EXCHANGE_ATTR_WITH, Res.STAT_NAMES[srcAttr])); - icons.draw(w, 0, Common::Point(118, 58)); - w.update(); - - int result = -1; - bool breakFlag = false; - while (!_vm->shouldExit() && !breakFlag) { - // Wait for an action - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_vm->shouldExit() && !_buttonValue); - if (_buttonValue == Common::KEYCODE_ESCAPE) - break; - - int destAttr = getAttribFromKeycode(_buttonValue); - - if (destAttr != -1 && srcAttr != destAttr) { - result = destAttr; - break; - } - } - - w.close(); - restoreButtons(); - _buttonValue = 0; - return result; -} - -bool CreateCharacterDialog::saveCharacter(Character &c, int classId, Race race, Sex sex) { - if (classId == -1) { - ErrorScroll::show(_vm, Res.SELECT_CLASS_BEFORE_SAVING); - return false; - } - - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Common::String name; - int result; - bool isDarkCc = _vm->_files->_isDarkCc; - - // Prompt for a character name - w.open(); - w.writeString(Res.NAME_FOR_NEW_CHARACTER); - saveButtons(); - result = Input::show(_vm, &w, name, 10, 200); - restoreButtons(); - w.close(); - - if (!result) - // Name aborted, so exit - return false; - - // Save new character details - c.clear(); - c._name = name; - c._savedMazeId = party._priorMazeId; - c._xeenSide = map._loadDarkSide; - c._sex = sex; - c._race = race; - c._class = (CharacterClass)classId; - c._level._permanent = isDarkCc ? 5 : 1; - - c._might._permanent = _attribs[MIGHT]; - c._intellect._permanent = _attribs[INTELLECT]; - c._personality._permanent = _attribs[PERSONALITY]; - c._endurance._permanent = _attribs[ENDURANCE]; - c._speed._permanent = _attribs[SPEED]; - c._accuracy._permanent = _attribs[ACCURACY]; - c._luck._permanent = _attribs[LUCK]; - - c._magicResistence._permanent = Res.RACE_MAGIC_RESISTENCES[race]; - c._fireResistence._permanent = Res.RACE_FIRE_RESISTENCES[race]; - c._electricityResistence._permanent = Res.RACE_ELECTRIC_RESISTENCES[race]; - c._coldResistence._permanent = Res.RACE_COLD_RESISTENCES[race]; - c._energyResistence._permanent = Res.RACE_ENERGY_RESISTENCES[race]; - c._poisonResistence._permanent = Res.RACE_POISON_RESISTENCES[race]; - - c._birthYear = party._year - 18; - c._birthDay = party._day; - c._hasSpells = false; - c._currentSpell = -1; - - // Set up any default spells for the character's class - for (int idx = 0; idx < 4; ++idx) { - if (Res.NEW_CHARACTER_SPELLS[c._class][idx] != -1) { - c._hasSpells = true; - c._currentSpell = Res.NEW_CHARACTER_SPELLS[c._class][idx]; - c._spells[c._currentSpell] = true; - } - } - - int classSkill = Res.NEW_CHAR_SKILLS[c._class]; - if (classSkill != -1) - c._skills[classSkill] = 1; - - int raceSkill = Res.NEW_CHAR_RACE_SKILLS[c._race]; - if (raceSkill != -1) - c._skills[raceSkill] = 1; - - c._currentHp = c.getMaxHP(); - c._currentSp = c.getMaxSP(); - return true; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_create_char.h b/engines/xeen/dialogs_create_char.h deleted file mode 100644 index de140e8626..0000000000 --- a/engines/xeen/dialogs_create_char.h +++ /dev/null @@ -1,124 +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_DIALOGS_CREATE_CHAR_H -#define XEEN_DIALOGS_CREATE_CHAR_H - -#include "xeen/dialogs.h" -#include "xeen/character.h" - -namespace Xeen { - -class CreateCharacterDialog : public ButtonContainer { -private: - SpriteResource _icons; - SpriteResource _dice; - Common::Point _diceSize; - int _diceFrame[3]; - Common::Point _dicePos[3]; - Common::Point _diceInc[3]; - uint _attribs[TOTAL_ATTRIBUTES]; - bool _allowedClasses[TOTAL_CLASSES]; -private: - /** - * Constructor - */ - CreateCharacterDialog(XeenEngine *vm); - - /** - * Loads the buttons for the dialog - */ - void loadButtons(); - - /** - * Draws on-screen icons - */ - void drawIcons(); - - /** - * Draws on-screen icons - */ - void drawIcons2(); - - /** - * Animate the dice rolling around - */ - void drawDice(); - - /** - * Executes the dialog - */ - void execute(); - - /** - * Returns the attribute that a given keycode represents - */ - int getAttribFromKeycode(int keycode) const; - - /** - * Handles the logic for swapping attributes - * @param keycode Key pressed representing one of the attributes - * @returns True if swap occurred - */ - bool swapAttributes(int keycode); - - /** - * Exchanging two attributes for the character being rolled - */ - int exchangeAttribute(int srcAttr); - - /** - * Set a list of flags for which classes the passed attribute set meet the - * minimum requirements of - */ - void checkClass(); - - /** - * Return details of the generated character - */ - int newCharDetails(Race race, Sex sex, int classId, int selectedClass, Common::String &msg); - - /** - * Print the selection arrow to indicate the selected class - */ - void printSelectionArrow(int selectedClass); - - /** - * Saves the rolled character into the roster - */ - bool saveCharacter(Character &c, int classId, Race race, Sex sex); - - /** - * Roll up some random values for the attributes, and return both them as - * well as a list of classes that the attributes meet the requirements for - */ - void rollAttributes(); -public: - /** - * Shows the Create Character dialog - */ - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_CREATE_CHAR_H */ diff --git a/engines/xeen/dialogs_difficulty.cpp b/engines/xeen/dialogs_difficulty.cpp deleted file mode 100644 index 8d542dc165..0000000000 --- a/engines/xeen/dialogs_difficulty.cpp +++ /dev/null @@ -1,75 +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_difficulty.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -int DifficultyDialog::show(XeenEngine *vm) { - DifficultyDialog *dlg = new DifficultyDialog(vm); - int result = dlg->execute(); - delete dlg; - - return result; -} - -DifficultyDialog::DifficultyDialog(XeenEngine *vm) : ButtonContainer(vm) { - loadButtons(); -} - -int DifficultyDialog::execute() { - EventsManager &events = *_vm->_events; - Windows &windows = *_vm->_windows; - - Window &w = windows[6]; - w.open(); - w.writeString(Res.DIFFICULTY_TEXT); - drawButtons(&w); - - int result = -1; - while (!_vm->shouldExit()) { - events.pollEventsAndWait(); - checkEvents(_vm); - - if (_buttonValue == Common::KEYCODE_a) - result = ADVENTURER; - else if (_buttonValue == Common::KEYCODE_w) - result = WARRIOR; - else if (_buttonValue != Common::KEYCODE_ESCAPE) - continue; - - break; - } - - w.close(); - return result; -} - -void DifficultyDialog::loadButtons() { - _sprites.load("choice.icn"); - addButton(Common::Rect(68, 167, 158, 187), Common::KEYCODE_a, &_sprites); - addButton(Common::Rect(166, 167, 256, 187), Common::KEYCODE_w, &_sprites); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_difficulty.h b/engines/xeen/dialogs_difficulty.h deleted file mode 100644 index e0771a50b9..0000000000 --- a/engines/xeen/dialogs_difficulty.h +++ /dev/null @@ -1,60 +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_DIALOGS_DIFFICULTY_H -#define XEEN_DIALOGS_DIFFICULTY_H - -#include "xeen/dialogs.h" -#include "xeen/party.h" - -namespace Xeen { - -class DifficultyDialog : public ButtonContainer { -private: - SpriteResource _sprites; - - /** - * Constructor - */ - DifficultyDialog(XeenEngine *vm); - - /** - * Shows the dialog - */ - int execute(); - - /** - * Loads buttons for the dialog - */ - void loadButtons(); -public: - /** - * Shows the difficulty selection dialog - * @param vm Engine reference - * @returns 0=Adventurer, 1=Warrior, -1 exit - */ - static int show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_DIFFICULTY_H */ diff --git a/engines/xeen/dialogs_dismiss.cpp b/engines/xeen/dialogs_dismiss.cpp deleted file mode 100644 index 52ac475e05..0000000000 --- a/engines/xeen/dialogs_dismiss.cpp +++ /dev/null @@ -1,95 +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_dismiss.h" -#include "xeen/party.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void Dismiss::show(XeenEngine *vm) { - Dismiss *dlg = new Dismiss(vm); - dlg->execute(); - delete dlg; -} - -void Dismiss::execute() { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - loadButtons(); - - Window &w = windows[31]; - w.open(); - _iconSprites.draw(w, 0, Common::Point(225, 120)); - w.update(); - - bool breakFlag = false; - while (!_vm->shouldExit() && !breakFlag) { - do { - events.updateGameCounter(); - intf.draw3d(false); - w.frame(); - w.writeString("\r"); - _iconSprites.draw(w, 0, Common::Point(225, 120)); - windows[3].update(); - w.update(); - - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_vm->shouldExit() && !_buttonValue && events.timeElapsed() == 0); - } while (!_vm->shouldExit() && !_buttonValue); - - if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { - _buttonValue -= Common::KEYCODE_F1; - - if (_buttonValue < (int)party._activeParty.size()) { - if (party._activeParty.size() == 1) { - w.close(); - ErrorScroll::show(_vm, Res.CANT_DISMISS_LAST_CHAR, WT_NONFREEZED_WAIT); - w.open(); - } else { - // Remove the character from the party - party._activeParty.remove_at(_buttonValue); - breakFlag = true; - } - break; - } - } else if (_buttonValue == Common::KEYCODE_ESCAPE) { - breakFlag = true; - } - } -} - -void Dismiss::loadButtons() { - _iconSprites.load("esc.icn"); - addButton(Common::Rect(225, 120, 249, 140), Common::KEYCODE_ESCAPE, &_iconSprites); - addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); - addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); - addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); - addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_dismiss.h b/engines/xeen/dialogs_dismiss.h deleted file mode 100644 index 7b73fc6f03..0000000000 --- a/engines/xeen/dialogs_dismiss.h +++ /dev/null @@ -1,46 +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_DIALOGS_DISMISS_H -#define XEEN_DIALOGS_DISMISS_H - -#include "xeen/dialogs.h" -#include "xeen/party.h" - -namespace Xeen { - -class Dismiss : public ButtonContainer { -private: - SpriteResource _iconSprites; - - Dismiss(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(); - - void loadButtons(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_DISMISS_H */ diff --git a/engines/xeen/dialogs_exchange.cpp b/engines/xeen/dialogs_exchange.cpp deleted file mode 100644 index d977656d35..0000000000 --- a/engines/xeen/dialogs_exchange.cpp +++ /dev/null @@ -1,80 +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_exchange.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void ExchangeDialog::show(XeenEngine *vm, Character *&c, int &charIndex) { - ExchangeDialog *dlg = new ExchangeDialog(vm); - dlg->execute(c, charIndex); - delete dlg; -} - -void ExchangeDialog::execute(Character *&c, int &charIndex) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - loadButtons(); - - Window &w = windows[31]; - w.open(); - w.writeString(Res.EXCHANGE_WITH_WHOM); - _iconSprites.draw(w, 0, Common::Point(225, 120)); - w.update(); - - while (!_vm->shouldExit()) { - events.pollEventsAndWait(); - checkEvents(_vm); - - if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)party._activeParty.size()) { - SWAP(party._activeParty[charIndex], party._activeParty[_buttonValue]); - - charIndex = _buttonValue; - c = &party._activeParty[charIndex]; - break; - } - } else if (_buttonValue == Common::KEYCODE_ESCAPE) { - break; - } - } - - w.close(); - intf.drawParty(true); - intf.highlightChar(charIndex); -} - -void ExchangeDialog::loadButtons() { - _iconSprites.load("esc.icn"); - addButton(Common::Rect(225, 120, 249, 245), Common::KEYCODE_ESCAPE, &_iconSprites); - addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); - addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); - addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); - addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_exchange.h b/engines/xeen/dialogs_exchange.h deleted file mode 100644 index e67c315133..0000000000 --- a/engines/xeen/dialogs_exchange.h +++ /dev/null @@ -1,46 +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_DIALOGS_EXCHANGE_H -#define XEEN_DIALOGS_EXCHANGE_H - -#include "xeen/dialogs.h" -#include "xeen/party.h" - -namespace Xeen { - -class ExchangeDialog : public ButtonContainer { -private: - SpriteResource _iconSprites; - - ExchangeDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(Character *&c, int &charIndex); - - void loadButtons(); -public: - static void show(XeenEngine *vm, Character *&c, int &charIndex); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_EXCHANGE_H */ diff --git a/engines/xeen/dialogs_info.cpp b/engines/xeen/dialogs_info.cpp deleted file mode 100644 index 4f51316b6e..0000000000 --- a/engines/xeen/dialogs_info.cpp +++ /dev/null @@ -1,129 +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_info.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void InfoDialog::show(XeenEngine *vm) { - InfoDialog *dlg = new InfoDialog(vm); - dlg->execute(); - delete dlg; -} - -void InfoDialog::execute() { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - - protectionText(); - Common::String statusText = ""; - for (uint idx = 0; idx < _lines.size(); ++idx) - statusText += _lines[idx]; - - Common::String gameName; - if (_vm->getGameID() == GType_Swords) - gameName = Res.SWORDS_GAME_TEXT; - else if (_vm->getGameID() == GType_Clouds) - gameName = Res.CLOUDS_GAME_TEXT; - else if (_vm->getGameID() == GType_DarkSide) - gameName = Res.DARKSIDE_GAME_TEXT; - else - gameName = Res.WORLD_GAME_TEXT; - - // Form the display message - int hour = party._minutes / 60; - Common::String details = Common::String::format(Res.GAME_INFORMATION, - gameName.c_str(), Res.WEEK_DAY_STRINGS[party._day % 10], - (hour > 12) ? hour - 12 : (!hour ? 12 : hour), - party._minutes % 60, (hour > 11) ? 'p' : 'a', - party._day, party._year, statusText.c_str()); - - Window &w = windows[28]; - w.setBounds(Common::Rect(88, 20, 248, 112 + (_lines.empty() ? 0 : _lines.size() * 9 + 13))); - w.open(); - w.writeString(details); - - do { - events.updateGameCounter(); - intf.draw3d(false, false); - w.frame(); - w.writeString(details); - w.update(); - - events.wait(1); - } while (!_vm->shouldExit() && !events.isKeyMousePressed()); - - events.clearEvents(); - w.close(); -} - -void InfoDialog::protectionText() { - Party &party = *_vm->_party; -// Common::StringArray _lines; - const char *const AA_L024 = "\x3l\n\x9""024"; - const char *const AA_R124 = "\x3r\x9""124"; - - if (party._lightCount) { - _lines.push_back(Common::String::format(Res.LIGHT_COUNT_TEXT, party._lightCount)); - } - - if (party._fireResistence) { - _lines.push_back(Common::String::format(Res.FIRE_RESISTENCE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._fireResistence)); - } - - if (party._electricityResistence) { - _lines.push_back(Common::String::format(Res.ELECRICITY_RESISTENCE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._electricityResistence)); - } - - if (party._coldResistence) { - _lines.push_back(Common::String::format(Res.COLD_RESISTENCE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._coldResistence)); - } - - if (party._poisonResistence) { - _lines.push_back(Common::String::format(Res.POISON_RESISTENCE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124, party._poisonResistence)); - } - - if (party._clairvoyanceActive) { - _lines.push_back(Common::String::format(Res.CLAIRVOYANCE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); - } - - if (party._levitateCount) { - _lines.push_back(Common::String::format(Res.LEVITATE_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); - } - - if (party._walkOnWaterActive) { - _lines.push_back(Common::String::format(Res.WALK_ON_WATER_TEXT, - _lines.size() == 0 ? 10 : 1, AA_L024, AA_R124)); - } -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_info.h b/engines/xeen/dialogs_info.h deleted file mode 100644 index 68c8403545..0000000000 --- a/engines/xeen/dialogs_info.h +++ /dev/null @@ -1,46 +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_DIALOGS_INFO_H -#define XEEN_DIALOGS_INFO_H - -#include "common/str-array.h" -#include "xeen/dialogs.h" - -namespace Xeen { - -class InfoDialog : public ButtonContainer { -private: - Common::StringArray _lines; - - InfoDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(); - - void protectionText(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_INFO_H */ diff --git a/engines/xeen/dialogs_input.cpp b/engines/xeen/dialogs_input.cpp deleted file mode 100644 index 0bf95f766b..0000000000 --- a/engines/xeen/dialogs_input.cpp +++ /dev/null @@ -1,323 +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_input.h" -#include "xeen/scripts.h" -#include "xeen/xeen.h" - -namespace Xeen { - -int Input::show(XeenEngine *vm, Window *window, Common::String &line, - uint maxLen, int maxWidth, bool isNumeric) { - Input *dlg = new Input(vm, window); - int result = dlg->getString(line, maxLen, maxWidth, isNumeric); - delete dlg; - - return result; -} - -int Input::getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric) { - _vm->_noDirectionSense = true; - Common::String msg = Common::String::format("\x3""l\t000\x4%03d\x3""c", maxWidth); - _window->writeString(msg); - _window->update(); - - while (!_vm->shouldExit()) { - Common::KeyState keyState = waitForKey(msg); - const Common::KeyCode keyCode = keyState.keycode; - - bool refresh = false; - if ((keyCode == Common::KEYCODE_BACKSPACE || keyCode == Common::KEYCODE_DELETE) - && line.size() > 0) { - line.deleteLastChar(); - refresh = true; - } else if (line.size() < maxLen && (line.size() > 0 || keyCode != Common::KEYCODE_SPACE) - && ((isNumeric && keyState.ascii >= '0' && keyState.ascii <= '9') || - (!isNumeric && keyState.ascii >= ' ' && keyState.ascii <= (char)127))) { - line += keyState.ascii; - refresh = true; - } else if (keyCode == Common::KEYCODE_RETURN || keyCode == Common::KEYCODE_KP_ENTER) { - break; - } else if (keyCode == Common::KEYCODE_ESCAPE) { - line = ""; - break; - } - - if (refresh) { - msg = Common::String::format("\x3""l\t000\x4%03d\x3""c%s", maxWidth, line.c_str()); - _window->writeString(msg); - _window->update(); - } - } - - _vm->_noDirectionSense = false; - return line.size(); -} - -Common::KeyState Input::waitForKey(const Common::String &msg) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Windows &windows = *_vm->_windows; - - bool oldUpDoorText = intf._upDoorText; - byte oldTillMove = intf._tillMove; - intf._upDoorText = false; - intf._tillMove = 0; - - bool flag = !_vm->_startupWindowActive && !windows[25]._enabled - && _vm->_mode != MODE_FF && _vm->_mode != MODE_17; - - Common::KeyState ks; - while (!_vm->shouldExit()) { - events.updateGameCounter(); - - if (flag) - intf.draw3d(false); - _window->writeString(msg); - animateCursor(); - _window->update(); - - if (flag) - windows[3].update(); - - events.wait(1); - - if (events.isKeyPending()) { - events.getKey(ks); - break; - } - } - - _window->writeString(""); - _window->update(); - - intf._tillMove = oldTillMove; - intf._upDoorText = oldUpDoorText; - - return ks; -} - -void Input::animateCursor() { - // Iterate through each frame - _cursorAnimIndex = _cursorAnimIndex ? _cursorAnimIndex - 1 : 5; - static const char CURSOR_ANIMATION_IDS[] = { 32, 124, 126, 127, 126, 124 }; - - // Form a string for the cursor and write it out - Common::Point writePos = _window->_writePos; - _window->writeCharacter(CURSOR_ANIMATION_IDS[_cursorAnimIndex]); - _window->_writePos = writePos; -} - -/*------------------------------------------------------------------------*/ - -StringInput::StringInput(XeenEngine *vm): Input(vm, &(*vm->_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) { - FileManager &files = *_vm->_files; - Interface &intf = *_vm->_interface; - Scripts &scripts = *_vm->_scripts; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Sound &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 - MirrorEntry me; - scripts._mirror.clear(); - - File f(Common::String::format("%smirr.txt", files._isDarkCc ? "dark" : "xeen"), 1); - while (me.synchronize(f)) - scripts._mirror.push_back(me); - f.close(); - - // Load in any extended mirror entries - Common::File f2; - if (f2.open(Common::String::format("%smirr.ext", files._isDarkCc ? "dark" : "xeen"))) { - while (me.synchronize(f2)) - scripts._mirror.push_back(me); - f2.close(); - } - - for (uint idx = 0; idx < scripts._mirror.size(); ++idx) { - if (!line.compareToIgnoreCase(scripts._mirror[idx]._name)) { - result = idx + 1; - sound.playFX(_vm->_files->_isDarkCc ? 35 : 61); - break; - } - } - } - } - - w.close(); - return result; -} - -/*------------------------------------------------------------------------*/ - -NumericInput::NumericInput(XeenEngine *vm, int window) : Input(vm, &(*vm->_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; -} - -/*------------------------------------------------------------------------*/ - -int Choose123::show(XeenEngine *vm, int numOptions) { - assert(numOptions <= 3); - Choose123 *dlg = new Choose123(vm); - int result = dlg->execute(numOptions); - delete dlg; - - return result; -} - -int Choose123::execute(int numOptions) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - LocationManager &loc = *_vm->_locations; - Windows &windows = *_vm->_windows; - - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_DIALOG_123; - - loadButtons(numOptions); - _iconSprites.draw(0, 7, Common::Point(232, 74)); - drawButtons(&windows[0]); - windows[34].update(); - - int result = -1; - while (result == -1) { - do { - events.updateGameCounter(); - int delay; - if (loc.isActive()) { - loc.drawAnim(true); - delay = 3; - } else { - intf.draw3d(true); - delay = 1; - } - - events.wait(delay); - if (_vm->shouldExit()) - return 0; - } while (!_buttonValue); - - switch (_buttonValue) { - case Common::KEYCODE_ESCAPE: - result = 0; - break; - case Common::KEYCODE_1: - case Common::KEYCODE_2: - case Common::KEYCODE_3: { - int v = _buttonValue - Common::KEYCODE_1 + 1; - if (v <= numOptions) - result = v; - break; - } - default: - break; - } - } - - _vm->_mode = oldMode; - intf.mainIconsPrint(); - - return result; -} - -void Choose123::loadButtons(int numOptions) { - _iconSprites.load("choose.icn"); - - if (numOptions >= 1) - addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_1, &_iconSprites); - if (numOptions >= 2) - addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_2, &_iconSprites); - if (numOptions >= 3) - addButton(Common::Rect(286, 75, 311, 95), Common::KEYCODE_3, &_iconSprites); -} - -/*------------------------------------------------------------------------*/ - -int HowMuch::show(XeenEngine *vm) { - HowMuch *dlg = new HowMuch(vm); - int result = dlg->execute(); - delete dlg; - - return result; -} - -int HowMuch::execute() { - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Common::String num; - - w.open(); - w.writeString(Res.HOW_MUCH); - w.update(); - int lineSize = Input::show(_vm, &w, num, 8, 70, true); - w.close(); - - if (!lineSize) - return -1; - return atoi(num.c_str()); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_input.h b/engines/xeen/dialogs_input.h deleted file mode 100644 index 3451fbc681..0000000000 --- a/engines/xeen/dialogs_input.h +++ /dev/null @@ -1,105 +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_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 Input : public ButtonContainer { -private: - /** - * Draws the text input and cursor and waits until the user presses a key - */ - Common::KeyState waitForKey(const Common::String &msg); - - /** - * Animates the box text cursor - */ - void animateCursor(); -protected: - Window *_window; - int _cursorAnimIndex; - - /** - * Allows the user to enter a string - */ - int getString(Common::String &line, uint maxLen, int maxWidth, bool isNumeric); - - Input(XeenEngine *vm, Window *window) : ButtonContainer(vm), - _window(window), _cursorAnimIndex(0) {} -public: - static int show(XeenEngine *vm, Window *window, Common::String &line, - uint maxLen, int maxWidth, bool isNumeric = false); -}; - -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 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); -}; - -class Choose123 : public ButtonContainer { -private: - SpriteResource _iconSprites; - - Choose123(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(int numOptions); - - void loadButtons(int numOptions); -public: - static int show(XeenEngine *vm, int numOptions); -}; - -class HowMuch : public ButtonContainer { -private: - SpriteResource _iconSprites; - - HowMuch(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(); -public: - static int show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_STRING_INPUT_H */ diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp deleted file mode 100644 index f7c0e48e41..0000000000 --- a/engines/xeen/dialogs_items.cpp +++ /dev/null @@ -1,1066 +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_items.h" -#include "xeen/dialogs_query.h" -#include "xeen/dialogs_quests.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -Character *ItemsDialog::show(XeenEngine *vm, Character *c, ItemsMode mode) { - ItemsDialog *dlg = new ItemsDialog(vm); - Character *result = dlg->execute(c, mode); - delete dlg; - - return result; -} - -Character *ItemsDialog::execute(Character *c, ItemsMode mode) { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - - Character *startingChar = c; - ItemCategory category = mode == ITEMMODE_RECHARGE || mode == ITEMMODE_COMBAT ? - CATEGORY_MISC : CATEGORY_WEAPON; - int varA = mode == ITEMMODE_COMBAT ? 1 : 0; - if (varA != 0) - mode = ITEMMODE_CHAR_INFO; - bool updateStock = mode == ITEMMODE_BLACKSMITH; - int itemIndex = -1; - Common::StringArray lines; - uint arr[40]; - int actionIndex = -1; - - events.setCursor(0); - loadButtons(mode, c); - - windows[29].open(); - windows[30].open(); - - enum { REDRAW_NONE, REDRAW_TEXT, REDRAW_FULL } redrawFlag = REDRAW_FULL; - for (;;) { - if (redrawFlag == REDRAW_FULL) { - if ((mode != ITEMMODE_CHAR_INFO || category != CATEGORY_MISC) && mode != ITEMMODE_ENCHANT - && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { - _buttons[4]._bounds.moveTo(148, _buttons[4]._bounds.top); - _buttons[9]._draw = false; - } else if (mode == ITEMMODE_RECHARGE) { - _buttons[4]._value = Common::KEYCODE_r; - } else if (mode == ITEMMODE_ENCHANT) { - _buttons[4]._value = Common::KEYCODE_e; - } else if (mode == ITEMMODE_TO_GOLD) { - _buttons[4]._value = Common::KEYCODE_g; - } else { - _buttons[4]._bounds.moveTo(0, _buttons[4]._bounds.top); - _buttons[9]._draw = true; - _buttons[9]._value = Common::KEYCODE_u; - } - - // Write text for the dialog - Common::String msg; - if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_8 && mode != ITEMMODE_ENCHANT - && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { - msg = Common::String::format(Res.ITEMS_DIALOG_TEXT1, - Res.BTN_BUY, Res.BTN_SELL, Res.BTN_IDENTIFY, Res.BTN_FIX); - } else if (mode != ITEMMODE_ENCHANT && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { - msg = Common::String::format(Res.ITEMS_DIALOG_TEXT1, - category == 3 ? Res.BTN_USE : Res.BTN_EQUIP, - Res.BTN_REMOVE, Res.BTN_DISCARD, Res.BTN_QUEST); - } else if (mode == ITEMMODE_ENCHANT) { - msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_ENCHANT); - } else if (mode == ITEMMODE_RECHARGE) { - msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_RECHARGE); - } else { - msg = Common::String::format(Res.ITEMS_DIALOG_TEXT2, Res.BTN_GOLD); - } - - windows[29].writeString(msg); - drawButtons(&windows[0]); - - Common::fill(&arr[0], &arr[40], 0); - itemIndex = -1; - } - - if (redrawFlag == REDRAW_TEXT || redrawFlag == REDRAW_FULL) { - lines.clear(); - - if (mode == ITEMMODE_CHAR_INFO || category != 3) { - _iconSprites.draw(0, 8, Common::Point(148, 109)); - } - if (mode != ITEMMODE_ENCHANT && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD) { - _iconSprites.draw(0, 10, Common::Point(182, 109)); - _iconSprites.draw(0, 12, Common::Point(216, 109)); - _iconSprites.draw(0, 14, Common::Point(250, 109)); - } - - switch (mode) { - case ITEMMODE_CHAR_INFO: - _iconSprites.draw(0, 9, Common::Point(148, 109)); - break; - case ITEMMODE_BLACKSMITH: - _iconSprites.draw(0, 11, Common::Point(182, 109)); - break; - case ITEMMODE_REPAIR: - _iconSprites.draw(0, 15, Common::Point(250, 109)); - break; - case ITEMMODE_IDENTIFY: - _iconSprites.draw(0, 13, Common::Point(216, 109)); - break; - default: - break; - } - - for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { - DrawStruct &ds = _itemsDrawList[idx]; - XeenItem &i = c->_items[category][idx]; - - ds._sprites = nullptr; - ds._x = 8; - ds._y = 18 + idx * 9; - - switch (category) { - case CATEGORY_WEAPON: - case CATEGORY_ARMOR: - case CATEGORY_ACCESSORY: - if (i._id) { - if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 - || mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE) { - lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE1, - arr[idx], idx + 1, - c->_items[category].getFullDescription(idx, arr[idx]).c_str())); - } else { - lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE2, - arr[idx], idx + 1, - c->_items[category].getFullDescription(idx, arr[idx]).c_str(), - calcItemCost(c, idx, mode, - mode == ITEMMODE_TO_GOLD ? 1 : startingChar->_skills[MERCHANT], - category) - )); - } - - ds._sprites = &_equipSprites; - if (c->_weapons.passRestrictions(i._id, true)) - ds._frame = i._frame; - else - ds._frame = 14; - } else if (ds._sprites == nullptr && idx == 0) { - lines.push_back(Res.NO_ITEMS_AVAILABLE); - } - break; - - case CATEGORY_MISC: - if (i._material == 0) { - // No item - if (idx == 0) { - lines.push_back(Res.NO_ITEMS_AVAILABLE); - } - } else { - ItemsMode tempMode = mode; - int skill = startingChar->_skills[MERCHANT]; - - if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 - || mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE) { - tempMode = ITEMMODE_ENCHANT; - } else if (mode == ITEMMODE_TO_GOLD) { - skill = 1; - } - - lines.push_back(Common::String::format(Res.ITEMS_DIALOG_LINE2, - arr[idx], idx + 1, - c->_items[category].getFullDescription(idx, arr[idx]).c_str(), - calcItemCost(c, idx, tempMode, skill, category) - )); - } - break; - - default: - break; - } - } - while (lines.size() < INV_ITEMS_TOTAL) - lines.push_back(""); - - // Draw out overall text and the list of items - switch (mode) { - case ITEMMODE_CHAR_INFO: - case ITEMMODE_8: - windows[30].writeString(Common::String::format(Res.X_FOR_THE_Y, - category == CATEGORY_MISC ? "\x3l" : "\x3c", - Res.CATEGORY_NAMES[category], c->_name.c_str(), Res.CLASS_NAMES[c->_class], - category == CATEGORY_MISC ? Res.FMT_CHARGES : " ", - lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), - lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), - lines[8].c_str() - )); - break; - - case ITEMMODE_BLACKSMITH: - windows[30].writeString(Common::String::format(Res.AVAILABLE_GOLD_COST, - Res.CATEGORY_NAMES[category], party._gold, - lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), - lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), - lines[8].c_str() - )); - break; - - case ITEMMODE_2: - case ITEMMODE_RECHARGE: - case ITEMMODE_ENCHANT: - case ITEMMODE_REPAIR: - case ITEMMODE_IDENTIFY: - case ITEMMODE_TO_GOLD: - windows[30].writeString(Common::String::format(Res.X_FOR_Y, - Res.CATEGORY_NAMES[category], startingChar->_name.c_str(), - (mode == ITEMMODE_RECHARGE || mode == ITEMMODE_ENCHANT) ? Res.CHARGES : Res.COST, - lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), - lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), - lines[8].c_str() - )); - break; - - case ITEMMODE_3: - case ITEMMODE_5: - windows[30].writeString(Common::String::format(Res.X_FOR_Y_GOLD, - Res.CATEGORY_NAMES[category], c->_name.c_str(), party._gold, Res.CHARGES, - lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), lines[3].c_str(), - lines[4].c_str(), lines[5].c_str(), lines[6].c_str(), lines[7].c_str(), - lines[8].c_str() - )); - break; - - default: - break; - } - - // Draw the glyphs for the items - windows[0].drawList(_itemsDrawList, INV_ITEMS_TOTAL); - windows[0].update(); - } - - redrawFlag = REDRAW_NONE; - - if (itemIndex != -1) { - switch (mode) { - case ITEMMODE_BLACKSMITH: - actionIndex = 0; - break; - case ITEMMODE_2: - actionIndex = 1; - break; - case ITEMMODE_REPAIR: - actionIndex = 3; - break; - case ITEMMODE_IDENTIFY: - actionIndex = 2; - break; - default: - break; - } - } - - // If it's time to do an item action, take care of it - if (actionIndex >= 0) { - int result = doItemOptions(*c, actionIndex, itemIndex, category, mode); - if (result == 1) { - // Finish dialog with no selected character - c = nullptr; - break; - } else if (result == 2) { - // Close dialogs and finish dialog with original starting character - windows[30].close(); - windows[29].close(); - c = startingChar; - break; - } - - // Otherwise, result and continue showing dialog - actionIndex = -1; - } - - // Wait for a selection - _buttonValue = 0; - while (!_vm->shouldExit() && !_buttonValue) { - events.pollEventsAndWait(); - checkEvents(_vm); - } - if (_vm->shouldExit()) - return nullptr; - - // Handle escaping out of dialog - if (_buttonValue == Common::KEYCODE_ESCAPE) { - if (mode == ITEMMODE_8) - continue; - c = startingChar; - break; - } - - // Handle other selections - 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: - if (!varA && mode != ITEMMODE_3 && mode != ITEMMODE_ENCHANT - && mode != ITEMMODE_RECHARGE && mode != ITEMMODE_TO_GOLD - && party._mazeId != 0) { - _buttonValue -= Common::KEYCODE_F1; - - if (_buttonValue < (int)(_vm->_mode == MODE_COMBAT ? - combat._combatParty.size() : party._activeParty.size())) { - // Character number is valid - redrawFlag = REDRAW_TEXT; - Character *newChar = _vm->_mode == MODE_COMBAT ? - combat._combatParty[_buttonValue] : &party._activeParty[_buttonValue]; - - if (mode == ITEMMODE_BLACKSMITH) { - _oldCharacter = newChar; - startingChar = newChar; - c = &_itemsCharacter; - } else if (mode != ITEMMODE_2 && mode != ITEMMODE_REPAIR - && mode != ITEMMODE_IDENTIFY && itemIndex != -1) { - InventoryItems &destItems = newChar->_items[category]; - XeenItem &destItem = destItems[INV_ITEMS_TOTAL - 1]; - InventoryItems &srcItems = c->_items[category]; - XeenItem &srcItem = srcItems[itemIndex]; - - if (srcItem._bonusFlags & ITEMFLAG_CURSED) - ErrorScroll::show(_vm, Res.CANNOT_REMOVE_CURSED_ITEM); - else if (destItems[INV_ITEMS_TOTAL - 1]._id) - ErrorScroll::show(_vm, Common::String::format( - Res.CATEGORY_BACKPACK_IS_FULL[category], c->_name.c_str())); - else { - destItem = srcItem; - srcItem.clear(); - destItem._frame = 0; - - srcItems.sort(); - destItems.sort(); - } - - continue; - } - - c = newChar; - startingChar = newChar; - intf.highlightChar(_buttonValue); - } - } - break; - - case Common::KEYCODE_1: - case Common::KEYCODE_2: - case Common::KEYCODE_3: - case Common::KEYCODE_4: - case Common::KEYCODE_5: - case Common::KEYCODE_6: - case Common::KEYCODE_7: - case Common::KEYCODE_8: - case Common::KEYCODE_9: - // Select an item - if (mode == ITEMMODE_3) - break; - - _buttonValue -= Common::KEYCODE_1; - if (_buttonValue != itemIndex) { - // Check whether the new selection has an associated item - if (!c->_items[category][_buttonValue].empty()) { - itemIndex = _buttonValue; - Common::fill(&arr[0], &arr[40], 0); - arr[itemIndex] = 15; - } - - redrawFlag = REDRAW_TEXT; - } - break; - - case Common::KEYCODE_a: - // Armor category - category = CATEGORY_ARMOR; - redrawFlag = REDRAW_FULL; - break; - - case Common::KEYCODE_b: - // Buy - if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && - mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { - mode = ITEMMODE_BLACKSMITH; - c = &_itemsCharacter; - redrawFlag = REDRAW_FULL; - } - break; - - case Common::KEYCODE_c: - // Accessories category - category = CATEGORY_ACCESSORY; - redrawFlag = REDRAW_FULL; - break; - - case Common::KEYCODE_d: - if (mode == ITEMMODE_CHAR_INFO) - actionIndex = 3; - break; - - case Common::KEYCODE_e: - if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_ENCHANT || - mode == ITEMMODE_TO_GOLD) { - if (category != CATEGORY_MISC) { - actionIndex = mode == ITEMMODE_ENCHANT ? 4 : 0; - } - } - break; - - case Common::KEYCODE_f: - if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && - mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { - mode = ITEMMODE_REPAIR; - c = startingChar; - redrawFlag = REDRAW_TEXT; - } - break; - - case Common::KEYCODE_g: - if (mode == ITEMMODE_TO_GOLD) - actionIndex = 6; - break; - - case Common::KEYCODE_i: - if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && - mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { - mode = ITEMMODE_IDENTIFY; - c = startingChar; - redrawFlag = REDRAW_TEXT; - } - break; - - case Common::KEYCODE_m: - // Misc - category = CATEGORY_MISC; - redrawFlag = REDRAW_TEXT; - break; - - case Common::KEYCODE_q: - // Quests - if (mode == ITEMMODE_CHAR_INFO) { - Quests::show(_vm); - redrawFlag = REDRAW_FULL; - } - break; - - case Common::KEYCODE_r: - if (mode == ITEMMODE_CHAR_INFO) - actionIndex = 1; - else if (mode == ITEMMODE_RECHARGE) - actionIndex = 5; - break; - - case Common::KEYCODE_s: - if (mode != ITEMMODE_CHAR_INFO && mode != ITEMMODE_RECHARGE && - mode != ITEMMODE_ENCHANT && mode != ITEMMODE_TO_GOLD) { - mode = ITEMMODE_2; - c = startingChar; - redrawFlag = REDRAW_TEXT; - } - break; - - case Common::KEYCODE_u: - if (mode == ITEMMODE_CHAR_INFO && category == CATEGORY_MISC) - actionIndex = 2; - break; - - case Common::KEYCODE_w: - // Weapons category - category = CATEGORY_WEAPON; - redrawFlag = REDRAW_TEXT; - break; - } - } - - windows[30].close(); - windows[29].close(); - - intf.drawParty(true); - if (updateStock) - charData2BlackData(); - - return c; -} - -void ItemsDialog::loadButtons(ItemsMode mode, Character *&c) { - _iconSprites.load(Common::String::format("%s.icn", - (mode == ITEMMODE_CHAR_INFO) ? "items" : "buy")); - _equipSprites.load("equip.icn"); - - if (mode == ITEMMODE_ENCHANT || mode == ITEMMODE_RECHARGE || mode == ITEMMODE_TO_GOLD) { - // Enchant button list - addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_w, &_iconSprites); - addButton(Common::Rect(46, 109, 70, 129), Common::KEYCODE_a, &_iconSprites); - addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_c, &_iconSprites); - addButton(Common::Rect(114, 109, 138, 129), Common::KEYCODE_m, &_iconSprites); - addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_e, &_iconSprites); - addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); - addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_u, &_iconSprites); - addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); - addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); - addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); - addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); - addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); - addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); - addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); - addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); - addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); - } else { - addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_w, &_iconSprites); - addButton(Common::Rect(46, 109, 70, 129), Common::KEYCODE_a, &_iconSprites); - addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_c, &_iconSprites); - addButton(Common::Rect(114, 109, 138, 129), Common::KEYCODE_m, &_iconSprites); - addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_e, &_iconSprites); - addButton(Common::Rect(182, 109, 206, 129), Common::KEYCODE_r, &_iconSprites); - addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_d, &_iconSprites); - addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_q, &_iconSprites); - addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); - addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); - addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); - addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); - addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); - addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); - addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); - addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); - addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); - addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); - addPartyButtons(_vm); - } - - if (mode == ITEMMODE_BLACKSMITH) { - _oldCharacter = c; - c = &_itemsCharacter; - blackData2CharData(); - - _buttons[4]._value = Common::KEYCODE_b; - _buttons[5]._value = Common::KEYCODE_s; - _buttons[6]._value = Common::KEYCODE_i; - _buttons[7]._value = Common::KEYCODE_f; - - setEquipmentIcons(); - } else { - _buttons[4]._value = Common::KEYCODE_e; - _buttons[5]._value = Common::KEYCODE_r; - _buttons[6]._value = Common::KEYCODE_d; - _buttons[7]._value = Common::KEYCODE_q; - } -} - -void ItemsDialog::blackData2CharData() { - Party &party = *_vm->_party; - bool isDarkCc = _vm->_files->_isDarkCc; - int slotIndex = 0; - while (slotIndex < 4 && party._mazeId != (int)Res.BLACKSMITH_MAP_IDS[isDarkCc][slotIndex]) - ++slotIndex; - if (slotIndex == 4) - slotIndex = 0; - - for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { - _itemsCharacter._weapons[idx] = party._blacksmithWeapons[isDarkCc][idx]; - _itemsCharacter._armor[idx] = party._blacksmithArmor[isDarkCc][idx]; - _itemsCharacter._accessories[idx] = party._blacksmithAccessories[isDarkCc][idx]; - _itemsCharacter._misc[idx] = party._blacksmithMisc[isDarkCc][idx]; - } -} - -void ItemsDialog::charData2BlackData() { - Party &party = *_vm->_party; - bool isDarkCc = _vm->_files->_isDarkCc; - int slotIndex = 0; - while (slotIndex < 4 && party._mazeId != (int)Res.BLACKSMITH_MAP_IDS[isDarkCc][slotIndex]) - ++slotIndex; - if (slotIndex == 4) - slotIndex = 0; - - for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { - party._blacksmithWeapons[isDarkCc][idx] = _itemsCharacter._weapons[idx]; - party._blacksmithArmor[isDarkCc][idx] = _itemsCharacter._armor[idx]; - party._blacksmithAccessories[isDarkCc][idx] = _itemsCharacter._accessories[idx]; - party._blacksmithMisc[isDarkCc][idx] = _itemsCharacter._misc[idx]; - } -} - -void ItemsDialog::setEquipmentIcons() { - for (int typeIndex = 0; typeIndex < 4; ++typeIndex) { - for (int idx = 0; idx < INV_ITEMS_TOTAL; ++idx) { - switch (typeIndex) { - case CATEGORY_WEAPON: { - XeenItem &i = _itemsCharacter._weapons[idx]; - if (i._id <= 17) - i._frame = 1; - else if (i._id <= 29 || i._id > 33) - i._frame = 13; - else - i._frame = 4; - break; - } - - case CATEGORY_ARMOR: { - XeenItem &i = _itemsCharacter._armor[idx]; - if (i._id <= 7) - i._frame = 3; - else if (i._id == 9) - i._frame = 5; - else if (i._id == 10) - i._frame = 9; - else if (i._id <= 12) - i._frame = 10; - else - i._frame = 6; - break; - } - - case CATEGORY_ACCESSORY: { - XeenItem &i = _itemsCharacter._accessories[idx]; - if (i._id == 1) - i._id = 8; - else if (i._id == 2) - i._frame = 12; - else if (i._id <= 7) - i._frame = 7; - else - i._frame = 11; - break; - } - - default: - break; - } - } - } -} - -int ItemsDialog::calcItemCost(Character *c, int itemIndex, ItemsMode mode, - int skillLevel, ItemCategory category) { - int amount1 = 0, amount2 = 0, amount3 = 0, amount4 = 0; - int result = 0; - int level = skillLevel & 0x7f; - - InventoryItems *invGroups[4] = { - &c->_weapons, &c->_armor, &c->_accessories, &c->_misc - }; - const int *BASE_COSTS[4] = { - Res.WEAPON_BASE_COSTS, Res.ARMOR_BASE_COSTS, Res.ACCESSORY_BASE_COSTS, Res.MISC_BASE_COSTS - }; - - switch (mode) { - case ITEMMODE_BLACKSMITH: - level = 0; - break; - case ITEMMODE_2: - case ITEMMODE_TO_GOLD: - level = level == 0 ? 1 : 0; - break; - case ITEMMODE_IDENTIFY: - level = 2; - break; - case ITEMMODE_REPAIR: - level = 3; - break; - default: - break; - } - - switch (category) { - case CATEGORY_WEAPON: - case CATEGORY_ARMOR: - case CATEGORY_ACCESSORY: { - XeenItem &i = (*invGroups[category])[itemIndex]; - amount1 = (BASE_COSTS[category])[i._id]; - - if (i._material > 36 && i._material < 59) { - switch (i._material) { - case 37: - amount1 /= 10; - break; - case 38: - amount1 /= 4; - break; - case 39: - amount1 /= 2; - break; - case 40: - amount1 /= 4; - break; - default: - amount1 *= Res.METAL_BASE_MULTIPLIERS[i._material - 37]; - break; - } - } - - if (i._material < 37) - amount2 = Res.ELEMENTAL_DAMAGE[i._material] * 100; - else if (i._material > 58) - amount3 = Res.ELEMENTAL_DAMAGE[i._material - 59 + 7] * 100; - - switch (mode) { - case ITEMMODE_BLACKSMITH: - case ITEMMODE_2: - case ITEMMODE_REPAIR: - case ITEMMODE_IDENTIFY: - case ITEMMODE_TO_GOLD: - result = (amount1 + amount2 + amount3 + amount4) / Res.ITEM_SKILL_DIVISORS[level]; - if (!result) - result = 1; - break; - default: - break; - } - break; - } - - case CATEGORY_MISC: { - // Misc - XeenItem &i = c->_misc[itemIndex]; - amount1 = Res.MISC_MATERIAL_COSTS[i._material]; - amount4 = Res.MISC_BASE_COSTS[i._id]; - - switch (mode) { - case ITEMMODE_BLACKSMITH: - case ITEMMODE_2: - case ITEMMODE_REPAIR: - case ITEMMODE_IDENTIFY: - case ITEMMODE_TO_GOLD: - result = (amount1 + amount2 + amount3 + amount4) / Res.ITEM_SKILL_DIVISORS[level]; - if (!result) - result = 1; - break; - default: - break; - } - break; - } - - default: - break; - } - - return (mode == ITEMMODE_CHAR_INFO) ? 0 : result; -} - -int ItemsDialog::doItemOptions(Character &c, int actionIndex, int itemIndex, ItemCategory category, - ItemsMode mode) { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Sound &sound = *_vm->_sound; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - bool isDarkCc = _vm->_files->_isDarkCc; - - XeenItem *itemCategories[4] = { &c._weapons[0], &c._armor[0], &c._accessories[0], &c._misc[0] }; - XeenItem *items = itemCategories[category]; - if (!items[0]._id) - // Inventory is empty - return category == CATEGORY_MISC ? 0 : 2; - - Window &w = windows[11]; - SpriteResource escSprites; - if (itemIndex < 0 || itemIndex > 8) { - saveButtons(); - - escSprites.load("esc.icn"); - addButton(Common::Rect(235, 111, 259, 131), Common::KEYCODE_ESCAPE, &escSprites); - addButton(Common::Rect(8, 20, 263, 28), Common::KEYCODE_1); - addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2); - addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3); - addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4); - addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5); - addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6); - addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7); - addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8); - addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9); - - w.open(); - w.writeString(Common::String::format(Res.WHICH_ITEM, Res.ITEM_ACTIONS[actionIndex])); - _iconSprites.draw(0, 0, Common::Point(235, 111)); - w.update(); - - while (!_vm->shouldExit()) { - while (!_buttonValue) { - events.pollEventsAndWait(); - checkEvents(_vm); - if (_vm->shouldExit()) - return false; - } - - if (_buttonValue == Common::KEYCODE_ESCAPE) { - itemIndex = -1; - break; - } else if (_buttonValue >= Common::KEYCODE_1 && _buttonValue <= Common::KEYCODE_9) { - // Check whether there's an item at the selected index - int selectedIndex = _buttonValue - Common::KEYCODE_1; - if (!items[selectedIndex]._id) - continue; - - itemIndex = selectedIndex; - break; - } - } - - w.close(); - restoreButtons(); - } - - if (itemIndex != -1) { - XeenItem &item = c._items[category][itemIndex]; - - switch (mode) { - case ITEMMODE_CHAR_INFO: - case ITEMMODE_8: - switch (actionIndex) { - case 0: - c._items[category].equipItem(itemIndex); - break; - case 1: - c._items[category].removeItem(itemIndex); - break; - case 2: - if (!party._mazeId) { - ErrorScroll::show(_vm, Res.WHATS_YOUR_HURRY); - } else { - XeenItem &i = c._misc[itemIndex]; - - Condition condition = c.worstCondition(); - switch (condition) { - case ASLEEP: - case PARALYZED: - case UNCONSCIOUS: - case DEAD: - case STONED: - case ERADICATED: - ErrorScroll::show(_vm, Common::String::format(Res.IN_NO_CONDITION, c._name.c_str())); - break; - default: - if (combat._itemFlag) { - ErrorScroll::show(_vm, Res.USE_ITEM_IN_COMBAT); - } else if (i._id && (i._bonusFlags & ITEMFLAG_BONUS_MASK) - && !(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED))) { - int charges = (i._bonusFlags & ITEMFLAG_BONUS_MASK) - 1; - i._bonusFlags = charges; - _oldCharacter = &c; - - windows[30].close(); - windows[29].close(); - windows[24].close(); - spells.castItemSpell(i._id); - - if (!charges) { - // Ran out of charges, so make item disappear - c._items[category][itemIndex].clear(); - c._items[category].sort(); - } - } else { - ErrorScroll::show(_vm, Common::String::format(Res.NO_SPECIAL_ABILITIES, - c._items[category].getFullDescription(itemIndex).c_str() - )); - } - } - } - break; - case 3: - c._items[category].discardItem(itemIndex); - break; - default: - break; - } - break; - - case ITEMMODE_BLACKSMITH: { - InventoryItems &invItems = _oldCharacter->_items[category]; - if (invItems[INV_ITEMS_TOTAL - 1]._id) { - // If the last slot is in use, it means the list is full - ErrorScroll::show(_vm, Common::String::format(Res.BACKPACK_IS_FULL, - _oldCharacter->_name.c_str())); - } else { - int cost = calcItemCost(_oldCharacter, itemIndex, mode, 0, category); - Common::String desc = c._items[category].getFullDescription(itemIndex); - if (Confirm::show(_vm, Common::String::format(Res.BUY_X_FOR_Y_GOLD, - desc.c_str(), cost))) { - if (party.subtract(CONS_GOLD, cost, WHERE_PARTY, WT_FREEZE_WAIT)) { - if (isDarkCc) { - sound.stopSound(); - sound.playSound("choice2.voc"); - } - - // Add entry to the end of the list - _oldCharacter->_items[category][8] = c._items[category][itemIndex]; - _oldCharacter->_items[category][8]._frame = 0; - c._items[category].clear(); - c._items[category].sort(); - _oldCharacter->_items[category].sort(); - } - } - } - return 0; - } - - case ITEMMODE_2: { - bool noNeed; - switch (category) { - case CATEGORY_WEAPON: - noNeed = (item._bonusFlags & ITEMFLAG_CURSED) || item._id == 34; - break; - default: - noNeed = item._bonusFlags & ITEMFLAG_CURSED; - break; - } - - if (noNeed) { - ErrorScroll::show(_vm, Common::String::format(Res.NO_NEED_OF_THIS, - c._items[category].getFullDescription(itemIndex).c_str())); - } else { - int cost = calcItemCost(&c, itemIndex, mode, c._skills[MERCHANT], category); - Common::String desc = c._items[category].getFullDescription(itemIndex); - Common::String msg = Common::String::format(Res.SELL_X_FOR_Y_GOLD, - desc.c_str(), cost); - - if (Confirm::show(_vm, msg)) { - // Remove the sold item and add gold to the party's total - item.clear(); - c._items[category].sort(); - - party._gold += cost; - } - } - return 0; - } - - case ITEMMODE_RECHARGE: - if (category != CATEGORY_MISC || c._misc[itemIndex]._material > 9 - || c._misc[itemIndex]._id == 53 || c._misc[itemIndex]._id == 0) { - sound.playFX(21); - ErrorScroll::show(_vm, Common::String::format(Res.NOT_RECHARGABLE, Res.SPELL_FAILED)); - } else { - int charges = MIN(63, _vm->getRandomNumber(1, 6) + - (c._misc[itemIndex]._bonusFlags & ITEMFLAG_BONUS_MASK)); - sound.playFX(20); - - c._misc[itemIndex]._bonusFlags = (c._misc[itemIndex]._bonusFlags - & ~ITEMFLAG_BONUS_MASK) | charges; - } - return 2; - - case ITEMMODE_ENCHANT: { - int amount = _vm->getRandomNumber(1, _oldCharacter->getCurrentLevel() / 5 + 1); - amount = MIN(amount, 5); - _oldCharacter->_items[category].enchantItem(itemIndex, amount); - break; - } - - case ITEMMODE_REPAIR: - if (!(item._bonusFlags & ITEMFLAG_BROKEN)) { - ErrorScroll::show(_vm, Res.ITEM_NOT_BROKEN); - } else { - int cost = calcItemCost(&c, itemIndex, mode, actionIndex, category); - Common::String msg = Common::String::format(Res.FIX_IDENTIFY_GOLD, - Res.FIX_IDENTIFY[0], - c._items[category].getFullDescription(itemIndex).c_str(), - cost); - - if (Confirm::show(_vm, msg) && party.subtract(CONS_GOLD, cost, WHERE_PARTY)) { - item._bonusFlags &= ~ITEMFLAG_BROKEN; - } - } - break; - - case ITEMMODE_IDENTIFY: { - int cost = calcItemCost(&c, itemIndex, mode, actionIndex, category); - Common::String msg = Common::String::format(Res.FIX_IDENTIFY_GOLD, - Res.FIX_IDENTIFY[1], - c._items[category].getFullDescription(itemIndex).c_str(), - cost); - - if (Confirm::show(_vm, msg) && party.subtract(CONS_GOLD, cost, WHERE_PARTY)) { - Common::String details = c._items[category].getIdentifiedDetails(itemIndex); - Common::String desc = c._items[category].getFullDescription(itemIndex); - Common::String str = Common::String::format(Res.IDENTIFY_ITEM_MSG, - desc.c_str(), details.c_str()); - - Window &win = windows[14]; - win.open(); - win.writeString(str); - win.update(); - - saveButtons(); - clearButtons(); - - while (!_vm->shouldExit() && !events.isKeyMousePressed()) - events.pollEventsAndWait(); - events.clearEvents(); - - restoreButtons(); - win.close(); - } - break; - } - - case ITEMMODE_TO_GOLD: - // Convert item in inventory to gold - itemToGold(c, itemIndex, category, mode); - return 2; - - default: - break; - } - } - - intf._charsShooting = false; - combat.moveMonsters(); - combat._whosTurn = -1; - return true; -} - -void ItemsDialog::itemToGold(Character &c, int itemIndex, ItemCategory category, - ItemsMode mode) { - XeenItem &item = c._items[category][itemIndex]; - Party &party = *_vm->_party; - Sound &sound = *_vm->_sound; - - if (category == CATEGORY_WEAPON && item._id == 34) { - sound.playFX(21); - ErrorScroll::show(_vm, Common::String::format("\v012\t000\x03""c%s", - Res.SPELL_FAILED)); - } else if (item._id != 0) { - // There is a valid item present - // Calculate cost of item and add it to the party's total - int cost = calcItemCost(&c, itemIndex, mode, 1, category); - party._gold += cost; - - // Remove the item from the inventory - item.clear(); - c._items[category].sort(); - } -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_items.h b/engines/xeen/dialogs_items.h deleted file mode 100644 index f35ef883b8..0000000000 --- a/engines/xeen/dialogs_items.h +++ /dev/null @@ -1,89 +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_DIALOGS_ITEMS_H -#define XEEN_DIALOGS_ITEMS_H - -#include "xeen/dialogs.h" -#include "xeen/party.h" -#include "xeen/window.h" - -namespace Xeen { - -enum ItemsMode { - ITEMMODE_CHAR_INFO = 0, ITEMMODE_BLACKSMITH = 1, ITEMMODE_2 = 2, ITEMMODE_3 = 3, - ITEMMODE_RECHARGE = 4, ITEMMODE_5 = 5, ITEMMODE_ENCHANT = 6, ITEMMODE_COMBAT = 7, ITEMMODE_8 = 8, - ITEMMODE_REPAIR = 9, ITEMMODE_IDENTIFY = 10, ITEMMODE_TO_GOLD = 11 -}; - -class ItemsDialog : public ButtonContainer { -private: - SpriteResource _iconSprites; - SpriteResource _equipSprites; - Character _itemsCharacter; - Character *_oldCharacter; - DrawStruct _itemsDrawList[INV_ITEMS_TOTAL]; - - ItemsDialog(XeenEngine *vm) : ButtonContainer(vm), _oldCharacter(nullptr) {} - - Character *execute(Character *c, ItemsMode mode); - - /** - * Load the buttons for the dialog - */ - void loadButtons(ItemsMode mode, Character *&c); - - /** - * Loads the temporary _itemsCharacter character with the item set - * the given blacksmith has available, so the user can "view" the - * set as if it were a standard character's inventory - */ - void blackData2CharData(); - - /** - * Saves the inventory from the temporary _itemsCharacter character back into the - * blacksmith storage, so changes in blacksmith inventory remain persistent - */ - void charData2BlackData(); - - /** - * Sets the equipment icon to use for each item for display - */ - void setEquipmentIcons(); - - /** - * Calculate the cost of an item - */ - int calcItemCost(Character *c, int itemIndex, ItemsMode mode, int skillLevel, - ItemCategory category); - - int doItemOptions(Character &c, int actionIndex, int itemIndex, - ItemCategory category, ItemsMode mode); - - void itemToGold(Character &c, int itemIndex, ItemCategory category, ItemsMode mode); -public: - static Character *show(XeenEngine *vm, Character *c, ItemsMode mode); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_ITEMS_H */ diff --git a/engines/xeen/dialogs_map.cpp b/engines/xeen/dialogs_map.cpp deleted file mode 100644 index d7442605c3..0000000000 --- a/engines/xeen/dialogs_map.cpp +++ /dev/null @@ -1,461 +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_map.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -#define MAP_SIZE 16 -#define MAP_DIFF (MAP_SIZE / 2) -#define MAP_XSTART 80 -#define MAP_YSTART 38 -#define TILE_WIDTH 10 -#define TILE_HEIGHT 8 - -void MapDialog::show(XeenEngine *vm) { - MapDialog *dlg = new MapDialog(vm); - dlg->execute(); - delete dlg; -} - -void MapDialog::execute() { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - - _pt = party._mazePosition; - _globalSprites.load("global.icn"); - - if (_pt.x < 8 && map.mazeData()._surroundingMazes._west == 0) { - _arrowPt.x = _pt.x * 10 + 4; - _pt.x = 7; - } else if (_pt.x > 23) { - _arrowPt.x = (byte)(_pt.x * 10 + 100); - _pt.x = 23; - } else if (_pt.x > 8 && map.mazeData()._surroundingMazes._east == 0) { - _arrowPt.x = (byte)(_pt.x * 10 + 4); - _pt.x = 7; - } else { - _arrowPt.x = 74; - } - - if (_pt.y < 8 && map.mazeData()._surroundingMazes._south == 0) { - _arrowPt.y = ((15 - _pt.y) << 3) + 13; - _pt.y = 8; - } else if (_pt.y > 24) { - _arrowPt.y = ((15 - (_pt.y - 16)) << 3) + 13; - _pt.y = 24; - } else if (_pt.y >= 8 && map.mazeData()._surroundingMazes._north == 0) { - _arrowPt.y = ((15 - _pt.y) << 3) + 13; - _pt.y = 8; - } else { - _arrowPt.y = 69; - } - - windows[5].open(); - bool drawFlag = true; - - events.updateGameCounter(); - do { - if (drawFlag) - intf.draw3d(false, false); - windows[5].writeString("\r"); - - if (map._isOutdoors) - drawOutdoors(); - else - drawIndoors(); - - windows[5].frame(); - if (!map._isOutdoors) { - map._tileSprites.draw(0, 52, Common::Point(76, 30)); - } else if (_frameEndFlag) { - _globalSprites.draw(0, party._mazeDirection + 1, - Common::Point(_arrowPt.x + 76, _arrowPt.y + 25)); - } - - if (events.timeElapsed() > 5) { - // Set the flag to make the basic arrow blinking effect - _frameEndFlag = !_frameEndFlag; - events.updateGameCounter(); - } - - windows[5].writeString(Common::String::format(Res.MAP_TEXT, - map._mazeName.c_str(), party._mazePosition.x, - party._mazePosition.y, Res.DIRECTION_TEXT[party._mazeDirection])); - windows[5].update(); - windows[3].update(); - - events.ipause5(2); - drawFlag = false; - } while (!_vm->shouldExit() && !events.isKeyMousePressed()); - - events.clearEvents(); - windows[5].close(); -} - -void MapDialog::drawOutdoors() { - Map &map = *g_vm->_map; - int v, frame; - - // Draw outdoors map - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - --mazeY, yp += TILE_HEIGHT) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); - assert(v != INVALID_CELL); - frame = map.mazeDataCurrent()._surfaceTypes[v]; - - if (map._currentSteppedOn) { - map._tileSprites.draw(0, frame, Common::Point(xp, yp)); - } - } - } - - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - --mazeY, yp += TILE_HEIGHT) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, mazeY), 4); - assert(v != INVALID_CELL); - frame = map.mazeDataCurrent()._wallTypes[v]; - - if (frame && map._currentSteppedOn) - map._tileSprites.draw(0, frame + 16, Common::Point(xp, yp)); - } - } - - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - --mazeY, yp += TILE_HEIGHT) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - frame = map.mazeLookup(Common::Point(mazeX, mazeY), 8, 0xff); - - if (frame && map._currentSteppedOn) - map._tileSprites.draw(0, frame + 32, Common::Point(xp, yp)); - } - } -} - -void MapDialog::drawIndoors() { - Map &map = *g_vm->_map; - Party &party = *g_vm->_party; - int v, frame; - int frame2 = _animFrame; - _animFrame = (_animFrame + 2) % 8; - - // Draw indoors map - frame2 = (frame2 + 2) % 8; - - // Draw default ground for all the valid explored areas - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - yp += TILE_HEIGHT, --mazeY) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); - - if (v != INVALID_CELL && map._currentSteppedOn) - map._tileSprites.draw(0, 0, Common::Point(xp, yp)); - } - } - - // Draw thinner ground tiles on the left edge of the map - for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - yp += TILE_HEIGHT, --mazeY) { - v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 0, 0xffff); - - if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) - map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ - map._currentSurfaceId], Common::Point(75, yp)); - } - - // Draw thin tile portion on top-left corner of map - v = map.mazeLookup(Common::Point(_pt.x - 8, _pt.y + 8), 0, 0xffff); - if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) - map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ - map._currentSurfaceId], Common::Point(75, 35)); - - // Draw any thin tiles at the very top of the map - for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0, 0xffff); - - if (v != INVALID_CELL && map._currentSurfaceId != 0 && map._currentSteppedOn) - map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ - map._currentSurfaceId], Common::Point(xp, 35)); - } - - // Draw the default ground tiles - for (int yp = MAP_YSTART + 5, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - yp += TILE_HEIGHT, --mazeY) { - for (int xp = MAP_XSTART + 5, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); - - if (v != INVALID_CELL && map._currentSurfaceId && map._currentSteppedOn) - map._tileSprites.draw(0, 36 + map.mazeData()._surfaceTypes[ - map._currentSurfaceId], Common::Point(xp, yp)); - } - } - - // Draw walls on left and top edges of map - for (int xp = MAP_XSTART, yp = MAP_YSTART + (MAP_SIZE - 1) * TILE_HEIGHT, - mazeX = _pt.x - (MAP_DIFF - 1), mazeY = _pt.y - MAP_DIFF; - mazeX < (_pt.x + MAP_DIFF); xp += TILE_WIDTH, yp -= TILE_HEIGHT, ++mazeX, ++mazeY) { - // Draw walls on left edge of map - v = map.mazeLookup(Common::Point(_pt.x - 8, mazeY), 12); - - switch (v) { - case SURFTYPE_DIRT: - frame = 18; - break; - case SURFTYPE_SNOW: - frame = 22; - break; - case SURFTYPE_SWAMP: - case SURFTYPE_CLOUD: - frame = 16; - break; - case SURFTYPE_LAVA: - case SURFTYPE_DWATER: - frame = 2; - break; - case SURFTYPE_DESERT: - frame = 30; - break; - case SURFTYPE_ROAD: - frame = 32; - break; - case SURFTYPE_TFLR: - frame = 20; - break; - case SURFTYPE_SKY: - frame = 28; - break; - case SURFTYPE_CROAD: - frame = 14; - break; - case SURFTYPE_SEWER: - frame = frame2 + 4; - break; - case SURFTYPE_SCORCH: - frame = 24; - break; - case SURFTYPE_SPACE: - frame = 26; - break; - default: - frame = -1; - break; - } - - if (frame != -1 && map._currentSteppedOn) - map._tileSprites.draw(0, frame, Common::Point(70, yp)); - - // Draw walls on top edge of map - v = map.mazeLookup(Common::Point(mazeX, _pt.y + 8), 0); - - switch (v) { - case SURFTYPE_DIRT: - frame = 19; - break; - case SURFTYPE_GRASS: - frame = 35; - break; - case SURFTYPE_SNOW: - frame = 23; - break; - case SURFTYPE_SWAMP: - case SURFTYPE_CLOUD: - frame = 17; - break; - case SURFTYPE_LAVA: - case SURFTYPE_DWATER: - frame = 3; - break; - case SURFTYPE_DESERT: - frame = 31; - break; - case SURFTYPE_ROAD: - frame = 33; - break; - case SURFTYPE_TFLR: - frame = 21; - break; - case SURFTYPE_SKY: - frame = 29; - break; - case SURFTYPE_CROAD: - frame = 15; - break; - case SURFTYPE_SEWER: - frame = frame2 + 5; - break; - case SURFTYPE_SCORCH: - frame = 25; - break; - case SURFTYPE_SPACE: - frame = 27; - break; - default: - frame = -1; - break; - } - - if (frame != -1 && map._currentSteppedOn) - map._tileSprites.draw(0, frame, Common::Point(xp, 30)); - } - - // Draw the walls for the remaining cells of the minimap - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1, yCtr = 0; yCtr < MAP_SIZE; - yp += TILE_HEIGHT, --mazeY, ++yCtr) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1), xCtr = 0; xCtr < MAP_SIZE; - xp += TILE_WIDTH, ++mazeX, ++xCtr) { - // Draw the arrow if at the correct position - if ((_arrowPt.x / 10) == xCtr && (14 - (_arrowPt.y / 10)) == yCtr && _frameEndFlag) { - _globalSprites.draw(0, party._mazeDirection + 1, - Common::Point(_arrowPt.x + 81, _arrowPt.y + 29)); - } - - v = map.mazeLookup(Common::Point(mazeX, mazeY), 12); - switch (v) { - case 1: - frame = 18; - break; - case 2: - frame = 34; - break; - case 3: - frame = 22; - break; - case 4: - case 13: - frame = 16; - break; - case 5: - case 8: - frame = 2; - break; - case 6: - frame = 30; - break; - case 7: - frame = 32; - break; - case 9: - frame = 20; - break; - case 10: - frame = 28; - break; - case 11: - frame = 14; - break; - case 12: - frame = frame2 + 4; - break; - case 14: - frame = 24; - break; - case 15: - frame = 26; - break; - default: - frame = -1; - break; - } - - if (frame != -1 && map._currentSteppedOn) - map._tileSprites.draw(0, frame, Common::Point(xp, yp)); - - v = map.mazeLookup(Common::Point(mazeX, mazeY), 0); - switch (v) { - case 1: - frame = 19; - break; - case 2: - frame = 35; - break; - case 3: - frame = 23; - break; - case 4: - case 13: - frame = 17; - break; - case 5: - case 8: - frame = 3; - break; - case 6: - frame = 31; - break; - case 7: - frame = 33; - break; - case 9: - frame = 21; - break; - case 10: - frame = 29; - break; - case 11: - frame = 15; - break; - case 12: - frame = frame2 + 5; - break; - case 14: - frame = 25; - break; - case 15: - frame = 27; - break; - default: - frame = -1; - break; - } - - if (frame != -1 && map._currentSteppedOn) - map._tileSprites.draw(0, frame, Common::Point(xp, yp)); - } - } - - // Draw overlay on cells that haven't been stepped on yet - for (int yp = MAP_YSTART, mazeY = _pt.y + MAP_DIFF - 1; mazeY >= (_pt.y - MAP_DIFF); - yp += TILE_HEIGHT, --mazeY) { - for (int xp = MAP_XSTART, mazeX = _pt.x - (MAP_DIFF - 1); mazeX <= (_pt.x + MAP_DIFF); - xp += TILE_WIDTH, ++mazeX) { - v = map.mazeLookup(Common::Point(mazeX, mazeY), 0, 0xffff); - - if (v == INVALID_CELL || !map._currentSteppedOn) - map._tileSprites.draw(0, 1, Common::Point(xp, yp)); - } - } -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_map.h b/engines/xeen/dialogs_map.h deleted file mode 100644 index 3c12afab49..0000000000 --- a/engines/xeen/dialogs_map.h +++ /dev/null @@ -1,62 +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_DIALOGS_MAP_H -#define XEEN_DIALOGS_MAP_H - -#include "xeen/dialogs.h" - -namespace Xeen { - -class XeenEngine; - -class MapDialog: public ButtonContainer { -private: - int _animFrame; - SpriteResource _globalSprites; - Common::Point _pt, _arrowPt; - bool _frameEndFlag; -private: - MapDialog(XeenEngine *vm) : ButtonContainer(vm), - _animFrame(0), _frameEndFlag(false) {} - - /** - * Draws the map contents when outdoors - */ - void drawOutdoors(); - - /** - * Draws the map contents when indoors - */ - void drawIndoors(); - - /** - * Handles the display of the dialog - */ - void execute(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_AUTOMAP_H */ diff --git a/engines/xeen/dialogs_message.cpp b/engines/xeen/dialogs_message.cpp deleted file mode 100644 index b0bc5b6634..0000000000 --- a/engines/xeen/dialogs_message.cpp +++ /dev/null @@ -1,123 +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 "common/scummsys.h" -#include "xeen/dialogs_message.h" -#include "xeen/events.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void MessageDialog::show(XeenEngine *vm, const Common::String &msg, MessageWaitType waitType) { - MessageDialog *dlg = new MessageDialog(vm); - dlg->execute(msg, waitType); - delete dlg; -} - -void MessageDialog::execute(const Common::String &msg, MessageWaitType waitType) { - EventsManager &events = *_vm->_events; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - - w.open(); - w.writeString(msg); - w.update(); - - switch (waitType) { - case WT_FREEZE_WAIT: - while (!_vm->shouldExit() && !events.isKeyMousePressed()) - events.pollEventsAndWait(); - - events.clearEvents(); - break; - - case WT_ANIMATED_WAIT: - if (windows[11]._enabled || _vm->_mode == MODE_17) { - g_vm->_locations->wait(); - break; - } - // fall through - - case WT_NONFREEZED_WAIT: - do { - events.updateGameCounter(); - _vm->_interface->draw3d(true); - - events.wait(1); - if (checkEvents(_vm)) - break; - } while (!_vm->shouldExit() && !_buttonValue); - break; - - case WT_LOC_WAIT: - g_vm->_locations->wait(); - break; - - default: - break; - } - - w.close(); -} - -/*------------------------------------------------------------------------*/ - -void ErrorScroll::show(XeenEngine *vm, const Common::String &msg, MessageWaitType waitType) { - Common::String s = Common::String::format("\x3""c\v010\t000%s", msg.c_str()); - MessageDialog::show(vm, s, waitType); -} - -/*------------------------------------------------------------------------*/ - -void CantCast::show(XeenEngine *vm, int spellId, int componentNum) { - CantCast *dlg = new CantCast(vm); - dlg->execute(spellId, componentNum); - delete dlg; -} - -void CantCast::execute(int spellId, int componentNum) { - EventsManager &events = *_vm->_events; - Sound &sound = *_vm->_sound; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_FF; - - sound.playFX(21); - w.open(); - w.writeString(Common::String::format(Res.NOT_ENOUGH_TO_CAST, - Res.SPELL_CAST_COMPONENTS[componentNum - 1], - spells._spellNames[spellId].c_str() - )); - w.update(); - - do { - events.pollEventsAndWait(); - } while (!_vm->shouldExit() && !events.isKeyMousePressed()); - events.clearEvents(); - - w.close(); - _vm->_mode = oldMode; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_message.h b/engines/xeen/dialogs_message.h deleted file mode 100644 index e092b30670..0000000000 --- a/engines/xeen/dialogs_message.h +++ /dev/null @@ -1,61 +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_dialogs_message_H -#define XEEN_dialogs_message_H - -#include "xeen/dialogs.h" -#include "xeen/character.h" - -namespace Xeen { - -enum MessageWaitType { WT_FREEZE_WAIT = 0, WT_NONFREEZED_WAIT = 1, - WT_LOC_WAIT = 2, WT_ANIMATED_WAIT = 3 }; - -class MessageDialog : public ButtonContainer { -private: - MessageDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(const Common::String &msg, MessageWaitType waitType); -public: - static void show(XeenEngine *vm, const Common::String &msg, - MessageWaitType waitType = WT_FREEZE_WAIT); -}; - -class ErrorScroll { -public: - static void show(XeenEngine *vm, const Common::String &msg, - MessageWaitType waitType = WT_FREEZE_WAIT); -}; - -class CantCast: public ButtonContainer { -private: - CantCast(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(int spellId, int componentNum); -public: - static void show(XeenEngine *vm, int spellId, int componentNum); -}; - -} // End of namespace Xeen - -#endif /* XEEN_dialogs_message_H */ diff --git a/engines/xeen/dialogs_party.cpp b/engines/xeen/dialogs_party.cpp deleted file mode 100644 index b0c638243d..0000000000 --- a/engines/xeen/dialogs_party.cpp +++ /dev/null @@ -1,451 +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_char_info.h" -#include "xeen/dialogs_create_char.h" -#include "xeen/dialogs_party.h" -#include "xeen/dialogs_input.h" -#include "xeen/dialogs_query.h" -#include "xeen/character.h" -#include "xeen/events.h" -#include "xeen/party.h" -#include "xeen/xeen.h" - -namespace Xeen { - -PartyDialog::PartyDialog(XeenEngine *vm) : ButtonContainer(vm), - PartyDrawer(vm), _vm(vm) { - initDrawStructs(); -} - -void PartyDialog::show(XeenEngine *vm) { - PartyDialog *dlg = new PartyDialog(vm); - dlg->execute(); - delete dlg; -} - -void PartyDialog::execute() { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; - Windows &windows = *_vm->_windows; - bool modeFlag = false; - int startingChar = 0; - - loadButtons(); - setupBackground(); - - while (!_vm->shouldExit()) { - _vm->_mode = MODE_1; - - // Build up a list of available characters in the Roster that are on the - // same side of Xeen as the player is currently on - _charList.clear(); - for (int i = 0; i < XEEN_TOTAL_CHARACTERS; ++i) { - Character &player = party._roster[i]; - if (player._name.empty() || player._xeenSide != (map._loadDarkSide ? 1 : 0)) - continue; - - _charList.push_back(i); - } - - Window &w = windows[11]; - w.open(); - setupFaces(startingChar, false); - w.writeString(Common::String::format(Res.PARTY_DIALOG_TEXT, _partyDetails.c_str())); - w.drawList(&_faceDrawStructs[0], 4); - - _uiSprites.draw(w, 0, Common::Point(16, 100)); - _uiSprites.draw(w, 2, Common::Point(52, 100)); - _uiSprites.draw(w, 4, Common::Point(87, 100)); - _uiSprites.draw(w, 6, Common::Point(122, 100)); - _uiSprites.draw(w, 8, Common::Point(157, 100)); - _uiSprites.draw(w, 10, Common::Point(192, 100)); - if (g_vm->getGameID() == GType_Swords) - Res._logoSprites.draw(1, 0, Common::Point(232, 9)); - - screen.loadPalette("mm4.pal"); - - if (modeFlag) { - windows[0].update(); - events.setCursor(0); - screen.fadeIn(); - } else { - if (_vm->getGameID() == GType_DarkSide) { - screen.fadeOut(); - windows[0].update(); - } - - doScroll(false, false); - events.setCursor(0); - - if (_vm->getGameID() == GType_DarkSide) { - screen.fadeIn(); - } - } - - bool breakFlag = false; - while (!_vm->shouldExit() && !breakFlag) { - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_vm->shouldExit() && !_buttonValue); - - switch (_buttonValue) { - case Common::KEYCODE_ESCAPE: - case Common::KEYCODE_SPACE: - case Common::KEYCODE_e: - case Common::KEYCODE_x: - if (party._activeParty.size() == 0) { - ErrorScroll::show(_vm, Res.NO_ONE_TO_ADVENTURE_WITH); - } else { - if (_vm->_mode != MODE_0) { - for (int idx = OBSCURITY_NONE; idx >= OBSCURITY_BLACK; --idx) { - events.updateGameCounter(); - intf.obscureScene((Obscurity)idx); - w.update(); - - while (events.timeElapsed() < 1) - events.pollEventsAndWait(); - } - } - - w.close(); - party._mazeId = party._priorMazeId; - - party.copyPartyToRoster(); - //_vm->_saves->writeCharFile(); - return; - } - break; - - case Common::KEYCODE_F1: - case Common::KEYCODE_F2: - case Common::KEYCODE_F3: - case Common::KEYCODE_F4: - case Common::KEYCODE_F5: - case Common::KEYCODE_F6: - // Show character info - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)party._activeParty.size()) - CharacterInfo::show(_vm, _buttonValue); - break; - - case Common::KEYCODE_1: - case Common::KEYCODE_2: - case Common::KEYCODE_3: - case Common::KEYCODE_4: - _buttonValue -= Common::KEYCODE_1 - 7; - if ((_buttonValue - 7 + startingChar) < (int)_charList.size()) { - // Check if the selected character is already in the party - uint idx = 0; - for (; idx < party._activeParty.size(); ++idx) { - if (_charList[_buttonValue - 7 + startingChar] == - party._activeParty[idx]._rosterId) - break; - } - - // Only add the character if they're not already in the party - if (idx == party._activeParty.size()) { - if (party._activeParty.size() == MAX_ACTIVE_PARTY) { - sound.playFX(21); - ErrorScroll::show(_vm, Res.YOUR_PARTY_IS_FULL); - } else { - // Add the character to the active party - party._activeParty.push_back(party._roster[ - _charList[_buttonValue - 7 + startingChar]]); - startingCharChanged(startingChar); - } - } - } - break; - - case Common::KEYCODE_UP: - case Common::KEYCODE_KP8: - // Up arrow - if (startingChar > 0) { - startingChar -= 4; - startingCharChanged(startingChar); - } - break; - - case Common::KEYCODE_DOWN: - case Common::KEYCODE_KP2: - // Down arrow - if (startingChar < ((int)_charList.size() - 4)) { - startingChar += 4; - startingCharChanged(startingChar); - } - break; - - case Common::KEYCODE_c: - // Create - if (_charList.size() == XEEN_TOTAL_CHARACTERS) { - ErrorScroll::show(_vm, Res.YOUR_ROSTER_IS_FULL); - } else { - screen.fadeOut(); - w.close(); - - // Show the create character dialog - CreateCharacterDialog::show(_vm); - - party.copyPartyToRoster(); - //_vm->_saves->writeCharFile(); - screen.fadeOut(); - modeFlag = true; - breakFlag = true; - } - break; - - case Common::KEYCODE_d: - // Delete character - if (_charList.size() > 0) { - int charButtonValue = selectCharacter(true, startingChar); - if (charButtonValue != 0) { - int charIndex = charButtonValue - Common::KEYCODE_1 + startingChar; - Character &c = party._roster[_charList[charIndex]]; - if (c.hasSlayerSword()) { - ErrorScroll::show(_vm, Res.HAS_SLAYER_SWORD); - } else { - Common::String msg = Common::String::format(Res.SURE_TO_DELETE_CHAR, - c._name.c_str(), Res.CLASS_NAMES[c._class]); - if (Confirm::show(_vm, msg)) { - // If the character is in the party, remove it - for (uint idx = 0; idx < party._activeParty.size(); ++idx) { - if (party._activeParty[idx]._rosterId == c._rosterId) { - party._activeParty.remove_at(idx); - break; - } - } - - // Empty the character in the roster - c.clear(); - - // Rebuild the character list - _charList.clear(); - for (int idx = 0; idx < XEEN_TOTAL_CHARACTERS; ++idx) { - Character &ch = party._roster[idx]; - if (!ch._name.empty() && ch._savedMazeId == party._priorMazeId) { - _charList.push_back(idx); - } - } - - startingCharChanged(startingChar); - } - } - } - } - break; - - case Common::KEYCODE_r: - // Remove character - if (party._activeParty.size() > 0) { - int charButtonValue = selectCharacter(false, startingChar); - if (charButtonValue != 0) { - party.copyPartyToRoster(); - party._activeParty.remove_at(charButtonValue - Common::KEYCODE_F1); - } - startingCharChanged(startingChar); - } - break; - - default: - break; - } - } - } -} - -void PartyDialog::loadButtons() { - _uiSprites.load("inn.icn"); - addButton(Common::Rect(16, 100, 40, 120), Common::KEYCODE_UP, &_uiSprites); - addButton(Common::Rect(52, 100, 76, 120), Common::KEYCODE_DOWN, &_uiSprites); - addButton(Common::Rect(87, 100, 111, 120), Common::KEYCODE_d, &_uiSprites); - addButton(Common::Rect(122, 100, 146, 120), Common::KEYCODE_r, &_uiSprites); - addButton(Common::Rect(157, 100, 181, 120), Common::KEYCODE_c, &_uiSprites); - addButton(Common::Rect(192, 100, 216, 120), Common::KEYCODE_x, &_uiSprites); - addButton(Common::Rect(0, 0, 0, 0), Common::KEYCODE_ESCAPE); -} - -void PartyDialog::initDrawStructs() { - _faceDrawStructs[0] = DrawStruct(0, 0, 0); - _faceDrawStructs[1] = DrawStruct(0, 101, 0); - _faceDrawStructs[2] = DrawStruct(0, 0, 43); - _faceDrawStructs[3] = DrawStruct(0, 101, 43); -} - -void PartyDialog::setupBackground() { - _vm->_screen->loadBackground("back.raw"); - _vm->_interface->assembleBorder(); -} - -void PartyDialog::setupFaces(int firstDisplayChar, bool updateFlag) { - Party &party = *_vm->_party; - Common::String charNames[4]; - Common::String charRaces[4]; - Common::String charSex[4]; - Common::String charClasses[4]; - int posIndex; - int charId; - - // Reset the button areas for the display character images - while (_buttons.size() > 7) - _buttons.remove_at(7); - addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); - addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); - addButton(Common::Rect(59, 59, 91, 91), Common::KEYCODE_3); - addButton(Common::Rect(117, 59, 151, 91), Common::KEYCODE_4); - - - for (posIndex = 0; posIndex < 4; ++posIndex) { - charId = (firstDisplayChar + posIndex) >= (int)_charList.size() ? -1 : - _charList[firstDisplayChar + posIndex]; - bool isInParty = party.isInParty(charId); - - if (charId == -1) { - while ((int)_buttons.size() >(7 + posIndex)) - _buttons.remove_at(_buttons.size() - 1); - break; - } - - Common::Rect &b = _buttons[7 + posIndex]._bounds; - b.moveTo((posIndex & 1) ? 117 : 16, b.top); - Character &ps = party._roster[_charList[firstDisplayChar + posIndex]]; - charNames[posIndex] = isInParty ? Res.IN_PARTY : ps._name; - charRaces[posIndex] = Res.RACE_NAMES[ps._race]; - charSex[posIndex] = Res.SEX_NAMES[ps._sex]; - charClasses[posIndex] = Res.CLASS_NAMES[ps._class]; - } - - drawParty(updateFlag); - - // Set up the sprite set to use for each face - for (posIndex = 0; posIndex < 4; ++posIndex) { - if ((firstDisplayChar + posIndex) >= (int)_charList.size()) - _faceDrawStructs[posIndex]._sprites = nullptr; - else - _faceDrawStructs[posIndex]._sprites = party._roster[ - _charList[firstDisplayChar + posIndex]]._faceSprites; - } - - _partyDetails = Common::String::format(Res.PARTY_DETAILS, - charNames[0].c_str(), charRaces[0].c_str(), charSex[0].c_str(), charClasses[0].c_str(), - charNames[1].c_str(), charRaces[1].c_str(), charSex[1].c_str(), charClasses[1].c_str(), - charNames[2].c_str(), charRaces[2].c_str(), charSex[2].c_str(), charClasses[2].c_str(), - charNames[3].c_str(), charRaces[3].c_str(), charSex[3].c_str(), charClasses[3].c_str() - ); -} - -void PartyDialog::startingCharChanged(int firstDisplayChar) { - Windows &windows = *_vm->_windows; - Window &w = windows[11]; - - setupFaces(firstDisplayChar, true); - w.writeString(Common::String::format(Res.PARTY_DIALOG_TEXT, _partyDetails.c_str())); - w.drawList(_faceDrawStructs, 4); - - _uiSprites.draw(w, 0, Common::Point(16, 100)); - _uiSprites.draw(w, 2, Common::Point(52, 100)); - _uiSprites.draw(w, 4, Common::Point(87, 100)); - _uiSprites.draw(w, 6, Common::Point(122, 100)); - _uiSprites.draw(w, 8, Common::Point(157, 100)); - _uiSprites.draw(w, 10, Common::Point(192, 100)); - - w.update(); -} - -int PartyDialog::selectCharacter(bool isDelete, int firstDisplayChar) { - EventsManager &events = *_vm->_events; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Window &w = windows[28]; - - SpriteResource iconSprites; - iconSprites.load("esc.icn"); - - w.setBounds(Common::Rect(50, isDelete ? 112 : 76, 266, isDelete ? 148 : 112)); - w.open(); - w.writeString(Common::String::format(Res.REMOVE_OR_DELETE_WHICH, - Res.REMOVE_DELETE[isDelete ? 1 : 0])); - iconSprites.draw(w, 0, Common::Point(225, isDelete ? 120 : 84)); - w.update(); - - saveButtons(); - addButton(Common::Rect(225, isDelete ? 120 : 84, 249, isDelete ? 140 : 104), - Common::KEYCODE_ESCAPE, &iconSprites); - addButton(Common::Rect(16, 16, 48, 48), Common::KEYCODE_1); - addButton(Common::Rect(117, 16, 149, 48), Common::KEYCODE_2); - addButton(Common::Rect(16, 59, 48, 91), Common::KEYCODE_3); - addButton(Common::Rect(117, 59, 149, 91), Common::KEYCODE_4); - addPartyButtons(_vm); - - int result = -1, v; - while (!_vm->shouldExit() && result == -1) { - _buttonValue = 0; - while (!_vm->shouldExit() && !_buttonValue) { - events.pollEventsAndWait(); - checkEvents(_vm); - } - - switch (_buttonValue) { - case Common::KEYCODE_ESCAPE: - result = 0; - break; - - case Common::KEYCODE_F1: - case Common::KEYCODE_F2: - case Common::KEYCODE_F3: - case Common::KEYCODE_F4: - case Common::KEYCODE_F5: - case Common::KEYCODE_F6: - if (!isDelete) { - v = _buttonValue - Common::KEYCODE_F1; - if (v < (int)party._activeParty.size()) - result = _buttonValue; - } - break; - - case Common::KEYCODE_1: - case Common::KEYCODE_2: - case Common::KEYCODE_3: - case Common::KEYCODE_4: - if (isDelete) { - v = _buttonValue - Common::KEYCODE_1; - if ((firstDisplayChar + v) < (int)_charList.size()) - result = _buttonValue; - } - break; - - default: - break; - } - } - - w.close(); - restoreButtons(); - return result == -1 ? 0 : result; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_party.h b/engines/xeen/dialogs_party.h deleted file mode 100644 index ba9c34cd0d..0000000000 --- a/engines/xeen/dialogs_party.h +++ /dev/null @@ -1,87 +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_DIALOGS_PARTY_H -#define XEEN_DIALOGS_PARTY_H - -#include "common/array.h" -#include "xeen/dialogs.h" -#include "xeen/interface.h" -#include "xeen/screen.h" -#include "xeen/sprites.h" - -namespace Xeen { - -/** - * Shows the Party dialog that's shown when signing into an inn - */ -class PartyDialog : public ButtonContainer, public PartyDrawer { -private: - XeenEngine *_vm; - SpriteResource _uiSprites; - DrawStruct _faceDrawStructs[4]; - Common::String _partyDetails; - Common::Array _charList; - - /** - * Constructor - */ - PartyDialog(XeenEngine *vm); - - /** - * Executes the dialog - */ - void execute(); - - /** - * Loads buttons for the dialog - */ - void loadButtons(); - - /** - * Initialises a list of elements to draw - */ - void initDrawStructs(); - - /** - * Sets up the background - */ - void setupBackground(); - - /** - * Sets up the faces from the avaialble roster for display in the party dialog - */ - void setupFaces(int firstDisplayChar, bool updateFlag); - - void startingCharChanged(int firstDisplayChar); - - int selectCharacter(bool isDelete, int firstDisplayChar); -public: - /** - * Show the Party dialog - */ - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_PARTY_H */ diff --git a/engines/xeen/dialogs_query.cpp b/engines/xeen/dialogs_query.cpp deleted file mode 100644 index 5fbf35f1c4..0000000000 --- a/engines/xeen/dialogs_query.cpp +++ /dev/null @@ -1,158 +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_query.h" -#include "xeen/xeen.h" - -namespace Xeen { - -bool Confirm::show(XeenEngine *vm, const Common::String &msg, int mode) { - Confirm *dlg = new Confirm(vm); - bool result = dlg->execute(msg, mode); - delete dlg; - - return result; -} - -bool Confirm::execute(const Common::String &msg, int mode) { - EventsManager &events = *_vm->_events; - Windows &windows = *_vm->_windows; - SpriteResource confirmSprites; - - confirmSprites.load("confirm.icn"); - addButton(Common::Rect(129, 112, 153, 122), Common::KEYCODE_y, &confirmSprites); - addButton(Common::Rect(185, 112, 209, 122), Common::KEYCODE_n, &confirmSprites); - - Window &w = windows[mode ? 22 : 21]; - w.open(); - - if (!mode) { - confirmSprites.draw(w, 0, Common::Point(129, 112)); - confirmSprites.draw(w, 2, Common::Point(185, 112)); - _buttons[0]._bounds.moveTo(129, 112); - _buttons[1]._bounds.moveTo(185, 112); - } else { - if (mode & 0x80) { - clearButtons(); - } else { - confirmSprites.draw(w, 0, Common::Point(120, 133)); - confirmSprites.draw(w, 2, Common::Point(176, 133)); - _buttons[0]._bounds.moveTo(120, 133); - _buttons[1]._bounds.moveTo(176, 133); - } - } - - w.writeString(msg); - w.update(); - - events.clearEvents(); - bool result = false; - - while (!_vm->shouldExit()) { - events.pollEvents(); - checkEvents(_vm); - - if ((mode & 0x80) || _buttonValue == Common::KEYCODE_ESCAPE - || _buttonValue == Common::KEYCODE_n) - break; - - if (_buttonValue == Common::KEYCODE_y) { - result = true; - break; - } - } - - w.close(); - return result; -} - -/*------------------------------------------------------------------------*/ - -bool YesNo::show(XeenEngine *vm, bool type, bool townFlag) { - YesNo *dlg = new YesNo(vm); - bool result = dlg->execute(type, townFlag); - delete dlg; - - return result; -} - -bool YesNo::execute(bool type, bool townFlag) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Resources &res = *_vm->_resources; - LocationManager &loc = *_vm->_locations; - Windows &windows = *_vm->_windows; - SpriteResource confirmSprites; - bool result = false; - - Mode oldMode = _vm->_mode; - _vm->_mode = oldMode == MODE_7 ? MODE_8 : MODE_7; - - if (!type) { - confirmSprites.load("confirm.icn"); - res._globalSprites.draw(0, 7, Common::Point(232, 74)); - confirmSprites.draw(0, 0, Common::Point(235, 75)); - confirmSprites.draw(0, 2, Common::Point(260, 75)); - windows[34].update(); - - addButton(Common::Rect(235, 75, 259, 95), Common::KEYCODE_y, &confirmSprites); - addButton(Common::Rect(260, 75, 284, 95), Common::KEYCODE_n, &confirmSprites); - - intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; - intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; - } - - while (!_vm->shouldExit()) { - events.updateGameCounter(); - - if (loc.isActive()) { - loc.drawAnim(townFlag); - //numFrames = 3; - } else { - intf.draw3d(true); - //numFrames = 1; - } - - events.wait(3); - checkEvents(_vm); - if (!_buttonValue) - continue; - - if (type || _buttonValue == Common::KEYCODE_y) { - result = true; - break; - } else if (_buttonValue == Common::KEYCODE_n || _buttonValue == Common::KEYCODE_ESCAPE) - break; - } - - intf._face1State = intf._face2State = 2; - _vm->_mode = oldMode; - - if (!type) - intf.mainIconsPrint(); - - return result; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_query.h b/engines/xeen/dialogs_query.h deleted file mode 100644 index 0b9b2687ac..0000000000 --- a/engines/xeen/dialogs_query.h +++ /dev/null @@ -1,50 +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_DIALOGS_QUERY_H -#define XEEN_DIALOGS_QUERY_H - -#include "xeen/dialogs.h" - -namespace Xeen { - -class Confirm : public ButtonContainer { -private: - Confirm(XeenEngine *vm) : ButtonContainer(vm) {} - - bool execute(const Common::String &msg, int mode); -public: - static bool show(XeenEngine *vm, const Common::String &msg, int mode = 0); -}; - -class YesNo : public ButtonContainer { -private: - YesNo(XeenEngine *vm) : ButtonContainer(vm) {} - - bool execute(bool type, bool townFlag); -public: - static bool show(XeenEngine *vm, bool type, bool townFlag = false); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_QUERY_H */ diff --git a/engines/xeen/dialogs_quests.cpp b/engines/xeen/dialogs_quests.cpp deleted file mode 100644 index 5e5171ea87..0000000000 --- a/engines/xeen/dialogs_quests.cpp +++ /dev/null @@ -1,254 +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 "common/scummsys.h" -#include "xeen/dialogs_quests.h" -#include "xeen/events.h" -#include "xeen/party.h" -#include "xeen/xeen.h" - -namespace Xeen { - -#define MAX_DIALOG_LINES 128 - -void Quests::show(XeenEngine *vm) { - Quests *dlg = new Quests(vm); - dlg->execute(); - delete dlg; -} - -void Quests::execute() { - EventsManager &events = *_vm->_events; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Mode oldMode = _vm->_mode; - int count = 0; - bool headerShown = false; - int topRow = 0; - - addButtons(); - loadQuestNotes(); - - enum { QUEST_ITEMS, CURRENT_QUESTS, AUTO_NOTES } mode = QUEST_ITEMS; - bool windowFlag; - if (windows[29]._enabled) { - windowFlag = false; - } else { - windows[29].open(); - windows[30].open(); - windowFlag = true; - } - - windows[29].writeString(Res.QUESTS_DIALOG_TEXT); - drawButtons(&windows[0]); - - while (!_vm->shouldExit()) { - Common::String lines[MAX_DIALOG_LINES]; - - switch (mode) { - case QUEST_ITEMS: - for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) - lines[idx] = "\b \b*"; - - count = 0; - headerShown = false; - for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) { - if (party._questItems[idx]) { - if (!count && !headerShown && idx < 35) { - lines[count++] = Res.CLOUDS_OF_XEEN_LINE; - } - if (idx >= 35 && !headerShown) { - lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; - headerShown = true; - } - - switch (idx) { - case 17: - case 26: - case 79: - case 80: - case 81: - case 82: - case 83: - case 84: - lines[count++] = Common::String::format("%d %s%c", - party._questItems[idx], Res.QUEST_ITEM_NAMES[idx], - party._questItems[idx] == 1 ? ' ' : 's'); - break; - default: - lines[count++] = Res.QUEST_ITEM_NAMES[idx]; - break; - } - } - } - - if (count == 0) { - windows[30].writeString(Res.NO_QUEST_ITEMS); - } else { - windows[30].writeString(Common::String::format(Res.QUEST_ITEMS_DATA, - lines[topRow].c_str(), lines[topRow + 1].c_str(), - lines[topRow + 2].c_str(), lines[topRow + 3].c_str(), - lines[topRow + 4].c_str(), lines[topRow + 5].c_str(), - lines[topRow + 6].c_str(), lines[topRow + 7].c_str(), - lines[topRow + 8].c_str() - )); - } - break; - - case CURRENT_QUESTS: - for (int idx = 0; idx < TOTAL_QUEST_ITEMS; ++idx) - lines[idx] = ""; - - count = 0; - headerShown = false; - for (int idx = 0; idx < TOTAL_QUEST_FLAGS; ++idx) { - if (party._questFlags[(idx + 1) / 30][(idx + 1) % 30]) { - if (!count && !headerShown && idx < 29) { - lines[count++] = Res.CLOUDS_OF_XEEN_LINE; - } - if (idx > 28 && !headerShown) { - lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; - headerShown = true; - } - - lines[count++] = _questNotes[idx]; - } - } - - if (count == 0) - lines[1] = Res.NO_CURRENT_QUESTS; - - windows[30].writeString(Common::String::format(Res.CURRENT_QUESTS_DATA, - lines[topRow].c_str(), lines[topRow + 1].c_str(), lines[topRow + 2].c_str())); - break; - - case AUTO_NOTES: - for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) - lines[idx] = ""; - - count = 0; - headerShown = false; - for (int idx = 0; idx < MAX_DIALOG_LINES; ++idx) { - if (party._worldFlags[idx]) { - if (!count && !headerShown && idx < 72) { - lines[count++] = Res.CLOUDS_OF_XEEN_LINE; - } - if (idx >= 72 && !headerShown) { - lines[count++] = Res.DARKSIDE_OF_XEEN_LINE; - headerShown = true; - } - - lines[count++] = _questNotes[idx + 56]; - } - } - - if (count == 0) - lines[1] = Res.NO_AUTO_NOTES; - - windows[30].writeString(Common::String::format(Res.AUTO_NOTES_DATA, - lines[topRow].c_str(), lines[topRow + 1].c_str(), - lines[topRow + 2].c_str(), lines[topRow + 3].c_str(), - lines[topRow + 4].c_str(), lines[topRow + 5].c_str(), - lines[topRow + 6].c_str(), lines[topRow + 7].c_str(), - lines[topRow + 8].c_str() - )); - break; - } - - windows[30].writeString("\v000\t000"); - windows[24].update(); - - // Key handling - _buttonValue = 0; - while (!_vm->shouldExit() && !_buttonValue) { - events.pollEventsAndWait(); - checkEvents(_vm); - } - - if (_buttonValue == Common::KEYCODE_ESCAPE) - break; - - switch (_buttonValue) { - case Common::KEYCODE_a: - mode = AUTO_NOTES; - topRow = 0; - break; - case Common::KEYCODE_i: - mode = QUEST_ITEMS; - topRow = 0; - break; - case Common::KEYCODE_q: - mode = CURRENT_QUESTS; - topRow = 0; - break; - case Common::KEYCODE_HOME: - topRow = 0; - break; - case Common::KEYCODE_END: - topRow = MAX(count - 1, 0); - break; - case Common::KEYCODE_PAGEUP: - topRow = MAX(topRow - 3, 0); - break; - case Common::KEYCODE_PAGEDOWN: - topRow = CLIP(topRow + 3, 0, MAX(count - 1, 0)); - break; - case Common::KEYCODE_UP: - case Common::KEYCODE_KP8: - topRow = MAX(topRow - 1, 0); - break; - case Common::KEYCODE_DOWN: - case Common::KEYCODE_KP2: - topRow = CLIP(topRow + 1, 0, MAX(count - 1, 0)); - break; - default: - break; - } - } - - if (windowFlag) { - windows[30].close(); - windows[29].close(); - } - _vm->_mode = oldMode; -} - -void Quests::addButtons() { - _iconSprites.load("quest.icn"); - - - addButton(Common::Rect(12, 109, 36, 129), Common::KEYCODE_i, &_iconSprites); - addButton(Common::Rect(80, 109, 104, 129), Common::KEYCODE_q, &_iconSprites); - addButton(Common::Rect(148, 109, 172, 129), Common::KEYCODE_a, &_iconSprites); - addButton(Common::Rect(216, 109, 240, 129), Common::KEYCODE_UP, &_iconSprites); - addButton(Common::Rect(250, 109, 274, 129), Common::KEYCODE_DOWN, &_iconSprites); - addButton(Common::Rect(284, 109, 308, 129), Common::KEYCODE_ESCAPE, &_iconSprites); -} - -void Quests::loadQuestNotes() { - File f("qnotes.bin"); - while (f.pos() < f.size()) - _questNotes.push_back(f.readString()); - f.close(); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_quests.h b/engines/xeen/dialogs_quests.h deleted file mode 100644 index dd1461f75b..0000000000 --- a/engines/xeen/dialogs_quests.h +++ /dev/null @@ -1,49 +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_DIALOGS_QUESTS_H -#define XEEN_DIALOGS_QUESTS_H - -#include "common/str-array.h" -#include "xeen/dialogs.h" - -namespace Xeen { - -class Quests : public ButtonContainer { -private: - SpriteResource _iconSprites; - Common::StringArray _questNotes; - - Quests(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(); - - void addButtons(); - - void loadQuestNotes(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_QUESTS_H */ diff --git a/engines/xeen/dialogs_quick_fight.cpp b/engines/xeen/dialogs_quick_fight.cpp deleted file mode 100644 index 74261a8e18..0000000000 --- a/engines/xeen/dialogs_quick_fight.cpp +++ /dev/null @@ -1,105 +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_quick_fight.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void QuickFight::show(XeenEngine *vm, Character *currentChar) { - QuickFight *dlg = new QuickFight(vm, currentChar); - dlg->execute(); - delete dlg; -} - -QuickFight::QuickFight(XeenEngine *vm, Character *currentChar) : ButtonContainer(vm), - _currentChar(currentChar) { - loadButtons(); -} - -void QuickFight::execute() { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Window &w = windows[10]; - w.open(); - - do { - // Draw the dialog text and buttons - Common::String msg = Common::String::format(Res.QUICK_FIGHT_TEXT, - _currentChar->_name.c_str(), - Res.QUICK_FIGHT_OPTIONS[_currentChar->_quickOption]); - w.writeString(msg); - drawButtons(&w); - - // Wait for selection - _buttonValue = 0; - events.updateGameCounter(); - do { - intf.draw3d(false, false); - - events.pollEventsAndWait(); - checkEvents(_vm); - if (_vm->shouldExit()) - return; - } while (!_buttonValue && !events.timeElapsed()); - - switch (_buttonValue) { - case Common::KEYCODE_n: - case Common::KEYCODE_t: - _currentChar->_quickOption = (QuickAction)(((int)_currentChar->_quickOption + 1) % 4); - break; - - case Common::KEYCODE_F1: - case Common::KEYCODE_F2: - case Common::KEYCODE_F3: - case Common::KEYCODE_F4: - case Common::KEYCODE_F5: - case Common::KEYCODE_F6: { - int charIdx = _buttonValue - Common::KEYCODE_F1; - if (charIdx < (int)combat._combatParty.size()) { - // Highlight new character - _currentChar = &party._activeParty[charIdx]; - intf.highlightChar(charIdx); - } - break; - } - - default: - break; - } - } while (_buttonValue != Common::KEYCODE_RETURN && _buttonValue != Common::KEYCODE_ESCAPE); - - w.close(); - events.clearEvents(); -} - -void QuickFight::loadButtons() { - _icons.load("train.icn"); - addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_ESCAPE, &_icons); - addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_icons); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_quick_fight.h b/engines/xeen/dialogs_quick_fight.h deleted file mode 100644 index 66f4d3cd8a..0000000000 --- a/engines/xeen/dialogs_quick_fight.h +++ /dev/null @@ -1,60 +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_DIALOGS_QUICK_FIGHT_H -#define XEEN_DIALOGS_QUICK_FIGHT_H - -#include "xeen/character.h" -#include "xeen/dialogs.h" -#include "xeen/sprites.h" - -namespace Xeen { - -class QuickFight : public ButtonContainer { -private: - SpriteResource _icons; - Character *_currentChar; -private: - /** - * Constructor - */ - QuickFight(XeenEngine *vm, Character *currentChar); - - /** - * Executes the display of the dialog - */ - void execute(); - - /** - * Load butons for the dialog - */ - void loadButtons(); -public: - /** - * Show the dialog - */ - static void show(XeenEngine *vm, Character *currentChar); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_QUICK_FIGHT_H */ diff --git a/engines/xeen/dialogs_quick_ref.cpp b/engines/xeen/dialogs_quick_ref.cpp deleted file mode 100644 index afc06966dd..0000000000 --- a/engines/xeen/dialogs_quick_ref.cpp +++ /dev/null @@ -1,88 +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_quick_ref.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -void QuickReferenceDialog::show(XeenEngine *vm) { - QuickReferenceDialog *dlg = new QuickReferenceDialog(vm); - dlg->execute(); - delete dlg; -} - -void QuickReferenceDialog::execute() { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Common::String lines[8]; - - events.setCursor(0); - - for (uint idx = 0; idx < (combat._globalCombat == 2 ? combat._combatParty.size() : - party._activeParty.size()); ++idx) { - Character &c = combat._globalCombat == 2 ? *combat._combatParty[idx] : - party._activeParty[idx]; - Condition condition = c.worstCondition(); - lines[idx] = Common::String::format(Res.QUICK_REF_LINE, - idx * 10 + 24, idx + 1, c._name.c_str(), - Res.CLASS_NAMES[c._class][0], Res.CLASS_NAMES[c._class][1], Res.CLASS_NAMES[c._class][2], - c.statColor(c.getCurrentLevel(), c._level._permanent), c._level._permanent, - c.statColor(c._currentHp, c.getMaxHP()), c._currentHp, - c.statColor(c._currentSp, c.getMaxSP()), c._currentSp, - c.statColor(c.getArmorClass(), c.getArmorClass(true)), c.getArmorClass(), - Res.CONDITION_COLORS[condition], - Res.CONDITION_NAMES[condition][0], Res.CONDITION_NAMES[condition][1], - Res.CONDITION_NAMES[condition][2], Res.CONDITION_NAMES[condition][3] - ); - } - - int food = (party._food / party._activeParty.size()) / 3; - Common::String msg = Common::String::format(Res.QUICK_REFERENCE, - lines[0].c_str(), lines[1].c_str(), lines[2].c_str(), - lines[3].c_str(), lines[4].c_str(), lines[5].c_str(), - lines[6].c_str(), lines[7].c_str(), - party._gold, party._gems, - food, food == 1 ? "" : "s" - ); - - Window &w = windows[24]; - bool windowOpen = w._enabled; - if (!windowOpen) - w.open(); - w.writeString(msg); - w.update(); - - // Wait for a key/mouse press - events.clearEvents(); - while (!_vm->shouldExit() && !events.isKeyMousePressed()) - events.pollEventsAndWait(); - events.clearEvents(); - - if (!windowOpen) - w.close(); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_quick_ref.h b/engines/xeen/dialogs_quick_ref.h deleted file mode 100644 index eaafd99537..0000000000 --- a/engines/xeen/dialogs_quick_ref.h +++ /dev/null @@ -1,41 +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_DIALOGS_QUICK_REF_H -#define XEEN_DIALOGS_QUICK_REF_H - -#include "xeen/dialogs.h" - -namespace Xeen { - -class QuickReferenceDialog : public ButtonContainer { -private: - QuickReferenceDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_QUICK_REF_H */ diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp deleted file mode 100644 index 96917e225c..0000000000 --- a/engines/xeen/dialogs_spells.cpp +++ /dev/null @@ -1,1045 +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_spells.h" -#include "xeen/dialogs_input.h" -#include "xeen/dialogs_query.h" -#include "xeen/resources.h" -#include "xeen/spells.h" -#include "xeen/sprites.h" -#include "xeen/xeen.h" - -namespace Xeen { - -Character *SpellsDialog::show(XeenEngine *vm, ButtonContainer *priorDialog, - Character *c, int isCasting) { - SpellsDialog *dlg = new SpellsDialog(vm); - Character *result = dlg->execute(priorDialog, c, isCasting); - delete dlg; - - return result; -} - -Character *SpellsDialog::execute(ButtonContainer *priorDialog, Character *c, int isCasting) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Sound &sound = *_vm->_sound; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - bool isDarkCc = _vm->_files->_isDarkCc; - loadButtons(); - - int castingCopy = isCasting; - isCasting &= 0x7f; - int selection = -1; - int topIndex = 0; - int newSelection; - windows[25].open(); - - do { - if (!isCasting) { - if (!c->guildMember()) { - sound.stopSound(); - intf._overallFrame = 5; - sound.playSound(isDarkCc ? "skull1.voc" : "guild11.voc", 1); - break; - } - - Common::String title = Common::String::format(Res.BUY_SPELLS, c->_name.c_str()); - Common::String msg = Common::String::format(Res.GUILD_OPTIONS, - title.c_str(), XeenEngine::printMil(party._gold).c_str()); - windows[10].writeString(msg); - - warning("TODO: Sprite draw using previously used button sprites"); - } - - _spells.clear(); - const char *errorMsg = setSpellText(c, castingCopy); - windows[25].writeString(Common::String::format(Res.SPELLS_FOR, - errorMsg == nullptr ? Res.SPELL_LINES_0_TO_9 : "", - c->_name.c_str())); - - // Setup and write out spell list - const char *names[10]; - int colors[10]; - Common::String emptyStr = ""; - Common::fill(&names[0], &names[10], emptyStr.c_str()); - Common::fill(&colors[0], &colors[10], 9); - - for (int idx = 0; idx < 10; ++idx) { - if ((topIndex + idx) < (int)_spells.size()) { - names[idx] = _spells[topIndex + idx]._name.c_str(); - colors[idx] = _spells[topIndex + idx]._color; - } - } - - if (selection >= topIndex && selection < (topIndex + 10)) - colors[selection - topIndex] = 15; - if (_spells.size() == 0) - names[0] = errorMsg; - - windows[37].writeString(Common::String::format(Res.SPELLS_DIALOG_SPELLS, - colors[0], names[0], colors[1], names[1], colors[2], names[2], - colors[3], names[3], colors[4], names[4], colors[5], names[5], - colors[6], names[6], colors[7], names[7], colors[8], names[8], - colors[9], names[9], - isCasting ? Res.SPELL_PTS : Res.GOLD, - isCasting ? c->_currentSp : party._gold - )); - - _scrollSprites.draw(0, 4, Common::Point(39, 26)); - _scrollSprites.draw(0, 0, Common::Point(187, 26)); - _scrollSprites.draw(0, 2, Common::Point(187, 111)); - if (isCasting) - _scrollSprites.draw(windows[25], 5, Common::Point(132, 123)); - - windows[25].update(); - - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_vm->shouldExit() && !_buttonValue); - - 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: - if (_vm->_mode != MODE_COMBAT) { - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - spells._lastCaster = _buttonValue; - intf.highlightChar(_buttonValue); - - if (_vm->_mode == MODE_17) { - windows[10].writeString(Common::String::format(Res.GUILD_OPTIONS, - XeenEngine::printMil(party._gold).c_str(), Res.GUILD_TEXT, c->_name.c_str())); - } else { - int category; - switch (c->_class) { - case CLASS_ARCHER: - case CLASS_SORCERER: - category = 1; - break; - case CLASS_DRUID: - case CLASS_RANGER: - category = 2; - break; - default: - category = 0; - break; - } - - int spellIndex = (c->_currentSpell == -1) ? 39 : c->_currentSpell; - int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; - windows[10].writeString(Common::String::format(Res.CAST_SPELL_DETAILS, - c->_name.c_str(), spells._spellNames[spellId].c_str(), - spells.calcSpellPoints(spellId, c->getCurrentLevel()), - Res.SPELL_GEM_COST[spellId], c->_currentSp)); - } - - if (priorDialog != nullptr) - priorDialog->drawButtons(&windows[0]); - windows[10].update(); - } - } - break; - - case Common::KEYCODE_RETURN: - case Common::KEYCODE_KP_ENTER: - case Common::KEYCODE_s: - if (selection != -1) - _buttonValue = Common::KEYCODE_ESCAPE; - break; - - case Common::KEYCODE_ESCAPE: - selection = -1; - _buttonValue = Common::KEYCODE_ESCAPE; - break; - - case Common::KEYCODE_0: - case Common::KEYCODE_1: - case Common::KEYCODE_2: - case Common::KEYCODE_3: - case Common::KEYCODE_4: - case Common::KEYCODE_5: - case Common::KEYCODE_6: - case Common::KEYCODE_7: - case Common::KEYCODE_8: - case Common::KEYCODE_9: - newSelection = topIndex + ((_buttonValue == Common::KEYCODE_0) ? 9 : - (_buttonValue - Common::KEYCODE_1)); - - if (newSelection < (int)_spells.size()) { - int expenseFactor = 0; - int category = 0; - - switch (c->_class) { - case CLASS_PALADIN: - expenseFactor = 1; - category = 0; - break; - case CLASS_ARCHER: - expenseFactor = 1; - category = 1; - break; - case CLASS_CLERIC: - category = 0; - break; - case CLASS_SORCERER: - category = 1; - break; - case CLASS_DRUID: - category = 2; - break; - case CLASS_RANGER: - expenseFactor = 1; - category = 2; - break; - default: - break; - } - - int spellIndex = _spells[newSelection]._spellIndex; - int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; - int spellCost = spells.calcSpellCost(spellId, expenseFactor); - - if (isCasting) { - selection = newSelection; - } else { - Common::String spellName = _spells[newSelection]._name; - Common::String msg = (castingCopy & 0x80) ? - Common::String::format(Res.SPELLS_PRESS_A_KEY, spellName.c_str()) : - Common::String::format(Res.SPELLS_PURCHASE, spellName.c_str(), spellCost); - - if (Confirm::show(_vm, msg, castingCopy + 1)) { - if (party.subtract(CONS_GOLD, spellCost, WHERE_PARTY, WT_FREEZE_WAIT)) { - c->_spells[spellIndex] = true; - sound.stopSound(); - intf._overallFrame = 0; - sound.playSound(isDarkCc ? "guild12.voc" : "parrot2.voc", 1); - } else { - sound.playFX(21); - } - } - } - } - break; - - case Common::KEYCODE_PAGEUP: - case Common::KEYCODE_KP9: - topIndex = MAX((int)topIndex - 10, 0); - break; - - case Common::KEYCODE_PAGEDOWN: - case Common::KEYCODE_KP3: - topIndex = MIN(topIndex + 10, (((int)_spells.size() - 1) / 10) * 10); - break; - - case Common::KEYCODE_UP: - case Common::KEYCODE_KP8: - if (topIndex > 0) - --topIndex; - break; - - case Common::KEYCODE_DOWN: - case Common::KEYCODE_KP2: - if (topIndex < ((int)_spells.size() - 10)) - ++topIndex; - break; - } - } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); - - windows[25].close(); - - if (_vm->shouldExit()) - selection = -1; - if (isCasting && selection != -1) - c->_currentSpell = _spells[selection]._spellIndex; - - return c; -} - -void SpellsDialog::loadButtons() { - _iconSprites.load("main.icn"); - _scrollSprites.load("scroll.icn"); - addButton(Common::Rect(187, 26, 198, 36), Common::KEYCODE_UP, &_scrollSprites); - addButton(Common::Rect(187, 111, 198, 121), Common::KEYCODE_DOWN, &_scrollSprites); - addButton(Common::Rect(40, 28, 187, 36), Common::KEYCODE_1); - addButton(Common::Rect(40, 37, 187, 45), Common::KEYCODE_2); - addButton(Common::Rect(40, 46, 187, 54), Common::KEYCODE_3); - addButton(Common::Rect(40, 55, 187, 63), Common::KEYCODE_4); - addButton(Common::Rect(40, 64, 187, 72), Common::KEYCODE_5); - addButton(Common::Rect(40, 73, 187, 81), Common::KEYCODE_6); - addButton(Common::Rect(40, 82, 187, 90), Common::KEYCODE_7); - addButton(Common::Rect(40, 91, 187, 99), Common::KEYCODE_8); - addButton(Common::Rect(40, 100, 187, 108), Common::KEYCODE_9); - addButton(Common::Rect(40, 109, 187, 117), Common::KEYCODE_0); - addButton(Common::Rect(174, 123, 198, 133), Common::KEYCODE_ESCAPE); - addButton(Common::Rect(187, 35, 198, 73), Common::KEYCODE_PAGEUP); - addButton(Common::Rect(187, 74, 198, 112), Common::KEYCODE_PAGEDOWN); - addButton(Common::Rect(132, 123, 168, 133), Common::KEYCODE_s); - addPartyButtons(_vm); -} - -const char *SpellsDialog::setSpellText(Character *c, int isCasting) { - Party &party = *_vm->_party; - Spells &spells = *_vm->_spells; - bool isDarkCc = _vm->_files->_isDarkCc; - int expenseFactor = 0; - int currLevel = c->getCurrentLevel(); - int category; - - if ((isCasting & 0x7f) == 0) { - switch (c->_class) { - case CLASS_PALADIN: - expenseFactor = 1; - category = 0; - break; - case CLASS_ARCHER: - expenseFactor = 1; - category = 1; - break; - case CLASS_CLERIC: - category = 0; - break; - case CLASS_SORCERER: - category = 1; - break; - case CLASS_DRUID: - category = 2; - break; - case CLASS_RANGER: - expenseFactor = 1; - category = 2; - break; - default: - category = -1; - break; - } - - if (category != -1) { - if (party._mazeId == 49 || party._mazeId == 37) { - for (uint spellId = 0; spellId < 76; ++spellId) { - int idx = 0; - while (idx < MAX_SPELLS_PER_CLASS && Res.SPELLS_ALLOWED[category][idx] != (int)spellId) - ++idx; - - // Handling if the spell is appropriate for the character's class - if (idx < MAX_SPELLS_PER_CLASS) { - if (!c->_spells[idx] || (isCasting & 0x80)) { - int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); - _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", - spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), - idx, spellId)); - } - } - } - } else if (isDarkCc) { - int groupIndex = (party._mazeId - 29) / 2; - for (int spellId = Res.DARK_SPELL_RANGES[groupIndex][0]; - spellId < Res.DARK_SPELL_RANGES[groupIndex][1]; ++spellId) { - int idx = 0; - while (idx < 40 && Res.SPELLS_ALLOWED[category][idx] == - Res.DARK_SPELL_OFFSETS[category][spellId]); - - if (idx < 40) { - if (!c->_spells[idx] || (isCasting & 0x80)) { - int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); - _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", - spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), - idx, spellId)); - } - } - } - } else { - for (int spellId = 0; spellId < 20; ++spellId) { - int idx = 0; - while (Res.CLOUDS_SPELL_OFFSETS[party._mazeId - 29][spellId] != - (int)Res.SPELLS_ALLOWED[category][idx] && idx < 40) ; - - if (idx < 40) { - if (!c->_spells[idx] || (isCasting & 0x80)) { - int cost = spells.calcSpellCost(Res.SPELLS_ALLOWED[category][idx], expenseFactor); - _spells.push_back(SpellEntry(Common::String::format("\x3l%s\x3r\x9""000%u", - spells._spellNames[Res.SPELLS_ALLOWED[category][idx]].c_str(), cost), - idx, spellId)); - } - } - } - } - } - - if (c->getMaxSP() == 0) - return Res.NOT_A_SPELL_CASTER; - - } else if ((isCasting & 0x7f) == 1) { - switch (c->_class) { - case CLASS_ARCHER: - case CLASS_SORCERER: - category = 1; - break; - case CLASS_DRUID: - case CLASS_RANGER: - category = 2; - break; - case CLASS_PALADIN: - case CLASS_CLERIC: - default: - category = 0; - break; - } - - if (c->getMaxSP() == 0) { - return Res.NOT_A_SPELL_CASTER; - } else { - for (int spellIndex = 0; spellIndex < MAX_SPELLS_PER_CLASS; ++spellIndex) { - if (c->_spells[spellIndex]) { - int spellId = Res.SPELLS_ALLOWED[category][spellIndex]; - int gemCost = Res.SPELL_GEM_COST[spellId]; - int spCost = spells.calcSpellPoints(spellId, currLevel); - - Common::String msg = Common::String::format("\x3l%s\x3r\x9""000%u/%u", - spells._spellNames[spellId].c_str(), spCost, gemCost); - _spells.push_back(SpellEntry(msg, spellIndex, spellId)); - } - } - } - } - - return nullptr; -} - -/*------------------------------------------------------------------------*/ - -CastSpell::CastSpell(XeenEngine *vm) : ButtonContainer(vm) { - Windows &windows = *_vm->_windows; - _oldMode = _vm->_mode; - _vm->_mode = MODE_3; - - windows[10].open(); - loadButtons(); -} - -CastSpell::~CastSpell() { - Interface &intf = *_vm->_interface; - Windows &windows = *_vm->_windows; - - windows[10].close(); - intf.unhighlightChar(); - - _vm->_mode = (Mode)_oldMode; -} - - -int CastSpell::show(XeenEngine *vm) { - Combat &combat = *vm->_combat; - Interface &intf = *vm->_interface; - Party &party = *vm->_party; - Spells &spells = *vm->_spells; - int charNum; - - // Get which character is doing the casting - if (vm->_mode == MODE_COMBAT) { - charNum = combat._whosTurn; - } else if (spells._lastCaster >= 0 && spells._lastCaster < (int)party._activeParty.size()) { - charNum = spells._lastCaster; - } else { - for (charNum = (int)party._activeParty.size() - 1; charNum >= 0; --charNum) { - if (party._activeParty[charNum]._hasSpells) { - spells._lastCaster = charNum; - break; - } - } - } - - Character *c = &party._activeParty[charNum]; - intf.highlightChar(charNum); - - return show(vm, c); -} - -int CastSpell::show(XeenEngine *vm, Character *&c) { - Spells &spells = *vm->_spells; - CastSpell *dlg = new CastSpell(vm); - int spellId; - int result = -1; - - do { - spellId = dlg->execute(c); - - if (g_vm->shouldExit() || spellId == -1) { - result = 0; - } else { - result = spells.castSpell(c, (MagicSpell)spellId); - } - } while (result == -1); - - delete dlg; - return result; -} - -int CastSpell::execute(Character *&c) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - Window &w = windows[10]; - - int spellId = -1; - bool redrawFlag = true; - do { - if (redrawFlag) { - int category = c->getClassCategory(); - int spellIndex = c->_currentSpell != -1 ? c->_currentSpell : 39; - spellId = Res.SPELLS_ALLOWED[category][spellIndex]; - int gemCost = Res.SPELL_GEM_COST[spellId]; - int spCost = spells.calcSpellPoints(spellId, c->getCurrentLevel()); - - w.writeString(Common::String::format(Res.CAST_SPELL_DETAILS, - c->_name.c_str(), spells._spellNames[spellId].c_str(), - spCost, gemCost, c->_currentSp)); - drawButtons(&windows[0]); - w.update(); - - redrawFlag = false; - } - - events.updateGameCounter(); - intf.draw3d(true); - - // Wait for event or time expiry - do { - events.pollEventsAndWait(); - checkEvents(_vm); - } while (!_vm->shouldExit() && events.timeElapsed() < 1 && !_buttonValue); - - 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: - // Only allow changing character if the party is not in combat - if (_oldMode != MODE_COMBAT) { - _vm->_mode = (Mode)_oldMode; - _buttonValue -= Common::KEYCODE_F1; - - if (_buttonValue < (int)party._activeParty.size()) { - c = &party._activeParty[_buttonValue]; - intf.highlightChar(_buttonValue); - redrawFlag = true; - break; - } - } - break; - - case Common::KEYCODE_ESCAPE: - spellId = -1; - break; - - case Common::KEYCODE_c: - // Cast spell - return the selected spell Id to be cast - if (c->_currentSpell != -1 && !c->noActions()) - _buttonValue = Common::KEYCODE_ESCAPE; - break; - - case Common::KEYCODE_n: - // Select new spell - _vm->_mode = (Mode)_oldMode; - c = SpellsDialog::show(_vm, this, c, 1); - redrawFlag = true; - break; - - default: - break; - } - } while (!_vm->shouldExit() && _buttonValue != Common::KEYCODE_ESCAPE); - - if (_vm->shouldExit()) - spellId = -1; - return spellId; -} - -void CastSpell::loadButtons() { - _iconSprites.load("cast.icn"); - addButton(Common::Rect(234, 108, 259, 128), Common::KEYCODE_c, &_iconSprites); - addButton(Common::Rect(261, 108, 285, 128), Common::KEYCODE_n, &_iconSprites); - addButton(Common::Rect(288, 108, 312, 128), Common::KEYCODE_ESCAPE, &_iconSprites); - addPartyButtons(_vm); -} - -/*------------------------------------------------------------------------*/ - -Character *SpellOnWho::show(XeenEngine *vm, int spellId) { - SpellOnWho *dlg = new SpellOnWho(vm); - int result = dlg->execute(spellId); - delete dlg; - - if (result == -1) - return nullptr; - - Combat &combat = *vm->_combat; - Party &party = *vm->_party; - return combat._combatMode == 2 ? combat._combatParty[result] : - &party._activeParty[result]; -} - -int SpellOnWho::execute(int spellId) { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Party &party = *_vm->_party; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - Window &w = windows[16]; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_3; - int result = 999; - - w.open(); - w.writeString(Res.ON_WHO); - w.update(); - addPartyButtons(_vm); - - while (result == 999) { - do { - events.updateGameCounter(); - intf.draw3d(true); - - do { - events.pollEventsAndWait(); - if (_vm->shouldExit()) - return -1; - - checkEvents(_vm); - } while (!_buttonValue && events.timeElapsed() < 1); - } while (!_buttonValue); - - switch (_buttonValue) { - case Common::KEYCODE_ESCAPE: - result = -1; - spells.addSpellCost(*combat._oldCharacter, spellId); - break; - - case Common::KEYCODE_F1: - case Common::KEYCODE_F2: - case Common::KEYCODE_F3: - case Common::KEYCODE_F4: - case Common::KEYCODE_F5: - case Common::KEYCODE_F6: - _buttonValue -= Common::KEYCODE_F1; - if (_buttonValue < (int)(combat._combatMode == 2 ? combat._combatParty.size() : - party._activeParty.size())) { - result = _buttonValue; - } - break; - } - } - - w.close(); - _vm->_mode = oldMode; - return result; -} - -/*------------------------------------------------------------------------*/ - -int SelectElement::show(XeenEngine *vm, int spellId) { - SelectElement *dlg = new SelectElement(vm); - int result = dlg->execute(spellId); - delete dlg; - - return result; -} - -int SelectElement::execute(int spellId) { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - Window &w = windows[15]; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_3; - int result = 999; - - loadButtons(); - - w.open(); - w.writeString(Res.WHICH_ELEMENT1); - drawButtons(&windows[0]); - w.update(); - - while (result == 999) { - do { - events.updateGameCounter(); - intf.draw3d(true); - w.frame(); - w.writeString(Res.WHICH_ELEMENT2); - drawButtons(&windows[0]); - w.update(); - - do { - events.pollEventsAndWait(); - if (_vm->shouldExit()) - return -1; - - checkEvents(_vm); - } while (!_buttonValue && events.timeElapsed() < 1); - } while (!_buttonValue); - - switch (_buttonValue) { - case Common::KEYCODE_ESCAPE: - result = -1; - spells.addSpellCost(*combat._oldCharacter, spellId); - break; - - case Common::KEYCODE_a: - result = DT_POISON; - break; - case Common::KEYCODE_c: - result = DT_COLD; - break; - case Common::KEYCODE_e: - result = DT_ELECTRICAL; - break; - case Common::KEYCODE_f: - result = DT_FIRE; - break; - default: - break; - } - } - - w.close(); - _vm->_mode = oldMode; - return result; -} - -void SelectElement::loadButtons() { - _iconSprites.load("element.icn"); - addButton(Common::Rect(60, 92, 84, 112), Common::KEYCODE_f, &_iconSprites); - addButton(Common::Rect(90, 92, 114, 112), Common::KEYCODE_e, &_iconSprites); - addButton(Common::Rect(120, 92, 144, 112), Common::KEYCODE_c, &_iconSprites); - addButton(Common::Rect(150, 92, 174, 112), Common::KEYCODE_a, &_iconSprites); -} - -/*------------------------------------------------------------------------*/ - -void NotWhileEngaged::show(XeenEngine *vm, int spellId) { - NotWhileEngaged *dlg = new NotWhileEngaged(vm); - dlg->execute(spellId); - delete dlg; -} - -void NotWhileEngaged::execute(int spellId) { - EventsManager &events = *_vm->_events; - Spells &spells = *_vm->_spells; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_3; - - w.open(); - w.writeString(Common::String::format(Res.CANT_CAST_WHILE_ENGAGED, - spells._spellNames[spellId].c_str())); - w.update(); - - while (!_vm->shouldExit() && !events.isKeyMousePressed()) - events.pollEventsAndWait(); - events.clearEvents(); - - w.close(); - _vm->_mode = oldMode; -} - -/*------------------------------------------------------------------------*/ - -bool LloydsBeacon::show(XeenEngine *vm) { - LloydsBeacon *dlg = new LloydsBeacon(vm); - bool result = dlg->execute(); - delete dlg; - - return result; -} - -bool LloydsBeacon::execute() { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Sound &sound = *_vm->_sound; - Windows &windows = *_vm->_windows; - Window &w = windows[10]; - bool isDarkCc = _vm->_files->_isDarkCc; - Character &c = *combat._oldCharacter; - - loadButtons(); - - if (!c._lloydMap) { - // No destination previously set, so have a default ready - if (isDarkCc) { - c._lloydSide = 1; - c._lloydPosition = Common::Point(25, 21); - c._lloydMap = 29; - } else { - c._lloydSide = 0; - c._lloydPosition = Common::Point(18, 4); - c._lloydMap = 28; - } - } - - // Open up the text file for the destination map and read in it's name - File textFile(Common::String::format("%s%c%03d.txt", - c._lloydSide == 0 ? "xeen" : "dark", - c._lloydMap >= 100 ? 'x' : '0', - c._lloydMap)); - Common::String mapName = textFile.readString(); - textFile.close(); - - // Display the dialog - w.open(); - w.writeString(Common::String::format(Res.LLOYDS_BEACON, - mapName.c_str(), c._lloydPosition.x, c._lloydPosition.y)); - drawButtons(&windows[0]); - w.update(); - - bool result = true; - do { - do { - events.updateGameCounter(); - intf.draw3d(true); - - do { - events.pollEventsAndWait(); - if (_vm->shouldExit()) - return true; - - checkEvents(_vm); - } while (!_buttonValue && events.timeElapsed() < 1); - } while (!_buttonValue); - - switch (_buttonValue) { - case Common::KEYCODE_r: - if (!isDarkCc && c._lloydMap >= 75 && c._lloydMap <= 78 && !party._cloudsEnd) { - result = false; - } else { - sound.playFX(51); - map._loadDarkSide = isDarkCc; - if (c._lloydMap != party._mazeId || c._lloydSide != (isDarkCc ? 1 : 0)) { - map.load(c._lloydMap); - } - - party._mazePosition = c._lloydPosition; - } - - _buttonValue = Common::KEYCODE_ESCAPE; - break; - - case Common::KEYCODE_s: - case Common::KEYCODE_t: - sound.playFX(20); - c._lloydMap = party._mazeId; - c._lloydPosition = party._mazePosition; - c._lloydSide = isDarkCc ? 1 : 0; - - _buttonValue = Common::KEYCODE_ESCAPE; - break; - } - } while (_buttonValue != Common::KEYCODE_ESCAPE); - - w.close(); - return result; -} - -void LloydsBeacon::loadButtons() { - _iconSprites.load("lloyds.icn"); - - addButton(Common::Rect(281, 108, 305, 128), Common::KEYCODE_r, &_iconSprites); - addButton(Common::Rect(242, 108, 266, 128), Common::KEYCODE_t, &_iconSprites); -} - -/*------------------------------------------------------------------------*/ - -int Teleport::show(XeenEngine *vm) { - Teleport *dlg = new Teleport(vm); - int result = dlg->execute(); - delete dlg; - - return result; -} - -int Teleport::execute() { - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Windows &windows = *_vm->_windows; - Window &w = windows[6]; - Common::String num; - - w.open(); - w.writeString(Common::String::format(Res.HOW_MANY_SQUARES, - Res.DIRECTION_TEXT[party._mazeDirection])); - w.update(); - int lineSize = Input::show(_vm, &w, num, 1, 200, true); - w.close(); - - if (!lineSize) - return -1; - int numSquares = atoi(num.c_str()); - Common::Point pt = party._mazePosition; - int v; - - switch (party._mazeDirection) { - case DIR_NORTH: - pt.y += numSquares; - break; - case DIR_EAST: - pt.x += numSquares; - break; - case DIR_SOUTH: - pt.y -= numSquares; - break; - case DIR_WEST: - pt.x -= numSquares; - break; - default: - break; - } - - v = map.mazeLookup(pt, map._isOutdoors ? 0xF : 0xFFFF, 0); - - if ((v != (map._isOutdoors ? 0 : INVALID_CELL)) && - (!map._isOutdoors || v == SURFTYPE_DWATER)) { - party._mazePosition = pt; - return 1; - } else { - return 0; - } -} - -/*------------------------------------------------------------------------*/ - -int TownPortal::show(XeenEngine *vm) { - TownPortal *dlg = new TownPortal(vm); - int townNumber = dlg->execute(); - delete dlg; - - return townNumber; -} - -int TownPortal::execute() { - Map &map = *_vm->_map; - Windows &windows = *_vm->_windows; - Window &w = windows[20]; - Common::String townNames[5]; - Mode oldMode = _vm->_mode; - _vm->_mode = MODE_FF; - - // Build up a lsit of the names of the towns on the current side of Xeen - for (int idx = 0; idx < 5; ++idx) { - File f(Common::String::format("%s%04d.txt", - map._sideTownPortal ? "dark" : "xeen", - Res.TOWN_MAP_NUMBERS[map._sideTownPortal][idx])); - townNames[idx] = f.readString(); - f.close(); - } - - w.open(); - w.writeString(Common::String::format(Res.TOWN_PORTAL, - townNames[0].c_str(), townNames[1].c_str(), townNames[2].c_str(), - townNames[3].c_str(), townNames[4].c_str() - )); - w.update(); - - // Get the town number - int townNumber; - Common::String num; - do { - int result = Input::show(_vm, &w, num, 1, 160, true); - townNumber = !result ? 0 : atoi(num.c_str()); - } while (townNumber > 5); - - w.close(); - _vm->_mode = oldMode; - - return townNumber; -} - -/*------------------------------------------------------------------------*/ - -void IdentifyMonster::show(XeenEngine *vm) { - IdentifyMonster *dlg = new IdentifyMonster(vm); - dlg->execute(); - delete dlg; -} - -void IdentifyMonster::execute() { - Combat &combat = *_vm->_combat; - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Sound &sound = *_vm->_sound; - Windows &windows = *_vm->_windows; - Window &w = windows[17]; - Common::String monsterDesc[3]; - - for (int monIndex = 0; monIndex < 3; ++monIndex) { - if (combat._attackMonsters[monIndex] == -1) - continue; - - MazeMonster &monster = map._mobData._monsters[combat._attackMonsters[monIndex]]; - MonsterStruct &monsterData = *monster._monsterData; - - monsterDesc[monIndex] = Common::String::format(Res.MONSTER_DETAILS, - monsterData._name.c_str(), - _vm->printK2(monster._hp).c_str(), - monsterData._armorClass, monsterData._numberOfAttacks, - Res.MONSTER_SPECIAL_ATTACKS[monsterData._specialAttack] - ); - } - - sound.playFX(20); - w.open(); - w.writeString(Common::String::format(Res.IDENTIFY_MONSTERS, - monsterDesc[0].c_str(), monsterDesc[1].c_str(), monsterDesc[2].c_str())); - w.update(); - - do { - events.updateGameCounter(); - intf.draw3d(false); - w.frame(); - windows[3].update(); - - events.wait(1, false); - } while (!events.isKeyMousePressed()); - - w.close(); -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_spells.h b/engines/xeen/dialogs_spells.h deleted file mode 100644 index 4781a8d08c..0000000000 --- a/engines/xeen/dialogs_spells.h +++ /dev/null @@ -1,151 +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_DIALOGS_SPELLS_H -#define XEEN_DIALOGS_SPELLS_H - -#include "common/array.h" -#include "xeen/dialogs.h" -#include "xeen/party.h" - -namespace Xeen { - -struct SpellEntry { - Common::String _name; - int _spellIndex; - int _spellId; - int _color; - - SpellEntry(const Common::String &name, int spellIndex, int spellId) : - _name(name), _spellIndex(spellIndex), _spellId(spellId), _color(9) {} -}; - -class SpellsDialog : public ButtonContainer { -private: - SpriteResource _iconSprites; - SpriteResource _scrollSprites; - Common::Array _spells; - - SpellsDialog(XeenEngine *vm) : ButtonContainer(vm) {} - - Character *execute(ButtonContainer *priorDialog, Character *c, int isCasting); - - void loadButtons(); - - const char *setSpellText(Character *c, int isCasting); -public: - static Character *show(XeenEngine *vm, ButtonContainer *priorDialog, - Character *c, int isCasting); -}; - -class CastSpell : public ButtonContainer { -private: - SpriteResource _iconSprites; - int _oldMode; -private: - CastSpell(XeenEngine *vm); - ~CastSpell(); - - int execute(Character *&c); - - void loadButtons(); -public: - static int show(XeenEngine *vm); - static int show(XeenEngine *vm, Character *&c); -}; - -class SpellOnWho : public ButtonContainer { -private: - SpellOnWho(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(int spellId); -public: - static Character *show(XeenEngine *vm, int spellId); -}; - -class SelectElement : public ButtonContainer { -private: - SpriteResource _iconSprites; - - SelectElement(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(int spellId); - - void loadButtons(); -public: - static int show(XeenEngine *vm, int spellId); -}; - -class NotWhileEngaged : public ButtonContainer { -private: - NotWhileEngaged(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(int spellId); -public: - static void show(XeenEngine *vm, int spellId); -}; - -class LloydsBeacon : public ButtonContainer { -private: - SpriteResource _iconSprites; - - LloydsBeacon(XeenEngine *vm) : ButtonContainer(vm) {} - - bool execute(); - - void loadButtons(); -public: - static bool show(XeenEngine *vm); -}; - -class Teleport : public ButtonContainer { -private: - SpriteResource _iconSprites; - - Teleport(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(); -public: - static int show(XeenEngine *vm); -}; - -class TownPortal : public ButtonContainer { -private: - TownPortal(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(); -public: - static int show(XeenEngine *vm); -}; - -class IdentifyMonster : public ButtonContainer { -private: - IdentifyMonster(XeenEngine *vm) : ButtonContainer(vm) {} - - void execute(); -public: - static void show(XeenEngine *vm); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_SPELLS_H */ diff --git a/engines/xeen/dialogs_whowill.cpp b/engines/xeen/dialogs_whowill.cpp deleted file mode 100644 index 1e32007d7f..0000000000 --- a/engines/xeen/dialogs_whowill.cpp +++ /dev/null @@ -1,105 +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_whowill.h" -#include "xeen/resources.h" -#include "xeen/xeen.h" - -namespace Xeen { - -int WhoWill::show(XeenEngine *vm, int message, int action, bool type) { - WhoWill *dlg = new WhoWill(vm); - int result = dlg->execute(message, action, type); - delete dlg; - - return result; -} - -int WhoWill::execute(int message, int action, bool type) { - EventsManager &events = *_vm->_events; - Interface &intf = *_vm->_interface; - Map &map = *_vm->_map; - Party &party = *_vm->_party; - Scripts &scripts = *_vm->_scripts; - LocationManager &loc = *_vm->_locations; - Windows &windows = *_vm->_windows; - int numFrames; - - if (party._activeParty.size() <= 1) - // Unless there's at least two characters, just return the first one - return 1; - - windows[38].close(); - windows[12].close(); - - Common::String actionStr = type ? map._events._text[action] : Res.WHO_WILL_ACTIONS[action]; - Common::String msg = Common::String::format(Res.WHO_WILL, actionStr.c_str(), - Res.WHO_ACTIONS[message], party._activeParty.size()); - - windows[36].open(); - windows[36].writeString(msg); - windows[36].update(); - - intf._face1State = map._headData[party._mazePosition.y][party._mazePosition.x]._left; - intf._face2State = map._headData[party._mazePosition.y][party._mazePosition.x]._right; - - while (!_vm->shouldExit()) { - events.updateGameCounter(); - - if (windows[11]._enabled) { - loc.drawAnim(false); - windows[36].frame(); - numFrames = 3; - } else { - intf.draw3d(false); - windows[36].frame(); - windows[3].update(); - numFrames = 1; - } - - events.wait(numFrames); - checkEvents(_vm); - if (!_buttonValue) - continue; - - if (_buttonValue == 27) { - _buttonValue = 0; - break; - } else if (_buttonValue >= Common::KEYCODE_F1 && _buttonValue <= Common::KEYCODE_F6) { - _buttonValue -= Common::KEYCODE_F1 - 1; - if (_buttonValue > (int)party._activeParty.size()) - continue; - - if (party._activeParty[_buttonValue - 1].noActions()) - continue; - - scripts._whoWill = _buttonValue; - break; - } - } - - intf._face1State = intf._face2State = 2; - windows[36].close(); - return _buttonValue; -} - -} // End of namespace Xeen diff --git a/engines/xeen/dialogs_whowill.h b/engines/xeen/dialogs_whowill.h deleted file mode 100644 index 8018cbb0ef..0000000000 --- a/engines/xeen/dialogs_whowill.h +++ /dev/null @@ -1,41 +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_DIALOGS_WHOWHILL_H -#define XEEN_DIALOGS_WHOWHILL_H - -#include "xeen/dialogs.h" - -namespace Xeen { - -class WhoWill : public ButtonContainer { -private: - WhoWill(XeenEngine *vm) : ButtonContainer(vm) {} - - int execute(int message, int action, bool type); -public: - static int show(XeenEngine *vm, int message, int action, bool type); -}; - -} // End of namespace Xeen - -#endif /* XEEN_DIALOGS_WHOWHILL_H */ diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp index f646eb8ac5..3d9f05b5a2 100644 --- a/engines/xeen/interface.cpp +++ b/engines/xeen/interface.cpp @@ -21,21 +21,21 @@ */ #include "xeen/interface.h" -#include "xeen/dialogs_char_info.h" -#include "xeen/dialogs_control_panel.h" -#include "xeen/dialogs_message.h" -#include "xeen/dialogs_quick_fight.h" -#include "xeen/dialogs_info.h" -#include "xeen/dialogs_items.h" -#include "xeen/dialogs_map.h" -#include "xeen/dialogs_query.h" -#include "xeen/dialogs_quests.h" -#include "xeen/dialogs_quick_ref.h" -#include "xeen/dialogs_spells.h" +#include "xeen/dialogs/dialogs_char_info.h" +#include "xeen/dialogs/dialogs_control_panel.h" +#include "xeen/dialogs/dialogs_message.h" +#include "xeen/dialogs/dialogs_quick_fight.h" +#include "xeen/dialogs/dialogs_info.h" +#include "xeen/dialogs/dialogs_items.h" +#include "xeen/dialogs/dialogs_map.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/dialogs/dialogs_quests.h" +#include "xeen/dialogs/dialogs_quick_ref.h" +#include "xeen/dialogs/dialogs_spells.h" #include "xeen/resources.h" #include "xeen/xeen.h" -#include "xeen/dialogs_party.h" +#include "xeen/dialogs/dialogs_party.h" namespace Xeen { diff --git a/engines/xeen/interface.h b/engines/xeen/interface.h index e2499d8fa3..bbc2a77f1e 100644 --- a/engines/xeen/interface.h +++ b/engines/xeen/interface.h @@ -24,7 +24,7 @@ #define XEEN_INTERFACE_H #include "common/scummsys.h" -#include "xeen/dialogs.h" +#include "xeen/dialogs/dialogs.h" #include "xeen/interface_minimap.h" #include "xeen/interface_scene.h" #include "xeen/party.h" diff --git a/engines/xeen/interface_scene.cpp b/engines/xeen/interface_scene.cpp index b82cd7ae38..4f03362b91 100644 --- a/engines/xeen/interface_scene.cpp +++ b/engines/xeen/interface_scene.cpp @@ -21,7 +21,7 @@ */ #include "xeen/interface_scene.h" -#include "xeen/dialogs_message.h" +#include "xeen/dialogs/dialogs_message.h" #include "xeen/resources.h" #include "xeen/xeen.h" diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp index 7a8290504a..4a9abf073d 100644 --- a/engines/xeen/locations.cpp +++ b/engines/xeen/locations.cpp @@ -21,11 +21,11 @@ */ #include "xeen/locations.h" -#include "xeen/dialogs_input.h" -#include "xeen/dialogs_items.h" -#include "xeen/dialogs_party.h" -#include "xeen/dialogs_query.h" -#include "xeen/dialogs_spells.h" +#include "xeen/dialogs/dialogs_input.h" +#include "xeen/dialogs/dialogs_items.h" +#include "xeen/dialogs/dialogs_party.h" +#include "xeen/dialogs/dialogs_query.h" +#include "xeen/dialogs/dialogs_spells.h" #include "xeen/resources.h" #include "xeen/xeen.h" diff --git a/engines/xeen/locations.h b/engines/xeen/locations.h index 246548c11e..bcc3c07209 100644 --- a/engines/xeen/locations.h +++ b/engines/xeen/locations.h @@ -25,8 +25,8 @@ #include "common/scummsys.h" #include "common/str-array.h" -#include "xeen/dialogs.h" -#include "xeen/dialogs_message.h" +#include "xeen/dialogs/dialogs.h" +#include "xeen/dialogs/dialogs_message.h" #include "xeen/party.h" namespace Xeen { diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk index fcd99a89d5..a49d5a3e33 100644 --- a/engines/xeen/module.mk +++ b/engines/xeen/module.mk @@ -14,26 +14,26 @@ MODULE_OBJS := \ cutscenes.o \ debugger.o \ detection.o \ - dialogs.o \ - dialogs_awards.o \ - dialogs_char_info.o \ - dialogs_control_panel.o \ - dialogs_create_char.o \ - dialogs_difficulty.o \ - dialogs_dismiss.o \ - dialogs_exchange.o \ - dialogs_info.o \ - dialogs_input.o \ - dialogs_items.o \ - dialogs_map.o \ - dialogs_message.o \ - dialogs_party.o \ - dialogs_query.o \ - dialogs_quests.o \ - dialogs_quick_fight.o \ - dialogs_quick_ref.o \ - dialogs_spells.o \ - dialogs_whowill.o \ + dialogs/dialogs.o \ + dialogs/dialogs_awards.o \ + dialogs/dialogs_char_info.o \ + dialogs/dialogs_control_panel.o \ + dialogs/dialogs_create_char.o \ + dialogs/dialogs_difficulty.o \ + dialogs/dialogs_dismiss.o \ + dialogs/dialogs_exchange.o \ + dialogs/dialogs_info.o \ + dialogs/dialogs_input.o \ + dialogs/dialogs_items.o \ + dialogs/dialogs_map.o \ + dialogs/dialogs_message.o \ + dialogs/dialogs_party.o \ + dialogs/dialogs_query.o \ + dialogs/dialogs_quests.o \ + dialogs/dialogs_quick_fight.o \ + dialogs/dialogs_quick_ref.o \ + dialogs/dialogs_spells.o \ + dialogs/dialogs_whowill.o \ events.o \ files.o \ font.o \ diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index b24030d380..62e74ae8c2 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -23,8 +23,8 @@ #include "common/scummsys.h" #include "common/algorithm.h" #include "xeen/party.h" -#include "xeen/dialogs_message.h" -#include "xeen/dialogs_input.h" +#include "xeen/dialogs/dialogs_message.h" +#include "xeen/dialogs/dialogs_input.h" #include "xeen/files.h" #include "xeen/resources.h" #include "xeen/saves.h" diff --git a/engines/xeen/party.h b/engines/xeen/party.h index 372e373676..40cf4ef1db 100644 --- a/engines/xeen/party.h +++ b/engines/xeen/party.h @@ -29,7 +29,7 @@ #include "common/serializer.h" #include "xeen/character.h" #include "xeen/combat.h" -#include "xeen/dialogs_message.h" +#include "xeen/dialogs/dialogs_message.h" namespace Xeen { diff --git a/engines/xeen/scripts.cpp b/engines/xeen/scripts.cpp index 679e48c5b0..a3aa67baf8 100644 --- a/engines/xeen/scripts.cpp +++ b/engines/xeen/scripts.cpp @@ -22,9 +22,9 @@ #include "common/config-manager.h" #include "xeen/scripts.h" -#include "xeen/dialogs_input.h" -#include "xeen/dialogs_whowill.h" -#include "xeen/dialogs_query.h" +#include "xeen/dialogs/dialogs_input.h" +#include "xeen/dialogs/dialogs_whowill.h" +#include "xeen/dialogs/dialogs_query.h" #include "xeen/party.h" #include "xeen/resources.h" #include "xeen/xeen.h" diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp index 72140a2d2f..9ba581249b 100644 --- a/engines/xeen/spells.cpp +++ b/engines/xeen/spells.cpp @@ -21,8 +21,8 @@ */ #include "xeen/spells.h" -#include "xeen/dialogs_items.h" -#include "xeen/dialogs_spells.h" +#include "xeen/dialogs/dialogs_items.h" +#include "xeen/dialogs/dialogs_spells.h" #include "xeen/files.h" #include "xeen/resources.h" #include "xeen/xeen.h" diff --git a/engines/xeen/swordsofxeen/swordsofxeen_menu.cpp b/engines/xeen/swordsofxeen/swordsofxeen_menu.cpp index ce424b90c0..6eb6a647b1 100644 --- a/engines/xeen/swordsofxeen/swordsofxeen_menu.cpp +++ b/engines/xeen/swordsofxeen/swordsofxeen_menu.cpp @@ -21,7 +21,7 @@ */ #include "xeen/swordsofxeen/swordsofxeen_menu.h" -#include "xeen/dialogs_difficulty.h" +#include "xeen/dialogs/dialogs_difficulty.h" #include "xeen/xeen.h" namespace Xeen { diff --git a/engines/xeen/swordsofxeen/swordsofxeen_menu.h b/engines/xeen/swordsofxeen/swordsofxeen_menu.h index 6457c2c859..e7e92b862c 100644 --- a/engines/xeen/swordsofxeen/swordsofxeen_menu.h +++ b/engines/xeen/swordsofxeen/swordsofxeen_menu.h @@ -23,7 +23,7 @@ #ifndef XEEN_SWORDSOFXEEN_MENU_H #define XEEN_SWORDSOFXEEN_MENU_H -#include "xeen/dialogs.h" +#include "xeen/dialogs/dialogs.h" namespace Xeen { namespace SwordsOfXeen { diff --git a/engines/xeen/worldofxeen/worldofxeen_menu.cpp b/engines/xeen/worldofxeen/worldofxeen_menu.cpp index a91a711a67..c0aa9008b5 100644 --- a/engines/xeen/worldofxeen/worldofxeen_menu.cpp +++ b/engines/xeen/worldofxeen/worldofxeen_menu.cpp @@ -23,7 +23,7 @@ #include "common/scummsys.h" #include "xeen/worldofxeen/worldofxeen_menu.h" #include "xeen/worldofxeen/worldofxeen.h" -#include "xeen/dialogs_difficulty.h" +#include "xeen/dialogs/dialogs_difficulty.h" #include "xeen/resources.h" namespace Xeen { diff --git a/engines/xeen/worldofxeen/worldofxeen_menu.h b/engines/xeen/worldofxeen/worldofxeen_menu.h index 3495f08923..92d770be80 100644 --- a/engines/xeen/worldofxeen/worldofxeen_menu.h +++ b/engines/xeen/worldofxeen/worldofxeen_menu.h @@ -24,7 +24,7 @@ #define XEEN_WORLDOFXEEN_WORLDOFXEEN_MENU_H #include "xeen/xeen.h" -#include "xeen/dialogs.h" +#include "xeen/dialogs/dialogs.h" namespace Xeen { namespace WorldOfXeen { diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h index 98ba00bf52..62b3a7e426 100644 --- a/engines/xeen/xeen.h +++ b/engines/xeen/xeen.h @@ -32,7 +32,7 @@ #include "engines/engine.h" #include "xeen/combat.h" #include "xeen/debugger.h" -#include "xeen/dialogs.h" +#include "xeen/dialogs/dialogs.h" #include "xeen/events.h" #include "xeen/files.h" #include "xeen/interface.h" -- cgit v1.2.3