|
|
|
@ -54,43 +54,34 @@ int Spells::calcSpellPoints(int spellId, int expenseFactor) const {
|
|
|
|
|
|
|
|
|
|
typedef void(Spells::*SpellMethodPtr)();
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
|
&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::suppressPoison, &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
|
|
|
|
|
void Spells::executeSpell(MagicSpell spellId) {
|
|
|
|
|
static const SpellMethodPtr SPELL_LIST[76] = {
|
|
|
|
|
&Spells::acidSpray, &Spells::awaken, &Spells::beastMaster,
|
|
|
|
|
&Spells::bless, &Spells::clairvoyance, &Spells::coldRay,
|
|
|
|
|
&Spells::createFood, &Spells::cureDisease, &Spells::cureParalysis,
|
|
|
|
|
&Spells::curePoison, &Spells::cureWounds, &Spells::dancingSword,
|
|
|
|
|
&Spells::dayOfProtection, &Spells::dayOfSorcery, &Spells::deadlySwarm,
|
|
|
|
|
&Spells::detectMonster, &Spells::divineIntervention, &Spells::dragonSleep,
|
|
|
|
|
&Spells::elementalStorm, &Spells::enchantItem, &Spells::energyBlast,
|
|
|
|
|
&Spells::etherialize, &Spells::fantasticFreeze, &Spells::fieryFlail,
|
|
|
|
|
&Spells::fingerOfDeath, &Spells::fireball, &Spells::firstAid,
|
|
|
|
|
&Spells::flyingFist, &Spells::frostbite, &Spells::golemStopper,
|
|
|
|
|
&Spells::heroism, &Spells::holyBonus, &Spells::holyWord,
|
|
|
|
|
&Spells::hypnotize, &Spells::identifyMonster, &Spells::implosion,
|
|
|
|
|
&Spells::incinerate, &Spells::inferno, &Spells::insectSpray,
|
|
|
|
|
&Spells::itemToGold, &Spells::jump, &Spells::levitate,
|
|
|
|
|
&Spells::light, &Spells::lightningBolt, &Spells::lloydsBeacon,
|
|
|
|
|
&Spells::magicArrow, &Spells::massDistortion, &Spells::megaVolts,
|
|
|
|
|
&Spells::moonRay, &Spells::naturesCure, &Spells::pain,
|
|
|
|
|
&Spells::poisonVolley, &Spells::powerCure, &Spells::powerShield,
|
|
|
|
|
&Spells::prismaticLight, &Spells::protectionFromElements, &Spells::raiseDead,
|
|
|
|
|
&Spells::rechargeItem, &Spells::resurrection, &Spells::revitalize,
|
|
|
|
|
&Spells::shrapMetal, &Spells::sleep, &Spells::sparks,
|
|
|
|
|
&Spells::starBurst, &Spells::stoneToFlesh, &Spells::sunRay,
|
|
|
|
|
&Spells::superShelter, &Spells::suppressDisease, &Spells::suppressPoison,
|
|
|
|
|
&Spells::teleport, &Spells::timeDistortion, &Spells::townPortal,
|
|
|
|
|
&Spells::toxicCloud, &Spells::turnUndead, &Spells::walkOnWater,
|
|
|
|
|
&Spells::wizardEye
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
(this->*SPELL_LIST[spellId])();
|
|
|
|
@ -106,23 +97,82 @@ void Spells::spellFailed() {
|
|
|
|
|
/**
|
|
|
|
|
* Cast a spell associated with an item
|
|
|
|
|
*/
|
|
|
|
|
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) {
|
|
|
|
|
ErrorDialog::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED,
|
|
|
|
|
_spellNames[spellId].c_str()));
|
|
|
|
|
void Spells::castItemSpell(int itemSpellId) {
|
|
|
|
|
switch (itemSpellId) {
|
|
|
|
|
case 15:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_Jump);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 20:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_WizardEye);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 27:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_LloydsBeacon);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 32:
|
|
|
|
|
frostbite2();
|
|
|
|
|
break;
|
|
|
|
|
case 41:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_Teleport);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 47:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_SuperShelter);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 54:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_TownPortal);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 57:
|
|
|
|
|
if (_vm->_mode == MODE_COMBAT) {
|
|
|
|
|
NotWhileEngaged::show(_vm, MS_Etheralize);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
executeSpell(spellId);
|
|
|
|
|
static const MagicSpell spells[73] = {
|
|
|
|
|
MS_Light, MS_Awaken, MS_MagicArrow, MS_FirstAid, MS_FlyingFist,
|
|
|
|
|
MS_EnergyBlast, MS_Sleep, MS_Revitalize, MS_CureWounds, MS_Sparks,
|
|
|
|
|
MS_Shrapmetal, MS_InsectSpray, MS_ToxicCloud, MS_ProtFromElements, MS_Pain,
|
|
|
|
|
MS_Jump, MS_BeastMaster, MS_Clairvoyance, MS_TurnUndead, MS_Levitate,
|
|
|
|
|
MS_WizardEye, MS_Bless, MS_IdentifyMonster, MS_LightningBolt, MS_HolyBonus,
|
|
|
|
|
MS_PowerCure, MS_NaturesCure, MS_LloydsBeacon, MS_PowerShield, MS_Heroism,
|
|
|
|
|
MS_Hynotize, MS_WalkOnWater, NO_SPELL, MS_DetectMonster, MS_Fireball,
|
|
|
|
|
MS_ColdRay, MS_CurePoison, MS_AcidSpray, MS_TimeDistortion, MS_DragonSleep,
|
|
|
|
|
MS_CureDisease, MS_Teleport, MS_FingerOfDeath, MS_CureParalysis, MS_GolemStopper,
|
|
|
|
|
MS_PoisonVolley, MS_DeadlySwarm, MS_SuperShelter, MS_DayOfProtection, MS_DayOfProtection,
|
|
|
|
|
MS_CreateFood, MS_FieryFlail, MS_RechargeItem, MS_FantasticFreeze, MS_TownPortal,
|
|
|
|
|
MS_StoneToFlesh, MS_RaiseDead, MS_Etheralize, MS_DancingSword, MS_MoonRay,
|
|
|
|
|
MS_MassDistortion, MS_PrismaticLight, MS_EnchantItem, MS_Incinerate, MS_HolyWord,
|
|
|
|
|
MS_Resurrection, MS_ElementalStorm, MS_MegaVolts, MS_Inferno, MS_SunRay,
|
|
|
|
|
MS_Implosion, MS_StarBurst, MS_DivineIntervention
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
executeSpell(spells[itemSpellId]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Cast a given spell
|
|
|
|
|
*/
|
|
|
|
|
int Spells::castSpell(Character *c, int spellId) {
|
|
|
|
|
int Spells::castSpell(Character *c, MagicSpell spellId) {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
int oldTillMove = intf._tillMove;
|
|
|
|
@ -137,21 +187,20 @@ int Spells::castSpell(Character *c, int spellId) {
|
|
|
|
|
} else {
|
|
|
|
|
// Some spells have special handling
|
|
|
|
|
switch (spellId) {
|
|
|
|
|
case 19: // Enchant item
|
|
|
|
|
case 21: // Etherialize
|
|
|
|
|
case 40: // Jump
|
|
|
|
|
case 44: // Lloyd's Beacon
|
|
|
|
|
case 66: // Super Shelter
|
|
|
|
|
case 69: // Teleport
|
|
|
|
|
case 71: // Town Portal
|
|
|
|
|
case 75: // Wizard Eye
|
|
|
|
|
case MS_EnchantItem:
|
|
|
|
|
case MS_Etheralize:
|
|
|
|
|
case MS_Jump:
|
|
|
|
|
case MS_LloydsBeacon:
|
|
|
|
|
case MS_SuperShelter:
|
|
|
|
|
case MS_Teleport:
|
|
|
|
|
case MS_TownPortal:
|
|
|
|
|
case MS_WizardEye:
|
|
|
|
|
if (_vm->_mode != MODE_COMBAT) {
|
|
|
|
|
executeSpell(spellId);
|
|
|
|
|
} else {
|
|
|
|
|
// Return the spell costs and flag that another spell can be selected
|
|
|
|
|
addSpellCost(*c, spellId);
|
|
|
|
|
ErrorDialog::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED,
|
|
|
|
|
_spellNames[spellId].c_str()));
|
|
|
|
|
NotWhileEngaged::show(_vm, spellId);
|
|
|
|
|
result = -1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
@ -209,18 +258,9 @@ void Spells::addSpellCost(Character &c, int spellId) {
|
|
|
|
|
party._gems += gemCost;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::light() {
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
void Spells::acidSpray() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
++party._lightCount;
|
|
|
|
|
if (intf._intrIndex1)
|
|
|
|
|
party._stepped = true;
|
|
|
|
|
sound.playFX(39);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::awaken() {
|
|
|
|
|
void Spells::awaken() {
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
@ -236,14 +276,82 @@ void Spells::awaken() {
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::magicArrow() {
|
|
|
|
|
void Spells::beastMaster() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::bless() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::clairvoyance() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::coldRay() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::createFood() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::cureDisease() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::cureParalysis() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::curePoison() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::cureWounds() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
combat._monsterDamage = 0;
|
|
|
|
|
combat._damageType = DT_MAGIC_ARROW;
|
|
|
|
|
combat._rangeType = RT_SINGLE;
|
|
|
|
|
combat.multiAttack(11);
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
|
|
|
|
|
if (charIndex == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
|
|
|
|
|
if (c.isDead()) {
|
|
|
|
|
spellFailed();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
c.addHitPoints(15);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::dancingSword() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::dayOfProtection() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::dayOfSorcery() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::deadlySwarm() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::detectMonster() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::divineIntervention() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::dragonSleep() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::elementalStorm() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::enchantItem() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::energyBlast() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
|
|
|
|
|
combat._damageType = DT_ENERGY;
|
|
|
|
|
combat._rangeType = RT_SINGLE;
|
|
|
|
|
sound.playFX(16);
|
|
|
|
|
combat.multiAttack(13);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::etherialize() { error("TODO: spell"); } // Not while engaged
|
|
|
|
|
|
|
|
|
|
void Spells::fantasticFreeze() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::fieryFlail() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::fingerOfDeath() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::fireball() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::firstAid() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
@ -258,7 +366,8 @@ void Spells::firstAid() {
|
|
|
|
|
|
|
|
|
|
if (c.isDead()) {
|
|
|
|
|
spellFailed();
|
|
|
|
|
} else {
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
c.addHitPoints(6);
|
|
|
|
|
}
|
|
|
|
@ -275,117 +384,119 @@ void Spells::flyingFist() {
|
|
|
|
|
combat.multiAttack(14);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::energyBlast() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
void Spells::frostbite() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::golemStopper() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::heroism() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::holyBonus() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::holyWord() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::hypnotize() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::identifyMonster() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::implosion() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::incinerate() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::inferno() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::insectSpray() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::itemToGold() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::jump() {
|
|
|
|
|
Map &map = *_vm->_map;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
|
|
|
|
|
combat._damageType = DT_ENERGY;
|
|
|
|
|
combat._rangeType = RT_SINGLE;
|
|
|
|
|
sound.playFX(16);
|
|
|
|
|
combat.multiAttack(13);
|
|
|
|
|
if (map._isOutdoors) {
|
|
|
|
|
map.getCell(7);
|
|
|
|
|
if (map._currentWall != 1) {
|
|
|
|
|
map.getCell(14);
|
|
|
|
|
if (map._currentSurfaceId != 0 && map._currentWall != 1) {
|
|
|
|
|
party._mazePosition += Common::Point(
|
|
|
|
|
SCREEN_POSITIONING_X[party._mazeDirection][14],
|
|
|
|
|
SCREEN_POSITIONING_Y[party._mazeDirection][14]
|
|
|
|
|
);
|
|
|
|
|
sound.playFX(51);
|
|
|
|
|
party._stepped = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
Common::Point pt = party._mazePosition + Common::Point(
|
|
|
|
|
SCREEN_POSITIONING_X[party._mazeDirection][7],
|
|
|
|
|
SCREEN_POSITIONING_Y[party._mazeDirection][7]);
|
|
|
|
|
if (!map.mazeLookup(party._mazePosition, MONSTER_GRID_BITMASK[party._mazeDirection]) &&
|
|
|
|
|
!map.mazeLookup(pt, MONSTER_GRID_BITMASK[party._mazeDirection])) {
|
|
|
|
|
party._mazePosition += Common::Point(
|
|
|
|
|
SCREEN_POSITIONING_X[party._mazeDirection][14],
|
|
|
|
|
SCREEN_POSITIONING_Y[party._mazeDirection][14]
|
|
|
|
|
);
|
|
|
|
|
sound.playFX(51);
|
|
|
|
|
party._stepped = true;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spellFailed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::sleep() {
|
|
|
|
|
void Spells::levitate() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::light() {
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
++party._lightCount;
|
|
|
|
|
if (intf._intrIndex1)
|
|
|
|
|
party._stepped = true;
|
|
|
|
|
sound.playFX(39);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::lightningBolt() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::lloydsBeacon() { error("TODO: spell"); } // Not while engaged
|
|
|
|
|
|
|
|
|
|
void Spells::magicArrow() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
combat._monsterDamage = 0;
|
|
|
|
|
combat._damageType = DT_MAGIC_ARROW;
|
|
|
|
|
combat._rangeType = RT_SINGLE;
|
|
|
|
|
combat.multiAttack(11);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::massDistortion() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::megaVolts() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::moonRay() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::naturesCure() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::pain() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 0;
|
|
|
|
|
combat._damageType = DT_SLEEP;
|
|
|
|
|
combat._damageType = DT_PHYSICAL;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(18);
|
|
|
|
|
combat.multiAttack(7);
|
|
|
|
|
combat.multiAttack(14);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::revitalize() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
void Spells::poisonVolley() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
int charIndex = SpellOnWho::show(_vm, MS_Revitalize);
|
|
|
|
|
if (charIndex == -1)
|
|
|
|
|
return;
|
|
|
|
|
void Spells::powerCure() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
void Spells::powerShield() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
c.addHitPoints(0);
|
|
|
|
|
c._conditions[WEAK] = 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)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
|
|
|
|
|
if (c.isDead()) {
|
|
|
|
|
spellFailed();
|
|
|
|
|
} else {
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
c.addHitPoints(15);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::sparks() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
|
|
|
|
|
combat._damageType = DT_ELECTRICAL;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(14);
|
|
|
|
|
combat.multiAttack(5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::shrapMetal() { error("TODO: spell"); }
|
|
|
|
|
void Spells::insectSpray() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::toxicCloud() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 10;
|
|
|
|
|
combat._damageType = DT_POISON;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(17);
|
|
|
|
|
combat.multiAttack(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::suppressPoison() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
|
|
|
|
|
if (charIndex == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
|
|
|
|
|
if (c._conditions[POISONED]) {
|
|
|
|
|
if (c._conditions[POISONED] >= 4) {
|
|
|
|
|
c._conditions[POISONED] -= 2;
|
|
|
|
|
} else {
|
|
|
|
|
c._conditions[POISONED] = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sound.playFX(20);
|
|
|
|
|
c.addHitPoints(0);
|
|
|
|
|
intf.drawParty(1);
|
|
|
|
|
}
|
|
|
|
|
void Spells::prismaticLight() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::protectionFromElements() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
@ -419,79 +530,132 @@ void Spells::protectionFromElements() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::pain() {
|
|
|
|
|
void Spells::raiseDead() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::rechargeItem() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::resurrection() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::revitalize() {
|
|
|
|
|
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)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
|
|
|
|
|
sound.playFX(30);
|
|
|
|
|
c.addHitPoints(0);
|
|
|
|
|
c._conditions[WEAK] = 0;
|
|
|
|
|
intf.drawParty(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::shrapMetal() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::sleep() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 0;
|
|
|
|
|
combat._damageType = DT_PHYSICAL;
|
|
|
|
|
combat._damageType = DT_SLEEP;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(18);
|
|
|
|
|
combat.multiAttack(14);
|
|
|
|
|
combat.multiAttack(7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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::sparks() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
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"); }
|
|
|
|
|
combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
|
|
|
|
|
combat._damageType = DT_ELECTRICAL;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(14);
|
|
|
|
|
combat.multiAttack(5);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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::starBurst() { 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"); }
|
|
|
|
|
void Spells::superShelter() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::suppressDisease() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::suppressPoison() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
Interface &intf = *_vm->_interface;
|
|
|
|
|
Party &party = *_vm->_party;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
int charIndex = SpellOnWho::show(_vm, MS_FirstAid);
|
|
|
|
|
if (charIndex == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] :
|
|
|
|
|
party._activeParty[charIndex];
|
|
|
|
|
|
|
|
|
|
if (c._conditions[POISONED]) {
|
|
|
|
|
if (c._conditions[POISONED] >= 4) {
|
|
|
|
|
c._conditions[POISONED] -= 2;
|
|
|
|
|
} else {
|
|
|
|
|
c._conditions[POISONED] = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sound.playFX(20);
|
|
|
|
|
c.addHitPoints(0);
|
|
|
|
|
intf.drawParty(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::teleport() { error("TODO: spell"); } // Not while engaged
|
|
|
|
|
|
|
|
|
|
void Spells::timeDistortion() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::townPortal() { error("TODO: spell"); } // Not while engaged
|
|
|
|
|
|
|
|
|
|
void Spells::toxicCloud() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 10;
|
|
|
|
|
combat._damageType = DT_POISON;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(17);
|
|
|
|
|
combat.multiAttack(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::turnUndead() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 0;
|
|
|
|
|
combat._damageType = DT_UNDEAD;
|
|
|
|
|
combat._rangeType = RT_GROUP;
|
|
|
|
|
sound.playFX(18);
|
|
|
|
|
combat.multiAttack(13);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Spells::walkOnWater() { error("TODO: spell"); }
|
|
|
|
|
|
|
|
|
|
void Spells::wizardEye() { error("TODO: spell"); } // Not while engaged
|
|
|
|
|
|
|
|
|
|
void Spells::frostbite2() {
|
|
|
|
|
Combat &combat = *_vm->_combat;
|
|
|
|
|
SoundManager &sound = *_vm->_sound;
|
|
|
|
|
|
|
|
|
|
combat._monsterDamage = 35;
|
|
|
|
|
combat._damageType = DT_COLD;
|
|
|
|
|
combat._rangeType = RT_SINGLE;
|
|
|
|
|
sound.playFX(15);
|
|
|
|
|
combat.multiAttack(9);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // End of namespace Xeen
|
|
|
|
|