diff options
author | Strangerke | 2016-09-28 00:29:07 +0200 |
---|---|---|
committer | Strangerke | 2016-09-28 00:29:07 +0200 |
commit | 9ca8d6511306724a08318076e74c6f52a7531559 (patch) | |
tree | b7bc054f550897c0ee7dcd58ebcc48bcb67759a7 | |
parent | bceeee08d0c8a0d83ad432bbc00e6ddc72438fff (diff) | |
download | scummvm-rg350-9ca8d6511306724a08318076e74c6f52a7531559.tar.gz scummvm-rg350-9ca8d6511306724a08318076e74c6f52a7531559.tar.bz2 scummvm-rg350-9ca8d6511306724a08318076e74c6f52a7531559.zip |
DM: More refactoring
-rw-r--r-- | engines/dm/dungeonman.cpp | 16 | ||||
-rw-r--r-- | engines/dm/gfx.cpp | 160 | ||||
-rw-r--r-- | engines/dm/group.cpp | 254 | ||||
-rw-r--r-- | engines/dm/inventory.cpp | 33 | ||||
-rw-r--r-- | engines/dm/menus.cpp | 97 |
5 files changed, 323 insertions, 237 deletions
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index 0c08caa4ae..5746ee03c2 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -572,6 +572,7 @@ void DungeonMan::loadDungeonFile(Common::InSaveFile *file) { 50 /* Explosion */ }; + Timeline &timeline = *_vm->_timeline; if (_vm->_gameMode != kDMModeLoadSavedGame) decompressDungeonFile(); @@ -690,7 +691,7 @@ void DungeonMan::loadDungeonFile(Common::InSaveFile *file) { _dungeonTextData[i] = dunDataStream->readUint16BE(); if (_vm->_gameMode != kDMModeLoadSavedGame) - _vm->_timeline->_eventMaxCount = 100; + timeline._eventMaxCount = 100; // load things for (uint16 thingType = kDMThingTypeDoor; thingType < kDMThingTypeTotal; ++thingType) { @@ -728,7 +729,7 @@ void DungeonMan::loadDungeonFile(Common::InSaveFile *file) { if (_vm->_gameMode != kDMModeLoadSavedGame) { if ((thingType == kDMThingTypeGroup) || thingType >= kDMThingTypeProjectile) - _vm->_timeline->_eventMaxCount += _dungeonFileHeader._thingCounts[thingType]; + timeline._eventMaxCount += _dungeonFileHeader._thingCounts[thingType]; for (uint16 i = 0; i < additionalThingCounts[thingType]; ++i) (_thingData[thingType] + (thingCount + i) * thingStoreWordCount)[0] = Thing::_none.toUint16(); @@ -1439,6 +1440,9 @@ Thing DungeonMan::getDiscardThing(uint16 thingType) { if (thingType == kDMThingTypeExplosion) return Thing::_none; + GroupMan &groupMan = *_vm->_groupMan; + ProjExpl &projExpl = *_vm->_projexpl; + int16 currentMapIdx = _currMapIndex; uint16 mapIndex = lastDiscardedThingMapIndex[thingType]; if ((mapIndex == _partyMapIndex) && (++mapIndex >= _dungeonFileHeader._mapCount)) @@ -1473,12 +1477,12 @@ Thing DungeonMan::getDiscardThing(uint16 thingType) { case kDMThingTypeProjectile: setCurrentMap(mapIndex); if (thingType == kDMThingTypeGroup) { - _vm->_groupMan->dropGroupPossessions(currMapX, currMapY, squareThing, kDMSoundModeDoNotPlaySound); - _vm->_groupMan->groupDelete(currMapX, currMapY); + groupMan.dropGroupPossessions(currMapX, currMapY, squareThing, kDMSoundModeDoNotPlaySound); + groupMan.groupDelete(currMapX, currMapY); } else { - _vm->_projexpl->projectileDeleteEvent(squareThing); + projExpl.projectileDeleteEvent(squareThing); unlinkThingFromList(squareThing, Thing(0), currMapX, currMapY); - _vm->_projexpl->projectileDelete(squareThing, 0, currMapX, currMapY); + projExpl.projectileDelete(squareThing, 0, currMapX, currMapY); } break; case kDMThingTypeArmour: diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 3bc6b0e78a..39ae3da50f 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -763,6 +763,8 @@ void DisplayMan::drawDoorButton(int16 doorButtonOrdinal, DoorButton doorButton) } }; + DungeonMan &dungeon = *_vm->_dungeonMan; + if (doorButtonOrdinal) { doorButtonOrdinal--; @@ -776,10 +778,10 @@ void DisplayMan::drawDoorButton(int16 doorButtonOrdinal, DoorButton doorButton) if (doorButton == kDMDoorButtonD1C) { bitmap = getNativeBitmapOrGraphic(nativeBitmapIndex); - _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.left = coordSetRedEagle[0]; - _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.right = coordSetRedEagle[1]; - _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.top = coordSetRedEagle[2]; - _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.bottom = coordSetRedEagle[3]; + dungeon._dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.left = coordSetRedEagle[0]; + dungeon._dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.right = coordSetRedEagle[1]; + dungeon._dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.top = coordSetRedEagle[2]; + dungeon._dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn]._rect.bottom = coordSetRedEagle[3]; } else { doorButtonOrdinal = kDMDerivedBitmapFirstDoorButton + (doorButtonOrdinal * 2) + ((doorButton != kDMDoorButtonD3R) ? 0 : (int16)doorButton - 1); if (!isDerivedBitmapInCache(doorButtonOrdinal)) { @@ -1109,12 +1111,14 @@ void DisplayMan::drawDoor(uint16 doorThingIndex, DoorState doorState, int16 *doo return; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; + DoorFrames *doorFramesTemp = doorFrames; - Door *door = (Door *)(_vm->_dungeonMan->_thingData[kDMThingTypeDoor]) + doorThingIndex; + Door *door = (Door *)(dungeon._thingData[kDMThingTypeDoor]) + doorThingIndex; uint16 doorType = door->getType(); memmove(_tmpBitmap, getNativeBitmapOrGraphic(doorNativeBitmapIndices[doorType]), byteCount * 2); drawDoorOrnament(door->getOrnOrdinal(), doorOrnament); - if (getFlag(_vm->_dungeonMan->_currMapDoorInfo[doorType]._attributes, kDMMaskDoorInfoAnimated)) { + if (getFlag(dungeon._currMapDoorInfo[doorType]._attributes, kDMMaskDoorInfoAnimated)) { if (_vm->getRandomNumber(2)) flipBitmapHorizontal(_tmpBitmap, doorFramesTemp->_closedOrDestroyed._srcByteWidth, doorFramesTemp->_closedOrDestroyed._srcHeight); @@ -1207,12 +1211,14 @@ void DisplayMan::drawDoorOrnament(int16 doorOrnOrdinal, DoorOrnament doorOrnamen } void DisplayMan::drawCeilingPit(int16 nativeBitmapIndex, Frame *frame, int16 mapX, int16 mapY, bool flipHorizontal) { - int16 mapIndex = _vm->_dungeonMan->getLocationAfterLevelChange(_vm->_dungeonMan->_currMapIndex, -1, &mapX, &mapY); + DungeonMan &dungeon = *_vm->_dungeonMan; + + int16 mapIndex = dungeon.getLocationAfterLevelChange(dungeon._currMapIndex, -1, &mapX, &mapY); if (mapIndex < 0) return; - int16 mapSquare = _vm->_dungeonMan->_dungeonMapData[mapIndex][mapX][mapY]; + int16 mapSquare = dungeon._dungeonMapData[mapIndex][mapX][mapY]; if ((Square(mapSquare).getType() == kDMElementTypePit) && getFlag(mapSquare, kDMSquareMaskPitOpen)) { if (flipHorizontal) drawFloorPitOrStairsBitmapFlippedHorizontally(nativeBitmapIndex, *frame); @@ -1272,7 +1278,9 @@ void DisplayMan::drawSquareD3L(Direction dir, int16 posX, int16 posY) { uint16 squareAspect[5]; CellOrder order; bool skip = false; - _vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY); + DungeonMan &dungeon = *_vm->_dungeonMan; + + dungeon.setSquareAspect(squareAspect, dir, posX, posY); switch (squareAspect[kDMSquareAspectElement]) { case kDMElementTypeStairsFront: if (squareAspect[kDMSquareAspectStairsUp]) @@ -1434,7 +1442,9 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) { CellOrder order; bool skip = false; - _vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY); + DungeonMan &dungeon = *_vm->_dungeonMan; + + dungeon.setSquareAspect(squareAspect, dir, posX, posY); switch (squareAspect[kDMSquareAspectElement]) { case kDMElementTypeStairsFront: if (squareAspect[kDMSquareAspectStairsUp]) @@ -1459,7 +1469,7 @@ void DisplayMan::drawSquareD3C(Direction dir, int16 posX, int16 posY) { drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD3C, doorFrameLeftD3C); memmove(_tmpBitmap, _bitmapWallSetDoorFrameLeftD3C, 32 * 44); drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD3C); - if (((Door *)_vm->_dungeonMan->_thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) + if (((Door *)dungeon._thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD3C); drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState], @@ -1682,7 +1692,8 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) { uint16 squareAspect[5]; bool skip = false; - _vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY); + DungeonMan &dungeon = *_vm->_dungeonMan; + dungeon.setSquareAspect(squareAspect, dir, posX, posY); switch (squareAspect[kDMSquareAspectElement]) { case kDMElementTypeStairsFront: if (squareAspect[kDMSquareAspectStairsUp]) @@ -1709,7 +1720,7 @@ void DisplayMan::drawSquareD2C(Direction dir, int16 posX, int16 posY) { drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD2C, doorFrameLeftD2C); memcpy(_tmpBitmap, _bitmapWallSetDoorFrameLeftD2C, 48 * 65); drawDoorFrameBitmapFlippedHorizontally(_tmpBitmap, &doorFrameRightD2C); - if (((Door *)_vm->_dungeonMan->_thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) + if (((Door *)dungeon._thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD2C); drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState], @@ -1921,8 +1932,10 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) { uint16 squareAspect[5]; bool skip = false; - _vm->_dungeonMan->setSquareAspect(squareAspect, dir, posX, posY); - switch (_vm->_dungeonMan->_squareAheadElement = (ElementType)squareAspect[kDMSquareAspectElement]) { + DungeonMan &dungeon = *_vm->_dungeonMan; + + dungeon.setSquareAspect(squareAspect, dir, posX, posY); + switch (dungeon._squareAheadElement = (ElementType)squareAspect[kDMSquareAspectElement]) { case kDMElementTypeStairsFront: if (squareAspect[kDMSquareAspectStairsUp]) drawFloorPitOrStairsBitmap(_stairsNativeBitmapIndexUpFrontD1C, frameStairsUpFrontD1C); @@ -1935,9 +1948,9 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) { drawCeilingPit(kDMGraphicIdxCeilingPitD1C, &frameCeilingPitD1C, posX, posY, false); break; case kDMElementTypeWall: - _vm->_dungeonMan->_isFacingAlcove = false; - _vm->_dungeonMan->_isFacingViAltar = false; - _vm->_dungeonMan->_isFacingFountain = false; + dungeon._isFacingAlcove = false; + dungeon._isFacingViAltar = false; + dungeon._isFacingFountain = false; if (championMan._party._event73Count_ThievesEye) { isDerivedBitmapInCache(kDMDerivedBitmapThievesEyeVisibleArea); blitToBitmap(_bitmapViewport, getDerivedBitmap(kDMDerivedBitmapThievesEyeVisibleArea), @@ -1965,7 +1978,7 @@ void DisplayMan::drawSquareD1C(Direction dir, int16 posX, int16 posY) { drawWallSetBitmap(_bitmapWallSetDoorFrameTopD1LCR, doorFrameTopD1C); drawWallSetBitmap(_bitmapWallSetDoorFrameLeftD1C, _doorFrameLeftD1C); drawWallSetBitmap(_bitmapWallSetDoorFrameRightD1C, _doorFrameRightD1C); - if (((Door *)_vm->_dungeonMan->_thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) + if (((Door *)dungeon._thingData[kDMThingTypeDoor])[squareAspect[kDMSquareAspectDoorThingIndex]].hasButton()) drawDoorButton(_vm->indexToOrdinal(k0_DoorButton), kDMDoorButtonD1C); drawDoor(squareAspect[kDMSquareAspectDoorThingIndex], (DoorState)squareAspect[kDMSquareAspectDoorState], @@ -2104,15 +2117,17 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) { static Frame floorFrame(0, 223, 66, 135, 112, 70, 0, 0); // @ K0013_s_Frame_Floor static Frame frameWallD3L2 = Frame(0, 15, 25, 73, 8, 49, 0, 0); // @ G0711_s_Graphic558_Frame_Wall_D3L2 + DungeonMan &dungeon = *_vm->_dungeonMan; + if (_drawFloorAndCeilingRequested) drawFloorAndCeiling(); _useByteBoxCoordinates = true; for (int16 i = 0; i < 6; ++i) - _vm->_dungeonMan->_dungeonViewClickableBoxes[i].setToZero(); + dungeon._dungeonViewClickableBoxes[i].setToZero(); for (uint16 i = 0; i < 6; ++i) - _vm->_dungeonMan->_dungeonViewClickableBoxes[i]._rect.left = 255; + dungeon._dungeonViewClickableBoxes[i]._rect.left = 255; _useFlippedWallAndFootprintsBitmap = (posX + posY + dir) & 1; if (_useFlippedWallAndFootprintsBitmap) { @@ -2131,67 +2146,67 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) { drawWallSetBitmap(_bitmapFloor, floorFrame); } - if (_vm->_dungeonMan->getRelSquareType(dir, 3, -2, posX, posY) == kDMElementTypeWall) + if (dungeon.getRelSquareType(dir, 3, -2, posX, posY) == kDMElementTypeWall) drawWallSetBitmap(_bitmapWallSetD3L2, frameWallD3L2); - if (_vm->_dungeonMan->getRelSquareType(dir, 3, 2, posX, posY) == kDMElementTypeWall) + if (dungeon.getRelSquareType(dir, 3, 2, posX, posY) == kDMElementTypeWall) drawWallSetBitmap(_bitmapWallSetD3R2, _frameWallD3R2); int16 tmpPosX = posX; int16 tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 4, -1, tmpPosX, tmpPosY); - drawObjectsCreaturesProjectilesExplosions(_vm->_dungeonMan->getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kViewSquareD4L, kDMCellOrderBackLeft); + dungeon.mapCoordsAfterRelMovement(dir, 4, -1, tmpPosX, tmpPosY); + drawObjectsCreaturesProjectilesExplosions(dungeon.getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kViewSquareD4L, kDMCellOrderBackLeft); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 4, 1, tmpPosX, tmpPosY); - drawObjectsCreaturesProjectilesExplosions(_vm->_dungeonMan->getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kDMViewSquareD4R, kDMCellOrderBackLeft); + dungeon.mapCoordsAfterRelMovement(dir, 4, 1, tmpPosX, tmpPosY); + drawObjectsCreaturesProjectilesExplosions(dungeon.getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kDMViewSquareD4R, kDMCellOrderBackLeft); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 4, 0, tmpPosX, tmpPosY); - drawObjectsCreaturesProjectilesExplosions(_vm->_dungeonMan->getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kDMViewSquareD4C, kDMCellOrderBackLeft); + dungeon.mapCoordsAfterRelMovement(dir, 4, 0, tmpPosX, tmpPosY); + drawObjectsCreaturesProjectilesExplosions(dungeon.getSquareFirstObject(tmpPosX, tmpPosY), dir, tmpPosX, tmpPosY, kDMViewSquareD4C, kDMCellOrderBackLeft); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 3, -1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 3, -1, tmpPosX, tmpPosY); drawSquareD3L(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 3, 1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 3, 1, tmpPosX, tmpPosY); drawSquareD3R(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 3, 0, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 3, 0, tmpPosX, tmpPosY); drawSquareD3C(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 2, -1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 2, -1, tmpPosX, tmpPosY); drawSquareD2L(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 2, 1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 2, 1, tmpPosX, tmpPosY); drawSquareD2R(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 2, 0, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 2, 0, tmpPosX, tmpPosY); drawSquareD2C(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 1, -1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 1, -1, tmpPosX, tmpPosY); drawSquareD1L(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 1, 1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 1, 1, tmpPosX, tmpPosY); drawSquareD1R(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 1, 0, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 1, 0, tmpPosX, tmpPosY); drawSquareD1C(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 0, -1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 0, -1, tmpPosX, tmpPosY); drawSquareD0L(dir, tmpPosX, tmpPosY); tmpPosX = posX; tmpPosY = posY; - _vm->_dungeonMan->mapCoordsAfterRelMovement(dir, 0, 1, tmpPosX, tmpPosY); + dungeon.mapCoordsAfterRelMovement(dir, 0, 1, tmpPosX, tmpPosY); drawSquareD0R(dir, tmpPosX, tmpPosY); drawSquareD0C(dir, posX, posY); @@ -2203,8 +2218,8 @@ void DisplayMan::drawDungeon(Direction dir, int16 posX, int16 posY) { _bitmapWallSetWallD0R = _bitmapWallD0RNative; } - drawViewport((_vm->_dungeonMan->_partyMapIndex != kDMMapIndexEntrance) ? 1 : 0); - if (_vm->_dungeonMan->_partyMapIndex != kDMMapIndexEntrance) + drawViewport((dungeon._partyMapIndex != kDMMapIndexEntrance) ? 1 : 0); + if (dungeon._partyMapIndex != kDMMapIndexEntrance) drawFloorAndCeiling(); } @@ -2356,8 +2371,10 @@ void DisplayMan::loadCurrentMapGraphics() { 3}; /* Arched Alcove */ static int16 g193_FountainOrnIndices[k1_FountainOrnCount] = {35}; // @ G0193_ai_Graphic558_FountainOrnamentIndices - loadFloorSet(_vm->_dungeonMan->_currMap->_floorSet); - loadWallSet(_vm->_dungeonMan->_currMap->_wallSet); + DungeonMan &dungeon = *_vm->_dungeonMan; + + loadFloorSet(dungeon._currMap->_floorSet); + loadWallSet(dungeon._currMap->_wallSet); _useByteBoxCoordinates = true; @@ -2378,7 +2395,7 @@ void DisplayMan::loadCurrentMapGraphics() { copyBitmapAndFlipHorizontal(_bitmapWallD0RNative = _bitmapWallSetWallD0R, _bitmapWallD0LFlipped, _frameWalls163[kDMViewSquareD0L]._srcByteWidth, _frameWalls163[kDMViewSquareD0L]._srcHeight); - int16 val = _vm->_dungeonMan->_currMap->_wallSet * k18_StairsGraphicCount + k90_FirstStairs; + int16 val = dungeon._currMap->_wallSet * k18_StairsGraphicCount + k90_FirstStairs; _stairsNativeBitmapIndexUpFrontD3L = val++; _stairsNativeBitmapIndexUpFrontD3C = val++; _stairsNativeBitmapIndexUpFrontD2L = val++; @@ -2405,8 +2422,8 @@ void DisplayMan::loadCurrentMapGraphics() { _currMapFountainOrnIndices[i] = -1; uint16 doorSets[2]; - doorSets[0] = _vm->_dungeonMan->_currMap->_doorSet0; - doorSets[1] = _vm->_dungeonMan->_currMap->_doorSet1; + doorSets[0] = dungeon._currMap->_doorSet0; + doorSets[1] = dungeon._currMap->_doorSet1; for (uint16 doorSet = 0; doorSet <= 1; doorSet++) { int16 counter = k108_FirstDoorSet + (doorSets[doorSet] * k3_DoorSetGraphicsCount); _doorNativeBitmapIndexFrontD3LCR[doorSet] = counter++; @@ -2416,7 +2433,7 @@ void DisplayMan::loadCurrentMapGraphics() { uint16 alcoveCount = 0; uint16 fountainCount = 0; - Map &currMap = *_vm->_dungeonMan->_currMap; + Map &currMap = *dungeon._currMap; _currMapViAltarIndex = -1; @@ -2671,16 +2688,20 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex if (!wallOrnOrd) return false; + wallOrnOrd--; int16 wallOrnamentIndex = wallOrnOrd; int16 ornNativeBitmapIndex = _currMapWallOrnInfo[wallOrnamentIndex].nativeIndice; int16 wallOrnamentCoordinateSetIndex = _currMapWallOrnInfo[wallOrnamentIndex].coordinateSet; byte *ornCoordSet = wallOrnamentCoordSets[wallOrnamentCoordinateSetIndex][viewWallIndex]; - bool isAlcove = _vm->_dungeonMan->isWallOrnAnAlcove(wallOrnamentIndex); + + DungeonMan &dungeon = *_vm->_dungeonMan; + + bool isAlcove = dungeon.isWallOrnAnAlcove(wallOrnamentIndex); unsigned char inscriptionString[70]; - bool isInscription = (wallOrnamentIndex == _vm->_dungeonMan->_currMapInscriptionWallOrnIndex); + bool isInscription = (wallOrnamentIndex == dungeon._currMapInscriptionWallOrnIndex); if (isInscription) - _vm->_dungeonMan->decodeText((char *)inscriptionString, _inscriptionThing, kDMTextTypeInscription); + dungeon.decodeText((char *)inscriptionString, _inscriptionThing, kDMTextTypeInscription); int16 blitPosX; byte *ornBlitBitmap; @@ -2713,14 +2734,13 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex } ornNativeBitmapIndex++; Box tmpBox(ornCoordSet[0], ornCoordSet[1], ornCoordSet[2], ornCoordSet[3]); - _vm->_dungeonMan->_dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn] = tmpBox; - _vm->_dungeonMan->_isFacingAlcove = isAlcove; - _vm->_dungeonMan->_isFacingViAltar = - (wallOrnamentIndex == _currMapViAltarIndex); - _vm->_dungeonMan->_isFacingFountain = false; + dungeon._dungeonViewClickableBoxes[kDMViewCellDoorButtonOrWallOrn] = tmpBox; + dungeon._isFacingAlcove = isAlcove; + dungeon._isFacingViAltar = (wallOrnamentIndex == _currMapViAltarIndex); + dungeon._isFacingFountain = false; for (int16 idx = 0; idx < k1_FountainOrnCount; idx++) { if (_currMapFountainOrnIndices[idx] == wallOrnamentIndex) { - _vm->_dungeonMan->_isFacingFountain = true; + dungeon._isFacingFountain = true; break; } } @@ -3110,6 +3130,8 @@ void DisplayMan::drawObjectsCreaturesProjectilesExplosions(Thing thingParam, Dir if (thingParam == Thing::_endOfList) return; + DungeonMan &dungeon = *_vm->_dungeonMan; + int16 orderedViewCellOrdinals = cellOrder; Group *group = nullptr; Thing groupThing = Thing::_none; @@ -3166,7 +3188,7 @@ void DisplayMan::drawObjectsCreaturesProjectilesExplosions(Thing thingParam, Dir } if ((viewSquareIndex >= kDMViewSquareD3C) && (viewSquareIndex <= kDMViewSquareD0C) && (thingParam.getCell() == cellYellowBear)) { /* Square where objects are visible and object is located on cell being processed */ - objectAspect = &(_objectAspects209[_vm->_dungeonMan->_objectInfos[_vm->_dungeonMan->getObjectInfoIndex(thingParam)]._objectAspectIndex]); + objectAspect = &(_objectAspects209[dungeon._objectInfos[dungeon.getObjectInfoIndex(thingParam)]._objectAspectIndex]); AL_4_nativeBitmapIndex = kDMGraphicIdxFirstObject + objectAspect->_firstNativeBitmapRelativeIndex; useAlcoveObjectImage = (L0135_B_DrawAlcoveObjects && getFlag(objectAspect->_graphicInfo, k0x0010_ObjectAlcoveMask) && (viewLane == kDMViewLaneCenter)); if (useAlcoveObjectImage) @@ -3255,7 +3277,7 @@ T0115015_DrawProjectileAsObject: if (drawingGrabbableObject) { bitmapGreenAnt = bitmapRedBanana; - Box *AL_6_box = &_vm->_dungeonMan->_dungeonViewClickableBoxes[AL_2_viewCell]; + Box *AL_6_box = &dungeon._dungeonViewClickableBoxes[AL_2_viewCell]; if (AL_6_box->_rect.left == 255) { /* If the grabbable object is the first */ *AL_6_box = boxByteGreen; @@ -3273,13 +3295,13 @@ T0115015_DrawProjectileAsObject: AL_6_box->_rect.bottom = MAX(AL_6_box->_rect.bottom, boxByteGreen._rect.bottom); } bitmapRedBanana = bitmapGreenAnt; - _vm->_dungeonMan->_pileTopObject[AL_2_viewCell] = thingParam; /* The object is at the top of the pile */ + dungeon._pileTopObject[AL_2_viewCell] = thingParam; /* The object is at the top of the pile */ } blitToBitmap(bitmapRedBanana, _bitmapViewport, boxByteGreen, AL_4_xPos, 0, getNormalizedByteWidth(byteWidth), k112_byteWidthViewport, kDMColorFlesh, heightRedEagle, k136_heightViewport); if (drawProjectileAsObject) goto T0115171_BackFromT0115015_DrawProjectileAsObject; } - } while ((thingParam = _vm->_dungeonMan->getNextThing(thingParam)) != Thing::_endOfList); + } while ((thingParam = dungeon.getNextThing(thingParam)) != Thing::_endOfList); if (AL_2_viewCell == kDMViewCellAlcove) break; /* End of processing when drawing objects in an alcove */ if (viewSquareIndex < kDMViewSquareD3C) @@ -3291,9 +3313,9 @@ T0115015_DrawProjectileAsObject: ActiveGroup *activeGroup; if (group == nullptr) { /* If all creature data and info has not already been gathered */ - group = (Group *)_vm->_dungeonMan->getThingData(groupThing); + group = (Group *)dungeon.getThingData(groupThing); activeGroup = &_vm->_groupMan->_activeGroups[group->getActiveGroupIndex()]; - CreatureInfo *creatureInfo = &_vm->_dungeonMan->_creatureInfos[group->_type]; + CreatureInfo *creatureInfo = &dungeon._creatureInfos[group->_type]; creatureAspectStruct = &_creatureAspects219[creatureInfo->_creatureAspectIndex]; creatureSize = getFlag(creatureInfo->_attributes, kDMCreatureMaskSize); creatureGraphicInfoGreen = creatureInfo->_graphicInfo; @@ -3545,8 +3567,8 @@ T0115129_DrawProjectiles: thingParam = firstThingToDraw; /* Restart processing list of objects from the beginning. The next loop draws only projectile objects among the list */ do { if ((thingParam.getType() == kDMThingTypeProjectile) && (thingParam.getCell() == cellYellowBear)) { - Projectile *projectile = (Projectile *)_vm->_dungeonMan->getThingData(thingParam); - AL_4_projectileAspect = _vm->_dungeonMan->getProjectileAspect(projectile->_slot); + Projectile *projectile = (Projectile *)dungeon.getThingData(thingParam); + AL_4_projectileAspect = dungeon.getProjectileAspect(projectile->_slot); if (AL_4_projectileAspect < 0) { /* Negative value: projectile aspect is the ordinal of a PROJECTIL_ASPECT */ objectAspect = (ObjectAspect *)&_projectileAspect[_vm->ordinalToIndex(-AL_4_projectileAspect)]; AL_4_nativeBitmapIndex = ((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + kDMGraphicIdxFirstProjectile; @@ -3661,7 +3683,7 @@ T0115129_DrawProjectiles: } } T0115171_BackFromT0115015_DrawProjectileAsObject:; - } while ((thingParam = _vm->_dungeonMan->getNextThing(thingParam)) != Thing::_endOfList); + } while ((thingParam = dungeon.getNextThing(thingParam)) != Thing::_endOfList); } while (remainingViewCellOrdinalsToProcess); /* Draw explosions */ @@ -3677,7 +3699,7 @@ T0115171_BackFromT0115015_DrawProjectileAsObject:; do { if (thingParam.getType() == kDMThingTypeExplosion) { AL_2_cellPurpleMan = thingParam.getCell(); - Explosion *explosion = (Explosion *)_vm->_dungeonMan->getThingData(thingParam); + Explosion *explosion = (Explosion *)dungeon.getThingData(thingParam); AL_4_explosionType = explosion->getType(); bool rebirthExplosion = ((uint16)AL_4_explosionType >= kDMExplosionTypeRebirthStep1); if (rebirthExplosion && ((AL_1_viewSquareExplosionIndex < kDMViewSquareD3CExplosion) || (AL_1_viewSquareExplosionIndex > kDMViewSquareD1CExplosion) || (AL_2_cellPurpleMan != cellYellowBear))) /* If explosion is rebirth and is not visible */ @@ -3693,7 +3715,7 @@ T0115171_BackFromT0115015_DrawProjectileAsObject:; AL_4_explosionAspectIndex = kDMExplosionAspectSmoke; } else { if (AL_4_explosionType == kDMExplosionTypeRebirthStep1) { - objectAspect = (ObjectAspect *)&_projectileAspect[_vm->ordinalToIndex(-_vm->_dungeonMan->getProjectileAspect(Thing::_explLightningBolt))]; + objectAspect = (ObjectAspect *)&_projectileAspect[_vm->ordinalToIndex(-dungeon.getProjectileAspect(Thing::_explLightningBolt))]; bitmapRedBanana = getNativeBitmapOrGraphic(((ProjectileAspect *)objectAspect)->_firstNativeBitmapRelativeIndex + (kDMGraphicIdxFirstProjectile + 1)); explosionCoordinates = rebirthStep1ExplosionCoordinates[AL_1_viewSquareExplosionIndex - 3]; byteWidth = getScaledDimension((((ProjectileAspect *)objectAspect)->_byteWidth), explosionCoordinates[2]); @@ -3797,7 +3819,7 @@ T0115200_DrawExplosion: blitToBitmap(bitmapRedBanana, _bitmapViewport, boxByteGreen, AL_4_xPos, 0, byteWidth, k112_byteWidthViewport, kDMColorFlesh, heightRedEagle, k136_heightViewport); } } - } while ((thingParam = _vm->_dungeonMan->getNextThing(thingParam))!= Thing::_endOfList); + } while ((thingParam = dungeon.getNextThing(thingParam))!= Thing::_endOfList); if ((fluxcageExplosion != 0) && (doorFrontViewDrawingPass != 1) && !_doNotDrawFluxcagesDuringEndgame) { /* Fluxcage is an explosion displayed as a field (like teleporters), above all other graphics */ AL_1_viewSquareExplosionIndex -= 3; /* Convert square index for explosions back to square index */ diff --git a/engines/dm/group.cpp b/engines/dm/group.cpp index c81ee32b73..b1d9766912 100644 --- a/engines/dm/group.cpp +++ b/engines/dm/group.cpp @@ -104,14 +104,16 @@ uint16 GroupMan::getGroupDirections(Group *group, int16 mapIndex) { } int16 GroupMan::getCreatureOrdinalInCell(Group *group, uint16 cell) { - uint16 currMapIndex = _vm->_dungeonMan->_currMapIndex; + DungeonMan &dungeon = *_vm->_dungeonMan; + + uint16 currMapIndex = dungeon._currMapIndex; byte groupCells = getGroupCells(group, currMapIndex); if (groupCells == kDMCreatureTypeSingleCenteredCreature) return _vm->indexToOrdinal(0); int retval = 0; byte creatureIndex = group->getCount(); - if (getFlag(_vm->_dungeonMan->_creatureInfos[group->_type]._attributes, kDMCreatureMaskSize) == kDMCreatureSizeHalf) { + if (getFlag(dungeon._creatureInfos[group->_type]._attributes, kDMCreatureMaskSize) == kDMCreatureSizeHalf) { if ((getGroupDirections(group, currMapIndex) & 1) == (cell & 1)) cell = _vm->turnDirLeft(cell); @@ -139,11 +141,13 @@ uint16 GroupMan::getCreatureValue(uint16 groupVal, uint16 creatureIndex) { } void GroupMan::dropGroupPossessions(int16 mapX, int16 mapY, Thing groupThing, SoundMode soundMode) { - Group *group = (Group *)_vm->_dungeonMan->getThingData(groupThing); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Group *group = (Group *)dungeon.getThingData(groupThing); CreatureType creatureType = group->_type; - if ((soundMode != kDMSoundModeDoNotPlaySound) && getFlag(_vm->_dungeonMan->_creatureInfos[creatureType]._attributes, kDMCreatureMaskDropFixedPoss)) { + if ((soundMode != kDMSoundModeDoNotPlaySound) && getFlag(dungeon._creatureInfos[creatureType]._attributes, kDMCreatureMaskDropFixedPoss)) { int16 creatureIndex = group->getCount(); - uint16 groupCells = getGroupCells(group, _vm->_dungeonMan->_currMapIndex); + uint16 groupCells = getGroupCells(group, dungeon._currMapIndex); do { dropCreatureFixedPossessions(creatureType, mapX, mapY, (groupCells == kDMCreatureTypeSingleCenteredCreature) ? (uint16)kDMCreatureTypeSingleCenteredCreature : getCreatureValue(groupCells, creatureIndex), soundMode); @@ -155,7 +159,7 @@ void GroupMan::dropGroupPossessions(int16 mapX, int16 mapY, Thing groupThing, So bool weaponDropped = false; Thing nextThing; do { - nextThing = _vm->_dungeonMan->getNextThing(currentThing); + nextThing = dungeon.getNextThing(currentThing); currentThing = _vm->thingWithNewCell(currentThing, _vm->getRandomNumber(4)); if ((currentThing).getType() == kDMThingTypeWeapon) { weaponDropped = true; @@ -228,6 +232,8 @@ void GroupMan::dropCreatureFixedPossessions(CreatureType creatureType, int16 map 0 }; + DungeonMan &dungeon = *_vm->_dungeonMan; + uint16 *fixedPossessions; bool cursedPossessions = false; switch (creatureType) { @@ -282,11 +288,11 @@ void GroupMan::dropCreatureFixedPossessions(CreatureType creatureType, int16 map currFixedPossession -= kDMObjectInfoIndexFirstWeapon; } - Thing nextUnusedThing = _vm->_dungeonMan->getUnusedThing(currThingType); + Thing nextUnusedThing = dungeon.getUnusedThing(currThingType); if ((nextUnusedThing) == Thing::_none) continue; - Weapon *currWeapon = (Weapon *)_vm->_dungeonMan->getThingData(nextUnusedThing); + Weapon *currWeapon = (Weapon *)dungeon.getThingData(nextUnusedThing); /* The same pointer type is used no matter the actual type k5_WeaponThingType, k6_ArmourThingType or k10_JunkThingType */ currWeapon->setType(currFixedPossession); currWeapon->setCursed(cursedPossessions); @@ -354,16 +360,18 @@ bool GroupMan::isDestVisibleFromSource(uint16 dir, int16 srcMapX, int16 srcMapY, } bool GroupMan::groupIsDoorDestoryedByAttack(uint16 mapX, uint16 mapY, int16 attack, bool magicAttack, int16 ticks) { - Door *curDoor = (Door *)_vm->_dungeonMan->getSquareFirstThingData(mapX, mapY); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Door *curDoor = (Door *)dungeon.getSquareFirstThingData(mapX, mapY); if ((magicAttack && !curDoor->isMagicDestructible()) || (!magicAttack && !curDoor->isMeleeDestructible())) return false; - if (attack >= _vm->_dungeonMan->_currMapDoorInfo[curDoor->getType()]._defense) { - byte *curSquare = &_vm->_dungeonMan->_currMapData[mapX][mapY]; + if (attack >= dungeon._currMapDoorInfo[curDoor->getType()]._defense) { + byte *curSquare = &dungeon._currMapData[mapX][mapY]; if (Square(*curSquare).getDoorState() == kDMDoorStateClosed) { if (ticks) { TimelineEvent newEvent; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, _vm->_gameTime + ticks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, _vm->_gameTime + ticks); newEvent._type = kDMEventTypeDoorDestruction; newEvent._priority = 0; newEvent._Bu._location._mapX = mapX; @@ -379,21 +387,25 @@ bool GroupMan::groupIsDoorDestoryedByAttack(uint16 mapX, uint16 mapY, int16 atta } Thing GroupMan::groupGetThing(int16 mapX, int16 mapY) { - Thing curThing = _vm->_dungeonMan->getSquareFirstThing(mapX, mapY); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Thing curThing = dungeon.getSquareFirstThing(mapX, mapY); while ((curThing != Thing::_endOfList) && (curThing.getType() != kDMThingTypeGroup)) - curThing = _vm->_dungeonMan->getNextThing(curThing); + curThing = dungeon.getNextThing(curThing); return curThing; } int16 GroupMan::groupGetDamageCreatureOutcome(Group *group, uint16 creatureIndex, int16 mapX, int16 mapY, int16 damage, bool notMoving) { + DungeonMan &dungeon = *_vm->_dungeonMan; + CreatureType creatureType = group->_type; - CreatureInfo *creatureInfo = &_vm->_dungeonMan->_creatureInfos[creatureType]; + CreatureInfo *creatureInfo = &dungeon._creatureInfos[creatureType]; if (getFlag(creatureInfo->_attributes, kDMCreatureMaskArchenemy)) /* Lord Chaos cannot be damaged */ return kDMKillOutcomeNoCreaturesInGroup; if (group->_health[creatureIndex] <= damage) { - uint16 groupCells = getGroupCells(group, _vm->_dungeonMan->_currMapIndex); + uint16 groupCells = getGroupCells(group, dungeon._currMapIndex); uint16 cell = (groupCells == kDMCreatureTypeSingleCenteredCreature) ? (uint16)kDMCreatureTypeSingleCenteredCreature : getCreatureValue(groupCells, creatureIndex); uint16 creatureCount = group->getCount(); uint16 retVal; @@ -405,14 +417,14 @@ int16 GroupMan::groupGetDamageCreatureOutcome(Group *group, uint16 creatureIndex } retVal = kDMKillOutcomeAllCreaturesInGroup; } else { /* If there are several creatures in the group */ - uint16 groupDirections = getGroupDirections(group, _vm->_dungeonMan->_currMapIndex); + uint16 groupDirections = getGroupDirections(group, dungeon._currMapIndex); if (getFlag(creatureInfo->_attributes, kDMCreatureMaskDropFixedPoss)) { if (notMoving) dropCreatureFixedPossessions(creatureType, mapX, mapY, cell, kDMSoundModePlayOneTickLater); else _dropMovingCreatureFixedPossessionsCell[_dropMovingCreatureFixedPossCellCount++] = cell; } - bool currentMapIsPartyMap = (_vm->_dungeonMan->_currMapIndex == _vm->_dungeonMan->_partyMapIndex); + bool currentMapIsPartyMap = (dungeon._currMapIndex == dungeon._partyMapIndex); ActiveGroup *activeGroup = nullptr; if (currentMapIsPartyMap) activeGroup = &_activeGroups[group->getActiveGroupIndex()]; @@ -421,7 +433,7 @@ int16 GroupMan::groupGetDamageCreatureOutcome(Group *group, uint16 creatureIndex TimelineEvent *curEvent = _vm->_timeline->_events; for (uint16 eventIndex = 0; eventIndex < _vm->_timeline->_eventMaxCount; eventIndex++) { uint16 curEventType = curEvent->_type; - if ((_vm->getMap(curEvent->_mapTime) == _vm->_dungeonMan->_currMapIndex) && + if ((_vm->getMap(curEvent->_mapTime) == dungeon._currMapIndex) && (curEvent->_Bu._location._mapX == mapX) && (curEvent->_Bu._location._mapY == mapY) && (curEventType > kDMEventTypeUpdateAspectGroup) && @@ -462,8 +474,8 @@ int16 GroupMan::groupGetDamageCreatureOutcome(Group *group, uint16 creatureIndex activeGroup->_aspect[curCreatureIndex] = activeGroup->_aspect[nextCreatureIndex]; } groupCells &= 0x003F; - _vm->_dungeonMan->setGroupCells(group, groupCells, _vm->_dungeonMan->_currMapIndex); - _vm->_dungeonMan->setGroupDirections(group, groupDirections, _vm->_dungeonMan->_currMapIndex); + dungeon.setGroupCells(group, groupCells, dungeon._currMapIndex); + dungeon.setGroupDirections(group, groupDirections, dungeon._currMapIndex); group->setCount(group->getCount() - 1); retVal = kDMKillOutcomeSomeCreaturesInGroup; } @@ -492,12 +504,14 @@ void GroupMan::groupDelete(int16 mapX, int16 mapY) { if (groupThing == Thing::_endOfList) return; - Group *group = (Group *)_vm->_dungeonMan->getThingData(groupThing); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Group *group = (Group *)dungeon.getThingData(groupThing); for (uint16 i = 0; i < 4; ++i) group->_health[i] = 0; _vm->_moveSens->getMoveResult(groupThing, mapX, mapY, kDMMapXNotOnASquare, 0); group->_nextThing = Thing::_none; - if (_vm->_dungeonMan->_currMapIndex == _vm->_dungeonMan->_partyMapIndex) { + if (dungeon._currMapIndex == dungeon._partyMapIndex) { _activeGroups[group->getActiveGroupIndex()]._groupThingIndex = -1; _currActiveGroupCount--; } @@ -505,10 +519,12 @@ void GroupMan::groupDelete(int16 mapX, int16 mapY) { } void GroupMan::groupDeleteEvents(int16 mapX, int16 mapY) { + DungeonMan &dungeon = *_vm->_dungeonMan; + TimelineEvent *curEvent = _vm->_timeline->_events; for (int16 eventIndex = 0; eventIndex < _vm->_timeline->_eventMaxCount; eventIndex++) { uint16 curEventType = curEvent->_type; - if ((_vm->getMap(curEvent->_mapTime) == _vm->_dungeonMan->_currMapIndex) && + if ((_vm->getMap(curEvent->_mapTime) == dungeon._currMapIndex) && (curEventType > kDMEventTypeGroupReactionDangerOnSquare - 1) && (curEventType < kDMEventTypeUpdateBehavior3 + 1) && (curEvent->_Bu._location._mapX == mapX) && (curEvent->_Bu._location._mapY == mapY)) { _vm->_timeline->deleteEvent(eventIndex); @@ -582,8 +598,10 @@ void GroupMan::processEvents29to41(int16 eventMapX, int16 eventMapY, TimelineEve #define AL0451_i_DistanceYToParty L0451_i_Multiple #define AL0451_i_TargetMapY L0451_i_Multiple + DungeonMan &dungeon = *_vm->_dungeonMan; + /* If the party is not on the map specified in the event and the event type is not one of 32, 33, 37, 38 then the event is ignored */ - if ((_vm->_dungeonMan->_currMapIndex != _vm->_dungeonMan->_partyMapIndex) + if ((dungeon._currMapIndex != dungeon._partyMapIndex) && (eventType != kDMEventTypeUpdateBehaviourGroup) && (eventType != kDMEventTypeUpdateAspectGroup) && (eventType != kDMEventTypeUpdateBehavior0) && (eventType != kDMEventTypeUpdateAspectCreature0)) return; @@ -595,16 +613,16 @@ void GroupMan::processEvents29to41(int16 eventMapX, int16 eventMapY, TimelineEve ChampionMan &championMan = *_vm->_championMan; - Group *curGroup = (Group *)_vm->_dungeonMan->getThingData(groupThing); - CreatureInfo creatureInfo = _vm->_dungeonMan->_creatureInfos[curGroup->_type]; + Group *curGroup = (Group *)dungeon.getThingData(groupThing); + CreatureInfo creatureInfo = dungeon._creatureInfos[curGroup->_type]; /* Update the event */ TimelineEvent nextEvent; - nextEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, _vm->_gameTime); + nextEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, _vm->_gameTime); nextEvent._priority = kDMMovementTicksImmobile - creatureInfo._movementTicks; /* The fastest creatures (with small MovementTicks value) get higher event priority */ nextEvent._Bu._location._mapX = eventMapX; nextEvent._Bu._location._mapY = eventMapY; /* If the creature is not on the party map then try and move the creature in a random direction and place a new event 37 in the timeline for the next creature movement */ - if (_vm->_dungeonMan->_currMapIndex != _vm->_dungeonMan->_partyMapIndex) { + if (dungeon._currMapIndex != dungeon._partyMapIndex) { if (isMovementPossible(&creatureInfo, eventMapX, eventMapY, AL0446_i_Direction = _vm->getRandomNumber(4), false)) { /* BUG0_67 A group that is not on the party map may wrongly move or not move into a teleporter. Normally, a creature type with Wariness >= 10 (Vexirk, Materializer / Zytaz, Demon, Lord Chaos, Red Dragon / Dragon) would only move into a teleporter if the creature type is allowed on the destination map. However, the variable G0380_T_CurrentGroupThing identifying the group is not set before being used by F0139_DUNGEON_IsCreatureAllowedOnMap called by f202_isMovementPossible so the check to see if the creature type is allowed may operate on another creature type and thus return an incorrect result, causing the creature to teleport while it should not, or not to teleport while it should */ AL0450_i_DestinationMapX = eventMapX; AL0451_i_DestinationMapY = eventMapY; @@ -616,7 +634,7 @@ void GroupMan::processEvents29to41(int16 eventMapX, int16 eventMapY, TimelineEve nextEvent._Bu._location._mapY = _vm->_moveSens->_moveResultMapY; } nextEvent._type = kDMEventTypeUpdateBehaviourGroup; - AL0446_i_Ticks = MAX(ABS(_vm->_dungeonMan->_currMapIndex - _vm->_dungeonMan->_partyMapIndex) << 4, creatureInfo._movementTicks << 1); + AL0446_i_Ticks = MAX(ABS(dungeon._currMapIndex - dungeon._partyMapIndex) << 4, creatureInfo._movementTicks << 1); /* BUG0_68 A group moves or acts with a wrong timing. Event is added below but L0465_s_NextEvent.C.Ticks has not been initialized. No consequence while the group is not on the party map. When the party enters the group map the first group event may have a wrong timing */ T0209005_AddEventAndReturn: nextEvent._mapTime += AL0446_i_Ticks; @@ -669,14 +687,14 @@ T0209005_AddEventAndReturn: AL0447_i_Behavior = curGroup->getBehaviour(); uint16 creatureCount = curGroup->getCount(); int16 creatureSize = getFlag(creatureInfo._attributes, kDMCreatureMaskSize); - AL0450_i_DistanceXToParty = ABS(eventMapX - _vm->_dungeonMan->_partyMapX); - AL0451_i_DistanceYToParty = ABS(eventMapY - _vm->_dungeonMan->_partyMapY); + AL0450_i_DistanceXToParty = ABS(eventMapX - dungeon._partyMapX); + AL0451_i_DistanceYToParty = ABS(eventMapY - dungeon._partyMapY); _currentGroupMapX = eventMapX; _currentGroupMapY = eventMapY; _currGroupThing = groupThing; _groupMovementTestedDirections[0] = 0; - _currGroupDistanceToParty = getDistanceBetweenSquares(eventMapX, eventMapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY); - _currGroupPrimaryDirToParty = getDirsWhereDestIsVisibleFromSource(eventMapX, eventMapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY); + _currGroupDistanceToParty = getDistanceBetweenSquares(eventMapX, eventMapY, dungeon._partyMapX, dungeon._partyMapY); + _currGroupPrimaryDirToParty = getDirsWhereDestIsVisibleFromSource(eventMapX, eventMapY, dungeon._partyMapX, dungeon._partyMapY); _currGroupSecondaryDirToParty = _vm->_projexpl->_secondaryDirToOrFromParty; int32 nextAspectUpdateTime = 0; bool notUpdateBehaviorFl = true; @@ -694,8 +712,8 @@ T0209005_AddEventAndReturn: groupDeleteEvents(eventMapX, eventMapY); goto T0209044_SetBehavior6_Attack; } - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; return; case kDMEventTypeCreateReactionHitByProjectile: /* This event is used for the reaction of a group after a projectile impacted with one creature in the group (some creatures may have been killed) */ if ((AL0447_i_Behavior == kDMBehaviorAttack) || (AL0447_i_Behavior == kDMBehaviorFlee)) /* If the creature is attacking the party or fleeing from the target then there is no reaction */ @@ -722,13 +740,13 @@ T0209005_AddEventAndReturn: nextEvent._type = (TimelineEventType)nextType; if (groupGetDistanceToVisibleParty(curGroup, kDMWholeCreatureGroup, eventMapX, eventMapY)) { if ((AL0447_i_Behavior != kDMBehaviorAttack) && (AL0447_i_Behavior != kDMBehaviorFlee)) { - if (_vm->getDistance(_vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, eventMapX, eventMapY) <= 1) + if (_vm->getDistance(dungeon._partyMapX, dungeon._partyMapY, eventMapX, eventMapY) <= 1) goto T0209044_SetBehavior6_Attack; if (((AL0447_i_Behavior == kDMBehaviorWander) || (AL0447_i_Behavior == kDMBehaviorUnknown3)) && (AL0447_i_Behavior != kDMBehaviorApproach)) /* BUG0_00 Useless code. Behavior cannot be 3 because this value is never used. Moreover, the second condition in the && is redundant (if the value is 0 or 3, it cannot be 7). The actual condition is: if (AL0447_i_Behavior == k0_behavior_WANDER) */ goto T0209054_SetBehavior7_Approach; } - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; } if (AL0447_i_Behavior == kDMBehaviorAttack) { AL0446_i_CreatureAspectIndex = eventType - kDMEventTypeUpdateAspectCreature0; /* Value -1 for event 32, meaning aspect will be updated for all creatures in the group */ @@ -755,8 +773,8 @@ T0209044_SetBehavior6_Attack: if (eventType == kDMEventTypeCreateReactionHitByProjectile) { groupDeleteEvents(eventMapX, eventMapY); } - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; curGroup->setBehaviour(kDMBehaviorAttack); AL0446_i_Direction = _currGroupPrimaryDirToParty; for (AL0447_i_CreatureIndex = creatureCount; AL0447_i_CreatureIndex >= 0; AL0447_i_CreatureIndex--) { @@ -779,8 +797,8 @@ T0209044_SetBehavior6_Attack: if (AL0447_i_Behavior != kDMBehaviorUnknown2) { /* BUG0_00 Useless code. Behavior cannot be 2 because this value is never used */ T0209054_SetBehavior7_Approach: curGroup->setBehaviour(kDMBehaviorApproach); - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; nextEvent._mapTime += 1; goto T0209134_SetEvent37; } @@ -828,8 +846,8 @@ T0209061_MoveGroup: !getFirstPossibleMovementDirOrdinal(&creatureInfo, eventMapX, eventMapY, false) || _vm->getRandomNumber(2))) goto T0209044_SetBehavior6_Attack; - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; } AL0446_i_Direction = _vm->turnDirRight(AL0446_i_Direction); } while (AL0446_i_Direction != AL0447_i_ReferenceDirection); @@ -868,8 +886,8 @@ T0209073_SetDirectionGroup: T0209081_RunTowardParty: movementTicks++; movementTicks = movementTicks >> 1; /* Running speed is half the movement ticks */ - AL0450_i_TargetMapX = (activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX); - AL0451_i_TargetMapY = (activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY); + AL0450_i_TargetMapX = (activeGroup->_targetMapX = dungeon._partyMapX); + AL0451_i_TargetMapY = (activeGroup->_targetMapY = dungeon._partyMapY); } else { T0209082_WalkTowardTarget: AL0450_i_TargetMapX = activeGroup->_targetMapX; @@ -916,8 +934,8 @@ T0209094_FleeFromTarget: /* If the creature can see the party then update target coordinates */ distanceToVisibleParty = groupGetDistanceToVisibleParty(curGroup, kDMWholeCreatureGroup, eventMapX, eventMapY); if (distanceToVisibleParty) { - AL0450_i_TargetMapX = (activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX); - AL0451_i_TargetMapY = (activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY); + AL0450_i_TargetMapX = (activeGroup->_targetMapX = dungeon._partyMapX); + AL0451_i_TargetMapY = (activeGroup->_targetMapY = dungeon._partyMapY); } else { if (!(--(activeGroup->_delayFleeingFromTarget))) { /* If the creature is not afraid anymore then stop fleeing from target */ T0209096_SetBehavior0_Wander: @@ -928,7 +946,7 @@ T0209096_SetBehavior0_Wander: if (_vm->getRandomNumber(2)) { /* If the creature cannot move and the party is adjacent then stop fleeing */ if (!getFirstPossibleMovementDirOrdinal(&creatureInfo, eventMapX, eventMapY, false)) { - if (_vm->getDistance(eventMapX, eventMapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY) <= 1) + if (_vm->getDistance(eventMapX, eventMapY, dungeon._partyMapX, dungeon._partyMapY) <= 1) goto T0209096_SetBehavior0_Wander; } /* Set creature target to the home square where the creature was located when the party entered the map */ @@ -968,8 +986,8 @@ T0209096_SetBehavior0_Wander: distanceToVisibleParty = groupGetDistanceToVisibleParty(curGroup, AL0447_i_CreatureIndex, eventMapX, eventMapY); /* If the party is visible, update the target coordinates */ if (distanceToVisibleParty) { - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; } /* If there is a single creature in the group that is not full square sized and 1/4 chance */ if (!creatureCount && (creatureSize != kDMCreatureSizeFull) && !((AL0446_i_GroupCellsCriteria = _vm->getRandomNumber(65536)) & 0x00C0)) { @@ -1035,8 +1053,8 @@ T0209096_SetBehavior0_Wander: } else { /* If the party is visible, update target coordinates */ if (groupGetDistanceToVisibleParty(curGroup, kDMWholeCreatureGroup, eventMapX, eventMapY)) { - activeGroup->_targetMapX = _vm->_dungeonMan->_partyMapX; - activeGroup->_targetMapY = _vm->_dungeonMan->_partyMapY; + activeGroup->_targetMapX = dungeon._partyMapX; + activeGroup->_targetMapY = dungeon._partyMapY; setGroupDirection(activeGroup, primaryDirectionToOrFromParty, AL0447_i_CreatureIndex, creatureCount && (creatureSize == kDMCreatureSizeHalf)); nextEvent._mapTime += 2; nextAspectUpdateTime = _vm->filterTime(nextEvent._mapTime); @@ -1077,12 +1095,15 @@ bool GroupMan::isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16 if (creatureInfo->_movementTicks == kDMMovementTicksImmobile) return false; - _vm->_dungeonMan->mapCoordsAfterRelMovement((Direction)dir, 1, 0, mapX, mapY); - uint16 curSquare = _vm->_dungeonMan->_currMapData[mapX][mapY]; + DungeonMan &dungeon = *_vm->_dungeonMan; + + + dungeon.mapCoordsAfterRelMovement((Direction)dir, 1, 0, mapX, mapY); + uint16 curSquare = dungeon._currMapData[mapX][mapY]; int16 curSquareType = Square(curSquare).getType(); _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter = - !(((mapX >= 0) && (mapX < _vm->_dungeonMan->_currMapWidth)) && - ((mapY >= 0) && (mapY < _vm->_dungeonMan->_currMapHeight)) && + !(((mapX >= 0) && (mapX < dungeon._currMapWidth)) && + ((mapY >= 0) && (mapY < dungeon._currMapHeight)) && (curSquareType != kDMElementTypeWall) && (curSquareType != kDMElementTypeStairs) && ((curSquareType != kDMElementTypePit) || (getFlag(curSquare, kDMSquareMaskPitImaginary) && allowMovementOverImaginaryPitsAndFakeWalls) || !getFlag(curSquare, kDMSquareMaskPitOpen) || getFlag(creatureInfo->_attributes, kDMCreatureMaskLevitation)) && @@ -1092,10 +1113,10 @@ bool GroupMan::isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16 return false; if (getFlag(creatureInfo->_attributes, kDMCreatureMaskArchenemy)) { - Thing curThing = _vm->_dungeonMan->getSquareFirstThing(mapX, mapY); + Thing curThing = dungeon.getSquareFirstThing(mapX, mapY); while (curThing != Thing::_endOfList) { if ((curThing).getType() == kDMThingTypeExplosion) { - Teleporter *curTeleporter = (Teleporter *)_vm->_dungeonMan->getThingData(curThing); + Teleporter *curTeleporter = (Teleporter *)dungeon.getThingData(curThing); if (((Explosion *)curTeleporter)->setType(kDMExplosionTypeFluxcage)) { _fluxCages[dir] = true; _fluxCageCount++; @@ -1103,23 +1124,23 @@ bool GroupMan::isMovementPossible(CreatureInfo *creatureInfo, int16 mapX, int16 return false; } } - curThing = _vm->_dungeonMan->getNextThing(curThing); + curThing = dungeon.getNextThing(curThing); } } if ((curSquareType == kDMElementTypeTeleporter) && getFlag(curSquare, kDMSquareMaskTeleporterOpen) && (creatureInfo->getWariness() >= 10)) { - Teleporter *curTeleporter = (Teleporter *)_vm->_dungeonMan->getSquareFirstThingData(mapX, mapY); - if (getFlag(curTeleporter->getScope(), kDMTeleporterScopeCreatures) && !_vm->_dungeonMan->isCreatureAllowedOnMap(_currGroupThing, curTeleporter->getTargetMapIndex())) { + Teleporter *curTeleporter = (Teleporter *)dungeon.getSquareFirstThingData(mapX, mapY); + if (getFlag(curTeleporter->getScope(), kDMTeleporterScopeCreatures) && !dungeon.isCreatureAllowedOnMap(_currGroupThing, curTeleporter->getTargetMapIndex())) { _groupMovBlockedByWallStairsPitFakeWalFluxCageTeleporter = true; return false; } } - _groupMovementBlockedByParty = (_vm->_dungeonMan->_currMapIndex == _vm->_dungeonMan->_partyMapIndex) && (mapX == _vm->_dungeonMan->_partyMapX) && (mapY == _vm->_dungeonMan->_partyMapY); + _groupMovementBlockedByParty = (dungeon._currMapIndex == dungeon._partyMapIndex) && (mapX == dungeon._partyMapX) && (mapY == dungeon._partyMapY); if (_groupMovementBlockedByParty) return false; if (curSquareType == kDMElementTypeDoor) { - Teleporter *curTeleporter = (Teleporter *)_vm->_dungeonMan->getSquareFirstThingData(mapX, mapY); + Teleporter *curTeleporter = (Teleporter *)dungeon.getSquareFirstThingData(mapX, mapY); if (((Square(curSquare).getDoorState()) > (((Door *)curTeleporter)->opensVertically() ? CreatureInfo::getHeight(creatureInfo->_attributes) : 1)) && ((Square(curSquare).getDoorState()) != kDMDoorStateDestroyed) && !getFlag(creatureInfo->_attributes, kDMCreatureMaskNonMaterial)) { _groupMovementBlockedByDoor = true; return false; @@ -1137,8 +1158,9 @@ int16 GroupMan::getDistanceBetweenSquares(int16 srcMapX, int16 srcMapY, int16 de int16 GroupMan::groupGetDistanceToVisibleParty(Group *group, int16 creatureIndex, int16 mapX, int16 mapY) { uint16 groupDirections; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; - CreatureInfo *groupCreatureInfo = &_vm->_dungeonMan->_creatureInfos[group->_type]; + CreatureInfo *groupCreatureInfo = &dungeon._creatureInfos[group->_type]; if (championMan._party._event71Count_Invisibility && !getFlag(groupCreatureInfo->_attributes, kDMCreatureMaskSeeInvisible)) return 0; @@ -1173,7 +1195,7 @@ int16 GroupMan::groupGetDistanceToVisibleParty(Group *group, int16 creatureIndex } while (checkDirectionsCount--) { - if (alwaysSee || isDestVisibleFromSource(creatureViewDirections[checkDirectionsCount], mapX, mapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY)) { + if (alwaysSee || isDestVisibleFromSource(creatureViewDirections[checkDirectionsCount], mapX, mapY, dungeon._partyMapX, dungeon._partyMapY)) { int16 sightRange = groupCreatureInfo->getSightRange(); if (!getFlag(groupCreatureInfo->_attributes, kDMCreatureMaskNightVision)) sightRange -= _vm->_displayMan->_dungeonViewPaletteIndex >> 1; @@ -1181,7 +1203,7 @@ int16 GroupMan::groupGetDistanceToVisibleParty(Group *group, int16 creatureIndex if (_currGroupDistanceToParty > MAX<int16>(1, sightRange)) return 0; - return getDistanceBetweenUnblockedSquares(mapX, mapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, &GroupMan::isViewPartyBlocked); + return getDistanceBetweenUnblockedSquares(mapX, mapY, dungeon._partyMapX, dungeon._partyMapY, &GroupMan::isViewPartyBlocked); } } return 0; @@ -1248,20 +1270,24 @@ int16 GroupMan::getDistanceBetweenUnblockedSquares(int16 srcMapX, int16 srcMapY, } bool GroupMan::isViewPartyBlocked(uint16 mapX, uint16 mapY) { - uint16 curSquare = _vm->_dungeonMan->_currMapData[mapX][mapY]; + DungeonMan &dungeon = *_vm->_dungeonMan; + + uint16 curSquare = dungeon._currMapData[mapX][mapY]; int16 curSquareType = Square(curSquare).getType(); if (curSquareType == kDMElementTypeDoor) { - Door *curDoor = (Door *)_vm->_dungeonMan->getSquareFirstThingData(mapX, mapY); + Door *curDoor = (Door *)dungeon.getSquareFirstThingData(mapX, mapY); int16 curDoorState = Square(curSquare).getDoorState(); - return ((curDoorState == kDMDoorStateThreeFourth) || (curDoorState == kDMDoorStateClosed)) && !getFlag(_vm->_dungeonMan->_currMapDoorInfo[curDoor->getType()]._attributes, kDMMaskDoorInfoCreaturesCanSeeThrough); + return ((curDoorState == kDMDoorStateThreeFourth) || (curDoorState == kDMDoorStateClosed)) && !getFlag(dungeon._currMapDoorInfo[curDoor->getType()]._attributes, kDMMaskDoorInfoCreaturesCanSeeThrough); } return (curSquareType == kDMElementTypeWall) || ((curSquareType == kDMElementTypeFakeWall) && !getFlag(curSquare, kDMSquareMaskFakeWallOpen)); } int32 GroupMan::getCreatureAspectUpdateTime(ActiveGroup *activeGroup, int16 creatureIndex, bool isAttacking) { - Group *group = &(((Group *)_vm->_dungeonMan->_thingData[kDMThingTypeGroup])[activeGroup->_groupThingIndex]); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Group *group = &(((Group *)dungeon._thingData[kDMThingTypeGroup])[activeGroup->_groupThingIndex]); CreatureType creatureType = group->_type; - uint16 creatureGraphicInfo = _vm->_dungeonMan->_creatureInfos[creatureType]._graphicInfo; + uint16 creatureGraphicInfo = dungeon._creatureInfos[creatureType]._graphicInfo; bool processGroup = (creatureIndex < 0); if (processGroup) /* If the creature index is negative then all creatures in the group are processed */ creatureIndex = group->getCount(); @@ -1323,7 +1349,7 @@ int32 GroupMan::getCreatureAspectUpdateTime(ActiveGroup *activeGroup, int16 crea } activeGroup->_aspect[creatureIndex] = aspect; } while (processGroup && (creatureIndex--)); - uint16 animationTicks = _vm->_dungeonMan->_creatureInfos[group->_type]._animationTicks; + uint16 animationTicks = dungeon._creatureInfos[group->_type]._animationTicks; return _vm->_gameTime + (isAttacking ? ((animationTicks >> 8) & 0xF) : ((animationTicks >> 4) & 0xF)) + _vm->getRandomNumber(2); } @@ -1370,8 +1396,9 @@ int16 GroupMan::getSmelledPartyPrimaryDirOrdinal(CreatureInfo *creatureInfo, int return 0; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; - if ((((smellRange + 1) >> 1) >= _currGroupDistanceToParty) && getDistanceBetweenUnblockedSquares(mapY, mapX, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, &GroupMan::isSmellPartyBlocked)) { + if ((((smellRange + 1) >> 1) >= _currGroupDistanceToParty) && getDistanceBetweenUnblockedSquares(mapY, mapX, dungeon._partyMapX, dungeon._partyMapY, &GroupMan::isSmellPartyBlocked)) { _vm->_projexpl->_secondaryDirToOrFromParty = _currGroupSecondaryDirToParty; return _vm->indexToOrdinal(_currGroupPrimaryDirToParty); } @@ -1604,8 +1631,10 @@ int16 GroupMan::getChampionDamage(Group *group, uint16 champIndex) { if (championMan._partyIsSleeping) championMan.wakeUp(); - int16 doubledMapDifficulty = _vm->_dungeonMan->_currMap->_difficulty << 1; - CreatureInfo creatureInfo = _vm->_dungeonMan->_creatureInfos[group->_type]; + DungeonMan &dungeon = *_vm->_dungeonMan; + + int16 doubledMapDifficulty = dungeon._currMap->_difficulty << 1; + CreatureInfo creatureInfo = dungeon._creatureInfos[group->_type]; championMan.addSkillExperience(champIndex, kDMSkillParry, creatureInfo.getExperience()); if (championMan._partyIsSleeping || (((championMan.getDexterity(curChampion) < (_vm->getRandomNumber(32) + creatureInfo._dexterity + doubledMapDifficulty - 16)) || !_vm->getRandomNumber(4)) && !championMan.isLucky(curChampion, 60))) { uint16 allowedWound; @@ -1638,7 +1667,7 @@ int16 GroupMan::getChampionDamage(Group *group, uint16 champIndex) { int16 damage = championMan.addPendingDamageAndWounds_getDamage(champIndex, attack, allowedWound, creatureInfo._attackType); if (damage) { - _vm->_sound->requestPlay(kDMSoundIndexChampion0Damaged + champIndex, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayOneTickLater); + _vm->_sound->requestPlay(kDMSoundIndexChampion0Damaged + champIndex, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayOneTickLater); uint16 poisonAttack = creatureInfo._poisonAttack; if (poisonAttack && _vm->getRandomNumber(2)) { @@ -1664,14 +1693,16 @@ void GroupMan::dropMovingCreatureFixedPossession(Thing thing, int16 mapX, int16 } void GroupMan::startWandering(int16 mapX, int16 mapY) { - Group *L0332_ps_Group = (Group *)_vm->_dungeonMan->getThingData(groupGetThing(mapX, mapY)); - if (L0332_ps_Group->getBehaviour() >= kDMBehaviorUnknown4) { + DungeonMan &dungeon = *_vm->_dungeonMan; + + Group *L0332_ps_Group = (Group *)dungeon.getThingData(groupGetThing(mapX, mapY)); + if (L0332_ps_Group->getBehaviour() >= kDMBehaviorUnknown4) L0332_ps_Group->setBehaviour(kDMBehaviorWander); - } + TimelineEvent nextEvent; - nextEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, (_vm->_gameTime + 1)); + nextEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, (_vm->_gameTime + 1)); nextEvent._type = kDMEventTypeUpdateBehaviourGroup; - nextEvent._priority = kDMMovementTicksImmobile - _vm->_dungeonMan->_creatureInfos[L0332_ps_Group->_type]._movementTicks; /* The fastest creatures (with small MovementTicks value) get higher event priority */ + nextEvent._priority = kDMMovementTicksImmobile - dungeon._creatureInfos[L0332_ps_Group->_type]._movementTicks; /* The fastest creatures (with small MovementTicks value) get higher event priority */ nextEvent._Cu._ticks = 0; nextEvent._Bu._location._mapX = mapX; nextEvent._Bu._location._mapY = mapY; @@ -1679,6 +1710,8 @@ void GroupMan::startWandering(int16 mapX, int16 mapY) { } void GroupMan::addActiveGroup(Thing thing, int16 mapX, int16 mapY) { + DungeonMan &dungeon = *_vm->_dungeonMan; + ActiveGroup *activeGroup = _activeGroups; int16 activeGroupIndex = 0; while (activeGroup->_groupThingIndex >= 0) { @@ -1690,8 +1723,8 @@ void GroupMan::addActiveGroup(Thing thing, int16 mapX, int16 mapY) { _currActiveGroupCount++; activeGroup->_groupThingIndex = (thing).getIndex(); - Group *curGroup = (Group *)(_vm->_dungeonMan->_thingData[kDMThingTypeGroup] + - _vm->_dungeonMan->_thingDataWordCount[kDMThingTypeGroup] * activeGroup->_groupThingIndex); + Group *curGroup = (Group *)(dungeon._thingData[kDMThingTypeGroup] + + dungeon._thingDataWordCount[kDMThingTypeGroup] * activeGroup->_groupThingIndex); activeGroup->_cells = curGroup->_cells; curGroup->getActiveGroupIndex() = activeGroupIndex; @@ -1730,10 +1763,12 @@ void GroupMan::removeAllActiveGroups() { } void GroupMan::addAllActiveGroups() { - byte *curSquare = _vm->_dungeonMan->_currMapData[0]; - Thing *squareCurThing = &_vm->_dungeonMan->_squareFirstThings[_vm->_dungeonMan->_currMapColCumulativeSquareFirstThingCount[0]]; - for (uint16 mapX = 0; mapX < _vm->_dungeonMan->_currMapWidth; mapX++) { - for (uint16 mapY = 0; mapY < _vm->_dungeonMan->_currMapHeight; mapY++) { + DungeonMan &dungeon = *_vm->_dungeonMan; + + byte *curSquare = dungeon._currMapData[0]; + Thing *squareCurThing = &dungeon._squareFirstThings[dungeon._currMapColCumulativeSquareFirstThingCount[0]]; + for (uint16 mapX = 0; mapX < dungeon._currMapWidth; mapX++) { + for (uint16 mapY = 0; mapY < dungeon._currMapHeight; mapY++) { if (getFlag(*curSquare++, kDMSquareMaskThingListPresent)) { Thing curThing = *squareCurThing++; do { @@ -1743,7 +1778,7 @@ void GroupMan::addAllActiveGroups() { startWandering(mapX, mapY); break; } - curThing = _vm->_dungeonMan->getNextThing(curThing); + curThing = dungeon.getNextThing(curThing); } while (curThing != Thing::_endOfList); } } @@ -1751,12 +1786,14 @@ void GroupMan::addAllActiveGroups() { } Thing GroupMan::groupGetGenerated(CreatureType creatureType, int16 healthMultiplier, uint16 creatureCount, Direction dir, int16 mapX, int16 mapY) { - Thing groupThing = _vm->_dungeonMan->getUnusedThing(kDMThingTypeGroup); - if (((_currActiveGroupCount >= (_maxActiveGroupCount - 5)) && (_vm->_dungeonMan->_currMapIndex == _vm->_dungeonMan->_partyMapIndex)) + DungeonMan &dungeon = *_vm->_dungeonMan; + + Thing groupThing = dungeon.getUnusedThing(kDMThingTypeGroup); + if (((_currActiveGroupCount >= (_maxActiveGroupCount - 5)) && (dungeon._currMapIndex == dungeon._partyMapIndex)) || (groupThing == Thing::_none)) { return Thing::_none; } - Group *group = (Group *)_vm->_dungeonMan->getThingData(groupThing); + Group *group = (Group *)dungeon.getThingData(groupThing); group->_slot = Thing::_endOfList; group->setDoNotDiscard(false); group->setDir(dir); @@ -1826,6 +1863,7 @@ int16 GroupMan::getMeleeActionDamage(Champion *champ, int16 champIndex, Group *g int16 L0569_i_Outcome; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; if (champIndex >= championMan._partyChampionCount) return 0; @@ -1833,8 +1871,8 @@ int16 GroupMan::getMeleeActionDamage(Champion *champ, int16 champIndex, Group *g if (!champ->_currHealth) return 0; - int16 doubledMapDifficulty = _vm->_dungeonMan->_currMap->_difficulty << 1; - CreatureInfo *creatureInfo = &_vm->_dungeonMan->_creatureInfos[group->_type]; + int16 doubledMapDifficulty = dungeon._currMap->_difficulty << 1; + CreatureInfo *creatureInfo = &dungeon._creatureInfos[group->_type]; int16 actionHandObjectIconIndex = _vm->_objectMan->getIconIndex(champ->_slots[kDMSlotActionHand]); bool actionHitsNonMaterialCreatures = getFlag(actionHitProbability, kDMActionMaskHitNonMaterialCreatures); if (actionHitsNonMaterialCreatures) @@ -1904,18 +1942,20 @@ T0231016: } void GroupMan::fluxCageAction(int16 mapX, int16 mapY) { - ElementType squareType = _vm->_dungeonMan->getSquare(mapX, mapY).getType(); + DungeonMan &dungeon = *_vm->_dungeonMan; + + ElementType squareType = dungeon.getSquare(mapX, mapY).getType(); if ((squareType == kDMElementTypeWall) || (squareType == kDMElementTypeStairs)) return; - Thing unusedThing = _vm->_dungeonMan->getUnusedThing(kDMThingTypeExplosion); + Thing unusedThing = dungeon.getUnusedThing(kDMThingTypeExplosion); if (unusedThing == Thing::_none) return; - _vm->_dungeonMan->linkThingToList(unusedThing, Thing(0), mapX, mapY); - (((Explosion *)_vm->_dungeonMan->_thingData[kDMThingTypeExplosion])[unusedThing.getIndex()]).setType(kDMExplosionTypeFluxcage); + dungeon.linkThingToList(unusedThing, Thing(0), mapX, mapY); + (((Explosion *)dungeon._thingData[kDMThingTypeExplosion])[unusedThing.getIndex()]).setType(kDMExplosionTypeFluxcage); TimelineEvent newEvent; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_currMapIndex, _vm->_gameTime + 100); + newEvent._mapTime = _vm->setMapAndTime(dungeon._currMapIndex, _vm->_gameTime + 100); newEvent._type = kDMEventTypeRemoveFluxcage; newEvent._priority = 0; newEvent._Cu._slot = unusedThing.toUint16(); @@ -1960,22 +2000,26 @@ uint16 GroupMan::isLordChaosOnSquare(int16 mapX, int16 mapY) { } bool GroupMan::isFluxcageOnSquare(int16 mapX, int16 mapY) { - ElementType squareType = _vm->_dungeonMan->getSquare(mapX, mapY).getType(); + DungeonMan &dungeon = *_vm->_dungeonMan; + + ElementType squareType = dungeon.getSquare(mapX, mapY).getType(); if ((squareType == kDMElementTypeWall) || (squareType == kDMElementTypeStairs)) return false; - Thing thing = _vm->_dungeonMan->getSquareFirstThing(mapX, mapY); + Thing thing = dungeon.getSquareFirstThing(mapX, mapY); while (thing != Thing::_endOfList) { - if ((thing.getType() == kDMThingTypeExplosion) && (((Explosion *)_vm->_dungeonMan->_thingData[kDMThingTypeExplosion])[thing.getIndex()].getType() == kDMExplosionTypeFluxcage)) + if ((thing.getType() == kDMThingTypeExplosion) && (((Explosion *)dungeon._thingData[kDMThingTypeExplosion])[thing.getIndex()].getType() == kDMExplosionTypeFluxcage)) return true; - thing = _vm->_dungeonMan->getNextThing(thing); + thing = dungeon.getNextThing(thing); } return false; } void GroupMan::fuseAction(uint16 mapX, uint16 mapY) { - if ((mapX >= _vm->_dungeonMan->_currMapWidth) || (mapY >= _vm->_dungeonMan->_currMapHeight)) + DungeonMan &dungeon = *_vm->_dungeonMan; + + if ((mapX >= dungeon._currMapWidth) || (mapY >= dungeon._currMapHeight)) return; _vm->_projexpl->createExplosion(Thing::_explHarmNonMaterial, 255, mapX, mapY, kDMCreatureTypeSingleCenteredCreature); /* BUG0_17 The game crashes after the Fuse action is performed while looking at a wall on a map boundary. An explosion thing is created on the square in front of the party but there is no check to ensure the square coordinates are in the map bounds. This corrupts a memory location and leads to a game crash */ diff --git a/engines/dm/inventory.cpp b/engines/dm/inventory.cpp index 5cb861397d..7ee28f3bea 100644 --- a/engines/dm/inventory.cpp +++ b/engines/dm/inventory.cpp @@ -485,7 +485,7 @@ void InventoryMan::drawPanelArrowOrEye(bool pressingEye) { void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { static Box boxObjectDescCircle(105, 136, 53, 79); // @ G0034_s_Graphic562_Box_ObjectDescriptionCircle - DungeonMan &dunMan = *_vm->_dungeonMan; + DungeonMan &dungeon = *_vm->_dungeonMan; ObjectMan &objMan = *_vm->_objectMan; DisplayMan &dispMan = *_vm->_displayMan; ChampionMan &champMan = *_vm->_championMan; @@ -494,7 +494,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { if (_vm->_pressingEye || _vm->_pressingMouth) closeChest(); - uint16 *rawThingPtr = dunMan.getThingData(thingToDraw); + uint16 *rawThingPtr = dungeon.getThingData(thingToDraw); drawPanelObjectDescriptionString("\f"); // form feed ThingType thingType = thingToDraw.getType(); if (thingType == kDMThingTypeScroll) @@ -574,7 +574,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { case kDMThingTypePotion: { potentialAttribMask = kDMDescriptionMaskConsumable; Potion *potion = (Potion *)rawThingPtr; - actualAttribMask = _vm->_dungeonMan->_objectInfos[kDMObjectInfoIndexFirstPotion + potion->getType()].getAllowedSlots(); + actualAttribMask = dungeon._objectInfos[kDMObjectInfoIndexFirstPotion + potion->getType()].getAllowedSlots(); break; } case kDMThingTypeJunk: { @@ -624,7 +624,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { } else { Junk *junk = (Junk *)rawThingPtr; potentialAttribMask = kDMDescriptionMaskConsumable; - actualAttribMask = _vm->_dungeonMan->_objectInfos[kDMObjectInfoIndexFirstJunk + junk->getType()].getAllowedSlots(); + actualAttribMask = dungeon._objectInfos[kDMObjectInfoIndexFirstJunk + junk->getType()].getAllowedSlots(); } break; } @@ -655,7 +655,7 @@ void InventoryMan::drawPanelObject(Thing thingToDraw, bool pressingEye) { drawPanelObjectDescriptionString(destString); } - uint16 weight = dunMan.getObjectWeight(thingToDraw); + uint16 weight = dungeon.getObjectWeight(thingToDraw); switch (_vm->getGameLanguage()) { // localized case Common::DE_DEU: str = "WIEGT " + champMan.getStringFromInteger(weight / 10, false, 3) + ","; @@ -689,8 +689,9 @@ void InventoryMan::setDungeonViewPalette() { static const int16 palIndexToLightAmmount[6] = {99, 75, 50, 25, 1, 0}; // @ G0040_ai_Graphic562_PaletteIndexToLightAmount DisplayMan &display = *_vm->_displayMan; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; - if (_vm->_dungeonMan->_currMap->_difficulty == 0) { + if (dungeon._currMap->_difficulty == 0) { display._dungeonViewPaletteIndex = 0; /* Brightest color palette index */ } else { /* Get torch light power from both hands of each champion in the party */ @@ -704,7 +705,7 @@ void InventoryMan::setDungeonViewPalette() { Thing slotThing = curChampion->_slots[slotIndex]; if ((_vm->_objectMan->getObjectType(slotThing) >= kDMIconIndiceWeaponTorchUnlit) && (_vm->_objectMan->getObjectType(slotThing) <= kDMIconIndiceWeaponTorchLit)) { - Weapon *curWeapon = (Weapon *)_vm->_dungeonMan->getThingData(slotThing); + Weapon *curWeapon = (Weapon *)dungeon.getThingData(slotThing); *curTorchLightPower = curWeapon->getChargeCount(); } else { *curTorchLightPower = 0; @@ -761,6 +762,8 @@ void InventoryMan::setDungeonViewPalette() { void InventoryMan::decreaseTorchesLightPower() { ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; + bool torchChargeCountChanged = false; int16 championCount = championMan._partyChampionCount; if (championMan._candidateChampionOrdinal) @@ -772,7 +775,7 @@ void InventoryMan::decreaseTorchesLightPower() { while (slotIndex--) { int16 iconIndex = _vm->_objectMan->getIconIndex(curChampion->_slots[slotIndex]); if ((iconIndex >= kDMIconIndiceWeaponTorchUnlit) && (iconIndex <= kDMIconIndiceWeaponTorchLit)) { - Weapon *curWeapon = (Weapon *)_vm->_dungeonMan->getThingData(curChampion->_slots[slotIndex]); + Weapon *curWeapon = (Weapon *)dungeon.getThingData(curChampion->_slots[slotIndex]); if (curWeapon->getChargeCount()) { if (curWeapon->setChargeCount(curWeapon->getChargeCount() - 1) == 0) { curWeapon->setDoNotDiscard(false); @@ -891,6 +894,8 @@ void InventoryMan::clickOnMouth() { DisplayMan &display = *_vm->_displayMan; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; + if (championMan._leaderEmptyHanded) { if (_panelContent == kDMPanelContentFoodWaterPoisoned) @@ -915,15 +920,15 @@ void InventoryMan::clickOnMouth() { return; Thing handThing = championMan._leaderHandObject; - if (!getFlag(_vm->_dungeonMan->_objectInfos[_vm->_dungeonMan->getObjectInfoIndex(handThing)]._allowedSlots, kDMMaskMouth)) + if (!getFlag(dungeon._objectInfos[dungeon.getObjectInfoIndex(handThing)]._allowedSlots, kDMMaskMouth)) return; uint16 iconIndex = _vm->_objectMan->getIconIndex(handThing); uint16 handThingType = handThing.getType(); - uint16 handThingWeight = _vm->_dungeonMan->getObjectWeight(handThing); + uint16 handThingWeight = dungeon.getObjectWeight(handThing); uint16 championIndex = _vm->ordinalToIndex(_inventoryChampionOrdinal); Champion *curChampion = &championMan._champions[championIndex]; - Junk *junkData = (Junk *)_vm->_dungeonMan->getThingData(handThing); + Junk *junkData = (Junk *)dungeon.getThingData(handThing); bool removeObjectFromLeaderHand; if ((iconIndex >= kDMIconIndiceJunkWater) && (iconIndex <= kDMIconIndiceJunkWaterSkin)) { if (!(junkData->getChargeCount())) @@ -974,7 +979,7 @@ void InventoryMan::clickOnMouth() { curChampion->_shieldDefense += adjustedPotionPower; TimelineEvent newEvent; newEvent._type = kDMEventTypeChampionShield; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + (adjustedPotionPower * adjustedPotionPower)); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + (adjustedPotionPower * adjustedPotionPower)); newEvent._priority = championIndex; newEvent._Bu._defense = adjustedPotionPower; _vm->_timeline->addEventGetEventIndex(&newEvent); @@ -1031,10 +1036,10 @@ void InventoryMan::clickOnMouth() { } } else { championMan.drawChangedObjectIcons(); - championMan._champions[championMan._leaderIndex]._load += _vm->_dungeonMan->getObjectWeight(handThing) - handThingWeight; + championMan._champions[championMan._leaderIndex]._load += dungeon.getObjectWeight(handThing) - handThingWeight; setFlag(championMan._champions[championMan._leaderIndex]._attributes, kDMAttributeLoad); } - _vm->_sound->requestPlay(kDMSoundIndexSwallow, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayImmediately); + _vm->_sound->requestPlay(kDMSoundIndexSwallow, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayImmediately); setFlag(curChampion->_attributes, kDMAttributeStatistics); if (_panelContent == kDMPanelContentFoodWaterPoisoned) diff --git a/engines/dm/menus.cpp b/engines/dm/menus.cpp index e4e4792039..ce5e6d2054 100644 --- a/engines/dm/menus.cpp +++ b/engines/dm/menus.cpp @@ -190,6 +190,7 @@ void MenuMan::drawActionIcon(ChampionIndex championIndex) { return; DisplayMan &dm = *_vm->_displayMan; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; Champion &champion = championMan._champions[championIndex]; Box box; @@ -207,7 +208,7 @@ void MenuMan::drawActionIcon(ChampionIndex championIndex) { IconIndice iconIndex; if (thing == Thing::_none) { iconIndex = kDMIconIndiceActionEmptyHand; - } else if (_vm->_dungeonMan->_objectInfos[_vm->_dungeonMan->getObjectInfoIndex(thing)]._actionSetIndex) { + } else if (dungeon._objectInfos[dungeon.getObjectInfoIndex(thing)]._actionSetIndex) { iconIndex = _vm->_objectMan->getIconIndex(thing); } else { dm.fillBitmap(bitmapIcon, kDMColorCyan, 16, 16); @@ -534,7 +535,7 @@ int16 MenuMan::getClickOnSpellCastResult() { int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { ChampionMan &championMan = *_vm->_championMan; - + DungeonMan &dungeon = *_vm->_dungeonMan; if (champIndex >= championMan._partyChampionCount) return kDMSpellCastFailure; @@ -569,10 +570,10 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { menusPrintSpellFailureMessage(curChampion, kDMFailureNeedsFlaskInHand, 0); return kDMSpellCastFailureNeedsFlask; } - uint16 emptyFlaskWeight = _vm->_dungeonMan->getObjectWeight(newObject); + uint16 emptyFlaskWeight = dungeon.getObjectWeight(newObject); newPotion->setType((PotionType)curSpell->getType()); newPotion->setPower(_vm->getRandomNumber(16) + (powerSymbolOrdinal * 40)); - curChampion->_load += _vm->_dungeonMan->getObjectWeight(newObject) - emptyFlaskWeight; + curChampion->_load += dungeon.getObjectWeight(newObject) - emptyFlaskWeight; championMan.drawChangedObjectIcons(); if (_vm->_inventoryMan->_inventoryChampionOrdinal == _vm->indexToOrdinal(champIndex)) { setFlag(curChampion->_attributes, kDMAttributeLoad); @@ -581,8 +582,8 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { } break; case kDMSpellKindProjectile: - if (curChampion->_dir != _vm->_dungeonMan->_partyDir) { - curChampion->_dir = _vm->_dungeonMan->_partyDir; + if (curChampion->_dir != dungeon._partyDir) { + curChampion->_dir = dungeon._partyDir; setFlag(curChampion->_attributes, kDMAttributeIcon); championMan.drawChampionState((ChampionIndex)champIndex); } @@ -624,7 +625,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { championMan._party._event73Count_ThievesEye++; spellPower = (spellPower >> 1); uint16 spellTicks = spellPower * spellPower; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + spellTicks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + spellTicks); _vm->_timeline->addEventGetEventIndex(&newEvent); } break; @@ -632,7 +633,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { newEvent._type = kDMEventTypeInvisibility; championMan._party._event71Count_Invisibility++; uint16 spellTicks = spellPower; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + spellTicks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + spellTicks); _vm->_timeline->addEventGetEventIndex(&newEvent); } break; @@ -645,7 +646,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { championMan._party._shieldDefense += newEvent._Bu._defense; _vm->_timeline->refreshAllChampionStatusBoxes(); uint16 spellTicks = spellPower * spellPower; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + spellTicks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + spellTicks); _vm->_timeline->addEventGetEventIndex(&newEvent); } break; @@ -659,16 +660,16 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { championMan._party._lastScentIndex = 0; uint16 spellTicks = spellPower * spellPower; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + spellTicks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + spellTicks); _vm->_timeline->addEventGetEventIndex(&newEvent); } break; case kDMSpellTypeOtherZokathra: { - Thing unusedObject = _vm->_dungeonMan->getUnusedThing(kDMThingTypeJunk); + Thing unusedObject = dungeon.getUnusedThing(kDMThingTypeJunk); if (unusedObject == Thing::_none) break; - Junk *junkData = (Junk *)_vm->_dungeonMan->getThingData(unusedObject); + Junk *junkData = (Junk *)dungeon.getThingData(unusedObject); junkData->setType(kDMJunkTypeZokathra); ChampionSlot slotIndex; if (curChampion->_slots[kDMSlotReadyHand] == Thing::_none) @@ -682,7 +683,7 @@ int16 MenuMan::getChampionSpellCastResult(uint16 champIndex) { championMan.addObjectInSlot((ChampionIndex)champIndex, unusedObject, slotIndex); championMan.drawChampionState((ChampionIndex)champIndex); } else - _vm->_moveSens->getMoveResult(unusedObject, kDMMapXNotOnASquare, 0, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY); + _vm->_moveSens->getMoveResult(unusedObject, kDMMapXNotOnASquare, 0, dungeon._partyMapX, dungeon._partyMapY); } break; @@ -815,11 +816,12 @@ void MenuMan::menusPrintSpellFailureMessage(Champion *champ, uint16 failureType, } Potion *MenuMan::getEmptyFlaskInHand(Champion *champ, Thing *potionThing) { + DungeonMan &dungeon = *_vm->_dungeonMan; for (int16 slotIndex = kDMSlotHead; --slotIndex >= kDMSlotReadyHand; ) { Thing curThing = champ->_slots[slotIndex]; if ((curThing != Thing::_none) && (_vm->_objectMan->getIconIndex(curThing) == kDMIconIndicePotionEmptyFlask)) { *potionThing = curThing; - return (Potion *)_vm->_dungeonMan->getThingData(curThing); + return (Potion *)dungeon.getThingData(curThing); } } return nullptr; @@ -1077,10 +1079,12 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { if (!curChampion->_currHealth) return false; - Weapon *weaponInHand = (Weapon *)_vm->_dungeonMan->getThingData(curChampion->_slots[kDMSlotActionHand]); + DungeonMan &dungeon = *_vm->_dungeonMan; + + Weapon *weaponInHand = (Weapon *)dungeon.getThingData(curChampion->_slots[kDMSlotActionHand]); - int16 nextMapX = _vm->_dungeonMan->_partyMapX; - int16 nextMapY = _vm->_dungeonMan->_partyMapY; + int16 nextMapX = dungeon._partyMapX; + int16 nextMapY = dungeon._partyMapY; nextMapX += _vm->_dirIntoStepCountEast[curChampion->_dir]; nextMapY += _vm->_dirIntoStepCountNorth[curChampion->_dir]; _actionTargetGroupThing = _vm->_groupMan->groupGetThing(nextMapX, nextMapY); @@ -1088,7 +1092,7 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { int16 actionSkillIndex = _actionSkillIndex[actionIndex]; int16 actionStamina = actionStaminaArray[actionIndex] + _vm->getRandomNumber(2); int16 actionExperienceGain = actionExperienceGainArray[actionIndex]; - uint16 targetSquare = _vm->_dungeonMan->getSquare(nextMapX, nextMapY).toByte(); + uint16 targetSquare = dungeon.getSquare(nextMapX, nextMapY).toByte(); int16 requiredManaAmount = 0; if (((actionSkillIndex >= kDMSkillFire) && (actionSkillIndex <= kDMSkillWater)) || (actionSkillIndex == kDMSkillWizard)) @@ -1126,10 +1130,10 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { case kDMActionSwing: case kDMActionChop: if ((Square(targetSquare).getType() == kDMElementTypeDoor) && (Square(targetSquare).getDoorState() == kDMDoorStateClosed)) { - _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayIfPrioritized); + _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayIfPrioritized); actionDisabledTicks = 6; _vm->_groupMan->groupIsDoorDestoryedByAttack(nextMapX, nextMapY, championMan.getStrength(champIndex, kDMSlotActionHand), false, 2); - _vm->_sound->requestPlay(kDMSoundIndexWoodenThudAttackTrolinAntmanStoneGolem, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayOneTickLater); + _vm->_sound->requestPlay(kDMSoundIndexWoodenThudAttackTrolinAntmanStoneGolem, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayOneTickLater); break; } case kDMActionDisrupt: @@ -1170,8 +1174,8 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { break; } - WeaponInfo *weaponInfoActionHand = &_vm->_dungeonMan->_weaponInfos[weaponInHand->getType()]; - WeaponInfo *weaponInfoReadyHand = _vm->_dungeonMan->getWeaponInfo(curChampion->_slots[kDMSlotReadyHand]); + WeaponInfo *weaponInfoActionHand = &dungeon._weaponInfos[weaponInHand->getType()]; + WeaponInfo *weaponInfoReadyHand = dungeon.getWeaponInfo(curChampion->_slots[kDMSlotReadyHand]); int16 actionHandWeaponClass = weaponInfoActionHand->_class; int16 readyHandWeaponClass = weaponInfoReadyHand->_class; int16 stepEnergy = actionHandWeaponClass; @@ -1195,7 +1199,7 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { setChampionDirectionToPartyDirection(curChampion); Thing removedObject = championMan.getObjectRemovedFromSlot(champIndex, kDMSlotReadyHand); - _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayIfPrioritized); + _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayIfPrioritized); championMan.championShootProjectile(curChampion, removedObject, weaponInfoActionHand->_kineticEnergy + weaponInfoReadyHand->_kineticEnergy, (weaponInfoActionHand->getShootAttack() + championMan.getSkillLevel(champIndex, kDMSkillShoot)) << 1, stepEnergy); } break; @@ -1257,9 +1261,9 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { break; case kDMActionFuse: setChampionDirectionToPartyDirection(curChampion); - nextMapX = _vm->_dungeonMan->_partyMapX; - nextMapY = _vm->_dungeonMan->_partyMapY; - nextMapX += _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir], nextMapY += _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir]; + nextMapX = dungeon._partyMapX; + nextMapY = dungeon._partyMapY; + nextMapX += _vm->_dirIntoStepCountEast[dungeon._partyDir], nextMapY += _vm->_dirIntoStepCountNorth[dungeon._partyDir]; _vm->_groupMan->fuseAction(nextMapX, nextMapY); break; case kDMActionHeal: { @@ -1295,24 +1299,24 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { TimelineEvent newEvent; newEvent._priority = 0; newEvent._type = kDMEventTypeThievesEye; - newEvent._mapTime = _vm->setMapAndTime(_vm->_dungeonMan->_partyMapIndex, _vm->_gameTime + windowTicks); + newEvent._mapTime = _vm->setMapAndTime(dungeon._partyMapIndex, _vm->_gameTime + windowTicks); _vm->_timeline->addEventGetEventIndex(&newEvent); championMan._party._event73Count_ThievesEye++; decrementCharges(curChampion); } break; case kDMActionClimbDown: - nextMapX = _vm->_dungeonMan->_partyMapX; - nextMapY = _vm->_dungeonMan->_partyMapY; - nextMapX += _vm->_dirIntoStepCountEast[_vm->_dungeonMan->_partyDir]; - nextMapY += _vm->_dirIntoStepCountNorth[_vm->_dungeonMan->_partyDir]; + nextMapX = dungeon._partyMapX; + nextMapY = dungeon._partyMapY; + nextMapX += _vm->_dirIntoStepCountEast[dungeon._partyDir]; + nextMapY += _vm->_dirIntoStepCountNorth[dungeon._partyDir]; /* CHANGE6_00_FIX The presence of a group over the pit is checked so that you cannot climb down a pit with the rope if there is a group levitating over it */ - if ((_vm->_dungeonMan->getSquare(nextMapX, nextMapY).getType() == kDMElementTypePit) && (_vm->_groupMan->groupGetThing(nextMapX, nextMapY) == Thing::_endOfList)) { + if ((dungeon.getSquare(nextMapX, nextMapY).getType() == kDMElementTypePit) && (_vm->_groupMan->groupGetThing(nextMapX, nextMapY) == Thing::_endOfList)) { /* BUG0_77 The party moves forward when using the rope in front of a closed pit. The engine does not check whether the pit is open before moving the party over the pit. This is not consistent with the behavior when using the rope in front of a corridor where nothing happens */ _vm->_moveSens->_useRopeToClimbDownPit = true; - _vm->_moveSens->getMoveResult(Thing::_party, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, nextMapX, nextMapY); + _vm->_moveSens->getMoveResult(Thing::_party, dungeon._partyMapX, dungeon._partyMapY, nextMapX, nextMapY); _vm->_moveSens->_useRopeToClimbDownPit = false; } else { actionDisabledTicks = 0; @@ -1342,7 +1346,7 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { break; case kDMActionThrow: setChampionDirectionToPartyDirection(curChampion); - actionPerformed = championMan.isObjectThrown(champIndex, kDMSlotActionHand, (curChampion->_cell == (ViewCell)_vm->turnDirRight(_vm->_dungeonMan->_partyDir)) || (curChampion->_cell == (ViewCell)_vm->returnOppositeDir(_vm->_dungeonMan->_partyDir))); + actionPerformed = championMan.isObjectThrown(champIndex, kDMSlotActionHand, (curChampion->_cell == (ViewCell)_vm->turnDirRight(dungeon._partyDir)) || (curChampion->_cell == (ViewCell)_vm->returnOppositeDir(dungeon._partyDir))); if (actionPerformed) _vm->_timeline->_events[curChampion->_enableActionEventIndex]._Bu._slotOrdinal = _vm->indexToOrdinal(kDMSlotActionHand); break; @@ -1377,8 +1381,10 @@ bool MenuMan::isActionPerformed(uint16 champIndex, int16 actionIndex) { } void MenuMan::setChampionDirectionToPartyDirection(Champion *champ) { - if (champ->_dir != _vm->_dungeonMan->_partyDir) { - champ->_dir = _vm->_dungeonMan->_partyDir; + DungeonMan &dungeon = *_vm->_dungeonMan; + + if (champ->_dir != dungeon._partyDir) { + champ->_dir = dungeon._partyDir; setFlag(champ->_attributes, kDMAttributeIcon); } } @@ -1502,12 +1508,13 @@ bool MenuMan::isMeleeActionPerformed(int16 champIndex, Champion *champ, int16 ac 0 /* FUSE */ }; - _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, kDMSoundModePlayIfPrioritized); + DungeonMan &dungeon = *_vm->_dungeonMan; + _vm->_sound->requestPlay(kDMSoundIndexAttackSkelettonAnimatedArmorDethKnight, dungeon._partyMapX, dungeon._partyMapY, kDMSoundModePlayIfPrioritized); if (_actionTargetGroupThing == Thing::_endOfList) return false; uint16 championCell = champ->_cell; - int16 targetCreatureOrdinal = _vm->_groupMan->getMeleeTargetCreatureOrdinal(targetMapX, targetMapY, _vm->_dungeonMan->_partyMapX, _vm->_dungeonMan->_partyMapY, championCell); + int16 targetCreatureOrdinal = _vm->_groupMan->getMeleeTargetCreatureOrdinal(targetMapX, targetMapY, dungeon._partyMapX, dungeon._partyMapY, championCell); if (targetCreatureOrdinal) { uint16 viewCell = _vm->normalizeModulo4(championCell + 4 - champ->_dir); switch (viewCell) { @@ -1522,7 +1529,7 @@ bool MenuMan::isMeleeActionPerformed(int16 champIndex, Champion *champ, int16 ac break; } - if ((actionIndex == kDMActionDisrupt) && !getFlag(_vm->_dungeonMan->getCreatureAttributes(_actionTargetGroupThing), kDMCreatureMaskNonMaterial)) + if ((actionIndex == kDMActionDisrupt) && !getFlag(dungeon.getCreatureAttributes(_actionTargetGroupThing), kDMCreatureMaskNonMaterial)) return false; uint16 actionHitProbability = actionHitProbabilityArray[actionIndex]; @@ -1530,7 +1537,7 @@ bool MenuMan::isMeleeActionPerformed(int16 champIndex, Champion *champ, int16 ac if ((_vm->_objectMan->getIconIndex(champ->_slots[kDMSlotActionHand]) == kDMIconIndiceWeaponVorpalBlade) || (actionIndex == kDMActionDisrupt)) { setFlag(actionHitProbability, kDMActionMaskHitNonMaterialCreatures); } - _actionDamage = _vm->_groupMan->getMeleeActionDamage(champ, champIndex, (Group *)_vm->_dungeonMan->getThingData(_actionTargetGroupThing), _vm->ordinalToIndex(targetCreatureOrdinal), targetMapX, targetMapY, actionHitProbability, actionDamageFactor, skillIndex); + _actionDamage = _vm->_groupMan->getMeleeActionDamage(champ, champIndex, (Group *)dungeon.getThingData(_actionTargetGroupThing), _vm->ordinalToIndex(targetCreatureOrdinal), targetMapX, targetMapY, actionHitProbability, actionDamageFactor, skillIndex); return true; } @@ -1543,6 +1550,7 @@ bool MenuMan::isGroupFrightenedByAction(int16 champIndex, uint16 actionIndex, in return retVal; ChampionMan &championMan = *_vm->_championMan; + DungeonMan &dungeon = *_vm->_dungeonMan; uint16 experience = 0; int16 frightAmount = 0; @@ -1569,9 +1577,10 @@ bool MenuMan::isGroupFrightenedByAction(int16 champIndex, uint16 actionIndex, in experience = 45; break; } + frightAmount += championMan.getSkillLevel(champIndex, kDMSkillInfluence); - Group *targetGroup = (Group *)_vm->_dungeonMan->getThingData(_actionTargetGroupThing); - CreatureInfo *creatureInfo = &_vm->_dungeonMan->_creatureInfos[targetGroup->_type]; + Group *targetGroup = (Group *)dungeon.getThingData(_actionTargetGroupThing); + CreatureInfo *creatureInfo = &dungeon._creatureInfos[targetGroup->_type]; uint16 fearResistance = creatureInfo->getFearResistance(); if ((fearResistance > _vm->getRandomNumber(frightAmount)) || (fearResistance == kDMImmuneToFear)) { experience >>= 1; @@ -1674,13 +1683,15 @@ void MenuMan::processCommands116To119_setActingChampion(uint16 champIndex) { if (getFlag(curChampion->_attributes, kDMAttributeDisableAction) || !curChampion->_currHealth) return; + DungeonMan &dungeon = *_vm->_dungeonMan; + uint16 actionSetIndex; Thing slotActionThing = curChampion->_slots[kDMSlotActionHand]; if (slotActionThing == Thing::_none) actionSetIndex = 2; /* Actions Punch, Kick and War Cry */ else { - actionSetIndex = _vm->_dungeonMan->_objectInfos[_vm->_dungeonMan->getObjectInfoIndex(slotActionThing)]._actionSetIndex; + actionSetIndex = dungeon._objectInfos[dungeon.getObjectInfoIndex(slotActionThing)]._actionSetIndex; if (actionSetIndex == 0) return; } |