XEEN: Partial implementation of doItemOptions

This commit is contained in:
Paul Gilbert 2015-02-04 19:18:51 -05:00
parent f34c5ad9b6
commit 4953b7954a
16 changed files with 656 additions and 27 deletions

View File

@ -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() {

View File

@ -59,6 +59,8 @@ public:
int _elemScale[12];
bool _shooting[8];
int _globalCombat;
int _whosTurn;
bool _itemFlag;
public:
Combat(XeenEngine *vm);

View File

@ -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;
}
/**

View File

@ -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();

View File

@ -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:

View File

@ -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

View File

@ -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);
};

View File

@ -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

View File

@ -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

View File

@ -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();
};

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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