From 5076b06bb654abe9eecf98c6fe60ef8a378acf2f Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Thu, 21 May 2009 22:29:49 +0000 Subject: LOL: - implemented Lightning Spell svn-id: r40776 --- dists/engine-data/kyra.dat | Bin 256972 -> 257015 bytes engines/kyra/lol.cpp | 72 ++++++++++++++++++++++++++++++++ engines/kyra/lol.h | 18 ++++++-- engines/kyra/resource.h | 1 + engines/kyra/scene_lol.cpp | 4 +- engines/kyra/script_lol.cpp | 10 ++--- engines/kyra/staticres.cpp | 12 +++++- tools/create_kyradat/create_kyradat.cpp | 3 +- tools/create_kyradat/create_kyradat.h | 1 + tools/create_kyradat/lol_cd.h | 1 + tools/create_kyradat/misc.h | 1 + 11 files changed, 111 insertions(+), 12 deletions(-) diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat index d7fbd60c03..82cde55139 100644 Binary files a/dists/engine-data/kyra.dat and b/dists/engine-data/kyra.dat differ diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 14b9cad751..5584fc8ddf 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -232,6 +232,12 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _automapShapes = 0; _defaultLegendData = 0; + _lightningProps = 0; + _lightningCurSfx = -1; + _lightningDiv = 0; + _lightningFirstSfx = 0; + _lightningSfxFrame = 0; + _compassTimer = 0; _timer3Para = 0; _scriptCharacterCycle = 0; @@ -362,6 +368,7 @@ LoLEngine::~LoLEngine() { delete[] _levelShapeProperties; delete[] _blockDrawingBuffer; delete[] _sceneWindowBuffer; + delete[] _lightningProps; if (_levelShapes) { for (int i = 0; i < 400; i++) @@ -2561,6 +2568,39 @@ void LoLEngine::processMagicMistOfDoom(int charNum, int spellLevel) { } void LoLEngine::processMagicLightning(int charNum, int spellLevel) { + _screen->hideMouse(); + _screen->copyPage(0, 2); + gui_drawScene(2); + _screen->copyPage(2, 12); + + _lightningCurSfx = _lightningProps[spellLevel].sfxId; + _lightningDiv = _lightningProps[spellLevel].frameDiv; + _lightningFirstSfx = 0; + + char wsafile[13]; + snprintf(wsafile, 13, "litning%d.wsa", spellLevel + 1); + WSAMovie_v2 *mov = new WSAMovie_v2(this, _screen); + mov->open(wsafile, 1, 0); + if (!mov->opened()) + error("Litning: Unable to load litning.wsa"); + + for (int i = 0; i < 4; i++) + playSpellAnimation(mov, 0, _lightningProps[spellLevel].lastFrame, 3, 93, 0, &LoLEngine::callbackProcessMagicLightning, 0, 0, 0, false); + + mov->close(); + delete mov; + + _screen->setScreenPalette(_screen->getPalette(1)); + _screen->copyPage(12, 2); + _screen->copyPage(12, 0); + updateDrawPage2(); + + static const uint8 lighntingDamage[] = { 18, 35, 50, 72 }; + inflictMagicalDamageForBlock(calcNewBlockPosition(_currentBlock, _currentDirection), charNum, lighntingDamage[spellLevel], 5); + + _sceneUpdateRequired = true; + gui_drawScene(0); + _screen->showMouse(); } void LoLEngine::processMagicFog() { @@ -2671,6 +2711,38 @@ void LoLEngine::callbackProcessMagicSwarm(WSAMovie_v2 *mov, int x, int y) { _swarmSpellStatus ^= 1; } +void LoLEngine::callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y) { + uint8 *tpal = new uint8[768]; + if (_lightningDiv == 2) + shakeScene(1, 2, 3, 0); + + uint8 *p1 = _screen->getPalette(1); + + if (_lightningSfxFrame % _lightningDiv) { + _screen->setScreenPalette(p1); + } else { + memcpy(tpal, p1, 768); + for (int i = 6; i < 384; i++) { + uint16 v = (tpal[i] * 120) / 64; + tpal[i] = (v < 64) ? v : 63; + } + _screen->setScreenPalette(tpal); + } + + if (_lightningDiv == 2) { + if (!_lightningFirstSfx) { + snd_playSoundEffect(_lightningCurSfx, -1); + _lightningFirstSfx = 1; + } + } else { + if (!(_lightningSfxFrame & 7)) + snd_playSoundEffect(_lightningCurSfx, -1); + } + + _lightningSfxFrame++; + delete[] tpal; +} + void LoLEngine::addSpellToScroll(int spell, int charNum) { bool assigned = false; int slot = 0; diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index fa1d58fac4..f3b89758eb 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -260,6 +260,12 @@ struct MapLegendData { uint16 stringId; }; +struct LightningProperty { + uint8 lastFrame; + uint8 frameDiv; + int16 sfxId; +}; + class LoLEngine : public KyraEngine_v1 { friend class GUI_LoL; friend class TextDisplayer_LoL; @@ -689,7 +695,7 @@ private: int olol_countSpecificMonsters(EMCState *script); int olol_updateBlockAnimations2(EMCState *script); int olol_checkPartyForItemType(EMCState *script); - int olol_setUnkDoorVar(EMCState *script); + int olol_blockDoor(EMCState *script); int olol_resetTimDialogueState(EMCState *script); int olol_getItemOnPos(EMCState *script); int olol_removeLevelItem(EMCState *script); @@ -955,7 +961,7 @@ private: int smoothScrollDrawSpecialShape(int pageNum); OpenDoorState _openDoorState[3]; - int _emcDoorState; + int _blockDoor; uint32 _smoothScrollTimer; int _smoothScrollModeNormal; @@ -1263,6 +1269,7 @@ private: void processMagicGuardian(int charNum, int spellLevel); void callbackProcessMagicSwarm(WSAMovie_v2 *mov, int x, int y); + void callbackProcessMagicLightning(WSAMovie_v2 *mov, int x, int y); void addSpellToScroll(int spell, int charNum); void transferSpellToScollAnimation(int charNum, int spell, int slot); @@ -1273,7 +1280,6 @@ private: 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]; int _selectedSpell; @@ -1281,6 +1287,12 @@ private: int _spellPropertiesSize; int _subMenuIndex; + LightningProperty *_lightningProps; + int16 _lightningCurSfx; + int16 _lightningDiv; + int16 _lightningFirstSfx; + int16 _lightningSfxFrame; + uint8 *_healOverlay; uint8 _swarmSpellStatus; diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 98d929d406..eb5ba3e23c 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -290,6 +290,7 @@ enum kKyraResources { lolSpellbookAnim, lolSpellbookCoords, lolHealShapeFrames, + lolLightningDefs, #endif // ENABLE_LOL kMaxResIDs diff --git a/engines/kyra/scene_lol.cpp b/engines/kyra/scene_lol.cpp index 7682da754b..68eb15fbb5 100644 --- a/engines/kyra/scene_lol.cpp +++ b/engines/kyra/scene_lol.cpp @@ -821,10 +821,10 @@ int LoLEngine::clickedDoorSwitch(uint16 block, uint16 direction) { return 0; snd_playSoundEffect(78, -1); - _emcDoorState = 0; + _blockDoor = 0; runLevelScript(block, 0x40); - if (!_emcDoorState) { + if (!_blockDoor) { delay(15 * _tickLength); processDoorSwitch(block, 0); } diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index 5b41b3da27..3041b4d5e2 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -1671,10 +1671,10 @@ int LoLEngine::olol_checkPartyForItemType(EMCState *script) { return 0; } -int LoLEngine::olol_setUnkDoorVar(EMCState *script) { - debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_setUnkDoorVar(%p) (%d)", (const void *)script, stackPos(0)); - _emcDoorState = stackPos(0); - return _emcDoorState; +int LoLEngine::olol_blockDoor(EMCState *script) { + debugC(3, kDebugLevelScriptFuncs, "LoLEngine::olol_blockDoor(%p) (%d)", (const void *)script, stackPos(0)); + _blockDoor = stackPos(0); + return _blockDoor; } int LoLEngine::olol_resetTimDialogueState(EMCState *script) { @@ -2453,7 +2453,7 @@ void LoLEngine::setupOpcodeTable() { // 0x84 Opcode(olol_updateBlockAnimations2); Opcode(olol_checkPartyForItemType); - Opcode(olol_setUnkDoorVar); + Opcode(olol_blockDoor); Opcode(olol_resetTimDialogueState); // 0x88 diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index 2d75705a9b..ad599fc9cb 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@ namespace Kyra { -#define RESFILE_VERSION 46 +#define RESFILE_VERSION 47 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -452,6 +452,7 @@ bool StaticResource::init() { { lolSpellbookAnim, kRawData, "MBOOKA.DEF" }, { lolSpellbookCoords, kRawData, "MBOOKC.DEF" }, { lolHealShapeFrames, kRawData, "MHEAL.SHP" }, + { lolLightningDefs, kRawData, "MLGHTNG.DEF" }, { 0, 0, 0 } }; @@ -1859,6 +1860,15 @@ void LoLEngine::initStaticResource() { _updateSpellBookAnimData = _staticres->loadRawData(lolSpellbookAnim, _updateSpellBookAnimDataSize); _healShapeFrames = _staticres->loadRawData(lolHealShapeFrames, _healShapeFramesSize); + tmp = _staticres->loadRawData(lolLightningDefs, tmpSize); + _lightningProps = new LightningProperty[5]; + for (int i = 0; i < 5; i++) { + _lightningProps[i].lastFrame = tmp[i << 2]; + _lightningProps[i].frameDiv = tmp[(i << 2) + 1]; + _lightningProps[i].sfxId = READ_LE_UINT16(&tmp[(i << 2) + 2]); + } + _staticres->unloadId(lolLightningDefs); + // assign music data static const char *pcMusicFileListIntro[] = { "LOREINTR" }; static const char *pcMusicFileListFinale[] = { "LOREFINL" }; diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index 50b294c6b8..3b5253eeb7 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -31,7 +31,7 @@ #include "md5.h" enum { - kKyraDatVersion = 46, + kKyraDatVersion = 47, kIndexSize = 12 }; @@ -344,6 +344,7 @@ const ExtractFilename extractFilenames[] = { { lolSpellbookAnim, k3TypeRaw16to8, "MBOOKA.DEF" }, { lolSpellbookCoords, k3TypeRaw16to8, "MBOOKC.DEF" }, { lolHealShapeFrames, kTypeRawData, "MHEAL.SHP" }, + { lolLightningDefs, kTypeRawData, "MLGHTNG.DEF" }, { -1, 0, 0 } }; diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h index 4c93cbd9e9..30336dea15 100644 --- a/tools/create_kyradat/create_kyradat.h +++ b/tools/create_kyradat/create_kyradat.h @@ -254,6 +254,7 @@ enum kExtractID { lolSpellbookAnim, lolSpellbookCoords, lolHealShapeFrames, + lolLightningDefs, kMaxResIDs }; diff --git a/tools/create_kyradat/lol_cd.h b/tools/create_kyradat/lol_cd.h index 3c07777627..1363489bc8 100644 --- a/tools/create_kyradat/lol_cd.h +++ b/tools/create_kyradat/lol_cd.h @@ -77,6 +77,7 @@ const ExtractEntry lolCDFile2[] = { { lolSpellbookAnim, 0x00032D94, 0x00032DCC }, { lolSpellbookCoords, 0x00032DCC, 0x00032DE4 }, { lolHealShapeFrames, 0x000297D0, 0x00029820 }, + { lolLightningDefs, 0x00032740, 0x00032754 }, { -1, 0, 0 } }; diff --git a/tools/create_kyradat/misc.h b/tools/create_kyradat/misc.h index f868e7ce2e..d5623d8efa 100644 --- a/tools/create_kyradat/misc.h +++ b/tools/create_kyradat/misc.h @@ -560,6 +560,7 @@ const int lolCDFile2Need[] = { lolSpellbookAnim, lolSpellbookCoords, lolHealShapeFrames, + lolLightningDefs, -1 }; -- cgit v1.2.3