diff options
-rw-r--r-- | devtools/create_kyradat/create_kyradat.cpp | 6 | ||||
-rw-r--r-- | devtools/create_kyradat/create_kyradat.h | 2 | ||||
-rw-r--r-- | devtools/create_kyradat/games.cpp | 5 | ||||
-rw-r--r-- | devtools/create_kyradat/tables.cpp | 19 | ||||
-rw-r--r-- | dists/engine-data/kyra.dat | bin | 458387 -> 458977 bytes | |||
-rw-r--r-- | engines/kyra/eob1.cpp | 51 | ||||
-rw-r--r-- | engines/kyra/eob1.h | 6 | ||||
-rw-r--r-- | engines/kyra/eob2.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/eobcommon.cpp | 18 | ||||
-rw-r--r-- | engines/kyra/eobcommon.h | 11 | ||||
-rw-r--r-- | engines/kyra/gui_eob.cpp | 15 | ||||
-rw-r--r-- | engines/kyra/magic_eob.cpp | 46 | ||||
-rw-r--r-- | engines/kyra/resource.h | 3 | ||||
-rw-r--r-- | engines/kyra/saveload_eob.cpp | 7 | ||||
-rw-r--r-- | engines/kyra/scene_eob.cpp | 6 | ||||
-rw-r--r-- | engines/kyra/script_eob.cpp | 4 | ||||
-rw-r--r-- | engines/kyra/sprites_eob.cpp | 15 | ||||
-rw-r--r-- | engines/kyra/staticres_eob.cpp | 3 | ||||
-rw-r--r-- | engines/kyra/text_eob.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/timer_eob.cpp | 5 |
20 files changed, 189 insertions, 37 deletions
diff --git a/devtools/create_kyradat/create_kyradat.cpp b/devtools/create_kyradat/create_kyradat.cpp index 9f749f0dfd..276564bc64 100644 --- a/devtools/create_kyradat/create_kyradat.cpp +++ b/devtools/create_kyradat/create_kyradat.cpp @@ -395,6 +395,7 @@ const ExtractFilename extractFilenames[] = { { kEobBaseSparkOfY, kTypeRawData, false }, { kEobBaseSpellProperties, kTypeRawData, false }, { kEobBaseMagicFlightProps, kTypeRawData, false }, + { kEobBaseTurnUndeadEffect, kTypeRawData, false }, // EYE OF THE BEHOLDER I { kEob1MainMenuStrings, kTypeStringList, true }, @@ -406,6 +407,7 @@ const ExtractFilename extractFilenames[] = { { kEob1MonsterDistAttSfx10, kTypeRawData, false }, { kEob1MonsterDistAttType17, kTypeRawData, false }, { kEob1MonsterDistAttSfx17, kTypeRawData, false }, + { kEob1TurnUndeadString, kTypeStringList, true }, // EYE OF THE BEHOLDER II { kEob2MainMenuStrings, kTypeStringList, true }, @@ -1602,6 +1604,8 @@ const char *getIdString(const int id) { return "kEobBaseSpellProperties"; case kEobBaseMagicFlightProps: return "kEobBaseMagicFlightProps"; + case kEobBaseTurnUndeadEffect: + return "kEobBaseTurnUndeadEffect"; case kEob1MainMenuStrings: return "kEob1MainMenuStrings"; case kEob1DoorShapeDefs: @@ -1618,6 +1622,8 @@ const char *getIdString(const int id) { return "kEob1MonsterDistAttType17"; case kEob1MonsterDistAttSfx17: return "kEob1MonsterDistAttSfx17"; + case kEob1TurnUndeadString: + return "kEob1TurnUndeadString"; case kEob2MainMenuStrings: return "kEob2MainMenuStrings"; case kEob2IntroStrings: diff --git a/devtools/create_kyradat/create_kyradat.h b/devtools/create_kyradat/create_kyradat.h index 598050d80c..a587147974 100644 --- a/devtools/create_kyradat/create_kyradat.h +++ b/devtools/create_kyradat/create_kyradat.h @@ -396,6 +396,7 @@ enum kExtractID { kEobBaseSpellProperties, kEobBaseMagicFlightProps, + kEobBaseTurnUndeadEffect, kEob1MainMenuStrings, kEob1DoorShapeDefs, @@ -407,6 +408,7 @@ enum kExtractID { kEob1MonsterDistAttSfx10, kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, + kEob1TurnUndeadString, kEob2MainMenuStrings, kEob2IntroStrings, diff --git a/devtools/create_kyradat/games.cpp b/devtools/create_kyradat/games.cpp index 0496acc4b1..4ab12028c2 100644 --- a/devtools/create_kyradat/games.cpp +++ b/devtools/create_kyradat/games.cpp @@ -1063,6 +1063,7 @@ const int eob1FloppyNeed[] = { kEob1MonsterDistAttSfx10, kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, + kEob1TurnUndeadString, kEobBasePryDoorStrings, kEobBaseWarningStrings, @@ -1077,6 +1078,8 @@ const int eob1FloppyNeed[] = { kEobBaseMagicObjectStrings, kEobBaseMagicObject5String, kEobBasePatternSuffix, + kEobBasePatternGrFix1, + kEobBasePatternGrFix2, kEobBaseValidateArmorString, kEobBaseValidateNoDropString, kEobBasePotionStrings, @@ -1169,6 +1172,7 @@ const int eob1FloppyNeed[] = { kEobBaseSpellProperties, kEobBaseMagicFlightProps, + kEobBaseTurnUndeadEffect, kLolEobCommonDscDoorShapeIndex, kEobBaseWllFlagPreset, @@ -1382,6 +1386,7 @@ const int eob2FloppyNeed[] = { kEobBaseSpellProperties, kEobBaseMagicFlightProps, + kEobBaseTurnUndeadEffect, kLolEobCommonDscDoorShapeIndex, kEobBaseWllFlagPreset, diff --git a/devtools/create_kyradat/tables.cpp b/devtools/create_kyradat/tables.cpp index c45b3d4c26..46239c2bee 100644 --- a/devtools/create_kyradat/tables.cpp +++ b/devtools/create_kyradat/tables.cpp @@ -2089,8 +2089,7 @@ const ExtractEntrySearchData kEobBaseSlotValidationFlagsProvider[] = { }; const ExtractEntrySearchData kEobBaseProjectileWeaponTypesProvider[] = { - { UNK_LANG, kPlatformPC, { 0x0000000D, 0x0000063E, { { 0xA6, 0x75, 0x6C, 0x39, 0x96, 0xCB, 0xA7, 0xC2, 0x31, 0xE0, 0x2A, 0x75, 0x30, 0x96, 0x58, 0x05 } } } }, // EOB 1 - { UNK_LANG, kPlatformPC, { 0x0000000C, 0x0000063E, { { 0x3E, 0x99, 0x6D, 0xE4, 0x6B, 0xC8, 0x49, 0x1B, 0x17, 0xD2, 0xBE, 0x9B, 0xE0, 0xCD, 0xA1, 0xC2 } } } }, // EOB 1 + { UNK_LANG, kPlatformPC, { 0x00000008, 0x0000061C, { { 0x05, 0x55, 0xA6, 0xD1, 0x3C, 0x12, 0x84, 0xDA, 0xA9, 0x33, 0xCF, 0x07, 0x05, 0x2A, 0xB2, 0x29 } } } }, // EOB 1 { UNK_LANG, kPlatformPC, { 0x0000000F, 0x00000829, { { 0x9F, 0x6A, 0x13, 0x8A, 0xA7, 0x40, 0xE8, 0x40, 0x2E, 0x87, 0x49, 0x6B, 0x67, 0xED, 0xE8, 0xCE } } } }, // EOB 2 EXTRACT_END_ENTRY }; @@ -2310,6 +2309,12 @@ const ExtractEntrySearchData kEobBaseMagicFlightPropsProvider[] = { EXTRACT_END_ENTRY }; +const ExtractEntrySearchData kEobBaseTurnUndeadEffectProvider[] = { + { UNK_LANG, kPlatformUnknown, { 0x0000008C, 0x00002E8B, { { 0x96, 0x15, 0x61, 0x12, 0x43, 0xCF, 0x3A, 0x84, 0x1A, 0x89, 0xB5, 0x32, 0x0D, 0xB3, 0x20, 0x67 } } } }, + + EXTRACT_END_ENTRY +}; + const ExtractEntrySearchData kEob1MainMenuStringsProvider[] = { { EN_ANY, kPlatformUnknown, { 0x00000037, 0x00000D79, { { 0x1D, 0x72, 0x7F, 0x8F, 0xEB, 0x4A, 0xBF, 0x82, 0xB7, 0xB5, 0x9D, 0xB0, 0x7B, 0xDA, 0xEC, 0xEE } } } }, { DE_DEU, kPlatformUnknown, { 0x00000034, 0x00000C6F, { { 0xF2, 0x5F, 0xBE, 0xFB, 0x27, 0x1C, 0x91, 0x33, 0x25, 0x09, 0xC1, 0xA0, 0x27, 0x89, 0xD7, 0xD5 } } } }, @@ -2356,6 +2361,14 @@ const ExtractEntrySearchData kEob1MonsterDistAttSfx17Provider[] = { EXTRACT_END_ENTRY }; +const ExtractEntrySearchData kEob1TurnUndeadStringProvider[] = { + { EN_ANY, kPlatformUnknown, { 0x00000027, 0x00000BF2, { { 0x43, 0x0A, 0x1E, 0xEE, 0x84, 0xD6, 0xD6, 0x87, 0x20, 0x9F, 0x15, 0x22, 0x9B, 0x65, 0x24, 0xDB } } } }, + { DE_DEU, kPlatformUnknown, { 0x00000030, 0x00000F48, { { 0xDA, 0x59, 0xEC, 0xC1, 0x9B, 0xCF, 0x90, 0x4A, 0x93, 0x3E, 0xE5, 0x26, 0x20, 0x8B, 0x74, 0x92 } } } }, + + EXTRACT_END_ENTRY +}; + + const ExtractEntrySearchData kEob2MainMenuStringsProvider[] = { { EN_ANY, kPlatformUnknown, { 0x0000005F, 0x000017BE, { { 0x77, 0x8A, 0x50, 0x9F, 0x42, 0xD8, 0x00, 0x05, 0x60, 0x2A, 0x80, 0x25, 0x00, 0xDC, 0x7C, 0x92 } } } }, { DE_DEU, kPlatformUnknown, { 0x0000005E, 0x000017F3, { { 0xD0, 0x93, 0x2E, 0x5F, 0x9D, 0xDB, 0xC4, 0xFB, 0x9E, 0x9F, 0x14, 0xD6, 0xB4, 0xBE, 0x3D, 0x0C } } } }, @@ -3698,6 +3711,7 @@ const ExtractEntry extractProviders[] = { { kEobBaseSpellProperties, kEobBaseSpellPropertiesProvider }, { kEobBaseMagicFlightProps, kEobBaseMagicFlightPropsProvider }, + { kEobBaseTurnUndeadEffect, kEobBaseTurnUndeadEffectProvider }, { kEob1MainMenuStrings, kEob1MainMenuStringsProvider }, { kEob1DoorShapeDefs, kEob1DoorShapeDefsProvider }, @@ -3709,6 +3723,7 @@ const ExtractEntry extractProviders[] = { { kEob1MonsterDistAttSfx10, kEob1MonsterDistAttSfx10Provider }, { kEob1MonsterDistAttType17, kEob1MonsterDistAttType17Provider }, { kEob1MonsterDistAttSfx17, kEob1MonsterDistAttSfx17Provider }, + { kEob1TurnUndeadString, kEob1TurnUndeadStringProvider }, { kEob2MainMenuStrings, kEob2MainMenuStringsProvider }, { kEob2IntroStrings, kEob2IntroStringsProvider }, diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex cd51c0b54c..2128a448b6 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp index a9051de833..d12283f140 100644 --- a/engines/kyra/eob1.cpp +++ b/engines/kyra/eob1.cpp @@ -83,7 +83,7 @@ void EobEngine::startupLoad() { } void EobEngine::npcSequence(int npcIndex) { - + error("EobEngine::npcSequence(): unimplemented"); } @@ -210,10 +210,54 @@ void EobEngine::drawDoorIntern(int type, int index, int x, int y, int w, int wal } } +void EobEngine::turnUndeadAuto() { + if (_currentLevel != 2 && _currentLevel != 7) + return; + + int oc = _openBookChar; + + for (int i = 0; i < 6; i++) { + if (!testCharacter(i, 0x0d)) + continue; + + EobCharacter *c = &_characters[i]; + + if (_itemTypes[_items[c->inventory[0]].type].extraProperties != 6 && _itemTypes[_items[c->inventory[1]].type].extraProperties != 6) + continue; + + int l = getCharacterLevelIndex(2, c->cClass); + if (l > -1) { + if (c->level[l] > _openBookCasterLevel) { + _openBookCasterLevel = c->level[l]; + _openBookChar = i; + } + } else { + l = getCharacterLevelIndex(4, c->cClass); + if (l > -1) { + if ((c->level[l] - 2) > _openBookCasterLevel) { + _openBookCasterLevel = (c->level[l] - 2); + _openBookChar = i; + } + } + } + } + + if (_openBookCasterLevel) + spellCallback_start_turnUndead(); + + _openBookChar = oc; + _openBookCasterLevel = 0; +} + +void EobEngine::turnUndeadAutoHit() { + _txt->printMessage(_turnUndeadString[0], -1, _characters[_openBookChar].name); + sparkEffectOffensive(); +} + bool EobEngine::checkPartyStatusExtra() { _screen->copyPage(0, 10); - gui_drawBox(0, 121, 319, 200, _color2_1, _color1_1, _bkgColor_1); - _screen->setScreenDim(9); + gui_drawBox(0, 121, 320, 80, _color1_1, _color2_1, _bkgColor_1); + _txt->setupField(9, false); _txt->printMessage(_menuStringsDefeat[0]); while (!shouldQuit()) { removeInputTop(); @@ -221,6 +265,7 @@ bool EobEngine::checkPartyStatusExtra() { break; } _screen->copyPage(10, 0); + _eventList.clear(); return true; } diff --git a/engines/kyra/eob1.h b/engines/kyra/eob1.h index 3460ac7591..8d41118e52 100644 --- a/engines/kyra/eob1.h +++ b/engines/kyra/eob1.h @@ -84,6 +84,12 @@ private: const uint8 *_doorSwitchShapeEncodeDefs; const uint8 *_doorSwitchCoords; + // Magic + void turnUndeadAuto(); + void turnUndeadAutoHit(); + + const char * const *_turnUndeadString; + // Misc bool checkPartyStatusExtra(); uint32 convertSpellFlagToEob2Format(uint32 flag, int ignoreInvisibility); diff --git a/engines/kyra/eob2.cpp b/engines/kyra/eob2.cpp index c3169b10bf..cd306863ba 100644 --- a/engines/kyra/eob2.cpp +++ b/engines/kyra/eob2.cpp @@ -338,7 +338,7 @@ void DarkMoonEngine::drawDoorIntern(int type, int, int x, int y, int w, int wall } void DarkMoonEngine::restParty_npc() { - + warning("DarkMoonEngine::restParty_npc(): implement!"); } bool DarkMoonEngine::restParty_extraAbortCondition() { diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp index 07c1f0760a..22c0519069 100644 --- a/engines/kyra/eobcommon.cpp +++ b/engines/kyra/eobcommon.cpp @@ -46,6 +46,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _playFinale = false; _runFlag = true; _configMouse = true; + _loading = false; _largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes = _wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0; @@ -82,7 +83,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _monsterOvl1 = _monsterOvl2 = 0; _monsters = 0; _dstMonsterIndex = 0; - _inflictMonsterDamageUnk = 0; + _preventMonsterFlash = false; _teleporterPulse = 0; @@ -124,7 +125,7 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _openBookSpellLevel = 0; _openBookSpellSelectedItem = 0; _openBookSpellListOffset = 0; - _openBookChar = _openBookCharBackup = 0; + _openBookChar = _openBookCharBackup = _openBookCasterLevel = 0; _openBookType = _openBookTypeBackup = 0; _openBookSpellList = 0; _openBookAvailableSpells = 0; @@ -415,7 +416,7 @@ void EobCoreEngine::writeSettings() { void EobCoreEngine::startupNew() { gui_setPlayFieldButtons(); _screen->_curPage = 0; - gui_drawPlayField(0); + gui_drawPlayField(false); _screen->_curPage = 0; gui_drawAllCharPortraitsWithStats(); drawScene(1); @@ -452,8 +453,7 @@ void EobCoreEngine::runLoop() { _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength); snd_processEnvironmentalSoundEffect(_flags.gameID == GI_EOB1 ? 30 : (rollDice(1, 2, -1) ? 27 : 28), _currentBlock + rollDice(1, 12, -1)); updateEnvironmentalSfx(0); - //TODO - //EOB1__level_2_7__turnUndead(); + turnUndeadAuto(); } } @@ -1540,7 +1540,11 @@ int EobCoreEngine::thrownAttack(int charIndex, int slotIndex, Item item) { int EobCoreEngine::projectileWeaponAttack(int charIndex, Item item) { int tp = _items[item].type; - int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 2 : tp]; + + if (_flags.gameID == GI_EOB1) + assert(tp >= 7); + + int t = _projectileWeaponAmmoTypes[_flags.gameID == GI_EOB1 ? tp - 7 : tp]; Item ammoItem = 0; if (t == 16) { @@ -1588,7 +1592,7 @@ void EobCoreEngine::inflictMonsterDamage(EobMonsterInPlay *m, int damage, bool g } else { if (checkSceneUpdateNeed(m->block)) { m->flags |= 2; - if (_inflictMonsterDamageUnk) + if (_preventMonsterFlash) return; flashMonsterShape(m); } diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h index 39919ca086..6463f839c8 100644 --- a/engines/kyra/eobcommon.h +++ b/engines/kyra/eobcommon.h @@ -406,6 +406,7 @@ protected: const EobCharacter *_npcPreset; bool _partyResting; + bool _loading; // Items void loadItemDefs(); @@ -634,7 +635,7 @@ protected: uint8 _scriptTimersMode; // Gui - void gui_drawPlayField(int pageNum); + void gui_drawPlayField(bool refresh); void gui_restorePlayField(); void gui_drawAllCharPortraitsWithStats(); void gui_drawCharPortraitWithStats(int index); @@ -858,7 +859,7 @@ protected: void explodeMonster(EobMonsterInPlay *m); int _dstMonsterIndex; - int _inflictMonsterDamageUnk; + bool _preventMonsterFlash; int16 _foundMonstersArray[5]; // magic @@ -867,6 +868,9 @@ protected: void usePotion(int charIndex, int weaponSlot); void useWand(int charIndex, int weaponSlot); + virtual void turnUndeadAuto() {}; + virtual void turnUndeadAutoHit() {}; + void castSpell(int spell, int weaponSlot); void removeCharacterEffect(int spell, int charIndex, int showWarning); void removeAllCharacterEffects(int charIndex); @@ -880,6 +884,7 @@ protected: bool magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int dcPips, int dcOffs, int level); bool magicObjectStatusHit(EobMonsterInPlay *m, int type, bool tryEvade, int mod); + bool turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel); void printWarning(const char* str); void printNoEffectWarning(); @@ -958,6 +963,7 @@ protected: uint8 _openBookType; uint8 _openBookCharBackup; uint8 _openBookTypeBackup; + uint8 _openBookCasterLevel; const char *const *_openBookSpellList; int8 *_openBookAvailableSpells; uint8 _activeSpellCaster; @@ -1011,6 +1017,7 @@ protected: const uint8 *_sparkEffectOfY; const uint8 *_magicFlightObjectProperties; + const uint8 *_turnUndeadEffect; // Menu EobMenuDef *_menuDefs; diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp index c7972299d1..ce5f3ea53f 100644 --- a/engines/kyra/gui_eob.cpp +++ b/engines/kyra/gui_eob.cpp @@ -149,17 +149,19 @@ Button *EobCoreEngine::gui_getButton(Button *buttonList, int index) { return 0; } -void EobCoreEngine::gui_drawPlayField(int pageNum) { +void EobCoreEngine::gui_drawPlayField(bool refresh) { _screen->loadEobCpsFileToPage("PLAYFLD", 0, 5, 3, 2); int cp = _screen->setCurPage(2); gui_drawCompass(true); - if (pageNum && !_sceneDrawPage2) + if (refresh && !_sceneDrawPage2) drawScene(0); _screen->setCurPage(cp); _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); + + if (!_loading) + _screen->updateScreen(); _screen->loadEobCpsFileToPage("INVENT", 0, 5, 3, 2); } @@ -167,7 +169,7 @@ void EobCoreEngine::gui_drawPlayField(int pageNum) { void EobCoreEngine::gui_restorePlayField() { loadVcnData(0, 0); _screen->_curPage = 0; - gui_drawPlayField(1); + gui_drawPlayField(true); gui_drawAllCharPortraitsWithStats(); } @@ -706,7 +708,8 @@ void EobCoreEngine::gui_drawSpellbook() { _screen->setCurPage(0); _screen->copyRegion(64, 121, 64, 121, 112, 56, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); + if (!_loading) + _screen->updateScreen(); } void EobCoreEngine::gui_drawSpellbookScrollArrow(int x, int y, int direction) { @@ -2245,7 +2248,7 @@ void GUI_Eob::runCampMenu() { if (cnt > 4) { _vm->dropCharacter(selectCharacterDialogue(53)); - _vm->gui_drawPlayField(0); + _vm->gui_drawPlayField(false); res = true; _screen->copyRegion(0, 120, 0, 0, 176, 24, 0, 14, Screen::CR_NO_P_CHECK); _screen->setFont(Screen::FID_6_FNT); diff --git a/engines/kyra/magic_eob.cpp b/engines/kyra/magic_eob.cpp index 593ef63544..f828625dbb 100644 --- a/engines/kyra/magic_eob.cpp +++ b/engines/kyra/magic_eob.cpp @@ -80,6 +80,9 @@ void EobCoreEngine::usePotion(int charIndex, int weaponSlot) { int val = deleteInventoryItem(charIndex, weaponSlot); snd_playSoundEffect(10); + if (_flags.gameID == GI_EOB1) + val--; + switch (val) { case 0: sparkEffectDefensive(charIndex); @@ -496,7 +499,7 @@ bool EobCoreEngine::magicObjectDamageHit(EobFlyingObject *fo, int dcTimes, int d level = 1; if ((_levelBlockProperties[fo->curBlock].flags & 7) && (fo->attackerId >= 0 || ignoreAttackerId)) { - _inflictMonsterDamageUnk = 1; + _preventMonsterFlash = true; for (const int16 *m = findBlockMonsters(fo->curBlock, fo->curPos, fo->direction, blockDamage, singleTargetCheckAdjacent); *m != -1; m++) { int dmg = rollDice(dcTimes, dcPips, dcOffs) * level; @@ -604,6 +607,23 @@ bool EobCoreEngine::magicObjectStatusHit(EobMonsterInPlay *m, int type, bool try return true; } +bool EobCoreEngine::turnUndeadHit(EobMonsterInPlay *m, int hitChance, int casterLevel) { + uint8 e = _turnUndeadEffect[_monsterProps[m->type].tuResist * 14 + MIN(casterLevel, 14)]; + + if (e == 0xff) { + calcAndInflictMonsterDamage(m, 0, 0, 500, 0x200, 5, 3); + } else if (hitChance < e) { + return false; + } else { + m->mode = 0; + m->flags |= 8; + m->spellStatusLeft = 40; + m->dir = (getNextMonsterDirection(m->block, _currentBlock) ^ 4) >> 1; + } + + return true; +} + void EobCoreEngine::printWarning(const char* str) { _txt->printMessage(str); snd_playSoundEffect(79); @@ -900,11 +920,33 @@ void EobCoreEngine::spellCallback_start_heal() { } void EobCoreEngine::spellCallback_start_layOnHands() { - + modifyCharacterHitpoints(_activeSpellCaster, _characters[_openBookChar].level[0] << 1); } void EobCoreEngine::spellCallback_start_turnUndead() { + uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection); + if (!(_levelBlockProperties[bl].flags & 7)) + return; + + int cl = _openBookCasterLevel ? _openBookCasterLevel : getCharacterClericPaladinLevel(_openBookChar); + int r = rollDice(1, 20); + bool hit = false; + + for (const int16 *m = findBlockMonsters(bl, 4, 4, 1, 1); *m != -1; m++) { + if ((_monsterProps[_monsters[*m].type].typeFlags & 4) && !(_monsters[*m].flags & 0x10)) { + _preventMonsterFlash = true; + _monsters[*m].flags |= 0x10; + hit |= turnUndeadHit(&_monsters[*m], r, cl); + } + } + + if (hit) { + turnUndeadAutoHit(); + snd_playSoundEffect(95); + updateAllMonsterShapes(); + } + _preventMonsterFlash = false; } bool EobCoreEngine::spellCallback_end_unk1Passive(EobFlyingObject *fo) { diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 02ee384f5c..5328aeff35 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -469,6 +469,7 @@ enum KyraResources { kEobBaseSpellProperties, kEobBaseMagicFlightProps, + kEobBaseTurnUndeadEffect, kEob1MainMenuStrings, kEob1DoorShapeDefs, @@ -481,6 +482,8 @@ enum KyraResources { kEob1MonsterDistAttType17, kEob1MonsterDistAttSfx17, + kEob1TurnUndeadString, + kEob2MainMenuStrings, kEob2IntroStrings, kEob2IntroCPSFiles, diff --git a/engines/kyra/saveload_eob.cpp b/engines/kyra/saveload_eob.cpp index 1fa26c26b1..43a230e590 100644 --- a/engines/kyra/saveload_eob.cpp +++ b/engines/kyra/saveload_eob.cpp @@ -149,6 +149,8 @@ Common::Error EobCoreEngine::loadGameState(int slot) { return Common::Error(Common::kReadingFailed); Common::SeekableSubReadStreamEndian in(saveFile, saveFile->pos(), saveFile->size(), !header.originalSave, DisposeAfterUse::YES); + _loading = true; + _screen->fadeToBlack(10); for (int i = 0; i < 6; i++) { EobCharacter *c = &_characters[i]; @@ -356,7 +358,7 @@ Common::Error EobCoreEngine::loadGameState(int slot) { _screen->setFont(Screen::FID_6_FNT); _screen->setCurPage(0); - gui_drawPlayField(0); + gui_drawPlayField(false); if (_currentControlMode) _screen->copyRegion(176, 0, 0, 0, 144, 168, 0, 5, Screen::CR_NO_P_CHECK); @@ -378,6 +380,9 @@ Common::Error EobCoreEngine::loadGameState(int slot) { while (!_screen->isMouseVisible()) _screen->showMouse(); + _loading = false; + _screen->fadeFromBlack(20); + return Common::kNoError; } diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp index 36584d462b..e6b3c26394 100644 --- a/engines/kyra/scene_eob.cpp +++ b/engines/kyra/scene_eob.cpp @@ -997,7 +997,9 @@ void EobCoreEngine::drawScene(int refresh) { if (refresh) _screen->fillRect(0, 0, 176, 120, 12); - _screen->setScreenPalette(_screen->getPalette(0)); + if (!_loading) + _screen->setScreenPalette(_screen->getPalette(0)); + _sceneDrawPage2 = 0; } @@ -1025,7 +1027,7 @@ void EobCoreEngine::drawScene(int refresh) { if (!_dialogueField && refresh && !_updateFlags) gui_drawCompass(false); - if (refresh && !_partyResting) + if (refresh && !_partyResting && !_loading) _screen->updateScreen(); if (_sceneDefaultUpdate) { diff --git a/engines/kyra/script_eob.cpp b/engines/kyra/script_eob.cpp index 9e18a14fb2..833413c69b 100644 --- a/engines/kyra/script_eob.cpp +++ b/engines/kyra/script_eob.cpp @@ -1397,12 +1397,12 @@ int EobInfProcessor::oeob_sequence(int8 *data) { case -2: // portal sequence - pos=pos; + error("EobInfProcessor::oeob_sequence(): unimplemented cmd -2"); break; case -1: // copy protection - pos=pos; + error("EobInfProcessor::oeob_sequence(): unimplemented cmd -1"); break; default: diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp index baa7a0bfda..0874de82e3 100644 --- a/engines/kyra/sprites_eob.cpp +++ b/engines/kyra/sprites_eob.cpp @@ -140,6 +140,12 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level) _timer->setCountdown(0x21 + (p << 1), v); } + 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); + } + if (_hasTempDataFlags & (1 << (level - 1))) return data + 420; @@ -302,12 +308,12 @@ bool EobCoreEngine::isMonsterOnPos(EobMonsterInPlay *m, uint16 block, int pos, i const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, int blockDamage, int singleTargetCheckAdjacent) { static const uint8 cpos4[] = { 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1 }; - int checkPos4 = (pos <= 4) ? cpos4[(dir << 2) + pos] : 1; + int include4 = (pos < 4) ? cpos4[(dir << 2) + pos] : 1; int16 *dst = _foundMonstersArray; if (blockDamage) { for (int i = 0; i < 30; i++) { - if (_monsters[i].block == block && (_monsters[i].pos != 4 || checkPos4)) + if (_monsters[i].block == block && (_monsters[i].pos != 4 || include4)) *dst++ = i; } @@ -338,7 +344,7 @@ const int16 *EobCoreEngine::findBlockMonsters(uint16 block, int pos, int dir, in } else { for (int i = 0; i < 30; i++) { - if (isMonsterOnPos(&_monsters[i], block, pos, checkPos4)) + if (isMonsterOnPos(&_monsters[i], block, pos, include4)) *dst++ = i; } } @@ -395,7 +401,7 @@ void EobCoreEngine::updateAllMonsterShapes() { } else { _sceneUpdateRequired = false; } - _inflictMonsterDamageUnk = 0; + _preventMonsterFlash = false; } void EobCoreEngine::drawBlockItems(int index) { @@ -684,7 +690,6 @@ void EobCoreEngine::drawTeleporter(int index) { void EobCoreEngine::updateMonsters(int unit) { for (int i = 0; i < 30; i++) { EobMonsterInPlay *m = &_monsters[i]; - if (m->unit == unit) { if (m->hitPointsCur <= 0 || m->flags & 0x20) continue; diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp index 19e2512da5..1cf78eef5c 100644 --- a/engines/kyra/staticres_eob.cpp +++ b/engines/kyra/staticres_eob.cpp @@ -528,6 +528,7 @@ void EobCoreEngine::initStaticResource() { _sparkEffectOfX = _staticres->loadRawData(kEobBaseSparkOfX, temp); _sparkEffectOfY = _staticres->loadRawData(kEobBaseSparkOfY, temp); _magicFlightObjectProperties = _staticres->loadRawData(kEobBaseMagicFlightProps, temp); + _turnUndeadEffect = _staticres->loadRawData(kEobBaseTurnUndeadEffect, temp); // Hard code the following strings, since EOB I doesn't have them in the original. // EOB I doesn't have load and save menus, because there is only one single @@ -1065,6 +1066,8 @@ void EobEngine::initStaticResource() { _monsterDistAttType17 = _staticres->loadRawData(kEob1MonsterDistAttType17, temp); _monsterDistAttSfx17 = _staticres->loadRawData(kEob1MonsterDistAttSfx17, temp); + _turnUndeadString = _staticres->loadStrings(kEob1TurnUndeadString, temp); + const uint8 *ps = _staticres->loadRawData(kEob1MonsterProperties, temp); temp /= 27; _monsterProps = new EobMonsterProperty[temp]; diff --git a/engines/kyra/text_eob.cpp b/engines/kyra/text_eob.cpp index c350666226..63d893d2cc 100644 --- a/engines/kyra/text_eob.cpp +++ b/engines/kyra/text_eob.cpp @@ -70,8 +70,6 @@ void TextDisplayer_Eob::setupField(int dim, bool mode) { clearCurDim(); else resetDimTextPositions(dim); - - //_textPageBreakFunc = textPageBreakMore; + 0x25 } void TextDisplayer_Eob::resetDimTextPositions(int dim) { diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp index 903dec2102..9e03bdebcf 100644 --- a/engines/kyra/timer_eob.cpp +++ b/engines/kyra/timer_eob.cpp @@ -101,6 +101,7 @@ void EobCoreEngine::setupTimers() { _timer->addTimer(0x21, TimerV2(timerProcessMonsters), 20, true); _timer->addTimer(0x22, TimerV2(timerProcessMonsters), 20, true); _timer->addTimer(0x23, TimerV2(timerProcessMonsters), 20, true); + _timer->setNextRun(0x20, _system->getMillis()); _timer->setNextRun(0x21, _system->getMillis() + 7 * _tickLength); _timer->setNextRun(0x22, _system->getMillis() + 14 * _tickLength); _timer->setNextRun(0x23, _system->getMillis() + 14 * _tickLength); @@ -274,7 +275,6 @@ void EobCoreEngine::timerProcessMonsters(int timerNum) { updateMonsters(timerNum & 0x0f); } - void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) { int charIndex = timerNum & 0x0f; EobCharacter *c = &_characters[charIndex]; @@ -346,7 +346,8 @@ void EobCoreEngine::timerSpecialCharacterUpdate(int timerNum) { case 12: c->effectFlags &= ~0x1000; - _txt->printMessage(_characterStatusStrings12[0], -1, c->name); + if (_characterStatusStrings12) + _txt->printMessage(_characterStatusStrings12[0], -1, c->name); break; default: |