diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp index a646bee5b1b..d5fc803f8f7 100644 --- a/devtools/create_kyradat/create_kyradat.cpp +++ b/devtools/create_kyradat/create_kyradat.cpp @@ -411,8 +411,8 @@ const ExtractFilename extractFilenames[] = { { kEob1DoorSwitchShapeDefs, kTypeRawData, false }, { kEob1DoorSwitchCoords, kTypeRawData, false }, { kEob1MonsterProperties, kTypeRawData, false }, - { kEob1MonsterDistAttType10, kTypeRawData, false }, - { kEob1MonsterDistAttSfx10, kTypeRawData, false }, + { kEob1EnemyMageSpellList, kTypeRawData, false }, + { kEob1EnemyMageSfx, kTypeRawData, false }, { kEob1MonsterDistAttType17, kTypeRawData, false }, { kEob1MonsterDistAttSfx17, kTypeRawData, false }, { kEob1TurnUndeadString, kTypeStringList, true }, @@ -1652,10 +1652,10 @@ const char *getIdString(const int id) { return "kEob1DoorSwitchCoords"; case kEob1MonsterProperties: return "kEob1MonsterProperties"; - case kEob1MonsterDistAttType10: - return "kEob1MonsterDistAttType10"; - case kEob1MonsterDistAttSfx10: - return "kEob1MonsterDistAttSfx10"; + case kEob1EnemyMageSpellList: + return "kEob1EnemyMageSpellList"; + case kEob1EnemyMageSfx: + return "kEob1EnemyMageSfx"; case kEob1MonsterDistAttType17: return "kEob1MonsterDistAttType17"; case kEob1MonsterDistAttSfx17: diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h index a7b53b4128f..75511b6a67f 100644 --- a/devtools/create_kyradat/create_kyradat.h +++ b/devtools/create_kyradat/create_kyradat.h @@ -412,8 +412,8 @@ enum kExtractID { kEob1DoorSwitchCoords, kEob1MonsterProperties, - kEob1MonsterDistAttType10, - kEob1MonsterDistAttSfx10, + kEob1EnemyMageSpellList, + kEob1EnemyMageSfx, kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, kEob1TurnUndeadString, diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp index 000c350f2ba..bfbab79ee8e 100644 --- a/devtools/create_kyradat/games.cpp +++ b/devtools/create_kyradat/games.cpp @@ -1059,8 +1059,8 @@ const int eob1FloppyNeed[] = { kEob1DoorSwitchShapeDefs, kEob1DoorSwitchCoords, kEob1MonsterProperties, - kEob1MonsterDistAttType10, - kEob1MonsterDistAttSfx10, + kEob1EnemyMageSpellList, + kEob1EnemyMageSfx, kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, kEob1TurnUndeadString, diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp index a92c09798bd..a30d248d28d 100644 --- a/devtools/create_kyradat/tables.cpp +++ b/devtools/create_kyradat/tables.cpp @@ -2388,12 +2388,12 @@ const ExtractEntrySearchData kEob1MonsterPropertiesProvider[] = { EXTRACT_END_ENTRY }; -const ExtractEntrySearchData kEob1MonsterDistAttType10Provider[] = { +const ExtractEntrySearchData kEob1EnemyMageSpellListProvider[] = { { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000000F, { { 0x01, 0x1B, 0x9C, 0x51, 0xC9, 0xA2, 0x10, 0xBB, 0xA7, 0x82, 0xD4, 0x91, 0x7E, 0x84, 0x54, 0x93 } } } }, EXTRACT_END_ENTRY }; -const ExtractEntrySearchData kEob1MonsterDistAttSfx10Provider[] = { +const ExtractEntrySearchData kEob1EnemyMageSfxProvider[] = { { UNK_LANG, kPlatformPC, { 0x0000000A, 0x0000029B, { { 0xA2, 0x9F, 0x2E, 0xDE, 0x15, 0x23, 0x78, 0xDD, 0x26, 0x98, 0x6E, 0xA3, 0x77, 0xEA, 0xB5, 0x80 } } } }, EXTRACT_END_ENTRY }; @@ -3870,8 +3870,8 @@ const ExtractEntry extractProviders[] = { { kEob1DoorSwitchCoords, kEob1DoorSwitchCoordsProvider }, { kEob1MonsterProperties, kEob1MonsterPropertiesProvider }, - { kEob1MonsterDistAttType10, kEob1MonsterDistAttType10Provider }, - { kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider }, + { kEob1EnemyMageSpellList, kEob1EnemyMageSpellListProvider }, + { kEob1EnemyMageSfx, kEob1EnemyMageSfxProvider }, { kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider }, { kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider }, { kEob1TurnUndeadString, kEob1TurnUndeadStringProvider }, diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp index 762b2d1bd10..f48e8502746 100644 --- a/engines/kyra/eob1.cpp +++ b/engines/kyra/eob1.cpp @@ -438,9 +438,9 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal case 11: v = ((wall < 30) ? (wall - _dscDoorScaleOffs[wall]) * _dscDoorScaleMult5[mDim] : _dscDoorScaleMult6[mDim]) * -1; x -= (shp[2] << 2); - y = _dscDoorY3[mDim] + v; + y = _dscDoorY4[mDim] + v; drawBlockObject(0, 2, shp, x, y + v, 5); - v >>= 4; + v = (v >> 3) + (v >> 2); y = _dscDoorY5[mDim]; drawBlockObject(0, 2, _doorShapes[shapeIndex + 3], x, y - v, 5); if (_wllShapeMap[wall] == -1) @@ -505,6 +505,7 @@ void EobEngine::turnUndeadAutoHit() { bool EobEngine::checkPartyStatusExtra() { _screen->copyPage(0, 10); + int cd = _screen->curDimIndex(); gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1); _txt->setupField(9, false); _txt->printMessage(_menuStringsDefeat[0]); @@ -515,6 +516,8 @@ bool EobEngine::checkPartyStatusExtra() { } _screen->copyPage(10, 0); _eventList.clear(); + _screen->setScreenDim(cd); + _txt->removePageBreakFlag(); return true; } diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp index 3e1001d2bdc..5fc50f667b7 100644 --- a/engines/kyra/eobcommon.cpp +++ b/engines/kyra/eobcommon.cpp @@ -55,8 +55,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _tempIconShape = 0; _monsterDustStrings = 0; - _monsterDistAttType10 = 0; - _monsterDistAttSfx10 = 0; + _enemyMageSpellList = 0; + _enemyMageSfx = 0; _monsterDistAttType17 = 0; _monsterDistAttSfx17 = 0; @@ -130,8 +130,8 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _openBookType = _openBookTypeBackup = 0; _openBookSpellList = 0; _openBookAvailableSpells = 0; - _activeSpellCaster = 0; - _activeSpellCasterPos = 0; + _activeSpellCharId = 0; + _activeSpellCharacterPos = 0; _activeSpell = 0; _returnAfterSpellCallback = false; _spells = 0; @@ -473,7 +473,7 @@ bool EobCoreEngine::checkPartyStatus(bool handleDeath) { if (!handleDeath) return true; - + gui_drawAllCharPortraitsWithStats(); if (checkPartyStatusExtra()) { @@ -1550,13 +1550,14 @@ void EobCoreEngine::seq_portal() { } else { s--; _screen->copyRegion((s % 5) << 6, s / 5 * 77, 56, 27, 64, 77, 2, 0, Screen::CR_NO_P_CHECK); - if (s == 0) - snd_playSoundEffect(31); - else if (s == 3) { - if (*(pos - 2) == 3) - snd_playSoundEffect(90); - } - } + } + + if (s == 1) + snd_playSoundEffect(31); + else if (s == 3) { + if (*(pos - 2) == 3) + snd_playSoundEffect(90); + } _screen->updateScreen(); delay(2 * _tickLength); @@ -1646,7 +1647,7 @@ int EobCoreEngine::closeDistanceAttack(int charIndex, Item item) { return -3; uint16 d = calcNewBlockPosition(_currentBlock, _currentDirection); - int r = getClosestMonsterPos(charIndex, d); + int r = getClosestMonster(charIndex, d); if (r == -1) { uint8 w = _specialWallTypes[_levelBlockProperties[d].walls[_sceneDrawVarDown]]; diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h index 33b4a2fc2d6..1b701cfeb30 100644 --- a/engines/kyra/eobcommon.h +++ b/engines/kyra/eobcommon.h @@ -486,8 +486,8 @@ protected: int countSpecificMonsters(int type); void updateAttackingMonsterFlags(); - const int8 *getMonsterBlockPositions(uint16 block); - int getClosestMonsterPos(int charIndex, int block); + const int8 *getMonstersOnBlockPositions(uint16 block); + int getClosestMonster(int charIndex, int block); bool blockHasMonsters(uint16 block); bool isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, int checkPos4); @@ -547,8 +547,8 @@ protected: const uint8 *_findBlockMonstersTable; const char *const *_monsterDustStrings; - const uint8 *_monsterDistAttType10; - const uint8 *_monsterDistAttSfx10; + const uint8 *_enemyMageSpellList; + const uint8 *_enemyMageSfx; const uint8 *_monsterDistAttType17; const uint8 *_monsterDistAttSfx17; const char *const *_monsterSpecAttStrings; @@ -912,7 +912,9 @@ protected: bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod); bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel); - void printWarning(const char* str); + int findSingleSpellTarget(int dist); + + void printWarning(const char *str); void printNoEffectWarning(); void spellCallback_start_empty() {} @@ -993,8 +995,8 @@ protected: uint8 _openBookCasterLevel; const char *const *_openBookSpellList; int8 *_openBookAvailableSpells; - uint8 _activeSpellCaster; - uint8 _activeSpellCasterPos; + uint8 _activeSpellCharId; + uint8 _activeSpellCharacterPos; uint8 _activeSpell; bool _returnAfterSpellCallback; @@ -1046,6 +1048,11 @@ protected: const uint8 *_magicFlightObjectProperties; const uint8 *_turnUndeadEffect; const uint8 *_burningHandsDest; + const int8 *_coneOfColdDest1; + const int8 *_coneOfColdDest2; + const int8 *_coneOfColdDest3; + const int8 *_coneOfColdDest4; + const int8 *_coneOfColdGfxTbl; // Menu EobMenuDef *_menuDefs; diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp index 04b863c325a..393bbab4a88 100644 --- a/engines/kyra/gui_eob.cpp +++ b/engines/kyra/gui_eob.cpp @@ -524,7 +524,7 @@ void EobCoreEngine::gui_drawCharPortraitStatusFrame(int index) { EobCharacter *c = &_characters[index]; bool redGreen = ((c->effectFlags & 0x4818) || (_partyEffectFlags & 0x20000) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false; - bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420) || c->effectsRemainder[0] || c->effectsRemainder[1]) ? true : false; + bool yellow = ((c->effectFlags & 0x13000) || (_partyEffectFlags & 0x8420)) ? true : false; if (redGreen || yellow) { if (redGreen && !yellow) { @@ -1108,9 +1108,9 @@ int EobCoreEngine::clickedSpellbookList(Button *button) { } int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) { - _activeSpellCaster = button->arg & 0xff; + _activeSpellCharId = button->arg & 0xff; - if (_activeSpellCaster == 0xff) { + if (_activeSpellCharId == 0xff) { printWarning(_magicStrings3[_flags.gameID == GI_EOB1 ? 2 : 1]); if (_castScrollSlot) { gui_updateSlotAfterScrollUse(); @@ -1119,7 +1119,7 @@ int EobCoreEngine::clickedCastSpellOnCharacter(Button *button) { gui_drawSpellbook(); } } else { - if (_characters[_activeSpellCaster].flags & 1) + if (_characters[_activeSpellCharId].flags & 1) startSpell(_activeSpell); } diff --git a/engines/kyra/items_eob.cpp b/engines/kyra/items_eob.cpp index b48c3934c80..e2d28703a89 100644 --- a/engines/kyra/items_eob.cpp +++ b/engines/kyra/items_eob.cpp @@ -256,22 +256,19 @@ bool EobCoreEngine::deletePartyItems(int16 itemType, int16 itemValue) { continue; EobCharacter *c = &_characters[i]; - int slot = checkInventoryForItem(i, itemType, itemValue); + for (int slot = checkInventoryForItem(i, itemType, itemValue); slot != -1; slot = checkInventoryForItem(i, itemType, itemValue)) { + int itm = c->inventory[slot]; + _items[itm].block = -1; + c->inventory[slot] = 0; + res = true; - if (slot == -1) - continue; + if (!_dialogueField) { + if (_currentControlMode == 0 && slot < 2 && i < 5) + gui_drawWeaponSlot(i, slot); - int itm = c->inventory[slot]; - _items[itm].block = -1; - c->inventory[slot] = 0; - res = true; - - if (!_dialogueField) { - if (_currentControlMode == 0 && slot < 2 && i < 5) - gui_drawWeaponSlot(i, slot); - - if (_currentControlMode == 1 && i == _updateCharNum) - gui_drawInventoryItem(slot, 1, 0); + if (_currentControlMode == 1 && i == _updateCharNum) + gui_drawInventoryItem(slot, 1, 0); + } } } @@ -379,9 +376,9 @@ void EobCoreEngine::printFullItemName(Item item) { if (v == 0) tmpString = nameUnid; else if (v < 0) - tmpString = Common::String::format(_cursedString[0], v, nameUnid); + tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_cursedString[0], nameUnid, v) : Common::String::format(_cursedString[0], v, nameUnid); else - tmpString = Common::String::format(_enchantedString[0], v, nameUnid); + tmpString = _flags.gameID == GI_EOB1 ? Common::String::format(_enchantedString[0], nameUnid, v) : Common::String::format(_enchantedString[0], v, nameUnid); break; case 9: diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp index 12d25245451..d06e15b36f0 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() { diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index f80fdd91c27..a54ae6cd9a6 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -485,8 +485,8 @@ enum KyraResources { kEob1DoorSwitchCoords, kEob1MonsterProperties, - kEob1MonsterDistAttType10, - kEob1MonsterDistAttSfx10, + kEob1EnemyMageSpellList, + kEob1EnemyMageSfx, kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp index 88f0c1c64ee..05eea820bb5 100644 --- a/engines/kyra/saveload_eob.cpp +++ b/engines/kyra/saveload_eob.cpp @@ -241,8 +241,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) { _openBookType = in.readByte(); _openBookCharBackup = in.readByte(); _openBookTypeBackup = in.readByte(); - _activeSpellCaster = in.readByte(); - _activeSpellCasterPos = in.readByte(); + _activeSpellCharId = in.readByte(); + _activeSpellCharacterPos = in.readByte(); _activeSpell = in.readByte(); _returnAfterSpellCallback = in.readByte() ? true : false; @@ -465,8 +465,8 @@ Common::Error EobCoreEngine::saveGameStateIntern(int slot, const char *saveName, out->writeByte(_openBookType); out->writeByte(_openBookCharBackup); out->writeByte(_openBookTypeBackup); - out->writeByte(_activeSpellCaster); - out->writeByte(_activeSpellCasterPos); + out->writeByte(_activeSpellCharId); + out->writeByte(_activeSpellCharacterPos); out->writeByte(_activeSpell); out->writeByte(_returnAfterSpellCallback ? 1 : 0); diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp index 802ba4e4c86..945ccaca178 100644 --- a/engines/kyra/sprites_eob.cpp +++ b/engines/kyra/sprites_eob.cpp @@ -54,8 +54,8 @@ int LolEobBaseEngine::getBlockDistance(uint16 block1, uint16 block2) { namespace Kyra { void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) { - Common::String s = _flags.gameID == GI_EOB1 && !scumm_stricmp(filename, "spider") ? "spider1" : filename; - if (GI_EOB1 && !scumm_stricmp(filename, "rust")) + Common::String s = filename; + if (GI_EOB1 && !scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn")) s += "1"; _screen->loadShapeSetBitmap(s.c_str(), 3, 3); @@ -147,7 +147,7 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level) uint32 ct = _system->getMillis(); for (int i = 0x20; i < 0x24; i++) { int32 del = _timer->getDelay(i); - _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) : ct + del); + _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength); } if (_hasTempDataFlags & (1 << (level - 1))) @@ -178,7 +178,7 @@ void EobCoreEngine::initMonster(int index, int unit, uint16 block, int pos, int if (index & 1) unit++; - m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 0; + m->stepsTillRemoteAttack = _flags.gameID == GI_EOB2 ? rollDice(1, 3, 0) : 5; m->type = type; m->numRemoteAttacks = p->numRemoteAttacks; m->curRemoteWeapon = 0; @@ -278,7 +278,7 @@ void EobCoreEngine::updateAttackingMonsterFlags() { _inf->setFlag(0x800); } -const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) { +const int8 *EobCoreEngine::getMonstersOnBlockPositions(uint16 block) { memset(_monsterBlockPosArray, -1, sizeof(_monsterBlockPosArray)); for (int8 i = 0; i < 30; i++) { if (_monsters[i].block != block) @@ -289,8 +289,8 @@ const int8 *EobCoreEngine::getMonsterBlockPositions(uint16 block) { return _monsterBlockPosArray; } -int EobCoreEngine::getClosestMonsterPos(int charIndex, int block) { - const int8 *pos = getMonsterBlockPositions(block); +int EobCoreEngine::getClosestMonster(int charIndex, int block) { + const int8 *pos = getMonstersOnBlockPositions(block); if (pos[4] != -1) return pos[4]; @@ -915,7 +915,7 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) { if (!m->numRemoteAttacks || ((_flags.gameID == GI_EOB1) && !(p->capsFlags & 0x40))) return false; - if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack == 5) || (_flags.gameID == GI_EOB2 && rollDice(1, 3) > m->stepsTillRemoteAttack)) { + if ((_flags.gameID == GI_EOB1 && m->stepsTillRemoteAttack < 5) || (_flags.gameID == GI_EOB2 && (rollDice(1, 3) > m->stepsTillRemoteAttack))) { m->stepsTillRemoteAttack++; return false; } @@ -940,8 +940,8 @@ bool EobCoreEngine::updateMonsterTryDistanceAttack(EobMonsterInPlay *m) { snd_processEnvironmentalSoundEffect(31, m->block); break; case 10: - launchMagicObject(-1, _monsterDistAttType10[m->numRemoteAttacks], m->block, m->pos, m->dir); - snd_processEnvironmentalSoundEffect(_monsterDistAttSfx10[m->numRemoteAttacks], m->block); + launchMagicObject(-1, _enemyMageSpellList[m->numRemoteAttacks], m->block, m->pos, m->dir); + snd_processEnvironmentalSoundEffect(_enemyMageSfx[m->numRemoteAttacks], m->block); break; case 11: itm = duplicateItem(60); diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp index f07cd1186f3..f30833cc083 100644 --- a/engines/kyra/staticres_eob.cpp +++ b/engines/kyra/staticres_eob.cpp @@ -1070,8 +1070,8 @@ void EobEngine::initStaticResource() { _dscDoorY7 = _staticres->loadRawData(kEobBaseDscDoorY7, temp); _dscDoorCoordsExt = (const int16*)_staticres->loadRawDataBe16(kEobBaseDscDoorCoordsExt, temp); - _monsterDistAttType10 = _staticres->loadRawData(kEob1MonsterDistAttType10, temp); - _monsterDistAttSfx10 = _staticres->loadRawData(kEob1MonsterDistAttSfx10, temp); + _enemyMageSpellList = _staticres->loadRawData(kEob1EnemyMageSpellList, temp); + _enemyMageSfx = _staticres->loadRawData(kEob1EnemyMageSfx, temp); _monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp); _monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp); diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp index ba4d6a24756..20a05f9ee6b 100644 --- a/engines/kyra/timer_eob.cpp +++ b/engines/kyra/timer_eob.cpp @@ -203,7 +203,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) { for (int ii = 0; ii < 10; ii++) { if (c->timers[ii] > ct) { uint32 chrt = c->timers[ii] - ct; - c->timers[ii] = chrt > millis ? chrt - millis : ct; + c->timers[ii] = chrt > millis ? ct + chrt - millis : ct; } } } @@ -214,7 +214,7 @@ void EobCoreEngine::advanceTimers(uint32 millis) { for (int i = 0; i < _scriptTimersCount; i++) { if (_scriptTimers[i].next > ct) { uint32 chrt = _scriptTimers[i].next - ct; - _scriptTimers[i].next = chrt > millis ? chrt - millis : ct; + _scriptTimers[i].next = chrt > millis ? ct + chrt - millis : ct; } } } @@ -331,7 +331,7 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) { case 9: if (c->flags & 4) { _txt->printMessage(_characterStatusStrings9[0], -1, c->name); - c->flags &= 0xfb; + c->flags &= ~4; gui_drawCharPortraitWithStats(charIndex); } break;