aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/magic_eob.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/kyra/magic_eob.cpp')
-rw-r--r--engines/kyra/magic_eob.cpp132
1 files changed, 96 insertions, 36 deletions
diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp
index 12d2524545..d06e15b36f 100644
--- a/engines/kyra/magic_eob.cpp
+++ b/engines/kyra/magic_eob.cpp
@@ -184,7 +184,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
if (ci > 3)
ci -= 2;
- _activeSpellCasterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
+ _activeSpellCharacterPos = _dropItemDirIndex[(_currentDirection << 2) + ci];
if (s->flags & 0x400) {
if (c->inventory[0] && c->inventory[1]) {
@@ -226,7 +226,7 @@ void EobCoreEngine::castSpell(int spell, int weaponSlot) {
return;
}
- _activeSpellCaster = _openBookChar;
+ _activeSpellCharId = _openBookChar;
startSpell(spell);
}
@@ -258,7 +258,7 @@ void EobCoreEngine::removeCharacterEffect(int spell, int charIndex, int showWarn
}
if (s->flags & 0x2)
- recalcArmorClass(_activeSpellCaster);
+ recalcArmorClass(_activeSpellCharId);
if (showWarning) {
if (s->flags & 0x20A0)
@@ -296,11 +296,11 @@ void EobCoreEngine::castOnWhomDialogue() {
void EobCoreEngine::startSpell(int spell) {
EobSpell *s = &_spells[spell];
- EobCharacter *c = &_characters[_activeSpellCaster];
+ EobCharacter *c = &_characters[_activeSpellCharId];
snd_playSoundEffect(s->sound);
if (s->flags & 0xa0)
- sparkEffectDefensive(_activeSpellCaster);
+ sparkEffectDefensive(_activeSpellCharId);
else if (s->flags & 0x40)
sparkEffectDefensive(-1);
else if (s->flags & 0x1000)
@@ -312,9 +312,17 @@ void EobCoreEngine::startSpell(int spell) {
}
if ((s->flags & 0x30) && (s->effectFlags & c->effectFlags)) {
- printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
+ if (_flags.gameID == GI_EOB1) {
+ // TODO: warnings seem to exist at least for bless and aid
+ } else {
+ printWarning(Common::String::format(_magicStrings7[0], c->name, s->name).c_str());
+ }
} else if ((s->flags & 0x50) && (s->effectFlags & _partyEffectFlags)) {
- printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
+ if (_flags.gameID == GI_EOB1) {
+ // TODO: warnings seem to exist at least for bless and aid
+ } else {
+ printWarning(Common::String::format(_magicStrings7[1], s->name).c_str());
+ }
} else {
if (s->flags & 8)
setSpellEventTimer(spell, s->timingPara[0], s->timingPara[1], s->timingPara[2], s->timingPara[3]);
@@ -341,10 +349,10 @@ void EobCoreEngine::startSpell(int spell) {
}
if (s->flags & 2)
- recalcArmorClass(_activeSpellCaster);
+ recalcArmorClass(_activeSpellCharId);
if (s->flags & 0x20A0)
- gui_drawCharPortraitWithStats(_activeSpellCaster);
+ gui_drawCharPortraitWithStats(_activeSpellCharId);
if (s->flags & 0x40)
gui_drawAllCharPortraitsWithStats();
}
@@ -438,7 +446,7 @@ void EobCoreEngine::sparkEffectOffensive() {
void EobCoreEngine::setSpellEventTimer(int spell, int timerBaseFactor, int timerLength, int timerLevelFactor, int updateExistingTimer) {
int l = _openBookType == 1 ? getCharacterClericPaladinLevel(_openBookChar) : getCharacterMageLevel(_openBookChar);
uint32 countdown = timerLength * timerBaseFactor + timerLength * l * timerLevelFactor;
- setCharEventTimer(_activeSpellCaster, countdown, -spell, updateExistingTimer);
+ setCharEventTimer(_activeSpellCharId, countdown, -spell, updateExistingTimer);
}
void EobCoreEngine::sortCharacterSpellList(int charIndex) {
@@ -624,7 +632,23 @@ bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int caster
return true;
}
-void EobCoreEngine::printWarning(const char* str) {
+int EobCoreEngine::findSingleSpellTarget(int dist) {
+ uint16 bl = _currentBlock;
+ int res = -1;
+
+ for (int i = 0; i < dist && res == -1; i++) {
+ bl = calcNewBlockPosition(bl, _currentDirection);
+ res = getClosestMonster(_openBookChar, bl);
+ if (!(_wllWallFlags[_levelBlockProperties[bl].walls[_sceneDrawVarDown]] & 1)) {
+ i = dist;
+ res = -1;
+ }
+ }
+
+ return res;
+}
+
+void EobCoreEngine::printWarning(const char *str) {
_txt->printMessage(str);
snd_playSoundEffect(79);
}
@@ -634,7 +658,9 @@ void EobCoreEngine::printNoEffectWarning() {
}
void EobCoreEngine::spellCallback_start_armor() {
-
+ _characters[_activeSpellCharId].effectsRemainder[0] = getCharacterMageLevel(_openBookChar) + 8;
+ if ((getDexterityArmorClassModifier(_characters[_activeSpellCharId].dexterityCur) + 6) >= _characters[_activeSpellCharId].armorClass)
+ printWarning(Common::String::format(_magicStrings6[0], _characters[_activeSpellCharId].name).c_str());
}
void EobCoreEngine::spellCallback_start_burningHands() {
@@ -649,7 +675,7 @@ void EobCoreEngine::spellCallback_start_burningHands() {
int cl = getCharacterMageLevel(_openBookChar);
int bl = calcNewBlockPosition(_currentBlock, _currentDirection);
- const int8 *pos = getMonsterBlockPositions(bl);
+ const int8 *pos = getMonstersOnBlockPositions(bl);
_preventMonsterFlash = true;
int numDest = (_flags.gameID == GI_EOB1) ? 2 : 6;
@@ -674,7 +700,7 @@ bool EobCoreEngine::spellCallback_end_detectMagic(EobFlyingObject*) {
}
void EobCoreEngine::spellCallback_start_magicMissile() {
- launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, 0, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_magicMissile(EobFlyingObject *fo) {
@@ -694,10 +720,11 @@ void EobCoreEngine::spellCallback_start_improvedIdentify() {
}
void EobCoreEngine::spellCallback_start_melfsAcidArrow() {
- launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, 1, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_melfsAcidArrow(EobFlyingObject *fo) {
+ assert(fo);
return magicObjectDamageHit(fo, 2, 4, 0, getCharacterMageLevel(fo->attackerId) / 3);
}
@@ -706,7 +733,7 @@ void EobCoreEngine::spellCallback_start_dispelMagic() {
}
void EobCoreEngine::spellCallback_start_fireball() {
- launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, 2, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
@@ -714,7 +741,7 @@ bool EobCoreEngine::spellCallback_end_fireball(EobFlyingObject *fo) {
}
void EobCoreEngine::spellCallback_start_flameArrow() {
- launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
@@ -722,7 +749,7 @@ bool EobCoreEngine::spellCallback_end_flameArrow(EobFlyingObject *fo) {
}
void EobCoreEngine::spellCallback_start_holdPerson() {
- launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 4 : 3, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
@@ -751,7 +778,7 @@ bool EobCoreEngine::spellCallback_end_holdPerson(EobFlyingObject *fo) {
}
void EobCoreEngine::spellCallback_start_lightningBolt() {
- launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 5 : 4, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_lightningBolt(EobFlyingObject *fo) {
@@ -776,7 +803,7 @@ void EobCoreEngine::spellCallback_start_fear() {
}
void EobCoreEngine::spellCallback_start_iceStorm() {
- launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 6 : 5, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
@@ -794,15 +821,32 @@ bool EobCoreEngine::spellCallback_end_iceStorm(EobFlyingObject *fo) {
}
void EobCoreEngine::spellCallback_start_removeCurse() {
-
+ for (int i = 0; i < 27; i++) {
+ Item itm = _characters[_activeSpellCharId].inventory[i];
+ if (itm && (_items[itm].flags & 0x20) && !isMagicWeapon(itm))
+ _items[itm].flags = (_items[itm].flags & ~0x20) | 0x40;
+ }
}
void EobCoreEngine::spellCallback_start_coneOfCold() {
+ static const int8 *dirTables[] = { _coneOfColdDest1, _coneOfColdDest2, _coneOfColdDest3, _coneOfColdDest4 };
+
+ int cl = getCharacterMageLevel(_openBookChar);
+ //drawConeOfColdEffect(150, 50, 10, 1, 100, _coneOfColdGfxTbl);
+
+ const int8 *tbl = dirTables[_currentDirection];
+ _preventMonsterFlash = true;
+
+ for (int i = 0; i < 7; i++) {
+ for (const int16 *m = findBlockMonsters((_currentBlock + tbl[i]) & 0x3ff, 4, _currentDirection, 1, 1); *m != -1; m++)
+ calcAndInflictMonsterDamage(&_monsters[*m], cl, 4, cl, 0x41, 5, 0);
+ }
+ updateAllMonsterShapes();
}
void EobCoreEngine::spellCallback_start_holdMonster() {
-
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 7 : 6, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_holdMonster(EobFlyingObject *fo) {
@@ -817,12 +861,16 @@ void EobCoreEngine::spellCallback_start_wallOfForce() {
}
void EobCoreEngine::spellCallback_start_disintegrate() {
-
+ int d = findSingleSpellTarget(1);
+ if (d != -1)
+ magicObjectStatusHit(&_monsters[d], 4, true, 4);
+ memset(_visibleBlocks[13]->walls, 0, 4);
+ _sceneUpdateRequired = true;
}
void EobCoreEngine::spellCallback_start_fleshToStone() {
sparkEffectOffensive();
- int t = getClosestMonsterPos(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
+ int t = getClosestMonster(_openBookChar, calcNewBlockPosition(_currentBlock, _currentDirection));
if (t != -1)
magicObjectStatusHit(&_monsters[t], 5, true, 4);
else
@@ -830,8 +878,8 @@ void EobCoreEngine::spellCallback_start_fleshToStone() {
}
void EobCoreEngine::spellCallback_start_stoneToFlesh() {
- if (_characters[_activeSpellCaster].flags & 8)
- _characters[_activeSpellCaster].flags &= ~8;
+ if (_characters[_activeSpellCharId].flags & 8)
+ _characters[_activeSpellCharId].flags &= ~8;
else
printNoEffectWarning();
}
@@ -846,11 +894,18 @@ bool EobCoreEngine::spellCallback_end_trueSeeing(EobFlyingObject*) {
}
void EobCoreEngine::spellCallback_start_slayLiving() {
-
+ int d = findSingleSpellTarget(2);
+ if (d != -1)
+ if (!magicObjectStatusHit(&_monsters[d], 3, true, 4))
+ inflictMonsterDamage(&_monsters[d], rollDice(2, 8, 1), true);
}
void EobCoreEngine::spellCallback_start_powerWordStun() {
-
+ int d = findSingleSpellTarget(2);
+ if (d != -1) {
+ if (_monsters[d].hitPointsCur < 90)
+ magicObjectStatusHit(&_monsters[d], 5, true, 4);
+ }
}
void EobCoreEngine::spellCallback_start_causeLightWounds() {
@@ -858,7 +913,7 @@ void EobCoreEngine::spellCallback_start_causeLightWounds() {
}
void EobCoreEngine::spellCallback_start_cureLightWounds() {
- modifyCharacterHitpoints(_activeSpellCaster, rollDice(1, 8));
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(1, 8));
}
void EobCoreEngine::spellCallback_start_aid() {
@@ -904,7 +959,7 @@ void EobCoreEngine::spellCallback_start_causeSeriousWounds() {
}
void EobCoreEngine::spellCallback_start_cureSeriousWounds() {
- modifyCharacterHitpoints(_activeSpellCaster, rollDice(2, 8, 1));
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(2, 8, 1));
}
void EobCoreEngine::spellCallback_start_neutralizePoison() {
@@ -916,11 +971,11 @@ void EobCoreEngine::spellCallback_start_causeCriticalWounds() {
}
void EobCoreEngine::spellCallback_start_cureCriticalWounds() {
- modifyCharacterHitpoints(_activeSpellCaster, rollDice(3, 8, 3));
+ modifyCharacterHitpoints(_activeSpellCharId, rollDice(3, 8, 3));
}
void EobCoreEngine::spellCallback_start_flameStrike() {
- launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCasterPos, _currentDirection);
+ launchMagicObject(_openBookChar, _flags.gameID == GI_EOB1 ? 8 : 7, _currentBlock, _activeSpellCharacterPos, _currentDirection);
}
bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
@@ -928,7 +983,12 @@ bool EobCoreEngine::spellCallback_end_flameStrike(EobFlyingObject *fo) {
}
void EobCoreEngine::spellCallback_start_raiseDead() {
-
+ if (_characters[_activeSpellCharId].hitPointsCur == -10 || ((_characters[_activeSpellCharId].raceSex >> 1) == 1)) {
+ _characters[_activeSpellCharId].hitPointsCur = 1;
+ gui_drawCharPortraitWithStats(_activeSpellCharId);
+ } else {
+ printNoEffectWarning();
+ }
}
void EobCoreEngine::spellCallback_start_harm() {
@@ -936,15 +996,15 @@ void EobCoreEngine::spellCallback_start_harm() {
}
void EobCoreEngine::spellCallback_start_heal() {
- EobCharacter *c = &_characters[_activeSpellCaster];
+ EobCharacter *c = &_characters[_activeSpellCharId];
if (c->hitPointsMax <= c->hitPointsCur)
printWarning(_magicStrings4[0]);
else
- modifyCharacterHitpoints(_activeSpellCaster, c->hitPointsMax - c->hitPointsCur);
+ modifyCharacterHitpoints(_activeSpellCharId, c->hitPointsMax - c->hitPointsCur);
}
void EobCoreEngine::spellCallback_start_layOnHands() {
- modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1);
+ modifyCharacterHitpoints(_activeSpellCharId, _characters[_openBookChar].level[0] << 1);
}
void EobCoreEngine::spellCallback_start_turnUndead() {