diff options
author | Paul Gilbert | 2015-02-04 19:18:51 -0500 |
---|---|---|
committer | Paul Gilbert | 2015-02-04 19:18:51 -0500 |
commit | 4953b7954aca078be9655971f925f82c51e472db (patch) | |
tree | 7037d7bfcd5148c2ebe41b6b526b5004b4f80e6c | |
parent | f34c5ad9b65f626884736faf802d627dc2fe68c0 (diff) | |
download | scummvm-rg350-4953b7954aca078be9655971f925f82c51e472db.tar.gz scummvm-rg350-4953b7954aca078be9655971f925f82c51e472db.tar.bz2 scummvm-rg350-4953b7954aca078be9655971f925f82c51e472db.zip |
XEEN: Partial implementation of doItemOptions
-rw-r--r-- | engines/xeen/combat.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/combat.h | 2 | ||||
-rw-r--r-- | engines/xeen/dialogs_char_info.cpp | 4 | ||||
-rw-r--r-- | engines/xeen/dialogs_error.cpp | 11 | ||||
-rw-r--r-- | engines/xeen/dialogs_error.h | 2 | ||||
-rw-r--r-- | engines/xeen/dialogs_items.cpp | 265 | ||||
-rw-r--r-- | engines/xeen/dialogs_items.h | 11 | ||||
-rw-r--r-- | engines/xeen/interface_map.h | 7 | ||||
-rw-r--r-- | engines/xeen/items.cpp | 58 | ||||
-rw-r--r-- | engines/xeen/items.h | 28 | ||||
-rw-r--r-- | engines/xeen/party.cpp | 2 | ||||
-rw-r--r-- | engines/xeen/party.h | 10 | ||||
-rw-r--r-- | engines/xeen/resources.cpp | 37 | ||||
-rw-r--r-- | engines/xeen/resources.h | 27 | ||||
-rw-r--r-- | engines/xeen/spells.cpp | 134 | ||||
-rw-r--r-- | engines/xeen/spells.h | 83 |
16 files changed, 656 insertions, 27 deletions
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp index 6237e0c5ba..fec244b63a 100644 --- a/engines/xeen/combat.cpp +++ b/engines/xeen/combat.cpp @@ -34,6 +34,8 @@ Combat::Combat(XeenEngine *vm): _vm(vm) { Common::fill(&_elemScale[0], &_elemScale[12], 0); Common::fill(&_shooting[0], &_shooting[8], 0); _globalCombat = 0; + _whosTurn = -1; + _itemFlag = false; } void Combat::clear() { diff --git a/engines/xeen/combat.h b/engines/xeen/combat.h index c2554d5bf9..ef82de5af2 100644 --- a/engines/xeen/combat.h +++ b/engines/xeen/combat.h @@ -59,6 +59,8 @@ public: int _elemScale[12]; bool _shooting[8]; int _globalCombat; + int _whosTurn; + bool _itemFlag; public: Combat(XeenEngine *vm); diff --git a/engines/xeen/dialogs_char_info.cpp b/engines/xeen/dialogs_char_info.cpp index 1d907cf7d9..0c71bfb0be 100644 --- a/engines/xeen/dialogs_char_info.cpp +++ b/engines/xeen/dialogs_char_info.cpp @@ -185,7 +185,7 @@ void CharacterInfo::execute(int charIndex) { case Common::KEYCODE_i: _vm->_mode = oldMode; - _vm->_treasure._v1 = _vm->_mode == MODE_InCombat; + _vm->_combat->_itemFlag = _vm->_mode == MODE_InCombat; c = ItemsDialog::show(_vm, c, ITEMMODE_CHAR_INFO); if (!c) { @@ -209,7 +209,7 @@ exit: w.close(); intf.unhighlightChar(); _vm->_mode = oldMode; - _vm->_treasure._v1 = false; + _vm->_combat->_itemFlag = false; } /** diff --git a/engines/xeen/dialogs_error.cpp b/engines/xeen/dialogs_error.cpp index e8512216c7..a58e0e9e78 100644 --- a/engines/xeen/dialogs_error.cpp +++ b/engines/xeen/dialogs_error.cpp @@ -38,7 +38,16 @@ void ErrorScroll::execute(const Common::String &msg, ErrorWaitType waitType) { EventsManager &events = *_vm->_events; Window &w = screen._windows[6]; - Common::String s = Common::String::format("\x03c\v010\t000%s", msg.c_str()); + Common::String s; + if (waitType == WT_UNFORMATTED) { + // This type isn't technically a waiting type, but it saved on adding + // yet another parameter + waitType = WT_FREEZE_WAIT; + s = msg; + } else { + s = Common::String::format("\x03c\v010\t000%s", msg.c_str()); + } + w.open(); w.writeString(s); w.update(); diff --git a/engines/xeen/dialogs_error.h b/engines/xeen/dialogs_error.h index ba36f285cf..1a86afce87 100644 --- a/engines/xeen/dialogs_error.h +++ b/engines/xeen/dialogs_error.h @@ -28,7 +28,7 @@ namespace Xeen { enum ErrorWaitType { WT_FREEZE_WAIT = 0, WT_NONFREEZED_WAIT = 1, - WT_2 = 2, WT_3 = 3}; + WT_2 = 2, WT_3 = 3, WT_UNFORMATTED = 9 }; class ErrorScroll: public ButtonContainer { private: diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp index 1043be8d9e..634fb2de39 100644 --- a/engines/xeen/dialogs_items.cpp +++ b/engines/xeen/dialogs_items.cpp @@ -40,7 +40,7 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) { Party &party = *_vm->_party; Screen &screen = *_vm->_screen; - Character *tempChar = c; + Character *startingChar = c; ItemCategory category = mode == ITEMMODE_4 || mode == ITEMMODE_COMBAT ? CATEGORY_MISC : CATEGORY_WEAPON; int varA = mode == ITEMMODE_COMBAT ? 1 : 0; @@ -130,8 +130,13 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) { _itemsDrawList[idx]._y = 10 + idx * 9; switch (category) { - case CATEGORY_WEAPON: - if (c->_weapons[idx]._id) { + case CATEGORY_WEAPON: + case CATEGORY_ARMOR: + case CATEGORY_ACCESSORY: { + XeenItem &i = (category == CATEGORY_WEAPON) ? c->_weapons[idx] : + ((category == CATEGORY_ARMOR) ? c->_armor[idx] : c->_accessories[idx]); + + if (i._id) { if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 || mode == ITEMMODE_6 || mode == ITEMMODE_4) { lines.push_back(Common::String::format(ITEMS_DIALOG_LINE1, @@ -142,26 +147,143 @@ Character *ItemsDialog::execute(Character *c, ItemsMode mode) { arr[idx], idx + 1, c->assembleItemName(idx, arr[idx], category), calcItemCost(c, idx, mode, - mode == ITEMMODE_TO_GOLD ? 1 : c->_skills[MERCHANT], + mode == ITEMMODE_TO_GOLD ? 1 : startingChar->_skills[MERCHANT], category) )); } DrawStruct &ds = _itemsDrawList[idx]; ds._sprites = &_equipSprites; - if (passRestrictions(c->_class, c->_weapons[idx]._id, true, CATEGORY_WEAPON)) - ds._frame = c->_weapons[idx]._frame; + if (passRestrictions(c->_class, i._id, true, CATEGORY_WEAPON)) + ds._frame = i._frame; else ds._frame = 14; } else if (_itemsDrawList[idx]._sprites == nullptr) { lines.push_back(NO_ITEMS_AVAILABLE); } break; - // TODO + } + + case CATEGORY_MISC: { + XeenItem &i = c->_misc[idx]; + _itemsDrawList[idx]._sprites = nullptr; + + if (i._material == 0) { + // No item + if (idx == 0) { + lines.push_back(NO_ITEMS_AVAILABLE); + } + } else { + ItemsMode tempMode = mode; + int skill = startingChar->_skills[MERCHANT]; + + if (mode == ITEMMODE_CHAR_INFO || mode == ITEMMODE_8 + || mode == ITEMMODE_6 || mode == ITEMMODE_4) { + tempMode = ITEMMODE_6; + } else if (mode == ITEMMODE_TO_GOLD) { + skill = 1; + } + + lines.push_back(Common::String::format(ITEMS_DIALOG_LINE2, + arr[idx], idx + 1, + c->assembleItemName(idx, arr[idx], category), + 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: + screen._windows[30].writeString(Common::String::format(X_FOR_THE_Y, + category == CATEGORY_MISC ? "\x3l" : "\x3c", + CATEGORY_NAMES[category], c->_name.c_str(), CLASS_NAMES[c->_class], + category == CATEGORY_MISC ? 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() + )); + + case ITEMMODE_BLACKSMITH: { + // Original uses var in this block that's never set?! + const int v1 = 0; + screen._windows[30].writeString(Common::String::format(AVAILABLE_GOLD_COST, + CATEGORY_NAMES[category], + v1 ? "" : "s", 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_4: + case ITEMMODE_6: + case ITEMMODE_9: + case ITEMMODE_10: + case ITEMMODE_TO_GOLD: + screen._windows[30].writeString(Common::String::format(X_FOR_Y, + CATEGORY_NAMES[category], startingChar->_name.c_str(), + (mode == ITEMMODE_4 || mode == ITEMMODE_6) ? CHARGES : 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: + screen._windows[30].writeString(Common::String::format(X_FOR_Y_GOLD, + CATEGORY_NAMES[category], c->_name.c_str(), party._gold, 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 + screen._windows[0].drawList(_itemsDrawList, INV_ITEMS_TOTAL); + screen._windows[0].update(); + + if (var2 != -1) { + int actionIndex = -1; + switch (mode) { + case ITEMMODE_BLACKSMITH: + actionIndex = 0; + break; + case ITEMMODE_2: + actionIndex = 1; + break; + case ITEMMODE_9: + actionIndex = 3; + break; + case ITEMMODE_10: + actionIndex = 2; + break; default: break; } + + if (actionIndex >= 0) { + doItemOptions(*c, actionIndex, var2, category, mode); + } } + + // TODO } return c; @@ -311,7 +433,7 @@ void ItemsDialog::setEquipmentIcons() { /** * Calculate the cost of an item */ -int ItemsDialog::calcItemCost(Character *c, int itemIndex, int mode, +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; @@ -468,4 +590,131 @@ bool ItemsDialog::passRestrictions(CharacterClass charClass, int itemId, return false; } +bool 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; + Screen &screen = *_vm->_screen; + Spells &spells = *_vm->_spells; + + XeenItem *itemCategories[4] = { &c._weapons[0], &c._armor[0], &c._accessories[0], &c._misc[0] }; + XeenItem *items = itemCategories[category]; + if (!items[0]._id) + return false; + + Window &w = screen._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, &escSprites, false); + addButton(Common::Rect(8, 29, 263, 37), Common::KEYCODE_2, &escSprites, false); + addButton(Common::Rect(8, 38, 263, 46), Common::KEYCODE_3, &escSprites, false); + addButton(Common::Rect(8, 47, 263, 55), Common::KEYCODE_4, &escSprites, false); + addButton(Common::Rect(8, 56, 263, 64), Common::KEYCODE_5, &escSprites, false); + addButton(Common::Rect(8, 65, 263, 73), Common::KEYCODE_6, &escSprites, false); + addButton(Common::Rect(8, 74, 263, 82), Common::KEYCODE_7, &escSprites, false); + addButton(Common::Rect(8, 83, 263, 91), Common::KEYCODE_8, &escSprites, false); + addButton(Common::Rect(8, 92, 263, 100), Common::KEYCODE_9, &escSprites, false); + + w.open(); + w.writeString(Common::String::format(WHICH_ITEM, ITEM_ACTIONS[actionIndex])); + _iconSprites.draw(screen, 0, Common::Point(235, 111)); + w.update(); + + while (!_vm->shouldQuit()) { + while (!_buttonValue) { + events.pollEventsAndWait(); + checkEvents(_vm); + if (_vm->shouldQuit()) + 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) { + 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, WHATS_YOUR_HURRY); + } else { + XeenItem &i = c._misc[itemIndex]; + + Condition condition = c.worstCondition(); + switch (condition) { + case SLEEP: + case PARALYZED: + case UNCONSCIOUS: + case DEAD: + case STONED: + case ERADICATED: + ErrorScroll::show(_vm, Common::String::format(IN_NO_CONDITION, c._name.c_str())); + break; + default: + if (combat._itemFlag) { + ErrorScroll::show(_vm, USE_ITEM_IN_COMBAT); + } else if (i._id && (i._bonusFlags & ITEMFLAG_BONUS_MASK) + && !(i._bonusFlags & (ITEMFLAG_BROKEN | ITEMFLAG_CURSED))) { + int bonus = (i._bonusFlags & ITEMFLAG_BONUS_MASK) - 1; + i._bonusFlags = bonus; + _oldCharacter = &c; + + screen._windows[30].close(); + screen._windows[29].close(); + screen._windows[24].close(); + spells.doSpell(i._id); + + if (!bonus) { + c._items[category].discardItem(itemIndex); + } + } else { + ErrorScroll::show(_vm, Common::String::format(NO_SPECIAL_ABILITIES, + c.assembleItemName(itemIndex, 15, category).c_str() + )); + } + } + } + case 3: + // TODO: Remaining switches + default: + break; + } + } + } + + intf._charsShooting = false; + intf.moveMonsters(); + combat._whosTurn = -1; + return true; +} + } // End of namespace Xeen diff --git a/engines/xeen/dialogs_items.h b/engines/xeen/dialogs_items.h index 74be9215ce..c30eaa9a4a 100644 --- a/engines/xeen/dialogs_items.h +++ b/engines/xeen/dialogs_items.h @@ -30,8 +30,8 @@ namespace Xeen { enum ItemsMode { - ITEMMODE_CHAR_INFO = 0, ITEMMODE_BLACKSMITH = 1, ITEMMODE_2 = 2, - ITEMMODE_4 = 4, ITEMMODE_6 = 6, ITEMMODE_COMBAT = 7, ITEMMODE_8 = 8, + ITEMMODE_CHAR_INFO = 0, ITEMMODE_BLACKSMITH = 1, ITEMMODE_2 = 2, ITEMMODE_3 = 3, + ITEMMODE_4 = 4, ITEMMODE_5 = 5, ITEMMODE_6 = 6, ITEMMODE_COMBAT = 7, ITEMMODE_8 = 8, ITEMMODE_9 = 9, ITEMMODE_10 = 10, ITEMMODE_TO_GOLD = 11 }; @@ -42,7 +42,7 @@ private: SpriteResource _equipSprites; Character _itemsCharacter; Character *_oldCharacter; - DrawStruct _itemsDrawList[9]; + DrawStruct _itemsDrawList[INV_ITEMS_TOTAL]; ItemsDialog(XeenEngine *vm) : ButtonContainer(), _vm(vm), _oldCharacter(nullptr) {} @@ -55,11 +55,14 @@ private: void setEquipmentIcons(); - int calcItemCost(Character *c, int itemIndex, int mode, int skillLevel, + int calcItemCost(Character *c, int itemIndex, ItemsMode mode, int skillLevel, ItemCategory category); bool passRestrictions(CharacterClass charClass, int itemId, bool showError, ItemCategory category) const; + + bool doItemOptions(Character &c, int actionIndex, int itemIndex, + ItemCategory category, ItemsMode mode); public: static Character *show(XeenEngine *vm, Character *c, ItemsMode mode); }; diff --git a/engines/xeen/interface_map.h b/engines/xeen/interface_map.h index fb448e1f29..197f239404 100644 --- a/engines/xeen/interface_map.h +++ b/engines/xeen/interface_map.h @@ -111,7 +111,6 @@ protected: bool _flipSky; bool _flipDefaultGround; bool _isShooting; - bool _charsShooting; bool _thinWall; bool _isAnimReset; int _blessedUIFrame; @@ -125,8 +124,6 @@ protected: void animate3d(); - void moveMonsters(); - void drawMiniMap(); virtual void setup(); @@ -144,6 +141,7 @@ public: int _objNumber; int _overallFrame; int _batUIFrame; + bool _charsShooting; public: InterfaceMap(XeenEngine *vm); @@ -166,6 +164,9 @@ public: void drawOutdoors(); void assembleBorder(); + + void moveMonsters(); + }; } // End of namespace Xeen diff --git a/engines/xeen/items.cpp b/engines/xeen/items.cpp index 5881fb378b..13418262bd 100644 --- a/engines/xeen/items.cpp +++ b/engines/xeen/items.cpp @@ -26,6 +26,10 @@ namespace Xeen { XeenItem::XeenItem() { + clear(); +} + +void XeenItem::clear() { _material = _id = _bonusFlags = 0; _frame = 0; } @@ -54,9 +58,61 @@ int XeenItem::getAttributeCategory() const { return idx; } +/*------------------------------------------------------------------------*/ + +InventoryItems::InventoryItems() : Common::Array<XeenItem>((XeenItem *)nullptr, INV_ITEMS_TOTAL) { +} + +void InventoryItems::discardItem(int itemIndex) { + operator[](itemIndex).clear(); + sort(); +} + +void InventoryItems::sort() { + for (uint idx = 0; idx < size(); ++idx) { + if (operator[](idx)._id == 0) { + // Found empty slot + operator[](idx).clear(); + + // Scan through the rest of the list to find any item + for (uint idx2 = idx + 1; idx2 < size(); ++idx2) { + if (operator[](idx2)._id) { + // Found an item, so move it into the blank slot + operator[](idx) = operator[](idx2); + operator[](idx2).clear(); + break; + } + } + } + } +} + +void InventoryItems::equipItem(int itemIndex) { + error("TODO"); +} + +void InventoryItems::removeItem(int itemIndex) { + error("TODO"); +} + +/*------------------------------------------------------------------------*/ + +InventoryItemsGroup::InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor, + InventoryItems &accessories, InventoryItems &misc) { + _itemSets[0] = &weapons; + _itemSets[1] = &armor; + _itemSets[2] = &accessories; + _itemSets[3] = &misc; +} + +InventoryItems &InventoryItemsGroup::operator[](ItemCategory category) { + return *_itemSets[category]; +} + +/*------------------------------------------------------------------------*/ + Treasure::Treasure() { _hasItems = false; - _v1 = false; } } // End of namespace Xeen diff --git a/engines/xeen/items.h b/engines/xeen/items.h index 5a8c4d71a1..c0b82b9fce 100644 --- a/engines/xeen/items.h +++ b/engines/xeen/items.h @@ -24,11 +24,13 @@ #define XEEN_ITEMS_H #include "common/scummsys.h" +#include "common/array.h" #include "common/serializer.h" namespace Xeen { #define TOTAL_ITEMS 10 +#define INV_ITEMS_TOTAL 9 enum BonusFlags { ITEMFLAG_BONUS_MASK = 0xBF, ITEMFLAG_CURSED = 0x40, ITEMFLAG_BROKEN = 0x80 @@ -47,6 +49,8 @@ public: public: XeenItem(); + void clear(); + void synchronize(Common::Serializer &s); int getElementalCategory() const; @@ -54,6 +58,29 @@ public: int getAttributeCategory() const; }; +class InventoryItems : public Common::Array<XeenItem> { +public: + InventoryItems(); + + void discardItem(int itemIndex); + + void equipItem(int itemIndex); + + void removeItem(int itemIndex); + + void sort(); +}; + +class InventoryItemsGroup { +private: + InventoryItems *_itemSets[4]; +public: + InventoryItemsGroup(InventoryItems &weapons, InventoryItems &armor, + InventoryItems &accessories, InventoryItems &misc); + + InventoryItems &operator[](ItemCategory category); +}; + class Treasure { public: XeenItem _misc[TOTAL_ITEMS]; @@ -61,7 +88,6 @@ public: XeenItem _armor[TOTAL_ITEMS]; XeenItem _weapons[TOTAL_ITEMS]; bool _hasItems; - bool _v1; public: Treasure(); }; diff --git a/engines/xeen/party.cpp b/engines/xeen/party.cpp index 0a276b29cd..7d47eafaf4 100644 --- a/engines/xeen/party.cpp +++ b/engines/xeen/party.cpp @@ -43,7 +43,7 @@ void AttributePair::synchronize(Common::Serializer &s) { /*------------------------------------------------------------------------*/ -Character::Character() { +Character::Character(): _items(_weapons, _armor, _accessories, _misc) { _sex = MALE; _race = HUMAN; _xeenSide = 0; diff --git a/engines/xeen/party.h b/engines/xeen/party.h index 6f70c4b49c..73de7065aa 100644 --- a/engines/xeen/party.h +++ b/engines/xeen/party.h @@ -74,7 +74,6 @@ enum Condition { CURSED = 0, HEART_BROKEN = 1, WEAK = 2, POISONED = 3, #define XEEN_TOTAL_CHARACTERS 24 #define MAX_ACTIVE_PARTY 6 #define TOTAL_STATS 7 -#define INV_ITEMS_TOTAL 9 class XeenEngine; @@ -115,10 +114,11 @@ public: bool _hasSpells; int _currentSpell; int _quickOption; - XeenItem _weapons[INV_ITEMS_TOTAL]; - XeenItem _armor[INV_ITEMS_TOTAL]; - XeenItem _accessories[INV_ITEMS_TOTAL]; - XeenItem _misc[INV_ITEMS_TOTAL]; + InventoryItemsGroup _items; + InventoryItems _weapons; + InventoryItems _armor; + InventoryItems _accessories; + InventoryItems _misc; int _lloydSide; AttributePair _fireResistence; AttributePair _coldResistence; diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp index 8a23216e90..1f1c979f7a 100644 --- a/engines/xeen/resources.cpp +++ b/engines/xeen/resources.cpp @@ -1088,4 +1088,41 @@ const char *const NOT_PROFICIENT = const char *const NO_ITEMS_AVAILABLE = "\x3""c\n" "\t000No items available."; +const char *const CATEGORY_NAMES[4] = { "Weapons", "Armor", "Accessories", "Miscellaneous" }; + +const char *const X_FOR_THE_Y = + "\x1\fd\r%s\v000\t000%s for %s the %s%s\v011\x2%s%s%s%s%s%s%s%s%s\x1\fd"; + +const char *const X_FOR_Y = + "\x1\xC""d\r\x3l\v000\t000%s for %s\x3r\t000%s\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d"; + +const char *const X_FOR_Y_GOLD = + "\x1\fd\r\x3l\v000\t000%s for %s\t150Gold - %lu%s\x3l\v011" + "\x2%s%s%s%s%s%s%s%s%s\x1\fd"; + +const char *const FMT_CHARGES = "\x3rr\t000Charges\x3l"; + +const char *const AVAILABLE_GOLD_COST = + "\x1\fd\r\x3l\v000\t000Available %s%s\t150Gold - %lu\x3r\t000Cost" + "\x3l\v011\x2%s%s%s%s%s%s%s%s%s\x1\xC""d"; + +const char *const CHARGES = "Charges"; + +const char *const COST = "Cost"; + +const char *const ITEM_ACTIONS[7] = { + "Equip", "Remove", "Use", "Discard", "Enchant", "Recharge", "Gold" +}; +const char *const WHICH_ITEM = "\t010\v005%s which item?"; + +const char *const WHATS_YOUR_HURRY = "\v007What's your hurry?\n" + "Wait till you get out of here!"; + +const char *const USE_ITEM_IN_COMBAT = + "\v007To use an item in Combat, invoke the Use command on your turn!"; + +const char *const NO_SPECIAL_ABILITIES = "\v005\x3""c%s\fdhas no special abilities!"; + +const char *const CANT_CAST_WHILE_ENGAGED = "\x03c\v007Can't cast %s while engaged!"; + } // End of namespace Xeen diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h index c851db75a4..88e01cdb51 100644 --- a/engines/xeen/resources.h +++ b/engines/xeen/resources.h @@ -371,6 +371,33 @@ extern const char *const NOT_PROFICIENT; extern const char *const NO_ITEMS_AVAILABLE; +extern const char *const CATEGORY_NAMES[4]; + +extern const char *const X_FOR_THE_Y; + +extern const char *const X_FOR_Y; + +extern const char *const X_FOR_Y_GOLD; + +extern const char *const FMT_CHARGES; + +extern const char *const AVAILABLE_GOLD_COST; + +extern const char *const CHARGES; + +extern const char *const COST; + +extern const char *const ITEM_ACTIONS[7]; +extern const char *const WHICH_ITEM; + +extern const char *const WHATS_YOUR_HURRY; + +extern const char *const USE_ITEM_IN_COMBAT; + +extern const char *const NO_SPECIAL_ABILITIES; + +extern const char *const CANT_CAST_WHILE_ENGAGED; + } // End of namespace Xeen #endif /* XEEN_RESOURCES_H */ diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp index 588fa1b510..3492510db9 100644 --- a/engines/xeen/spells.cpp +++ b/engines/xeen/spells.cpp @@ -56,4 +56,138 @@ int Spells::calcSpellPoints(int spellId, int expenseFactor) const { return (amount >= 0) ? amount : amount * -1 * expenseFactor; } +typedef void(Spells::*SpellMethodPtr)(); + +void Spells::doSpell(int spellId) { + static const SpellMethodPtr SPELL_LIST[73] = { + &Spells::light, &Spells::awaken, &Spells::magicArrow, &Spells::firstAid, + &Spells::flyingFist, &Spells::energyBlast, &Spells::sleep, + &Spells::revitalize, &Spells::cureWounds, &Spells::sparks, + + &Spells::shrapMetal, &Spells::insectSpray, &Spells::toxicCloud, + &Spells::protectionFromElements, &Spells::pain, &Spells::jump, + &Spells::beastMaster, &Spells::clairvoyance, &Spells::turnUndead, + &Spells::levitate, + + &Spells::wizardEye, &Spells::bless, &Spells::identifyMonster, + &Spells::lightningBolt, &Spells::holyBonus, &Spells::powerCure, + &Spells::naturesCure, &Spells::lloydsBeacon, &Spells::powerShield, + &Spells::heroism, + + &Spells::hypnotize, &Spells::walkOnWater, &Spells::frostByte, + &Spells::detectMonster, &Spells::fireball, &Spells::coldRay, + &Spells::curePoison, &Spells::acidSpray, &Spells::timeDistortion, + &Spells::dragonSleep, + + &Spells::cureDisease, &Spells::teleport, &Spells::fingerOfDeath, + &Spells::cureParalysis, &Spells::golemStopper, &Spells::poisonVolley, + &Spells::deadlySwarm, &Spells::superShelter, &Spells::dayOfProtection, + &Spells::dayOfSorcery, + + &Spells::createFood, &Spells::fieryFlail, &Spells::rechargeItem, + &Spells::fantasticFreeze, &Spells::townPortal, &Spells::stoneToFlesh, + &Spells::raiseDead, &Spells::etherialize, &Spells::dancingSword, + &Spells::moonRay, + + &Spells::massDistortion, &Spells::prismaticLight, &Spells::enchantItem, + &Spells::incinerate, &Spells::holyWord, &Spells::resurrection, + &Spells::elementalStorm, &Spells::megaVolts, &Spells::inferno, + &Spells::sunRay, + + &Spells::implosion, &Spells::starBurst, &Spells::divineIntervention + }; + + if (_vm->_mode == MODE_InCombat) { + if (spellId == 15 || spellId == 20 || spellId == 27 || spellId == 41 + || spellId == 47 || spellId == 54 || spellId == 57) { + ErrorScroll::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED, + _spellNames[spellId].c_str()), WT_UNFORMATTED); + return; + } + } + + (this->*SPELL_LIST[spellId])(); +} + +void Spells::light() { error("TODO: spell"); } +void Spells::awaken() { error("TODO: spell"); } +void Spells::magicArrow() { error("TODO: spell"); } +void Spells::firstAid() { error("TODO: spell"); } +void Spells::flyingFist() { error("TODO: spell"); } +void Spells::energyBlast() { error("TODO: spell"); } +void Spells::sleep() { error("TODO: spell"); } +void Spells::revitalize() { error("TODO: spell"); } +void Spells::cureWounds() { error("TODO: spell"); } +void Spells::sparks() { error("TODO: spell"); } + +void Spells::shrapMetal() { error("TODO: spell"); } +void Spells::insectSpray() { error("TODO: spell"); } +void Spells::toxicCloud() { error("TODO: spell"); } +void Spells::protectionFromElements() { error("TODO: spell"); } +void Spells::pain() { error("TODO: spell"); } +void Spells::jump() { error("TODO: spell"); } // Not while engaged +void Spells::beastMaster() { error("TODO: spell"); } +void Spells::clairvoyance() { error("TODO: spell"); } +void Spells::turnUndead() { error("TODO: spell"); } +void Spells::levitate() { error("TODO: spell"); } + +void Spells::wizardEye() { error("TODO: spell"); } // Not while engaged +void Spells::bless() { error("TODO: spell"); } +void Spells::identifyMonster() { error("TODO: spell"); } +void Spells::lightningBolt() { error("TODO: spell"); } +void Spells::holyBonus() { error("TODO: spell"); } +void Spells::powerCure() { error("TODO: spell"); } +void Spells::naturesCure() { error("TODO: spell"); } +void Spells::lloydsBeacon() { error("TODO: spell"); } // Not while engaged +void Spells::powerShield() { error("TODO: spell"); } +void Spells::heroism() { error("TODO: spell"); } + +void Spells::hypnotize() { error("TODO: spell"); } +void Spells::walkOnWater() { error("TODO: spell"); } +void Spells::frostByte() { error("TODO: spell"); } +void Spells::detectMonster() { error("TODO: spell"); } +void Spells::fireball() { error("TODO: spell"); } +void Spells::coldRay() { error("TODO: spell"); } +void Spells::curePoison() { error("TODO: spell"); } +void Spells::acidSpray() { error("TODO: spell"); } +void Spells::timeDistortion() { error("TODO: spell"); } +void Spells::dragonSleep() { error("TODO: spell"); } + +void Spells::cureDisease() { error("TODO: spell"); } +void Spells::teleport() { error("TODO: spell"); } // Not while engaged +void Spells:: fingerOfDeath() { error("TODO: spell"); } +void Spells::cureParalysis() { error("TODO: spell"); } +void Spells::golemStopper() { error("TODO: spell"); } +void Spells::poisonVolley() { error("TODO: spell"); } +void Spells::deadlySwarm() { error("TODO: spell"); } +void Spells::superShelter() { error("TODO: spell"); } // Not while engaged +void Spells::dayOfProtection() { error("TODO: spell"); } +void Spells::dayOfSorcery() { error("TODO: spell"); } + +void Spells::createFood() { error("TODO: spell"); } +void Spells::fieryFlail() { error("TODO: spell"); } +void Spells::rechargeItem() { error("TODO: spell"); } +void Spells::fantasticFreeze() { error("TODO: spell"); } +void Spells::townPortal() { error("TODO: spell"); } // Not while engaged +void Spells::stoneToFlesh() { error("TODO: spell"); } +void Spells::raiseDead() { error("TODO: spell"); } +void Spells::etherialize() { error("TODO: spell"); } // Not while engaged +void Spells::dancingSword() { error("TODO: spell"); } +void Spells::moonRay() { error("TODO: spell"); } + +void Spells::massDistortion() { error("TODO: spell"); } +void Spells::prismaticLight() { error("TODO: spell"); } +void Spells::enchantItem() { error("TODO: spell"); } +void Spells::incinerate() { error("TODO: spell"); } +void Spells::holyWord() { error("TODO: spell"); } +void Spells::resurrection() { error("TODO: spell"); } +void Spells::elementalStorm() { error("TODO: spell"); } +void Spells::megaVolts() { error("TODO: spell"); } +void Spells::inferno() { error("TODO: spell"); } +void Spells::sunRay() { error("TODO: spell"); } + +void Spells::implosion() { error("TODO: spell"); } +void Spells::starBurst() { error("TODO: spell"); } +void Spells::divineIntervention() { error("TODO: spell"); } + } // End of namespace Xeen diff --git a/engines/xeen/spells.h b/engines/xeen/spells.h index 96f491684e..241d35dca7 100644 --- a/engines/xeen/spells.h +++ b/engines/xeen/spells.h @@ -37,6 +37,88 @@ private: XeenEngine *_vm; void load(); + + // Spell list + void light(); + void awaken(); + void magicArrow(); + void firstAid(); + void flyingFist(); + void energyBlast(); + void sleep(); + void revitalize(); + void cureWounds(); + void sparks(); + + void shrapMetal(); + void insectSpray(); + void toxicCloud(); + void protectionFromElements(); + void pain(); + void jump(); // Not while engaged + void beastMaster(); + void clairvoyance(); + void turnUndead(); + void levitate(); + + void wizardEye(); // Not while engaged + void bless(); + void identifyMonster(); + void lightningBolt(); + void holyBonus(); + void powerCure(); + void naturesCure(); + void lloydsBeacon(); // Not while engaged + void powerShield(); + void heroism(); + + void hypnotize(); + void walkOnWater(); + void frostByte(); + void detectMonster(); + void fireball(); + void coldRay(); + void curePoison(); + void acidSpray(); + void timeDistortion(); + void dragonSleep(); + + void cureDisease(); + void teleport(); // Not while engaged + void fingerOfDeath(); + void cureParalysis(); + void golemStopper(); + void poisonVolley(); + void deadlySwarm(); + void superShelter(); // Not while engaged + void dayOfProtection(); + void dayOfSorcery(); + + void createFood(); + void fieryFlail(); + void rechargeItem(); + void fantasticFreeze(); + void townPortal(); // Not while engaged + void stoneToFlesh(); + void raiseDead(); + void etherialize(); // Not while engaged + void dancingSword(); + void moonRay(); + + void massDistortion(); + void prismaticLight(); + void enchantItem(); + void incinerate(); + void holyWord(); + void resurrection(); + void elementalStorm(); + void megaVolts(); + void inferno(); + void sunRay(); + + void implosion(); + void starBurst(); + void divineIntervention(); public: Common::StringArray _spellNames; Common::StringArray _maeNames; @@ -48,6 +130,7 @@ public: int calcSpellPoints(int spellId, int expenseFactor) const; + void doSpell(int spellId); }; } // End of namespace Xeen |