From cf798c2d3190844413cd98be518118ffd5f4aeaa Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 4 Jun 2023 14:00:22 -0700 Subject: [PATCH] MM: MM1: Finished Duplication spell views --- devtools/create_mm/files/mm1/strings_en.yml | 2 + engines/mm/mm1/game/duplication.cpp | 53 +++++++++++++++++++ engines/mm/mm1/game/duplication.h | 46 ++++++++++++++++ engines/mm/mm1/views/spells/duplication.cpp | 29 ++-------- engines/mm/mm1/views/spells/duplication.h | 16 ++---- .../mm/mm1/views_enh/character_inventory.h | 2 +- engines/mm/mm1/views_enh/dialogs.h | 2 + .../{duplicate_item.cpp => duplication.cpp} | 20 +++---- .../{duplicate_item.h => duplication.h} | 12 ++--- .../mm/mm1/views_enh/spells/recharge_item.cpp | 2 +- engines/mm/module.mk | 2 + 11 files changed, 130 insertions(+), 56 deletions(-) create mode 100644 engines/mm/mm1/game/duplication.cpp create mode 100644 engines/mm/mm1/game/duplication.h rename engines/mm/mm1/views_enh/spells/{duplicate_item.cpp => duplication.cpp} (75%) rename engines/mm/mm1/views_enh/spells/{duplicate_item.h => duplication.h} (83%) diff --git a/devtools/create_mm/files/mm1/strings_en.yml b/devtools/create_mm/files/mm1/strings_en.yml index 683ea4f1497..9e64b83d4ee 100644 --- a/devtools/create_mm/files/mm1/strings_en.yml +++ b/devtools/create_mm/files/mm1/strings_en.yml @@ -564,6 +564,7 @@ enhdialogs: discard: "Discard" use: "Use" charge: "Charge" + copy: "Copy" buttons: buttons: weapons: "\x01""37Weap" @@ -581,6 +582,7 @@ enhdialogs: trade: "\x01""37Trade" use: "\x01""37Use" charge: "\x01""37Charg" + copy: "\x01""37Copy" location: store: "Store" options: "options" diff --git a/engines/mm/mm1/game/duplication.cpp b/engines/mm/mm1/game/duplication.cpp new file mode 100644 index 00000000000..b155ec9ef9f --- /dev/null +++ b/engines/mm/mm1/game/duplication.cpp @@ -0,0 +1,53 @@ +/* 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 3 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, see . + * + */ + +#include "mm/mm1/game/duplication.h" +#include "mm/mm1/globals.h" + +namespace MM { +namespace MM1 { +namespace Game { + +bool Duplication::duplicate(Character &c, Inventory &inv, int itemIndex) { + if (c._backpack.full()) + // No space to duplicate + return false; + + if (getRandomNumber(100) == 100) { + // OMG: The original seriously had this fringe + // case that happens so rarely + inv.removeAt(itemIndex); // Break item + return false; + + } else if (inv[itemIndex]._id >= 230) { + // Item range that can't be duplicated + return false; + + } else { + // Add a copy of the item + c._backpack.add(inv[itemIndex]._id, inv[itemIndex]._charges); + return true; + } +} + +} // namespace Game +} // namespace MM1 +} // namespace MM diff --git a/engines/mm/mm1/game/duplication.h b/engines/mm/mm1/game/duplication.h new file mode 100644 index 00000000000..e742e3f6797 --- /dev/null +++ b/engines/mm/mm1/game/duplication.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 3 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, see . + * + */ + +#ifndef MM1_GAME_DUPLICATION_H +#define MM1_GAME_DUPLICATION_H + +#include "mm/mm1/game/game_logic.h" +#include "mm/mm1/data/character.h" +#include "mm/mm1/data/items.h" + +namespace MM { +namespace MM1 { +namespace Game { + +class Duplication : public GameLogic { +protected: + /** + * Charge a given item + * @returns Returns true if the spell succeeded + */ + bool duplicate(Character &c, Inventory &inv, int itemIndex); +}; + +} // namespace Game +} // namespace MM1 +} // namespace MM + +#endif diff --git a/engines/mm/mm1/views/spells/duplication.cpp b/engines/mm/mm1/views/spells/duplication.cpp index fb5b01ed19a..4ab1f74e330 100644 --- a/engines/mm/mm1/views/spells/duplication.cpp +++ b/engines/mm/mm1/views/spells/duplication.cpp @@ -28,13 +28,6 @@ namespace MM1 { namespace Views { namespace Spells { -void Duplication::show() { - UIElement *view = dynamic_cast(g_events->findView("Duplication")); - assert(view); - - view->open(); -} - Duplication::Duplication() : SpellView("Duplication") { _bounds = getLineBounds(20, 24); } @@ -43,7 +36,7 @@ void Duplication::draw() { clearSurface(); escToGoBack(0); - writeString(10, 0, STRING["dialogs.charcater.which_item"]); + writeString(10, 0, STRING["dialogs.character.which"]); } bool Duplication::msgKeypress(const KeypressMessage &msg) { @@ -53,24 +46,10 @@ bool Duplication::msgKeypress(const KeypressMessage &msg) { msg.keycode < (Common::KEYCODE_a + (int)inv.size())) { int itemIndex = msg.keycode - Common::KEYCODE_a; - if (inv.full()) { - // No space to duplicate + if (duplicate(*g_globals->_currCharacter, inv, itemIndex)) + spellDone(); + else spellFailed(); - return true; - } - - if (g_engine->getRandomNumber(100) == 100) { - // OMG: The original seriously had this fringe - // case that happens so rarely - inv.removeAt(itemIndex); // Break item - spellFailed(); - } else if (inv[itemIndex]._id >= 230) { - spellFailed(); - } else { - // Add a copy of the item - inv.add(inv[itemIndex]._id, - inv[itemIndex]._charges); - } } return true; diff --git a/engines/mm/mm1/views/spells/duplication.h b/engines/mm/mm1/views/spells/duplication.h index 949f056b6d9..1caef30617e 100644 --- a/engines/mm/mm1/views/spells/duplication.h +++ b/engines/mm/mm1/views/spells/duplication.h @@ -23,30 +23,20 @@ #define MM1_VIEWS_SPELLS_DUPLICATION_H #include "mm/mm1/views/spells/spell_view.h" +#include "mm/mm1/game/duplication.h" namespace MM { namespace MM1 { namespace Views { namespace Spells { -class Duplication : public SpellView { +class Duplication : public SpellView, public MM1::Game::Duplication { private: - enum Mode { - SELECT_ITEM, CAST - }; + enum Mode { SELECT_ITEM, CAST }; Mode _mode = SELECT_ITEM; char _direction = '\0'; int _squares = 0; - /** - * Handle the Duplicationing - */ - void duplicate(); -public: - /** - * Show the view - */ - static void show(); public: /** * Constructor diff --git a/engines/mm/mm1/views_enh/character_inventory.h b/engines/mm/mm1/views_enh/character_inventory.h index 16ea8bcd1e0..d7a55b951bc 100644 --- a/engines/mm/mm1/views_enh/character_inventory.h +++ b/engines/mm/mm1/views_enh/character_inventory.h @@ -35,7 +35,7 @@ class CharacterInventory : public ItemsView, public Game::EquipRemove, public Game::UseItem { protected: enum SelectedButton { - BTN_NONE, BTN_EQUIP, BTN_REMOVE, BTN_DISCARD, BTN_USE, BTN_CHARGE + BTN_NONE, BTN_EQUIP, BTN_REMOVE, BTN_DISCARD, BTN_USE, BTN_CHARGE, BTN_COPY }; enum DisplayMode { ARMS_MODE, BACKPACK_MODE diff --git a/engines/mm/mm1/views_enh/dialogs.h b/engines/mm/mm1/views_enh/dialogs.h index f7d1610df63..204b6cf1a5f 100644 --- a/engines/mm/mm1/views_enh/dialogs.h +++ b/engines/mm/mm1/views_enh/dialogs.h @@ -88,6 +88,7 @@ #include "mm/mm1/views_enh/spells/cast_spell.h" #include "mm/mm1/views_enh/spells/spellbook.h" #include "mm/mm1/views_enh/spells/detect_magic.h" +#include "mm/mm1/views_enh/spells/duplication.h" #include "mm/mm1/views_enh/spells/fly.h" #include "mm/mm1/views_enh/spells/location.h" #include "mm/mm1/views_enh/spells/recharge_item.h" @@ -143,6 +144,7 @@ private: ViewsEnh::Spells::CastSpell _castSpell; ViewsEnh::Spells::Spellbook _spellbook; ViewsEnh::Spells::DetectMagic _detectMagic; + ViewsEnh::Spells::Duplication _duplicateItem; ViewsEnh::Spells::Fly _fly; ViewsEnh::Spells::Location _location; ViewsEnh::Spells::RechargeItem _rechargeItem; diff --git a/engines/mm/mm1/views_enh/spells/duplicate_item.cpp b/engines/mm/mm1/views_enh/spells/duplication.cpp similarity index 75% rename from engines/mm/mm1/views_enh/spells/duplicate_item.cpp rename to engines/mm/mm1/views_enh/spells/duplication.cpp index 7e5321c23a6..0ffcff6c2ea 100644 --- a/engines/mm/mm1/views_enh/spells/duplicate_item.cpp +++ b/engines/mm/mm1/views_enh/spells/duplication.cpp @@ -19,7 +19,7 @@ * */ -#include "mm/mm1/views_enh/spells/recharge_item.h" +#include "mm/mm1/views_enh/spells/duplication.h" #include "mm/mm1/globals.h" namespace MM { @@ -27,34 +27,34 @@ namespace MM1 { namespace ViewsEnh { namespace Spells { -RechargeItem::RechargeItem() : CharacterInventory("RechargeItem") { +Duplication::Duplication() : CharacterInventory("Duplication") { clearButtons(); addButton(2, STRING["enhdialogs.items.buttons.arms"], Common::KEYCODE_a); addButton(6, STRING["enhdialogs.items.buttons.backpack"], Common::KEYCODE_b); - addButton(8, STRING["enhdialogs.items.buttons.charge"], Common::KEYCODE_c); + addButton(14, STRING["enhdialogs.items.buttons.copy"], Common::KEYCODE_c); addButton(16, STRING["enhdialogs.misc.exit"], Common::KEYCODE_ESCAPE); } -bool RechargeItem::msgKeypress(const KeypressMessage &msg) { +bool Duplication::msgKeypress(const KeypressMessage &msg) { if (msg.keycode == Common::KEYCODE_a || msg.keycode == Common::KEYCODE_b || (msg.keycode >= Common::KEYCODE_1 && msg.keycode <= Common::KEYCODE_6)) { - // Allow switching between + // Keys we can allow the base view to handle CharacterInventory::msgKeypress(msg); - } else if (msg.keycode == Common::KEYCODE_c) { - selectButton(BTN_CHARGE); + } else if (msg.keycode == Common::KEYCODE_c || msg.keycode == Common::KEYCODE_d) { + selectButton(BTN_COPY); } return true; } -void RechargeItem::performAction() { - assert(_selectedButton == BTN_CHARGE); +void Duplication::performAction() { + assert(_selectedButton == BTN_COPY); Inventory &inv = _mode == ARMS_MODE ? g_globals->_currCharacter->_equipped : g_globals->_currCharacter->_backpack; - bool result = charge(inv, _selectedItem); + bool result = duplicate(*g_globals->_currCharacter, inv, _selectedItem); close(); g_events->send(InfoMessage(STRING[result ? "spells.done" : "spells.failed"])); diff --git a/engines/mm/mm1/views_enh/spells/duplicate_item.h b/engines/mm/mm1/views_enh/spells/duplication.h similarity index 83% rename from engines/mm/mm1/views_enh/spells/duplicate_item.h rename to engines/mm/mm1/views_enh/spells/duplication.h index 2c6b09dcd85..aac0b6f1a1b 100644 --- a/engines/mm/mm1/views_enh/spells/duplicate_item.h +++ b/engines/mm/mm1/views_enh/spells/duplication.h @@ -19,18 +19,18 @@ * */ -#ifndef MM1_VIEWS_ENH_SPELLS_RECHARGE_ITEM_H -#define MM1_VIEWS_ENH_SPELLS_RECHARGE_ITEM_H +#ifndef MM1_VIEWS_ENH_SPELLS_DUPLICATE_ITEM_H +#define MM1_VIEWS_ENH_SPELLS_DUPLICATE_ITEM_H #include "mm/mm1/views_enh/character_inventory.h" -#include "mm/mm1/game/recharge_item.h" +#include "mm/mm1/game/duplication.h" namespace MM { namespace MM1 { namespace ViewsEnh { namespace Spells { -class RechargeItem : public CharacterInventory, public MM1::Game::RechargeItem { +class Duplication : public CharacterInventory, public MM1::Game::Duplication { protected: /** * Handle action with selected button mode and selected item @@ -41,12 +41,12 @@ public: /** * Constructor */ - RechargeItem(); + Duplication(); /** * Destructor */ - virtual ~RechargeItem() {} + virtual ~Duplication() {} bool msgKeypress(const KeypressMessage &msg) override; }; diff --git a/engines/mm/mm1/views_enh/spells/recharge_item.cpp b/engines/mm/mm1/views_enh/spells/recharge_item.cpp index 24df953c0bf..c4c4ce8ea3a 100644 --- a/engines/mm/mm1/views_enh/spells/recharge_item.cpp +++ b/engines/mm/mm1/views_enh/spells/recharge_item.cpp @@ -39,7 +39,7 @@ RechargeItem::RechargeItem() : CharacterInventory("RechargeItem") { bool RechargeItem::msgKeypress(const KeypressMessage &msg) { if (msg.keycode == Common::KEYCODE_a || msg.keycode == Common::KEYCODE_b || (msg.keycode >= Common::KEYCODE_1 && msg.keycode <= Common::KEYCODE_6)) { - // Allow switching between + // Keys we can allow the base view to handle CharacterInventory::msgKeypress(msg); } else if (msg.keycode == Common::KEYCODE_c) { diff --git a/engines/mm/module.mk b/engines/mm/module.mk index 00bd2001796..f0bd4f7827e 100644 --- a/engines/mm/module.mk +++ b/engines/mm/module.mk @@ -41,6 +41,7 @@ MODULE_OBJS += \ mm1/game/detect_magic.o \ mm1/game/game_logic.o \ mm1/game/combat.o \ + mm1/game/duplication.o \ mm1/game/encounter.o \ mm1/game/equip_remove.o \ mm1/game/fly.o \ @@ -138,6 +139,7 @@ MODULE_OBJS += \ mm1/views_enh/spells/cast_spell.o \ mm1/views_enh/spells/spellbook.o \ mm1/views_enh/spells/detect_magic.o \ + mm1/views_enh/spells/duplication.o \ mm1/views_enh/spells/fly.o \ mm1/views_enh/spells/location.o \ mm1/views_enh/spells/recharge_item.o \