aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/xeen/combat.cpp3
-rw-r--r--engines/xeen/dialogs_items.cpp2
-rw-r--r--engines/xeen/dialogs_spells.cpp18
-rw-r--r--engines/xeen/dialogs_spells.h4
-rw-r--r--engines/xeen/interface.cpp28
-rw-r--r--engines/xeen/spells.cpp68
-rw-r--r--engines/xeen/spells.h8
7 files changed, 106 insertions, 25 deletions
diff --git a/engines/xeen/combat.cpp b/engines/xeen/combat.cpp
index b77ef6e95d..7ed349906d 100644
--- a/engines/xeen/combat.cpp
+++ b/engines/xeen/combat.cpp
@@ -721,7 +721,6 @@ void Combat::block() {
void Combat::quickFight() {
Spells &spells = *_vm->_spells;
Character *c = _combatParty[_whosTurn];
- int spellId;
switch (c->_quickOption) {
case QUICK_ATTACK:
@@ -729,7 +728,7 @@ void Combat::quickFight() {
break;
case QUICK_SPELL:
if (c->_currentSpell != -1) {
- spells.castSpell(SPELLS_ALLOWED[c->getClassCategory()][c->_currentSpell]);
+ spells.castSpell(c, SPELLS_ALLOWED[c->getClassCategory()][c->_currentSpell]);
}
break;
case QUICK_BLOCK:
diff --git a/engines/xeen/dialogs_items.cpp b/engines/xeen/dialogs_items.cpp
index ec82afbbd2..f8131db0f1 100644
--- a/engines/xeen/dialogs_items.cpp
+++ b/engines/xeen/dialogs_items.cpp
@@ -889,7 +889,7 @@ int ItemsDialog::doItemOptions(Character &c, int actionIndex, int itemIndex, Ite
screen._windows[30].close();
screen._windows[29].close();
screen._windows[24].close();
- spells.doSpell(i._id);
+ spells.castItemSpell(i._id);
if (!charges) {
// Ran out of charges, so make item disappear
diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp
index 7abca3fb85..2f4026b2ad 100644
--- a/engines/xeen/dialogs_spells.cpp
+++ b/engines/xeen/dialogs_spells.cpp
@@ -29,9 +29,9 @@
namespace Xeen {
-Character *SpellsDialog::show(XeenEngine *vm, Character *c, int v2) {
+Character *SpellsDialog::show(XeenEngine *vm, Character *c, int isCasting) {
SpellsDialog *dlg = new SpellsDialog(vm);
- Character *result = dlg->execute(c, v2);
+ Character *result = dlg->execute(c, isCasting);
delete dlg;
return result;
@@ -116,6 +116,10 @@ Character *SpellsDialog::execute(Character *c, int isCasting) {
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;
@@ -143,7 +147,7 @@ Character *SpellsDialog::execute(Character *c, int isCasting) {
break;
}
- int spellIndex = (c->_currentSp == -1) ? 39 : c->_currentSpell;
+ int spellIndex = (c->_currentSpell == -1) ? 39 : c->_currentSpell;
int spellId = SPELLS_ALLOWED[category][spellIndex];
screen._windows[10].writeString(Common::String::format(SPELL_DETAILS,
spells._spellNames[spellId].c_str(),
@@ -445,17 +449,17 @@ int CastSpell::show(XeenEngine *vm, int mode) {
}
}
- Character &c = party._activeParty[charNum];
+ Character *c = &party._activeParty[charNum];
intf.highlightChar(charNum);
CastSpell *dlg = new CastSpell(vm);
- int spellId = dlg->execute(&c, mode);
+ int spellId = dlg->execute(c, mode);
delete dlg;
return spellId;
}
-int CastSpell::show(XeenEngine *vm, Character *c, int mode) {
+int CastSpell::show(XeenEngine *vm, Character *&c, int mode) {
CastSpell *dlg = new CastSpell(vm);
int spellId = dlg->execute(c, mode);
delete dlg;
@@ -463,7 +467,7 @@ int CastSpell::show(XeenEngine *vm, Character *c, int mode) {
return spellId;
}
-int CastSpell::execute(Character *c, int mode) {
+int CastSpell::execute(Character *&c, int mode) {
EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;
Party &party = *_vm->_party;
diff --git a/engines/xeen/dialogs_spells.h b/engines/xeen/dialogs_spells.h
index c27567cd5c..f091da66cf 100644
--- a/engines/xeen/dialogs_spells.h
+++ b/engines/xeen/dialogs_spells.h
@@ -64,12 +64,12 @@ private:
CastSpell(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
- int execute(Character *c, int mode);
+ int execute(Character *&c, int mode);
void loadButtons();
public:
static int show(XeenEngine *vm, int mode);
- static int show(XeenEngine *vm, Character *c, int mode);
+ static int show(XeenEngine *vm, Character *&c, int mode);
};
} // End of namespace Xeen
diff --git a/engines/xeen/interface.cpp b/engines/xeen/interface.cpp
index 3bd3ef12b6..7efc7a7068 100644
--- a/engines/xeen/interface.cpp
+++ b/engines/xeen/interface.cpp
@@ -521,9 +521,25 @@ void Interface::perform() {
case Common::KEYCODE_c: {
// Cast spell
- int spellId = CastSpell::show(_vm, _vm->_mode);
- if (spellId != -1)
- spells.castSpell(spellId);
+ if (_tillMove) {
+ combat.moveMonsters();
+ draw3d(true);
+ }
+
+ int result = 0;
+ do {
+ Character *c = nullptr;
+ int spellId = CastSpell::show(_vm, c, _vm->_mode);
+ if (spellId == -1 || c == nullptr)
+ break;
+
+ result = spells.castSpell(c, spellId);
+ } while (result != -1);
+
+ if (result == 1) {
+ chargeStep();
+ doStepCode();
+ }
break;
}
@@ -1952,8 +1968,10 @@ void Interface::doCombat() {
case Common::KEYCODE_c: {
// Cast spell
int spellId = CastSpell::show(_vm, _vm->_mode);
- if (spellId != -1)
- spells.castSpell(spellId);
+ if (spellId != -1) {
+ Character *c = combat._combatParty[combat._whosTurn];
+ spells.castSpell(c, spellId);
+ }
break;
}
diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp
index 20ba480a6b..3b753bc90b 100644
--- a/engines/xeen/spells.cpp
+++ b/engines/xeen/spells.cpp
@@ -53,7 +53,7 @@ int Spells::calcSpellPoints(int spellId, int expenseFactor) const {
typedef void(Spells::*SpellMethodPtr)();
-void Spells::doSpell(int spellId) {
+void Spells::executeSpell(int spellId) {
static const SpellMethodPtr SPELL_LIST[73] = {
&Spells::light, &Spells::awaken, &Spells::magicArrow, &Spells::firstAid,
&Spells::flyingFist, &Spells::energyBlast, &Spells::sleep,
@@ -92,6 +92,10 @@ void Spells::doSpell(int spellId) {
&Spells::implosion, &Spells::starBurst, &Spells::divineIntervention
};
+ (this->*SPELL_LIST[spellId])();
+}
+
+void Spells::castItemSpell(int spellId) {
if (_vm->_mode == MODE_COMBAT) {
if (spellId == 15 || spellId == 20 || spellId == 27 || spellId == 41
|| spellId == 47 || spellId == 54 || spellId == 57) {
@@ -101,12 +105,47 @@ void Spells::doSpell(int spellId) {
}
}
- (this->*SPELL_LIST[spellId])();
+ executeSpell(spellId);
}
-void Spells::castSpell(int spellId) {
- // TODO
- error("TODO: castSpell");
+/**
+ * Cast a given spell
+ */
+int Spells::castSpell(Character *c, int spellId) {
+ Combat &combat = *_vm->_combat;
+ Interface &intf = *_vm->_interface;
+ int oldTillMove = intf._tillMove;
+ int result = 1;
+ combat._oldCharacter = c;
+
+ // Try and subtract the SP and gem requirements for the spell
+ int resultError = subSpellCost(*c, spellId);
+ if (resultError) {
+ CantCast::show(_vm, spellId, resultError);
+ result = -1;
+ } else {
+ // Some spells have special handling
+ switch (spellId) {
+ case 19:
+ // Enchant item
+ if (_vm->_mode != MODE_COMBAT) {
+ enchantItem();
+ } else {
+ // Return the spell costs and flag that another spell can be selected
+ addSpellCost(*c, spellId);
+ result = -1;
+ }
+ break;
+
+ default:
+ executeSpell(spellId);
+ break;
+ }
+ }
+
+ _vm->_moveMonsters = 1;
+ intf._tillMove = oldTillMove;
+ return result;
}
/**
@@ -126,7 +165,7 @@ int Spells::subSpellCost(Character &c, int spellId) {
if (spCost > c._currentSp)
// Not enough SP
return 1;
- if (gemCost > party._gems)
+ if (gemCost > (int)party._gems)
// Not enough gems
return 2;
@@ -135,6 +174,23 @@ int Spells::subSpellCost(Character &c, int spellId) {
return 0;
}
+/**
+ * Add the SP and gem requirements for a given spell to the given
+ * character and party
+ */
+void Spells::addSpellCost(Character &c, int spellId) {
+ Party &party = *_vm->_party;
+ int gemCost = SPELL_GEM_COST[spellId];
+ int spCost = SPELL_COSTS[spellId];
+
+ if (spCost < 1)
+ spCost *= -1 * c.getCurrentLevel();
+
+ c._currentSp += spCost;
+ party._gems += gemCost;
+}
+
+
void Spells::light() { error("TODO: spell"); }
void Spells::awaken() { error("TODO: spell"); }
void Spells::magicArrow() { error("TODO: spell"); }
diff --git a/engines/xeen/spells.h b/engines/xeen/spells.h
index cffb302c51..af52511efa 100644
--- a/engines/xeen/spells.h
+++ b/engines/xeen/spells.h
@@ -67,6 +67,8 @@ private:
void load();
+ void executeSpell(int spellId);
+
// Spell list
void light();
void awaken();
@@ -158,11 +160,13 @@ public:
int calcSpellPoints(int spellId, int expenseFactor) const;
- void doSpell(int spellId);
+ void castItemSpell(int spellId);
- void castSpell(int spellId);
+ int castSpell(Character *c, int spellId);
int subSpellCost(Character &c, int spellId);
+
+ void addSpellCost(Character &c, int spellId);
};
} // End of namespace Xeen