XEEN: Fix ordering of spell list and methods

This commit is contained in:
Paul Gilbert 2015-02-28 22:53:17 -05:00
parent 9789962605
commit 07f504fe16
8 changed files with 520 additions and 315 deletions

View File

@ -64,10 +64,6 @@ static const int MONSTER_GRID_BITINDEX2[48] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
static const int MONSTER_GRID_BITMASK[12] = {
0xC, 8, 4, 0, 0xF, 0xF000, 0xF00, 0xF0, 0xF00, 0xF0, 0x0F, 0xF000
};
static const int ATTACK_TYPE_FX[23] = { static const int ATTACK_TYPE_FX[23] = {
49, 18, 13, 14, 15, 17, 16, 0, 6, 1, 2, 3, 49, 18, 13, 14, 15, 17, 16, 0, 6, 1, 2, 3,
4, 5, 4, 9, 27, 29, 44, 51, 53, 61, 71 4, 5, 4, 9, 27, 29, 44, 51, 53, 61, 71
@ -1598,7 +1594,7 @@ void Combat::quickFight() {
break; break;
case QUICK_SPELL: case QUICK_SPELL:
if (c->_currentSpell != -1) { if (c->_currentSpell != -1) {
spells.castSpell(c, SPELLS_ALLOWED[c->getClassCategory()][c->_currentSpell]); spells.castSpell(c, (MagicSpell)SPELLS_ALLOWED[c->getClassCategory()][c->_currentSpell]);
} }
break; break;
case QUICK_BLOCK: case QUICK_BLOCK:

View File

@ -658,7 +658,6 @@ int SelectElement::execute(int spellId) {
Combat &combat = *_vm->_combat; Combat &combat = *_vm->_combat;
EventsManager &events = *_vm->_events; EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface; Interface &intf = *_vm->_interface;
Party &party = *_vm->_party;
Screen &screen = *_vm->_screen; Screen &screen = *_vm->_screen;
Spells &spells = *_vm->_spells; Spells &spells = *_vm->_spells;
Window &w = screen._windows[15]; Window &w = screen._windows[15];
@ -727,4 +726,34 @@ void SelectElement::loadButtons() {
addButton(Common::Rect(150, 92, 174, 112), Common::KEYCODE_a, &_iconSprites); addButton(Common::Rect(150, 92, 174, 112), Common::KEYCODE_a, &_iconSprites);
} }
/*------------------------------------------------------------------------*/
void NotWhileEngaged::show(XeenEngine *vm, int spellId) {
NotWhileEngaged *dlg = new NotWhileEngaged(vm);
dlg->execute(spellId);
delete dlg;
}
void NotWhileEngaged::execute(int spellId) {
EventsManager &events = *_vm->_events;
Screen &screen = *_vm->_screen;
Spells &spells = *_vm->_spells;
Window &w = screen._windows[6];
Mode oldMode = _vm->_mode;
_vm->_mode = MODE_3;
w.open();
w.writeString(Common::String::format(CANT_CAST_WHILE_ENGAGED,
spells._spellNames[spellId].c_str()));
w.update();
while (!_vm->shouldQuit() && !events.isKeyMousePressed())
events.pollEventsAndWait();
events.clearEvents();
w.close();
_vm->_mode = oldMode;
}
} // End of namespace Xeen } // End of namespace Xeen

View File

@ -98,6 +98,18 @@ public:
static int show(XeenEngine *vm, int spellId); static int show(XeenEngine *vm, int spellId);
}; };
class NotWhileEngaged : public ButtonContainer {
private:
XeenEngine *_vm;
NotWhileEngaged(XeenEngine *vm) : ButtonContainer(), _vm(vm) {}
void execute(int spellId);
public:
static void show(XeenEngine *vm, int spellId);
};
} // End of namespace Xeen } // End of namespace Xeen
#endif /* XEEN_DIALOGS_SPELLS_H */ #endif /* XEEN_DIALOGS_SPELLS_H */

View File

@ -541,7 +541,7 @@ void Interface::perform() {
if (spellId == -1 || c == nullptr) if (spellId == -1 || c == nullptr)
break; break;
result = spells.castSpell(c, spellId); result = spells.castSpell(c, (MagicSpell)spellId);
} while (result != -1); } while (result != -1);
if (result == 1) { if (result == 1) {
@ -2008,7 +2008,7 @@ void Interface::doCombat() {
int spellId = CastSpell::show(_vm); int spellId = CastSpell::show(_vm);
if (spellId != -1) { if (spellId != -1) {
Character *c = combat._combatParty[combat._whosTurn]; Character *c = combat._combatParty[combat._whosTurn];
spells.castSpell(c, spellId); spells.castSpell(c, (MagicSpell)spellId);
nextChar(); nextChar();
} else { } else {
highlightChar(combat._combatParty[combat._whosTurn]->_rosterId); highlightChar(combat._combatParty[combat._whosTurn]->_rosterId);

View File

@ -438,6 +438,10 @@ const int8 SCREEN_POSITIONING_Y[4][48] = {
} }
}; };
const int MONSTER_GRID_BITMASK[12] = {
0xC, 8, 4, 0, 0xF, 0xF000, 0xF00, 0xF0, 0xF00, 0xF0, 0x0F, 0xF000
};
const int INDOOR_OBJECT_X[2][12] = { const int INDOOR_OBJECT_X[2][12] = {
{ 5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 }, { 5, -7, -112, 98, -8, -65, 49, -9, -34, 16, -58, 40 },
{ -35, -35, -142, 68, -35, -95, 19, -35, -62, -14, -98, 16 } { -35, -35, -142, 68, -35, -95, 19, -35, -62, -14, -98, 16 }
@ -827,7 +831,7 @@ const int MISC_SPELL_INDEX[74] = {
MS_Levitate, MS_WizardEye, MS_Bless, MS_IdentifyMonster, MS_Levitate, MS_WizardEye, MS_Bless, MS_IdentifyMonster,
MS_LightningBolt, MS_HolyBonus, MS_PowerCure, MS_NaturesCure, MS_LightningBolt, MS_HolyBonus, MS_PowerCure, MS_NaturesCure,
MS_LloydsBeacon, MS_PowerShield, MS_Heroism, MS_Hynotize, MS_LloydsBeacon, MS_PowerShield, MS_Heroism, MS_Hynotize,
MS_WalkOnWater, MS_FrostBite, MS_DetectMonster, MS_FireBall, MS_WalkOnWater, MS_FrostBite, MS_DetectMonster, MS_Fireball,
MS_ColdRay, MS_CurePoison, MS_AcidSpray, MS_TimeDistortion, MS_ColdRay, MS_CurePoison, MS_AcidSpray, MS_TimeDistortion,
MS_DragonSleep, MS_CureDisease, MS_Teleport, MS_FingerOfDeath, MS_DragonSleep, MS_CureDisease, MS_Teleport, MS_FingerOfDeath,
MS_CureParalysis, MS_GolemStopper, MS_PoisonVolley, MS_DeadlySwarm, MS_CureParalysis, MS_GolemStopper, MS_PoisonVolley, MS_DeadlySwarm,

View File

@ -127,6 +127,8 @@ extern const int8 SCREEN_POSITIONING_X[4][48];
extern const int8 SCREEN_POSITIONING_Y[4][48]; extern const int8 SCREEN_POSITIONING_Y[4][48];
extern const int MONSTER_GRID_BITMASK[12];
extern const int INDOOR_OBJECT_X[2][12]; extern const int INDOOR_OBJECT_X[2][12];
extern const int MAP_OBJECT_Y[2][12]; extern const int MAP_OBJECT_Y[2][12];

View File

@ -54,43 +54,34 @@ int Spells::calcSpellPoints(int spellId, int expenseFactor) const {
typedef void(Spells::*SpellMethodPtr)(); typedef void(Spells::*SpellMethodPtr)();
void Spells::executeSpell(int spellId) { void Spells::executeSpell(MagicSpell spellId) {
static const SpellMethodPtr SPELL_LIST[73] = { static const SpellMethodPtr SPELL_LIST[76] = {
&Spells::light, &Spells::awaken, &Spells::magicArrow, &Spells::firstAid, &Spells::acidSpray, &Spells::awaken, &Spells::beastMaster,
&Spells::flyingFist, &Spells::energyBlast, &Spells::sleep, &Spells::bless, &Spells::clairvoyance, &Spells::coldRay,
&Spells::revitalize, &Spells::cureWounds, &Spells::sparks, &Spells::createFood, &Spells::cureDisease, &Spells::cureParalysis,
&Spells::curePoison, &Spells::cureWounds, &Spells::dancingSword,
&Spells::shrapMetal, &Spells::insectSpray, &Spells::toxicCloud, &Spells::dayOfProtection, &Spells::dayOfSorcery, &Spells::deadlySwarm,
&Spells::protectionFromElements, &Spells::pain, &Spells::jump, &Spells::detectMonster, &Spells::divineIntervention, &Spells::dragonSleep,
&Spells::beastMaster, &Spells::clairvoyance, &Spells::turnUndead, &Spells::elementalStorm, &Spells::enchantItem, &Spells::energyBlast,
&Spells::levitate, &Spells::etherialize, &Spells::fantasticFreeze, &Spells::fieryFlail,
&Spells::fingerOfDeath, &Spells::fireball, &Spells::firstAid,
&Spells::wizardEye, &Spells::bless, &Spells::identifyMonster, &Spells::flyingFist, &Spells::frostbite, &Spells::golemStopper,
&Spells::lightningBolt, &Spells::holyBonus, &Spells::powerCure, &Spells::heroism, &Spells::holyBonus, &Spells::holyWord,
&Spells::naturesCure, &Spells::lloydsBeacon, &Spells::powerShield, &Spells::hypnotize, &Spells::identifyMonster, &Spells::implosion,
&Spells::heroism, &Spells::incinerate, &Spells::inferno, &Spells::insectSpray,
&Spells::itemToGold, &Spells::jump, &Spells::levitate,
&Spells::hypnotize, &Spells::walkOnWater, &Spells::frostByte, &Spells::light, &Spells::lightningBolt, &Spells::lloydsBeacon,
&Spells::detectMonster, &Spells::fireball, &Spells::coldRay, &Spells::magicArrow, &Spells::massDistortion, &Spells::megaVolts,
&Spells::curePoison, &Spells::acidSpray, &Spells::timeDistortion, &Spells::moonRay, &Spells::naturesCure, &Spells::pain,
&Spells::dragonSleep, &Spells::poisonVolley, &Spells::powerCure, &Spells::powerShield,
&Spells::prismaticLight, &Spells::protectionFromElements, &Spells::raiseDead,
&Spells::suppressPoison, &Spells::teleport, &Spells::fingerOfDeath, &Spells::rechargeItem, &Spells::resurrection, &Spells::revitalize,
&Spells::cureParalysis, &Spells::golemStopper, &Spells::poisonVolley, &Spells::shrapMetal, &Spells::sleep, &Spells::sparks,
&Spells::deadlySwarm, &Spells::superShelter, &Spells::dayOfProtection, &Spells::starBurst, &Spells::stoneToFlesh, &Spells::sunRay,
&Spells::dayOfSorcery, &Spells::superShelter, &Spells::suppressDisease, &Spells::suppressPoison,
&Spells::teleport, &Spells::timeDistortion, &Spells::townPortal,
&Spells::createFood, &Spells::fieryFlail, &Spells::rechargeItem, &Spells::toxicCloud, &Spells::turnUndead, &Spells::walkOnWater,
&Spells::fantasticFreeze, &Spells::townPortal, &Spells::stoneToFlesh, &Spells::wizardEye
&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
}; };
(this->*SPELL_LIST[spellId])(); (this->*SPELL_LIST[spellId])();
@ -106,23 +97,82 @@ void Spells::spellFailed() {
/** /**
* Cast a spell associated with an item * Cast a spell associated with an item
*/ */
void Spells::castItemSpell(int spellId) { void Spells::castItemSpell(int itemSpellId) {
if (_vm->_mode == MODE_COMBAT) { switch (itemSpellId) {
if (spellId == 15 || spellId == 20 || spellId == 27 || spellId == 41 case 15:
|| spellId == 47 || spellId == 54 || spellId == 57) { if (_vm->_mode == MODE_COMBAT) {
ErrorDialog::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED, NotWhileEngaged::show(_vm, MS_Jump);
_spellNames[spellId].c_str()));
return; 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 * Cast a given spell
*/ */
int Spells::castSpell(Character *c, int spellId) { int Spells::castSpell(Character *c, MagicSpell spellId) {
Combat &combat = *_vm->_combat; Combat &combat = *_vm->_combat;
Interface &intf = *_vm->_interface; Interface &intf = *_vm->_interface;
int oldTillMove = intf._tillMove; int oldTillMove = intf._tillMove;
@ -137,21 +187,20 @@ int Spells::castSpell(Character *c, int spellId) {
} else { } else {
// Some spells have special handling // Some spells have special handling
switch (spellId) { switch (spellId) {
case 19: // Enchant item case MS_EnchantItem:
case 21: // Etherialize case MS_Etheralize:
case 40: // Jump case MS_Jump:
case 44: // Lloyd's Beacon case MS_LloydsBeacon:
case 66: // Super Shelter case MS_SuperShelter:
case 69: // Teleport case MS_Teleport:
case 71: // Town Portal case MS_TownPortal:
case 75: // Wizard Eye case MS_WizardEye:
if (_vm->_mode != MODE_COMBAT) { if (_vm->_mode != MODE_COMBAT) {
executeSpell(spellId); executeSpell(spellId);
} else { } else {
// Return the spell costs and flag that another spell can be selected // Return the spell costs and flag that another spell can be selected
addSpellCost(*c, spellId); addSpellCost(*c, spellId);
ErrorDialog::show(_vm, Common::String::format(CANT_CAST_WHILE_ENGAGED, NotWhileEngaged::show(_vm, spellId);
_spellNames[spellId].c_str()));
result = -1; result = -1;
} }
break; break;
@ -209,18 +258,9 @@ void Spells::addSpellCost(Character &c, int spellId) {
party._gems += gemCost; party._gems += gemCost;
} }
void Spells::light() { void Spells::acidSpray() { error("TODO: spell"); }
Interface &intf = *_vm->_interface;
Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
++party._lightCount; void Spells::awaken() {
if (intf._intrIndex1)
party._stepped = true;
sound.playFX(39);
}
void Spells::awaken() {
Interface &intf = *_vm->_interface; Interface &intf = *_vm->_interface;
Party &party = *_vm->_party; Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound; SoundManager &sound = *_vm->_sound;
@ -236,14 +276,82 @@ void Spells::awaken() {
sound.playFX(30); 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 &combat = *_vm->_combat;
combat._monsterDamage = 0; Party &party = *_vm->_party;
combat._damageType = DT_MAGIC_ARROW; SoundManager &sound = *_vm->_sound;
combat._rangeType = RT_SINGLE;
combat.multiAttack(11); 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() { void Spells::firstAid() {
Combat &combat = *_vm->_combat; Combat &combat = *_vm->_combat;
Party &party = *_vm->_party; Party &party = *_vm->_party;
@ -258,7 +366,8 @@ void Spells::firstAid() {
if (c.isDead()) { if (c.isDead()) {
spellFailed(); spellFailed();
} else { }
else {
sound.playFX(30); sound.playFX(30);
c.addHitPoints(6); c.addHitPoints(6);
} }
@ -275,117 +384,119 @@ void Spells::flyingFist() {
combat.multiAttack(14); combat.multiAttack(14);
} }
void Spells::energyBlast() { void Spells::frostbite() { error("TODO: spell"); }
Combat &combat = *_vm->_combat;
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; SoundManager &sound = *_vm->_sound;
combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2; if (map._isOutdoors) {
combat._damageType = DT_ENERGY; map.getCell(7);
combat._rangeType = RT_SINGLE; if (map._currentWall != 1) {
sound.playFX(16); map.getCell(14);
combat.multiAttack(13); 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; Combat &combat = *_vm->_combat;
SoundManager &sound = *_vm->_sound; SoundManager &sound = *_vm->_sound;
combat._monsterDamage = 0; combat._monsterDamage = 0;
combat._damageType = DT_SLEEP; combat._damageType = DT_PHYSICAL;
combat._rangeType = RT_GROUP; combat._rangeType = RT_GROUP;
sound.playFX(18); sound.playFX(18);
combat.multiAttack(7); combat.multiAttack(14);
} }
void Spells::revitalize() { void Spells::poisonVolley() { error("TODO: spell"); }
Combat &combat = *_vm->_combat;
Interface &intf = *_vm->_interface;
Party &party = *_vm->_party;
SoundManager &sound = *_vm->_sound;
int charIndex = SpellOnWho::show(_vm, MS_Revitalize); void Spells::powerCure() { error("TODO: spell"); }
if (charIndex == -1)
return;
Character &c = combat._combatMode == 2 ? *combat._combatParty[charIndex] : void Spells::powerShield() { error("TODO: spell"); }
party._activeParty[charIndex];
sound.playFX(30); void Spells::prismaticLight() { error("TODO: spell"); }
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::protectionFromElements() { void Spells::protectionFromElements() {
Combat &combat = *_vm->_combat; 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; Combat &combat = *_vm->_combat;
SoundManager &sound = *_vm->_sound; SoundManager &sound = *_vm->_sound;
combat._monsterDamage = 0; combat._monsterDamage = 0;
combat._damageType = DT_PHYSICAL; combat._damageType = DT_SLEEP;
combat._rangeType = RT_GROUP; combat._rangeType = RT_GROUP;
sound.playFX(18); sound.playFX(18);
combat.multiAttack(14); combat.multiAttack(7);
} }
void Spells::jump() { error("TODO: spell"); } // Not while engaged void Spells::sparks() {
void Spells::beastMaster() { error("TODO: spell"); } Combat &combat = *_vm->_combat;
void Spells::clairvoyance() { error("TODO: spell"); } SoundManager &sound = *_vm->_sound;
void Spells::turnUndead() { error("TODO: spell"); }
void Spells::levitate() { error("TODO: spell"); }
void Spells::wizardEye() { error("TODO: spell"); } // Not while engaged combat._monsterDamage = combat._oldCharacter->getCurrentLevel() * 2;
void Spells::bless() { error("TODO: spell"); } combat._damageType = DT_ELECTRICAL;
void Spells::identifyMonster() { error("TODO: spell"); } combat._rangeType = RT_GROUP;
void Spells::lightningBolt() { error("TODO: spell"); } sound.playFX(14);
void Spells::holyBonus() { error("TODO: spell"); } combat.multiAttack(5);
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::starBurst() { 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::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::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::sunRay() { error("TODO: spell"); }
void Spells::implosion() { error("TODO: spell"); } void Spells::superShelter() { error("TODO: spell"); }
void Spells::starBurst() { error("TODO: spell"); }
void Spells::divineIntervention() { 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 } // End of namespace Xeen

View File

@ -42,7 +42,7 @@ enum MagicSpell {
MS_DivineIntervention = 16, MS_DragonSleep = 17, MS_ElementalStorm = 18, MS_DivineIntervention = 16, MS_DragonSleep = 17, MS_ElementalStorm = 18,
MS_EnchantItem = 19, MS_EnergyBlast = 20, MS_Etheralize = 21, MS_EnchantItem = 19, MS_EnergyBlast = 20, MS_Etheralize = 21,
MS_FantasticFreeze = 22, MS_FieryFlail = 23, MS_FingerOfDeath = 24, MS_FantasticFreeze = 22, MS_FieryFlail = 23, MS_FingerOfDeath = 24,
MS_FireBall = 25, MS_FirstAid = 26, MS_FlyingFist = 27, MS_Fireball = 25, MS_FirstAid = 26, MS_FlyingFist = 27,
MS_FrostBite = 28, MS_GolemStopper = 29, MS_Heroism = 30, MS_FrostBite = 28, MS_GolemStopper = 29, MS_Heroism = 30,
MS_HolyBonus = 31, MS_HolyWord = 32, MS_Hynotize = 33, MS_HolyBonus = 31, MS_HolyWord = 32, MS_Hynotize = 33,
MS_IdentifyMonster = 34, MS_Implosion = 35, MS_Incinerate = 36, MS_IdentifyMonster = 34, MS_Implosion = 35, MS_Incinerate = 36,
@ -67,91 +67,89 @@ private:
void load(); void load();
void executeSpell(int spellId); void executeSpell(MagicSpell spellId);
void spellFailed(); void spellFailed();
// Spell list // 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 acidSpray();
void timeDistortion(); void awaken();
void dragonSleep(); void beastMaster();
void bless();
void suppressPoison(); void clairvoyance();
void teleport(); // Not while engaged void coldRay();
void fingerOfDeath(); void createFood();
void cureDisease();
void cureParalysis(); void cureParalysis();
void golemStopper(); void curePoison();
void poisonVolley(); void cureWounds();
void deadlySwarm(); void dancingSword();
void superShelter(); // Not while engaged
void dayOfProtection(); void dayOfProtection();
void dayOfSorcery(); void dayOfSorcery();
void deadlySwarm();
void createFood(); void detectMonster();
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(); void divineIntervention();
void dragonSleep();
void elementalStorm();
void enchantItem();
void energyBlast();
void etherialize();
void fantasticFreeze();
void fieryFlail();
void fingerOfDeath();
void fireball();
void firstAid();
void flyingFist();
void frostbite();
void golemStopper();
void heroism();
void holyBonus();
void holyWord();
void hypnotize();
void identifyMonster();
void implosion();
void incinerate();
void inferno();
void insectSpray();
void itemToGold();
void jump();
void levitate();
void light();
void lightningBolt();
void lloydsBeacon();
void magicArrow();
void massDistortion();
void megaVolts();
void moonRay();
void naturesCure();
void pain();
void poisonVolley();
void powerCure();
void powerShield();
void prismaticLight();
void protectionFromElements();
void raiseDead();
void rechargeItem();
void resurrection();
void revitalize();
void shrapMetal();
void sleep();
void sparks();
void starBurst();
void stoneToFlesh();
void sunRay();
void superShelter();
void suppressDisease();
void suppressPoison();
void teleport();
void timeDistortion();
void townPortal();
void toxicCloud();
void turnUndead();
void walkOnWater();
void wizardEye();
void frostbite2();
public: public:
Common::StringArray _spellNames; Common::StringArray _spellNames;
int _lastCaster; int _lastCaster;
@ -162,9 +160,9 @@ public:
int calcSpellPoints(int spellId, int expenseFactor) const; int calcSpellPoints(int spellId, int expenseFactor) const;
void castItemSpell(int spellId); void castItemSpell(int itemSpellId);
int castSpell(Character *c, int spellId); int castSpell(Character *c, MagicSpell spellId);
int subSpellCost(Character &c, int spellId); int subSpellCost(Character &c, int spellId);