From f7032c126dd097e8083e0fc740c7c856e0f2dd58 Mon Sep 17 00:00:00 2001 From: athrxx Date: Wed, 17 Aug 2011 18:46:29 +0200 Subject: KYRA: (EOB) - fix some bugs - fix monster movement - fix character level gain - add some static res for party transfer --- engines/kyra/chargen.cpp | 13 ++++++++---- engines/kyra/eob1.cpp | 4 ++-- engines/kyra/eobcommon.cpp | 30 ++++++++++++++++++-------- engines/kyra/eobcommon.h | 8 +++++-- engines/kyra/gui_eob.cpp | 4 +--- engines/kyra/lol.cpp | 1 + engines/kyra/loleobbase.cpp | 16 +++++++------- engines/kyra/resource.h | 3 +++ engines/kyra/scene_eob.cpp | 8 +++---- engines/kyra/screen_eob.cpp | 24 +++++++++++---------- engines/kyra/sprites_eob.cpp | 48 ++++++++++++++++++++++++------------------ engines/kyra/staticres_eob.cpp | 3 +++ engines/kyra/timer.cpp | 4 ++++ engines/kyra/timer_eob.cpp | 3 +++ engines/kyra/timer_lol.cpp | 1 + 15 files changed, 106 insertions(+), 64 deletions(-) (limited to 'engines') diff --git a/engines/kyra/chargen.cpp b/engines/kyra/chargen.cpp index e97b7a1b2d..7516916f67 100644 --- a/engines/kyra/chargen.cpp +++ b/engines/kyra/chargen.cpp @@ -108,10 +108,6 @@ private: Screen_Eob *_screen; }; -bool EobCoreEngine::startCharacterGeneration() { - return CharacterGenerator(this, _screen).start(_characters, &_faceShapes); -} - CharacterGenerator::CharacterGenerator(EobCoreEngine *vm, Screen_Eob *screen) : _vm(vm), _screen(screen), _characters(0), _faceShapes(0), _chargenMagicShapes(0), _chargenButtonLabels(0), _chargenMagicShapeTimer(0), _updateBoxShapesIndex(0), _lastUpdateBoxShapesIndex(0), _magicShapesBox(6), _activeBox(0) { @@ -1445,6 +1441,15 @@ const int16 CharacterGenerator::_raceModifiers[] = { 0, 0, 0, 0, 1, -1, 0, 1, -1, 0, 0, 0, -1, 0, 0, 1, 0, 0 }; +bool EobCoreEngine::startCharacterGeneration() { + return CharacterGenerator(this, _screen).start(_characters, &_faceShapes); +} + +bool EobCoreEngine::transferParty() { + + return false; +} + } // End of namespace Kyra #endif // ENABLE_EOB diff --git a/engines/kyra/eob1.cpp b/engines/kyra/eob1.cpp index 71644c5a87..8ce41d6b5b 100644 --- a/engines/kyra/eob1.cpp +++ b/engines/kyra/eob1.cpp @@ -78,8 +78,8 @@ Common::Error EobEngine::init() { _scriptTimersCount = 1; - _wllWallFlags[132] = 1; - _wllWallFlags[133] = 1; + //_wllWallFlags[132] = 1; + //_wllWallFlags[133] = 1; return Common::kNoError; } diff --git a/engines/kyra/eobcommon.cpp b/engines/kyra/eobcommon.cpp index c94cb16703..3a298d84ad 100644 --- a/engines/kyra/eobcommon.cpp +++ b/engines/kyra/eobcommon.cpp @@ -40,14 +40,16 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _teleporterWallId(flags.gameID == GI_EOB1 ? 52 : 44) { _screen = 0; _gui = 0; - //_processingButtons=false; - //_runLoopUnk2 = 0; - //_runLoopTimerUnk = 0; + _playFinale = false; _runFlag = true; _configMouse = true; _loading = false; + _envAudioTimer = 0; + _flashShapeTimer = 0; + _drawSceneTimer = 0; + _largeItemShapes = _smallItemShapes = _thrownItemShapes = _spellShapes = _firebeamShapes = _itemIconShapes = _wallOfForceShapes = _teleporterShapes = _sparkShapes = _compassShapes = 0; _redSplatShape = _greenSplatShape = _deadCharShape = _disabledCharGrid = _blackBoxSmallGrid = @@ -60,6 +62,9 @@ EobCoreEngine::EobCoreEngine(OSystem *system, const GameFlags &flags) : LolEobBa _beholderSpellList = 0; _beholderSfx = 0; + _transferConvertTable = 0; + _transferExpTable = 0; + _faceShapes = 0; _characters = 0; _items = 0; @@ -297,6 +302,13 @@ Common::Error EobCoreEngine::init() { memset(&_wllShapeMap[3], -1, 5); memset(&_wllShapeMap[13], -1, 5); + /*int clen = _flags.gameID == GI_EOB2 ? 80 : 70; + memcpy(&_wllShapeMap[256 - clen], _wllVmpMap, clen); + memcpy(&_specialWallTypes[256 - 2 * clen], _wllVmpMap, clen); + memcpy(&_specialWallTypes[256 - clen], _wllShapeMap, clen); + memcpy(&_wllWallFlags[256 - 2 * clen], _wllShapeMap, clen); + memcpy(&_wllWallFlags[256 - clen], _specialWallTypes, clen);*/ + _wllVcnOffset = 16; _monsters = new EobMonsterInPlay[30]; @@ -384,7 +396,9 @@ Common::Error EobCoreEngine::go() { startupNew(); } else if (action == -3) { // transfer party - repeatLoop = false; + repeatLoop = transferParty(); + if (repeatLoop && !shouldQuit()) + startupNew(); } } @@ -441,15 +455,13 @@ void EobCoreEngine::runLoop() { _envAudioTimer = _system->getMillis() + (rollDice(1, 10, 3) * 18 * _tickLength); _flashShapeTimer = 0; _drawSceneTimer = _system->getMillis(); - //__unkB__ = 1; + _screen->setFont(Screen::FID_6_FNT); _screen->setScreenDim(7); - //_runLoopUnk2 = _currentBlock; _runFlag = true; while (!shouldQuit() && _runFlag) { - //_runLoopUnk2 = _currentBlock; checkPartyStatus(true); checkInput(_activeButtons, true, 0); removeInputTop(); @@ -723,7 +735,7 @@ int EobCoreEngine::generateCharacterHitpointsByLevel(int charIndex, int levelInd int EobCoreEngine::getClassAndConstHitpointsModifier(int cclass, int constitution) { int res = _hpConstModifiers[constitution]; - + // This also applies to EOB1 despite being coded differently there if (res <= 2 || (_classModifierFlags[cclass] & 0x31)) return res; @@ -1176,7 +1188,7 @@ uint32 EobCoreEngine::getRequiredExperience(int cClass, int levelIndex, int leve void EobCoreEngine::increaseCharacterLevel(int charIndex, int levelIndex) { _characters[charIndex].level[levelIndex]++; - int hpInc = generateCharacterHitpointsByLevel(charIndex, levelIndex); + int hpInc = generateCharacterHitpointsByLevel(charIndex, 1 << levelIndex); _characters[charIndex].hitPointsCur += hpInc; _characters[charIndex].hitPointsMax += hpInc; diff --git a/engines/kyra/eobcommon.h b/engines/kyra/eobcommon.h index ffc951e80d..5f1bf8b709 100644 --- a/engines/kyra/eobcommon.h +++ b/engines/kyra/eobcommon.h @@ -317,8 +317,9 @@ protected: bool _runFlag; //int _runLoopUnk2; - // Create Party + // Character generation / party transfer bool startCharacterGeneration(); + bool transferParty(); uint8 **_faceShapes; @@ -329,6 +330,9 @@ protected: static const uint8 _charClassModUnk[]; const uint8 *_classModifierFlags; + + const uint8 *_transferConvertTable; + const uint32 *_transferExpTable; // timers void setupTimers(); @@ -509,7 +513,7 @@ protected: void updateMonsters(int unit); void updateMonsterDest(EobMonsterInPlay *m); - void updateMonsterDest2(EobMonsterInPlay *m); + void updateMonsterAttackMode(EobMonsterInPlay *m); void updateAllMonsterDests(); void turnFriendlyMonstersHostile(); int getNextMonsterDirection(int curBlock, int destBlock); diff --git a/engines/kyra/gui_eob.cpp b/engines/kyra/gui_eob.cpp index 7778feba8e..a5f06c551e 100644 --- a/engines/kyra/gui_eob.cpp +++ b/engines/kyra/gui_eob.cpp @@ -1978,8 +1978,6 @@ int GUI_Eob::processButtonList(Kyra::Button *buttonList, uint16 inputFlags, int8 if (!result) result = inputFlags; - //_vm->_processingButtons=false; - return result; } @@ -2773,7 +2771,6 @@ int GUI_Eob::selectSaveSlotDialogue(int x, int y, int id) { // Display highlighted slot index in the bottom left corner to avoid people getting lost with the 990 save slots _screen->setFont(Screen::FID_6_FNT); - _screen->fillRect(_saveSlotX + 5, _saveSlotY + 135, _saveSlotX + 46, _saveSlotY + 140, _vm->_bkgColor_1); int sli = (newHighlight == 6) ? _savegameOffset : (_savegameOffset + newHighlight); _screen->printText(Common::String::format("%03d/989", sli).c_str(), _saveSlotX + 5, _saveSlotY + 135, _vm->_color2_1, _vm->_bkgColor_1); _screen->setFont(Screen::FID_8_FNT); @@ -3980,6 +3977,7 @@ void GUI_Eob::releaseButtons(Button *list) { delete list; list = n; } + _vm->gui_notifyButtonListChanged(); } void GUI_Eob::setupSaveMenuSlots() { diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 4fc78c0b64..030b1dec7a 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -1163,6 +1163,7 @@ void LoLEngine::setCharacterUpdateEvent(int charNum, int updateType, int updateD l->characterUpdateEvents[i] = updateType; l->characterUpdateDelay[i] = updateDelay; _timer->setNextRun(3, _system->getMillis()); + _timer->resetNextRun(); _timer->enable(3); break; } diff --git a/engines/kyra/loleobbase.cpp b/engines/kyra/loleobbase.cpp index 2ffae915b1..c2ec8da706 100644 --- a/engines/kyra/loleobbase.cpp +++ b/engines/kyra/loleobbase.cpp @@ -164,14 +164,14 @@ Common::Error LolEobBaseEngine::init() { _levelBlockProperties = new LevelBlockProperty[1025]; memset(_levelBlockProperties, 0, 1025 * sizeof(LevelBlockProperty)); - _wllVmpMap = new uint8[255]; - memset(_wllVmpMap, 0, 255); - _wllShapeMap = new int8[255]; - memset(_wllShapeMap, 0, 255); - _specialWallTypes = new uint8[255]; - memset(_specialWallTypes, 0, 255); - _wllWallFlags = new uint8[255]; - memset(_wllWallFlags, 0, 255); + _wllVmpMap = new uint8[256]; + memset(_wllVmpMap, 0, 256); + _wllShapeMap = new int8[256]; + memset(_wllShapeMap, 0, 256); + _specialWallTypes = new uint8[256]; + memset(_specialWallTypes, 0, 256); + _wllWallFlags = new uint8[256]; + memset(_wllWallFlags, 0, 256); _blockDrawingBuffer = new uint16[1320]; memset(_blockDrawingBuffer, 0, 1320 * sizeof(uint16)); diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index f330d42004..cd3865736f 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -537,6 +537,9 @@ enum KyraResources { kEob1Npc7Strings, kEob2MainMenuStrings, + kEob2TransferConvertTable, + kEob2TransferExpTable, + kEob2IntroStrings, kEob2IntroCPSFiles, kEob2IntroSeqData00, diff --git a/engines/kyra/scene_eob.cpp b/engines/kyra/scene_eob.cpp index afce9efdfa..1bd7fca04a 100644 --- a/engines/kyra/scene_eob.cpp +++ b/engines/kyra/scene_eob.cpp @@ -1012,8 +1012,8 @@ void EobCoreEngine::drawScene(int refresh) { } if (_sceneDefaultUpdate) { - resetSkipFlag(); delayUntil(_drawSceneTimer); + removeInputTop(); } if (refresh && !_partyResting) @@ -1029,7 +1029,7 @@ void EobCoreEngine::drawScene(int refresh) { if (_sceneDefaultUpdate) { _sceneDefaultUpdate = false; - _drawSceneTimer = _system->getMillis() /*+ 4 * _tickLength*/; + _drawSceneTimer = _system->getMillis() + 4 * _tickLength; } _sceneUpdateRequired = false; @@ -1141,8 +1141,8 @@ int EobCoreEngine::calcNewBlockPositionAndTestPassability(uint16 curBlock, uint1 int w = _levelBlockProperties[b].walls[direction ^ 2]; int f = _wllWallFlags[w]; - if (!f) - assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80)); + //if (!f) + assert((_flags.gameID == GI_EOB1 && w < 70) || (_flags.gameID == GI_EOB2 && w < 80)); if (_flags.gameID == GI_EOB2 && w == 74 && _currentBlock == curBlock) { for (int i = 0; i < 5; i++) { diff --git a/engines/kyra/screen_eob.cpp b/engines/kyra/screen_eob.cpp index c9ee9119db..d29af69f0a 100644 --- a/engines/kyra/screen_eob.cpp +++ b/engines/kyra/screen_eob.cpp @@ -151,9 +151,6 @@ void Screen_Eob::loadShapeSetBitmap(const char *file, int tempPage, int destPage } void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int tempPage, int destPage, int copyToPage) { - //Common::String tmp = file; - //if (_vm->game() == GI_EOB1 && tmp.equalsIgnoreCase("spider")) - // tmp += "1"; Common::String tmp = Common::String::format("%s.CPS", file); Common::SeekableReadStream *s = _vm->resource()->createReadStream(tmp); bool loadAlternative = false; @@ -170,15 +167,20 @@ void Screen_Eob::loadEobBitmap(const char *file, const uint8 *ditheringData, int } if (loadAlternative) { - tmp.setChar('X', 0); - s = _vm->resource()->createReadStream(tmp); - if (!s) - error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); - s->seek(768); - loadFileDataToPage(s, destPage, 64000); - delete s; + if (_vm->game() == GI_EOB1) { + tmp.insertChar('1', tmp.size() - 4); + loadBitmap(tmp.c_str(), tempPage, destPage, 0); + } else { + tmp.setChar('X', 0); + s = _vm->resource()->createReadStream(tmp); + if (!s) + error("Screen_Eob::loadEobBitmap(): CPS file loading failed."); + s->seek(768); + loadFileDataToPage(s, destPage, 64000); + delete s; + } } - + if (copyToPage == -1) { return; } else if (copyToPage == 0) { diff --git a/engines/kyra/sprites_eob.cpp b/engines/kyra/sprites_eob.cpp index caf4a748da..bd5ab27ead 100644 --- a/engines/kyra/sprites_eob.cpp +++ b/engines/kyra/sprites_eob.cpp @@ -53,12 +53,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 = filename; - if ((_flags.gameID == GI_EOB1) && (!scumm_stricmp(filename, "rust") || !scumm_stricmp(filename, "drider") || !scumm_stricmp(filename, "spider") || !scumm_stricmp(filename, "mantis") || !scumm_stricmp(filename, "xorn") || !scumm_stricmp(filename, "xanath"))) - s += "1"; - - _screen->loadShapeSetBitmap(s.c_str(), 3, 3); +void EobCoreEngine::loadMonsterShapes(const char *filename, int monsterIndex, bool hasDecorations, int encodeTableIndex) { + _screen->loadShapeSetBitmap(filename, 3, 3); const uint16 *enc = &_encodeMonsterShpTable[encodeTableIndex << 2]; for (int i = 0; i < 6; i++, enc += 4) @@ -149,6 +145,7 @@ const uint8 *EobCoreEngine::loadActiveMonsterData(const uint8 *data, int level) int32 del = _timer->getDelay(i); _timer->setNextRun(i, (i & 1) ? ct + (del >> 1) * _tickLength : ct + del * _tickLength); } + _timer->resetNextRun(); if (_hasTempDataFlags & (1 << (level - 1))) return data + 420; @@ -470,6 +467,12 @@ void EobCoreEngine::drawBlockItems(int index) { void EobCoreEngine::drawDoor(int index) { int s = _visibleBlocks[index]->walls[_sceneDrawVarDown]; + + if (_flags.gameID == GI_EOB1 && s == 0x85) + s = 0; + + assert((_flags.gameID == GI_EOB1 && s < 32) || (_flags.gameID == GI_EOB2 && s < 53)); + int type = _dscDoorShpIndex[s]; int d = _dscDimMap[index]; int w = _dscShapeCoords[(index * 5 + 4) << 1]; @@ -722,7 +725,7 @@ void EobCoreEngine::updateMonsters(int unit) { updateMonsterDest(m); if (m->mode > 0) - updateMonsterDest2(m); + updateMonsterAttackMode(m); switch (m->mode) { case 0: @@ -780,7 +783,7 @@ void EobCoreEngine::updateMonsterDest(EobMonsterInPlay *m) { m->dest = _currentBlock; } -void EobCoreEngine::updateMonsterDest2(EobMonsterInPlay *m) { +void EobCoreEngine::updateMonsterAttackMode(EobMonsterInPlay *m) { if (!(m->flags & 1) || m->mode == 10) return; if (m->mode == 8) { @@ -902,7 +905,7 @@ void EobCoreEngine::updateMoveMonster(EobMonsterInPlay *m) { EobMonsterProperty *p = &_monsterProps[m->type]; int d = getNextMonsterDirection(m->block, _currentBlock); - if ((p->capsFlags & 0x800) && !(d & 1)) + if ((_flags.gameID == GI_EOB2) && (p->capsFlags & 0x800) && !(d & 1)) d >>= 1; else d = m->dir; @@ -1102,31 +1105,34 @@ void EobCoreEngine::walkMonster(EobMonsterInPlay *m, int destBlock) { return; if (m->flags & 8) { + // Interestingly, the fear spell in EOB 1 does not expire. + // I don't know whether this is intended or not. if (_flags.gameID == GI_EOB1 ) { d ^= 4; - } else if (--m->spellStatusLeft <= 0) { - m->spellStatusLeft = 0; - m->flags &= ~8; - } else { - d ^= 4; + } else if (m->spellStatusLeft > 0) { + if (--m->spellStatusLeft == 0) + m->flags &= ~8; + else + d ^= 4; } } int d2 = (d - s) & 7; - if (b + _monsterStepTable0[_flags.gameID == GI_EOB1 ? (d >> 1) : d] == destBlock) { - if (_flags.gameID == GI_EOB1 && !(d & 1)) { - if (d2 >= 5) { + if (_flags.gameID == GI_EOB1) { + if ((b + _monsterStepTable0[d >> 1] == _currentBlock) && !(d & 1)) { + if (d2 >= 5) s = m->dir - 1; - } else if (d2 != 0) { + else if (d2 != 0) s = m->dir + 1; - } walkMonsterNextStep(m, -1, s & 3); return; - } else if (_flags.gameID == GI_EOB2) { + } + } else if (_flags.gameID == GI_EOB2) { + if (b + _monsterStepTable0[d] == destBlock) { if (d & 1) { int e = _monsterStepTable1[((d - 1) << 1) + m->dir]; - if (e && !((_monsterProps[m->type].capsFlags & 0x200) && (rollDice(1, 4) == 4))) { + if (e && (!(_monsterProps[m->type].capsFlags & 0x200) || (rollDice(1, 4) < 4))) { if (walkMonsterNextStep(m, b + e, -1)) return; } diff --git a/engines/kyra/staticres_eob.cpp b/engines/kyra/staticres_eob.cpp index 069bf1337d..57ee737ba0 100644 --- a/engines/kyra/staticres_eob.cpp +++ b/engines/kyra/staticres_eob.cpp @@ -1241,6 +1241,9 @@ void EobEngine::initSpells() { void DarkMoonEngine::initStaticResource() { int temp; _mainMenuStrings = _staticres->loadStrings(kEob2MainMenuStrings, temp); + _transferConvertTable = _staticres->loadRawData(kEob2TransferConvertTable, temp); + _transferExpTable = _staticres->loadRawDataBe32(kEob2TransferExpTable, temp); + _introStrings = _staticres->loadStrings(kEob2IntroStrings, temp); _cpsFilesIntro = _staticres->loadStrings(kEob2IntroCPSFiles, temp); diff --git a/engines/kyra/timer.cpp b/engines/kyra/timer.cpp index 2ab2b621f3..95c283f063 100644 --- a/engines/kyra/timer.cpp +++ b/engines/kyra/timer.cpp @@ -149,6 +149,8 @@ void TimerManager::setCountdown(uint8 id, int32 countdown) { uint32 curTime = _system->getMillis(); timer->lastUpdate = curTime; timer->nextRun = curTime + countdown * _vm->tickLength(); + if (timer->enabled & 2) + timer->pauseStartTime = curTime; _nextRun = MIN(_nextRun, timer->nextRun); } @@ -177,6 +179,8 @@ int32 TimerManager::getDelay(uint8 id) const { void TimerManager::setNextRun(uint8 id, uint32 nextRun) { Iterator timer = Common::find_if(_timers.begin(), _timers.end(), TimerEqual(id)); if (timer != _timers.end()) { + if (timer->enabled & 2) + timer->pauseStartTime = _system->getMillis(); timer->nextRun = nextRun; return; } diff --git a/engines/kyra/timer_eob.cpp b/engines/kyra/timer_eob.cpp index 61fa554193..caeae8cb29 100644 --- a/engines/kyra/timer_eob.cpp +++ b/engines/kyra/timer_eob.cpp @@ -115,6 +115,7 @@ void EobCoreEngine::setupTimers() { _timer->addTimer(5, TimerV2(timerUpdateTeleporters), 10, true); _timer->addTimer(6, TimerV2(timerUpdateFoodStatus), 1080, true); _timer->addTimer(7, TimerV2(timerUpdateMonsterIdleAnim), 25, true); + _timer->resetNextRun(); } void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, int updateExistingTimer) { @@ -132,6 +133,7 @@ void EobCoreEngine::setCharEventTimer(int charIndex, uint32 countdown, int evnt, if (ntime < _timer->getNextRun(timerId)) _timer->setNextRun(timerId, ntime); + _timer->resetNextRun(); if (updateExistingTimer) { bool updated = false; @@ -194,6 +196,7 @@ void EobCoreEngine::setupCharacterTimers() { _timer->setCountdown(0x30 | i, (nextTimer - ctime) / _tickLength); } } + _timer->resetNextRun(); } void EobCoreEngine::advanceTimers(uint32 millis) { diff --git a/engines/kyra/timer_lol.cpp b/engines/kyra/timer_lol.cpp index 5a6677a4f6..d0b4062a65 100644 --- a/engines/kyra/timer_lol.cpp +++ b/engines/kyra/timer_lol.cpp @@ -45,6 +45,7 @@ void LoLEngine::setupTimers() { _timer->addTimer(9, TimerV2(timerUpdatePortraitAnimations), 10, true); _timer->addTimer(10, TimerV2(timerUpdateLampState), 360, true); _timer->addTimer(11, TimerV2(timerFadeMessageText), 360, false); + _timer->resetNextRun(); } void LoLEngine::timerProcessMonsters(int timerNum) { -- cgit v1.2.3