aboutsummaryrefslogtreecommitdiff
path: root/engines/xeen
diff options
context:
space:
mode:
authorPaul Gilbert2015-03-01 10:07:03 -0500
committerPaul Gilbert2015-03-01 10:07:03 -0500
commitc6506b567c791c6ef9a80df01f666c2c6d6d4b48 (patch)
tree4178a2f85aaedc4c41798e40f4c0a866040d19be /engines/xeen
parentb243768887c3aabbc6fe57e83971562bf2eba0f5 (diff)
downloadscummvm-rg350-c6506b567c791c6ef9a80df01f666c2c6d6d4b48.tar.gz
scummvm-rg350-c6506b567c791c6ef9a80df01f666c2c6d6d4b48.tar.bz2
scummvm-rg350-c6506b567c791c6ef9a80df01f666c2c6d6d4b48.zip
XEEN: Implemented more spells
Diffstat (limited to 'engines/xeen')
-rw-r--r--engines/xeen/dialogs_spells.cpp116
-rw-r--r--engines/xeen/dialogs_spells.h25
-rw-r--r--engines/xeen/map.h2
-rw-r--r--engines/xeen/resources.cpp18
-rw-r--r--engines/xeen/resources.h6
-rw-r--r--engines/xeen/spells.cpp411
6 files changed, 464 insertions, 114 deletions
diff --git a/engines/xeen/dialogs_spells.cpp b/engines/xeen/dialogs_spells.cpp
index f5357766ba..eb7373313e 100644
--- a/engines/xeen/dialogs_spells.cpp
+++ b/engines/xeen/dialogs_spells.cpp
@@ -21,6 +21,7 @@
*/
#include "xeen/dialogs_spells.h"
+#include "xeen/dialogs_input.h"
#include "xeen/dialogs_query.h"
#include "xeen/resources.h"
#include "xeen/spells.h"
@@ -579,12 +580,18 @@ void CastSpell::loadButtons() {
/*------------------------------------------------------------------------*/
-int SpellOnWho::show(XeenEngine *vm, int spellId) {
+Character *SpellOnWho::show(XeenEngine *vm, int spellId) {
SpellOnWho *dlg = new SpellOnWho(vm);
int result = dlg->execute(spellId);
delete dlg;
- return result;
+ 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) {
@@ -773,7 +780,6 @@ bool LloydsBeacon::execute() {
Party &party = *_vm->_party;
Screen &screen = *_vm->_screen;
SoundManager &sound = *_vm->_sound;
- Spells &spells = *_vm->_spells;
Window &w = screen._windows[10];
bool isDarkCc = _vm->_files->_isDarkCc;
Character &c = *combat._oldCharacter;
@@ -863,4 +869,108 @@ void LloydsBeacon::loadButtons() {
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;
+ Screen &screen = *_vm->_screen;
+ Window &w = screen._windows[6];
+ Common::String num;
+
+ w.open();
+ w.writeString(Common::String::format(HOW_MANY_SQUARES,
+ 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;
+ }
+
+ 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;
+ Screen &screen = *_vm->_screen;
+ Window &w = screen._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",
+ TOWN_MAP_NUMBERS[map._sideTownPortal][idx]));
+ townNames[idx] = f.readString();
+ f.close();
+ }
+
+ w.open();
+ w.writeString(Common::String::format(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;
+}
+
} // End of namespace Xeen
diff --git a/engines/xeen/dialogs_spells.h b/engines/xeen/dialogs_spells.h
index ca7bb17b5e..9f4af15636 100644
--- a/engines/xeen/dialogs_spells.h
+++ b/engines/xeen/dialogs_spells.h
@@ -81,7 +81,7 @@ private:
int execute(int spellId);
public:
- static int show(XeenEngine *vm, int spellId);
+ static Character *show(XeenEngine *vm, int spellId);
};
class SelectElement : public ButtonContainer {
@@ -123,6 +123,29 @@ public:
static bool show(XeenEngine *vm);
};
+class Teleport : public ButtonContainer {
+private:
+ XeenEngine *_vm;
+ SpriteResource _iconSprites;
+
+ Teleport(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
+
+ int execute();
+public:
+ static int show(XeenEngine *vm);
+};
+
+class TownPortal : public ButtonContainer {
+private:
+ XeenEngine *_vm;
+
+ TownPortal(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
+
+ int execute();
+public:
+ static int show(XeenEngine *vm);
+};
+
} // End of namespace Xeen
#endif /* XEEN_DIALOGS_SPELLS_H */
diff --git a/engines/xeen/map.h b/engines/xeen/map.h
index bfc09ec053..a7e88c1726 100644
--- a/engines/xeen/map.h
+++ b/engines/xeen/map.h
@@ -356,7 +356,6 @@ private:
XeenEngine *_vm;
MazeData _mazeData[9];
SpriteResource _wallPicSprites;
- int _sideTownPortal;
int _sidePictures;
int _sideObjects;
int _sideMonsters;
@@ -387,6 +386,7 @@ public:
int _currentSurfaceId;
bool _currentSteppedOn;
bool _loadDarkSide;
+ int _sideTownPortal;
public:
Map(XeenEngine *vm);
diff --git a/engines/xeen/resources.cpp b/engines/xeen/resources.cpp
index a75f77ba5c..085cfab58d 100644
--- a/engines/xeen/resources.cpp
+++ b/engines/xeen/resources.cpp
@@ -1554,4 +1554,22 @@ const char *const LLOYDS_BEACON =
"%s\x3l\n"
"x = %d\x3r\t000y = %d\x3""c\x2\v122\t021\f15S\fdet\t060\f15R\fdeturn\x1";
+const char *const HOW_MANY_SQUARES = "\x03cTeleport\nHow many squares %s (1-9)";
+
+const char *const TOWN_PORTAL =
+ "\x3""cTown Portal\x3l\n"
+ "\n"
+ "\t0101. %s\n"
+ "\t0102. %s\n"
+ "\t0103. %s\n"
+ "\t0104. %s\n"
+ "\t0105. %s\x3""c\n"
+ "\n"
+ "To which Town (1-5)\n"
+ "\n";
+
+const int TOWN_MAP_NUMBERS[2][5] = {
+ { 28, 29, 30, 31, 32 }, { 29, 31, 33, 35, 37 }
+};
+
} // End of namespace Xeen
diff --git a/engines/xeen/resources.h b/engines/xeen/resources.h
index 89dc74a4fe..29e86112a1 100644
--- a/engines/xeen/resources.h
+++ b/engines/xeen/resources.h
@@ -550,6 +550,12 @@ extern const char *const DETECT_MONSTERS;
extern const char *const LLOYDS_BEACON;
+extern const char *const HOW_MANY_SQUARES;
+
+extern const char *const TOWN_PORTAL;
+
+extern const int TOWN_MAP_NUMBERS[2][5];
+
} // End of namespace Xeen
#endif /* XEEN_RESOURCES_H */
diff --git a/engines/xeen/spells.cpp b/engines/xeen/spells.cpp
index e3978aef65..e2e8cfde36 100644
--- a/engines/xeen/spells.cpp
+++ b/engines/xeen/spells.cpp
@@ -331,79 +331,59 @@ void Spells::createFood() {
}
void Spells::cureDisease() {
- Combat &combat = *_vm->_combat;
Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_CureDisease);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
sound.playFX(30);
- c.addHitPoints(0);
- c._conditions[DISEASED] = 0;
+ c->addHitPoints(0);
+ c->_conditions[DISEASED] = 0;
intf.drawParty(true);
}
void Spells::cureParalysis() {
- Combat &combat = *_vm->_combat;
Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_CureParalysis);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
sound.playFX(30);
- c.addHitPoints(0);
- c._conditions[PARALYZED] = 0;
+ c->addHitPoints(0);
+ c->_conditions[PARALYZED] = 0;
intf.drawParty(true);
}
void Spells::curePoison() {
- Combat &combat = *_vm->_combat;
Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_CurePoison);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
sound.playFX(30);
- c.addHitPoints(0);
- c._conditions[POISONED] = 0;
+ c->addHitPoints(0);
+ c->_conditions[POISONED] = 0;
intf.drawParty(true);
}
void Spells::cureWounds() {
- Combat &combat = *_vm->_combat;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_CureWounds);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
- if (c.isDead()) {
+ if (c->isDead()) {
spellFailed();
} else {
sound.playFX(30);
- c.addHitPoints(15);
+ c->addHitPoints(15);
}
}
@@ -559,17 +539,13 @@ void Spells::elementalStorm() {
}
void Spells::enchantItem() {
- Combat &combat = *_vm->_combat;
- Party &party = *_vm->_party;
Mode oldMode = _vm->_mode;
- int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_EnchantItem);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
- ItemsDialog::show(_vm, &c, ITEMMODE_ENCHANT);
+ ItemsDialog::show(_vm, c, ITEMMODE_ENCHANT);
_vm->_mode = oldMode;
}
@@ -648,23 +624,17 @@ void Spells::fireball() {
}
void Spells::firstAid() {
- Combat &combat = *_vm->_combat;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_FirstAid);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
- if (c.isDead()) {
+ if (c->isDead()) {
spellFailed();
- }
- else {
+ } else {
sound.playFX(30);
- c.addHitPoints(6);
+ c->addHitPoints(6);
}
}
@@ -788,20 +758,15 @@ void Spells::insectSpray() {
}
void Spells::itemToGold() {
- Combat &combat = *_vm->_combat;
- Party &party = *_vm->_party;
-
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_ItemToGold);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
Mode oldMode = _vm->_mode;
_vm->_mode = MODE_FF;
_vm->_screen->_windows[11].close();
- ItemsDialog::show(_vm, &c, ITEMMODE_TO_GOLD);
+ ItemsDialog::show(_vm, c, ITEMMODE_TO_GOLD);
_vm->_mode = oldMode;
}
@@ -931,23 +896,17 @@ void Spells::moonRay() {
}
void Spells::naturesCure() {
- Combat &combat = *_vm->_combat;
- Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_NaturesCure);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
-
- if (c.isDead()) {
+ if (c->isDead()) {
spellFailed();
} else {
sound.playFX(30);
- c.addHitPoints(25);
+ c->addHitPoints(25);
}
}
@@ -974,12 +933,39 @@ void Spells::poisonVolley() {
}
void Spells::powerCure() {
-
+ SoundManager &sound = *_vm->_sound;
+
+ Character *c = SpellOnWho::show(_vm, MS_PowerCure);
+ if (!c)
+ return;
+
+ if (c->isDead()) {
+ spellFailed();
+ } else {
+ sound.playFX(30);
+ c->addHitPoints(_vm->getRandomNumber(2, 12) * _vm->_combat->_oldCharacter->getCurrentLevel());
+ }
+}
+
+void Spells::powerShield() {
+ Combat &combat = *_vm->_combat;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ sound.playFX(20);
+ party._powerShield = combat._oldCharacter->getCurrentLevel();
}
-void Spells::powerShield() { error("TODO: spell"); }
+void Spells::prismaticLight() {
+ Combat &combat = *_vm->_combat;
+ SoundManager &sound = *_vm->_sound;
-void Spells::prismaticLight() { error("TODO: spell"); }
+ combat._monsterDamage = 80;
+ combat._damageType = (DamageType)_vm->getRandomNumber(DT_PHYSICAL, DT_ENERGY);
+ combat._rangeType = RT_ALL;
+ sound.playFX(18);
+ combat.multiAttack(14);
+}
void Spells::protectionFromElements() {
Combat &combat = *_vm->_combat;
@@ -1013,32 +999,91 @@ void Spells::protectionFromElements() {
}
}
-void Spells::raiseDead() { error("TODO: spell"); }
+void Spells::raiseDead() {
+ Interface &intf = *_vm->_interface;
+ SoundManager &sound = *_vm->_sound;
-void Spells::rechargeItem() { error("TODO: spell"); }
+ Character *c = SpellOnWho::show(_vm, MS_RaiseDead);
+ if (!c)
+ return;
-void Spells::resurrection() { error("TODO: spell"); }
+ if (!c->_conditions[DEAD]) {
+ spellFailed();
+ } else {
+ c->_conditions[DEAD] = 0;
+ c->_conditions[UNCONSCIOUS] = 0;
+ c->_currentHp = 0;
+ sound.playFX(30);
+ c->addHitPoints(1);
+ if (--c->_endurance._permanent < 1)
+ c->_endurance._permanent = 1;
-void Spells::revitalize() {
- Combat &combat = *_vm->_combat;
+ intf.drawParty(true);
+ }
+}
+
+void Spells::rechargeItem() {
+ Mode oldMode = _vm->_mode;
+
+ Character *c = SpellOnWho::show(_vm, MS_RechargeItem);
+ if (!c)
+ return;
+
+ ItemsDialog::show(_vm, c, ITEMMODE_RECHARGE);
+ _vm->_mode = oldMode;
+}
+
+void Spells::resurrection() {
Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
- if (charIndex == -1)
+ Character *c = SpellOnWho::show(_vm, MS_RaiseDead);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
+ if (!c->_conditions[ERADICATED]) {
+ spellFailed();
+ sound.playFX(30);
+ } else {
+ sound.playFX(30);
+ c->addHitPoints(0);
+ c->_conditions[ERADICATED] = 0;
+
+ if (--c->_endurance._permanent < 1)
+ c->_endurance._permanent = 1;
+ if ((c->_tempAge + 5) >= 250)
+ c->_tempAge = 250;
+ else
+ c->_tempAge += 5;
+
+ intf.drawParty(true);
+ }
+}
+
+void Spells::revitalize() {
+ Interface &intf = *_vm->_interface;
+ SoundManager &sound = *_vm->_sound;
+
+ Character *c = SpellOnWho::show(_vm, MS_Revitalize);
+ if (!c)
+ return;
sound.playFX(30);
- c.addHitPoints(0);
- c._conditions[WEAK] = 0;
+ c->addHitPoints(0);
+ c->_conditions[WEAK] = 0;
intf.drawParty(true);
}
-void Spells::shrapMetal() { error("TODO: spell"); }
+void Spells::shrapMetal() {
+ Combat &combat = *_vm->_combat;
+ SoundManager &sound = *_vm->_sound;
+
+ combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
+ combat._damageType = DT_PHYSICAL;
+ combat._rangeType = RT_GROUP;
+ sound.playFX(16);
+ combat.multiAttack(15);
+}
void Spells::sleep() {
Combat &combat = *_vm->_combat;
@@ -1062,47 +1107,182 @@ void Spells::sparks() {
combat.multiAttack(5);
}
-void Spells::starBurst() { error("TODO: spell"); }
+void Spells::starBurst() {
+ Combat &combat = *_vm->_combat;
+ SoundManager &sound = *_vm->_sound;
-void Spells::stoneToFlesh() { error("TODO: spell"); }
+ combat._monsterDamage = 500;
+ combat._damageType = DT_FIRE;
+ combat._rangeType = RT_ALL;
+ sound.playFX(13);
+ combat.multiAttack(15);
+}
-void Spells::sunRay() { error("TODO: spell"); }
+void Spells::stoneToFlesh() {
+ Interface &intf = *_vm->_interface;
+ SoundManager &sound = *_vm->_sound;
-void Spells::superShelter() { error("TODO: spell"); }
+ Character *c = SpellOnWho::show(_vm, MS_StoneToFlesh);
+ if (!c)
+ return;
-void Spells::suppressDisease() { error("TODO: spell"); }
+ sound.playFX(30);
+ c->addHitPoints(0);
+ c->_conditions[STONED] = 0;
+ intf.drawParty(true);
+}
-void Spells::suppressPoison() {
+void Spells::sunRay() {
Combat &combat = *_vm->_combat;
+ SoundManager &sound = *_vm->_sound;
+
+ combat._monsterDamage = 200;
+ combat._damageType = DT_ENERGY;
+ combat._rangeType = RT_ALL;
+ sound.playFX(16);
+ combat.multiAttack(13);
+}
+
+void Spells::superShelter() {
Interface &intf = *_vm->_interface;
- Party &party = *_vm->_party;
+ Map &map = *_vm->_map;
SoundManager &sound = *_vm->_sound;
- int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
- if (charIndex == -1)
+ if (map.mazeData()._mazeFlags & RESTRICTION_SUPER_SHELTER) {
+ spellFailed();
+ } else {
+ Mode oldMode = _vm->_mode;
+ _vm->_mode = MODE_12;
+ sound.playFX(30);
+ intf.rest();
+ _vm->_mode = oldMode;
+ }
+}
+
+void Spells::suppressDisease() {
+ Interface &intf = *_vm->_interface;
+ SoundManager &sound = *_vm->_sound;
+
+ Character *c = SpellOnWho::show(_vm, MS_SuppressDisease);
+ if (!c)
return;
- Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
- party._activeParty[charIndex];
+ if (c->_conditions[DISEASED]) {
+ if (c->_conditions[DISEASED] >= 4)
+ c->_conditions[DISEASED] -= 3;
+ else
+ c->_conditions[DISEASED] = 1;
+
+ sound.playFX(20);
+ c->addHitPoints(0);
+ intf.drawParty(true);
+ }
+}
+
+void Spells::suppressPoison() {
+ Interface &intf = *_vm->_interface;
+ SoundManager &sound = *_vm->_sound;
+
+ Character *c = SpellOnWho::show(_vm, MS_FirstAid);
+ if (!c)
+ return;
- if (c._conditions[POISONED]) {
- if (c._conditions[POISONED] >= 4) {
- c._conditions[POISONED] -= 2;
+ if (c->_conditions[POISONED]) {
+ if (c->_conditions[POISONED] >= 4) {
+ c->_conditions[POISONED] -= 2;
} else {
- c._conditions[POISONED] = 1;
+ c->_conditions[POISONED] = 1;
}
}
sound.playFX(20);
- c.addHitPoints(0);
+ c->addHitPoints(0);
intf.drawParty(1);
}
-void Spells::teleport() { error("TODO: spell"); } // Not while engaged
+void Spells::teleport() {
+ Map &map = *_vm->_map;
+ SoundManager &sound = *_vm->_sound;
-void Spells::timeDistortion() { error("TODO: spell"); }
+ if (map.mazeData()._mazeFlags & RESTRICTION_TELPORT) {
+ spellFailed();
+ } else {
+ switch (Teleport::show(_vm)) {
+ case 0:
+ spellFailed();
+ break;
+ case 1:
+ sound.playFX(51);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+void Spells::timeDistortion() {
+ Interface &intf = *_vm->_interface;
+ Map &map = *_vm->_map;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ if (map.mazeData()._mazeFlags & RESTRICTION_TIME_DISTORTION) {
+ spellFailed();
+ } else {
+ party.moveToRunLocation();
+ sound.playFX(51);
+ intf.draw3d(true);
+ }
+}
+
+void Spells::townPortal() {
+ Map &map = *_vm->_map;
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ if (map.mazeData()._mazeFlags & RESTRICTION_TOWN_PORTAL) {
+ spellFailed();
+ return;
+ }
+
+ int townNumber = TownPortal::show(_vm);
+ if (!townNumber)
+ return;
+
+ sound.playFX(51);
+ map._loadDarkSide = map._sideTownPortal;
+ _vm->_files->_isDarkCc = map._sideTownPortal > 0;
+ map.load(TOWN_MAP_NUMBERS[map._sideTownPortal][townNumber - 1]);
-void Spells::townPortal() { error("TODO: spell"); } // Not while engaged
+ if (!_vm->_files->_isDarkCc) {
+ party.moveToRunLocation();
+ } else {
+ switch (townNumber) {
+ case 1:
+ party._mazePosition = Common::Point(14, 11);
+ party._mazeDirection = DIR_SOUTH;
+ break;
+ case 2:
+ party._mazePosition = Common::Point(5, 12);
+ party._mazeDirection = DIR_WEST;
+ break;
+ case 3:
+ party._mazePosition = Common::Point(2, 15);
+ party._mazeDirection = DIR_EAST;
+ break;
+ case 4:
+ party._mazePosition = Common::Point(8, 11);
+ party._mazeDirection = DIR_NORTH;
+ break;
+ case 5:
+ party._mazePosition = Common::Point(2, 6);
+ party._mazeDirection = DIR_NORTH;
+ break;
+ default:
+ break;
+ }
+ }
+}
void Spells::toxicCloud() {
Combat &combat = *_vm->_combat;
@@ -1126,9 +1306,22 @@ void Spells::turnUndead() {
combat.multiAttack(13);
}
-void Spells::walkOnWater() { error("TODO: spell"); }
+void Spells::walkOnWater() {
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
+
+ party._walkOnWaterActive = true;
+ sound.playFX(20);
+}
+
+void Spells::wizardEye() {
+ Party &party = *_vm->_party;
+ SoundManager &sound = *_vm->_sound;
-void Spells::wizardEye() { error("TODO: spell"); } // Not while engaged
+ party._wizardEyeActive = true;
+ party._automapOn = false;
+ sound.playFX(20);
+}
void Spells::frostbite2() {
Combat &combat = *_vm->_combat;