diff options
-rw-r--r-- | engines/kyra/gui_lol.cpp | 3 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 203 | ||||
-rw-r--r-- | engines/kyra/lol.h | 12 | ||||
-rw-r--r-- | engines/kyra/saveload.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/saveload_lol.cpp | 19 | ||||
-rw-r--r-- | engines/kyra/scene_lol.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/screen_lol.cpp | 10 | ||||
-rw-r--r-- | engines/kyra/screen_lol.h | 2 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 43 | ||||
-rw-r--r-- | engines/kyra/sprites_lol.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/timer_lol.cpp | 2 |
11 files changed, 258 insertions, 50 deletions
diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index 0500411b98..bedc1a2d39 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -1048,7 +1048,7 @@ int LoLEngine::clickedAttackButton(Button *button) { int bl = calcNewBlockPosition(_currentBlock, _currentDirection); if (_levelBlockProperties[bl].flags & 0x10) { - attackWall(0, 0); + breakIceWall(0, 0); return 1; } @@ -1750,6 +1750,7 @@ int LoLEngine::clickedAutomap(Button *button) { if (!(_gameFlags[15] & 0x1000)) return 0; + removeInputTop(); displayAutomap(); gui_drawPlayField(); diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 724a9316bb..14b9cad751 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -123,7 +123,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _lastButtonShape = 0; _buttonPressTimer = 0; _selectedCharacter = 0; - _unkFlag = 0; + _gameFlags[36] = 0; _suspendScript = _sceneUpdateRequired = false; _scriptDirection = 0; _currentDirection = 0; @@ -226,7 +226,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _floatingCursorsEnabled = false; memset(_lvlTempData, 0, sizeof(_lvlTempData)); - _freezeStateFlags = 0; + _gameFlags[26] = 0; _mapOverlay = 0; _automapShapes = 0; @@ -868,7 +868,7 @@ void LoLEngine::runLoop() { enableSysTimer(2); bool _runFlag = true; - _unkFlag |= 0x800; + _gameFlags[36] |= 0x800; while (!shouldQuit() && _runFlag) { if (_nextScriptFunc) { @@ -2411,26 +2411,143 @@ void LoLEngine::processMagicIce(int charNum, int spellLevel) { gui_drawScene(0); _screen->copyPage(0, 12); - //uint8 pal2[768]; - //uint8 pal3[768]; + uint8 *tpal = new uint8[768]; + uint8 *swampCol = new uint8[768]; - if (_currentLevel == 11 && !(_freezeStateFlags & 4)) { - for (int i = 1; i < 384; i++) { + if (_currentLevel == 11 && !(_gameFlags[26] & 4)) { + uint8 *sc = _screen->_currentPalette; + uint8 *dc = _screen->getPalette(2); + for (int i = 1; i < 768; i++) + SWAP(sc[i], dc[i]); + _gameFlags[26] |= 4; + static const uint8 freezeTimes[] = { 20, 28, 40, 60 }; + setCharacterUpdateEvent(charNum, 8, freezeTimes[spellLevel], 1); + } - ///////// TODO + uint8 *sc = _res->fileData("swampice.col", 0); + memcpy(swampCol, sc, 384); + uint8 *s = _screen->getPalette(1); + for (int i = 384; i < 768; i++) + swampCol[i] = tpal[i] = s[i] & 0x3f; + + for (int i = 1; i < 128; i++) { + tpal[i * 3] = 0; + uint16 v = (s[i * 3] + s[i * 3 + 1] + s[i * 3 + 2]) / 3; + tpal[i * 3 + 1] = v; + tpal[i * 3 + 2] = v << 1; + + if (tpal[i * 3 + 2] > 0x3f) + tpal[i * 3 + 2] = 0x3f; + } + generateBrightnessPalette(tpal, tpal, _brightness, _lampEffect); + generateBrightnessPalette(swampCol, swampCol, _brightness, _lampEffect); + swampCol[0] = swampCol[1] = swampCol[2] = tpal[0] = tpal[1] = tpal[2] = 0; + + generateBrightnessPalette(_screen->_currentPalette, s, _brightness, _lampEffect); + + int sX = 112; + int sY = 0; + WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen); + + if (spellLevel == 0) { + sX = 0; + } if (spellLevel == 1 || spellLevel == 2) { + mov->open("snow.wsa", 1, 0); + if (!mov->opened()) + error("Ice: Unable to load snow.wsa"); + } if (spellLevel == 3) { + mov->open("ice.wsa", 1, 0); + if (!mov->opened()) + error("Ice: Unable to load ice.wsa"); + sX = 136; + sY = 12; + } - } + snd_playSoundEffect(71, -1); - _freezeStateFlags |= 4; - static const uint8 freezeTimes[] = { 20, 28, 40, 60 }; - setCharacterUpdateEvent(charNum, 8, freezeTimes[spellLevel], 1); + playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, tpal, 40, false); + + _screen->fadePaletteStep(s, tpal, _system->getMillis(), _tickLength); + if (mov->opened()) { + int r = true; + if (spellLevel > 2) { + _levelBlockProperties[calcNewBlockPosition(_currentBlock, _currentDirection)].flags |= 0x10; + snd_playSoundEffect(165, -1); + r = false; + }; + + playSpellAnimation(mov, 0, mov->frames(), 2, sX, sY, 0, 0, 0, 0, r); + mov->close(); + } + + delete mov; + static const uint8 snowDamage[] = { 10, 20, 30, 55 }; + static const uint8 iceDamageMax[] = {1, 2, 15, 20, 35}; + static const uint8 iceDamageMin[] = {10, 10, 3, 4, 4}; + static const uint8 iceDamageAdd[] = {5, 10, 30, 10, 10}; + + bool breakWall = false; + + if (spellLevel < 3) { + inflictMagicalDamageForBlock(calcNewBlockPosition(_currentBlock, _currentDirection), charNum, snowDamage[spellLevel], 3); + } else { + uint16 o = _levelBlockProperties[calcNewBlockPosition(_currentBlock, _currentDirection)].assignedObjects; + while (o & 0x8000) { + int might = _rnd.getRandomNumberRng(iceDamageMin[spellLevel], iceDamageMax[spellLevel]) + iceDamageAdd[spellLevel]; + int dmg = calcInflictableDamagePerItem(charNum, 0, might, 3, 2); + + MonsterInPlay *m = &_monsters[o & 0x7fff]; + if (m->hitPoints <= dmg) { + increaseExperience(charNum, 2, m->hitPoints); + o = m->nextAssignedObject; + + if (m->flags & 0x20) { + m->mode = 0; + monsterDropItems(m); + if (_currentLevel != 29) + setMonsterMode(m, 14); + runLevelScriptCustom(0x404, -1, o, o, 0, 0); + checkSceneUpdateNeed(m->block); + if (m->mode != 14) + placeMonster(m, 0, 0); + + } else { + killMonster(m); + } + + } else { + breakWall = true; + inflictDamage(o, dmg, charNum, 2, 3); + m->damageReceived = 0; + o = m->nextAssignedObject; + } + + if (m->flags & 0x20) + break; + } } - ////////// TODO - generateBrightnessPalette(_screen->_currentPalette, _screen->getPalette(1), _brightness, _lampEffect); + updateDrawPage2(); + gui_drawScene(0); + enableSysTimer(2); - ////////// TODO + if (_currentLevel != 11) + generateBrightnessPalette(_screen->_currentPalette, swampCol, _brightness, _lampEffect); + playSpellAnimation(0, 0, 0, 2, 0, 0, 0, tpal, swampCol, 40, 0); + + _screen->fadePaletteStep(tpal, swampCol, _system->getMillis(), _tickLength); + + if (breakWall) + breakIceWall(tpal, swampCol); + + static const uint8 freezeTime[] = { 20, 28, 40, 60 }; + if (_currentLevel == 11) + setCharacterUpdateEvent(charNum, 8, freezeTime[spellLevel], 1); + + delete[] sc; + delete[] swampCol; + delete[] tpal; _screen->setCurPage(cp); } @@ -2724,15 +2841,15 @@ void LoLEngine::playSpellAnimation(WSAMovie_v2 *mov, int firstFrame, int lastFra int step = del > _tickLength ? _tickLength : del; if (!pal1 || !pal2) { - delay(step); + delay(step, false, true); del -= step; continue; } - if (!_screen->fadePalSpecial(pal1, pal2, _system->getMillis() - startTime, _tickLength * fadeDelay) && !mov) + if (!_screen->fadePaletteStep(pal1, pal2, _system->getMillis() - startTime, _tickLength * fadeDelay) && !mov) return; - delay(step); + delay(step, false, true); del -= step; } while (del > 0); @@ -2793,6 +2910,16 @@ void LoLEngine::inflictMagicalDamage(int target, int attacker, int damage, int i inflictDamage(target, damage, attacker, 2, index); } +void LoLEngine::inflictMagicalDamageForBlock(int block, int attacker, int damage, int index) { + uint16 o = _levelBlockProperties[block].assignedObjects; + while (o & 0x8000) { + inflictDamage(o, calcInflictableDamagePerItem(attacker, o, damage, index, 2), attacker, 2, index); + if ((_monsters[o & 0x7fff].flags & 0x20) && (_currentLevel != 22)) + break; + o = _monsters[o & 0x7fff].nextAssignedObject; + } +} + // fight int LoLEngine::battleHitSkillTest(int16 attacker, int16 target, int skill) { @@ -3221,13 +3348,49 @@ void LoLEngine::stunCharacter(int charNum) { _txt->printMessage(6, getLangString(0x4026), _characters[charNum].name); } -void LoLEngine::level11specialUnk() { +void LoLEngine::restoreSwampPalette() { + _gameFlags[26] &= 0xfffb; + if (_currentLevel != 11) + return; + + uint8 *s = _screen->getPalette(2); + uint8 *d = _screen->_currentPalette; + uint8 *d2 = _screen->getPalette(1); + + for (int i = 1; i < 768; i++) + SWAP(s[i], d[i]); + + generateBrightnessPalette(d, d2, _brightness, _lampEffect); + _screen->loadSpecialColors(s); + _screen->loadSpecialColors(d2); + + playSpellAnimation(0, 0, 0, 2, 0, 0, 0, s, d2, 40, 0); } void LoLEngine::launchMagicViper() { } -void LoLEngine::attackWall(int a, int b) { +void LoLEngine::breakIceWall(uint8 *pal1, uint8 *pal2) { + _screen->hideMouse(); + uint16 bl = calcNewBlockPosition(_currentBlock, _currentDirection); + _levelBlockProperties[bl].flags &= 0xef; + _screen->copyPage(0, 2); + gui_drawScene(2); + _screen->copyPage(2, 10); + + WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen); + int numFrames = mov->open("shatter.wsa", 1, 0); + if (!mov->opened()) + error("Shatter: Unable to load shatter.wsa"); + snd_playSoundEffect(166, -1); + playSpellAnimation(mov, 0, numFrames, 1, 58, 0, 0, pal1, pal2, 20, true); + mov->close(); + delete mov; + + _screen->copyPage(10, 0); + updateDrawPage2(); + gui_drawScene(0); + _screen->showMouse(); } uint16 LoLEngine::getNearestMonsterFromCharacter(int charNum) { diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 79c7ead338..fa1d58fac4 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -568,7 +568,7 @@ private: uint16 _currentBlock; bool _sceneUpdateRequired; int16 _visibleBlockIndex[18]; - uint16 _gameFlags[16]; + uint16 _gameFlags[40]; int16 _globalScriptVars[24]; // emc opcode @@ -639,6 +639,7 @@ private: int olol_createHandItem(EMCState *script); int olol_playAttackSound(EMCState *script); int olol_characterJoinsParty(EMCState *script); + int olol_giveItem(EMCState *script); int olol_loadTimScript(EMCState *script); int olol_runTimScript(EMCState *script); int olol_releaseTimScript(EMCState *script); @@ -710,6 +711,7 @@ private: int olol_getNextActiveCharacter(EMCState *script); int olol_paralyzePoisonCharacter(EMCState *script); int olol_drawCharPortrait(EMCState *script); + int olol_placeInventoryItemInHand(EMCState *script); int olol_castSpell(EMCState *script); int olol_pitDrop(EMCState *script); int olol_paletteFlash(EMCState *script); @@ -967,7 +969,6 @@ private: const uint8 *_scrollYBottom; int _scrollYBottomSize; - int _unkFlag; int _nextScriptFunc; uint8 _currentLevel; int _sceneDefaultUpdate; @@ -1270,6 +1271,8 @@ private: int checkMagic(int charNum, int spellNum, int spellLevel); int getSpellTargetBlock(int currentBlock, int direction, int maxDistance, uint16 &targetBlock); void inflictMagicalDamage(int target, int attacker, int damage, int index, int hitType); + void inflictMagicalDamageForBlock(int block, int attacker, int damage, int index); + ActiveSpell _activeSpell; int8 _availableSpells[7]; @@ -1278,7 +1281,6 @@ private: int _spellPropertiesSize; int _subMenuIndex; - uint16 _freezeStateFlags; uint8 *_healOverlay; uint8 _swarmSpellStatus; @@ -1311,12 +1313,12 @@ private: int paralyzePoisonCharacter(int charNum, int typeFlag, int immunityFlags, int hitChance, int redraw); void paralyzePoisonAllCharacters(int typeFlag, int immunityFlags, int hitChance); void stunCharacter(int charNum); - void level11specialUnk(); + void restoreSwampPalette(); void distObj1Sub(int a, int b, int c, int d); void launchMagicViper(); - void attackWall(int a, int b); + void breakIceWall(uint8 *pal1, uint8 *pal2); uint16 getNearestMonsterFromCharacter(int charNum); uint16 getNearestMonsterFromCharacterForBlock(uint16 block, int charNum); diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp index f6302d39c1..7349cab9b5 100644 --- a/engines/kyra/saveload.cpp +++ b/engines/kyra/saveload.cpp @@ -30,7 +30,7 @@ #include "kyra/kyra_v1.h" -#define CURRENT_SAVE_VERSION 14 +#define CURRENT_SAVE_VERSION 15 #define GF_FLOPPY (1 << 0) #define GF_TALKIE (1 << 1) diff --git a/engines/kyra/saveload_lol.cpp b/engines/kyra/saveload_lol.cpp index 11e18d0f31..4998795f73 100644 --- a/engines/kyra/saveload_lol.cpp +++ b/engines/kyra/saveload_lol.cpp @@ -119,10 +119,15 @@ Common::Error LoLEngine::loadGameState(int slot) { _inventoryCurItem = in.readSint16BE(); _itemInHand = in.readSint16BE(); _lastMouseRegion = in.readSint16BE(); - for (int i = 0; i < 16; i++) - _gameFlags[i] = in.readUint16BE(); - _freezeStateFlags = in.readUint16BE(); - _unkFlag = in.readUint16BE(); + if (header.version == 14) { + for (int i = 0; i < 16; i++) + _gameFlags[i] = in.readUint16BE(); + _gameFlags[26] = in.readUint16BE(); + _gameFlags[36] = in.readUint16BE(); + } else { + for (int i = 0; i < 40; i++) + _gameFlags[i] = in.readUint16BE(); + } for (int i = 0; i < 24; i++) _globalScriptVars[i] = in.readUint16BE(); _brightness = in.readByte(); @@ -240,7 +245,7 @@ Common::Error LoLEngine::loadGameState(int slot) { loadLevel(_currentLevel); gui_drawPlayField(); timerSpecialCharacterUpdate(0); - _unkFlag |= 0x800; + _gameFlags[36] |= 0x800; while (!_screen->isMouseVisible()) _screen->showMouse(); @@ -318,10 +323,8 @@ Common::Error LoLEngine::saveGameState(int slot, const char *saveName, const Gra out->writeSint16BE(_inventoryCurItem); out->writeSint16BE(_itemInHand); out->writeSint16BE(_lastMouseRegion); - for (int i = 0; i < 16; i++) + for (int i = 0; i < 40; i++) out->writeUint16BE(_gameFlags[i]); - out->writeUint16BE(_freezeStateFlags); - out->writeUint16BE(_unkFlag); for (int i = 0; i < 24; i++) out->writeUint16BE(_globalScriptVars[i]); out->writeByte(_brightness); diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index dcdecb15e8..7682da754b 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -36,7 +36,7 @@ namespace Kyra { void LoLEngine::loadLevel(int index) { - _unkFlag |= 0x800; + _gameFlags[36] |= 0x800; setMouseCursorToIcon(0x85); _nextScriptFunc = 0; @@ -395,10 +395,10 @@ void LoLEngine::loadLevelGraphics(const char *file, int specialColor, int weight if (_currentLevel == 11) { uint8 *swampPal = _res->fileData("SWAMPICE.COL", 0); memcpy(_screen->getPalette(2), swampPal, 384); - memcpy(_screen->getPalette(2) + 0x180, _screen->_currentPalette, 384); + memcpy(_screen->getPalette(2) + 384, _screen->_currentPalette + 384, 384); delete[] swampPal; - if (_freezeStateFlags & 4) { + if (_gameFlags[26] & 4) { uint8 *pal0 = _screen->_currentPalette; uint8 *pal2 = _screen->getPalette(2); for (int i = 1; i < 768; i++) @@ -651,12 +651,12 @@ void LoLEngine::moveParty(uint16 direction, int unk1, int unk2, int buttonShape) _sceneDefaultUpdate = 1; calcCoordinates(_partyPosX, _partyPosY, _currentBlock, 0x80, 0x80); - _unkFlag &= 0xfdff; + _gameFlags[36] &= 0xfdff; runLevelScript(opos, 4); runLevelScript(npos, 1); - if (!(_unkFlag & 0x200)) { + if (!(_gameFlags[36] & 0x200)) { initTextFading(2, 0); if (_sceneDefaultUpdate) { diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp index edc95fd36a..2f7a938374 100644 --- a/engines/kyra/screen_lol.cpp +++ b/engines/kyra/screen_lol.cpp @@ -815,20 +815,20 @@ bool Screen_LoL::fadeColor(int dstColorIndex, int srcColorIndex, uint32 elapsedT return res; } -bool Screen_LoL::fadePalSpecial(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime) { +bool Screen_LoL::fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime) { uint8 tpal[768]; - uint8 *p1 = _palettes[1]; + uint8 *p1 = _palettes[0]; bool res = false; for (int i = 0; i < 768; i++) { uint8 out = 0; if (elapsedTime < targetTime) { - int d = (pal2[i] & 0x3f) - (pal1[i] & 0x3f); + int32 d = ((pal2[i] & 0x3f) - (pal1[i] & 0x3f)); if (d) res = true; - int val = ((((d << 8) / targetTime) * elapsedTime) >> 8) & 0xff; - out = ((pal1[i] & 0x3f) + val) & 0xff; + int32 val = ((((d << 8) / (int32)targetTime) * (int32)elapsedTime) >> 8); + out = ((pal1[i] & 0x3f) + (int8)val); } else { out = p1[i] = (pal2[i] & 0x3f); res = false; diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h index 6de38ff78d..7ef73bddcb 100644 --- a/engines/kyra/screen_lol.h +++ b/engines/kyra/screen_lol.h @@ -70,7 +70,7 @@ public: void loadSpecialColors(uint8 *destPalette); void copyColor(int dstColorIndex, int srcColorIndex); bool fadeColor(int dstColorIndex, int srcColorIndex, uint32 elapsedTime, uint32 targetTime); - bool fadePalSpecial(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime); + bool fadePaletteStep(uint8 *pal1, uint8 *pal2, uint32 elapsedTime, uint32 targetTime); void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool skipSpecialColors); uint8 *generateLevelOverlay(const uint8 *srcPal, uint8 *ovl, int opColor, int weight); diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index b17d17685d..5b41b3da27 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -202,6 +202,9 @@ int LoLEngine::olol_delay(EMCState *script) { int LoLEngine::olol_setGameFlag(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setGameFlag(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + + assert((stackPos(0) >> 4) < 40); + if (stackPos(1)) _gameFlags[stackPos(0) >> 4] |= (1 << (stackPos(0) & 0x0f)); else @@ -215,6 +218,8 @@ int LoLEngine::olol_testGameFlag(EMCState *script) { if (stackPos(0) < 0) return 0; + assert((stackPos(0) >> 4) < 40); + if (_gameFlags[stackPos(0) >> 4] & (1 << (stackPos(0) & 0x0f))) return 1; @@ -1104,6 +1109,15 @@ int LoLEngine::olol_characterJoinsParty(EMCState *script) { return 1; } +int LoLEngine::olol_giveItem(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_giveItem(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); + int item = makeItem(stackPos(0), stackPos(1), stackPos(2)); + if (addItemToInventory(item)) + return 1; + + deleteItem(item); + return 0; +} int LoLEngine::olol_loadTimScript(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_loadTimScript(%p) (%d, %s)", (const void *)script, stackPos(0), stackPosString(1)); @@ -1854,6 +1868,31 @@ int LoLEngine::olol_drawCharPortrait(EMCState *script) { return 1; } +int LoLEngine::olol_placeInventoryItemInHand(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_placeInventoryItemInHand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1)); + int itemType = stackPos(0); + int i = 0; + for (; i < 48; i++) { + if (!_inventory[i]) + continue; + if (_itemsInPlay[_inventory[i]].itemPropertyIndex == itemType) + break; + } + + if (i == 48) + return -1; + + _inventoryCurItem = i; + int r = _itemInHand; + setHandItem(_inventory[i]); + _inventory[i] = r; + + if (stackPos(1)) + gui_drawInventory(); + + return r; +} + int LoLEngine::olol_castSpell(EMCState *script) { debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_castSpell(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2)); return castSpell(stackPos(0), stackPos(1), stackPos(2)); @@ -2328,7 +2367,7 @@ void LoLEngine::setupOpcodeTable() { Opcode(olol_characterJoinsParty); // 0x4C - OpcodeUnImpl(); + Opcode(olol_giveItem); OpcodeUnImpl(); Opcode(olol_loadTimScript); Opcode(olol_runTimScript); @@ -2472,7 +2511,7 @@ void LoLEngine::setupOpcodeTable() { OpcodeUnImpl(); // 0xAC - OpcodeUnImpl(); + Opcode(olol_placeInventoryItemInHand); Opcode(olol_castSpell); Opcode(olol_pitDrop); OpcodeUnImpl(); diff --git a/engines/kyra/sprites_lol.cpp b/engines/kyra/sprites_lol.cpp index 7b66907733..35350103fc 100644 --- a/engines/kyra/sprites_lol.cpp +++ b/engines/kyra/sprites_lol.cpp @@ -1232,7 +1232,7 @@ bool LoLEngine::chasePartyWithDistanceAttacks(MonsterInPlay *monster) { s = monster->properties->numDistWeapons ? _rnd.getRandomNumberRng(1, monster->properties->numDistWeapons) : 0; } else { s = monster->curDistWeapon++; - if (monster->curDistWeapon == monster->properties->numDistWeapons) + if (monster->curDistWeapon >= monster->properties->numDistWeapons) monster->curDistWeapon = 0; } diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp index b17fdc7d46..eb0ecb5537 100644 --- a/engines/kyra/timer_lol.cpp +++ b/engines/kyra/timer_lol.cpp @@ -172,7 +172,7 @@ void LoLEngine::timerSpecialCharacterUpdate(int timerNum) { break; case 7: - level11specialUnk(); + restoreSwampPalette(); break; default: |