diff options
author | Bendegúz Nagy | 2016-06-23 23:54:37 +0200 |
---|---|---|
committer | Bendegúz Nagy | 2016-08-26 23:02:22 +0200 |
commit | 4044dfa3647f0ba40493d8f07863b2d1f5f76f09 (patch) | |
tree | cd0004eaa8fc88ec4ca11786e2ec48c092d1369d | |
parent | d40e328e519cafe25cd1f5c668b3dd90c993d865 (diff) | |
download | scummvm-rg350-4044dfa3647f0ba40493d8f07863b2d1f5f76f09.tar.gz scummvm-rg350-4044dfa3647f0ba40493d8f07863b2d1f5f76f09.tar.bz2 scummvm-rg350-4044dfa3647f0ba40493d8f07863b2d1f5f76f09.zip |
DM: Add F0157_DUNGEON_GetSquareFirstThingData, F0377_COMMAND_ProcessType80_ClickInDungeonView
Also add ElementType enum and G0462_as_Graphic561_Box_ObjectPiles, refactor DungeonMan::_dungeonViewClickableBoxes into Box type
-rw-r--r-- | engines/dm/dungeonman.cpp | 11 | ||||
-rw-r--r-- | engines/dm/dungeonman.h | 23 | ||||
-rw-r--r-- | engines/dm/eventman.cpp | 106 | ||||
-rw-r--r-- | engines/dm/eventman.h | 3 | ||||
-rw-r--r-- | engines/dm/gfx.cpp | 14 | ||||
-rw-r--r-- | engines/dm/gfx.h | 1 | ||||
-rw-r--r-- | engines/dm/objectman.h | 2 |
7 files changed, 147 insertions, 13 deletions
diff --git a/engines/dm/dungeonman.cpp b/engines/dm/dungeonman.cpp index 0041307d06..dcf2325d2a 100644 --- a/engines/dm/dungeonman.cpp +++ b/engines/dm/dungeonman.cpp @@ -423,9 +423,8 @@ DungeonMan::DungeonMan(DMEngine *dmEngine) : _vm(dmEngine), _rawDunFileData(NULL _isFacingViAltar = false; _isFacingFountain = false; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 6; j++) - _dungeonViewClickableBoxes[j][i] = 0; + for (int j = 0; j < 6; j++) + _dungeonViewClickableBoxes[j].setToZero(); } DungeonMan::~DungeonMan() { @@ -975,6 +974,10 @@ uint16 *DungeonMan::getThingData(Thing thing) { return _dunData._thingsData[thing.getType()][thing.getIndex()]; } +uint16* DungeonMan::getSquareFirstThingData(int16 mapX, int16 mapY) { + return getThingData(getSquareFirstThing(mapX, mapY)); +} + Thing DungeonMan::getNextThing(Thing thing) { return getThingData(thing)[0]; // :) } @@ -1151,7 +1154,7 @@ void DungeonMan::decodeText(char *destString, Thing thing, TextType type) { uint16 DungeonMan::getObjectWeight(Thing thing) { static const uint16 junkInfo[] = { // @ G0241_auc_Graphic559_JunkInfo // COMPASS - WATERSKIN - JEWEL SYMAL - ILLUMULET - ASHES - 1, 3, 2, 2, 4, + 1, 3, 2, 2, 4, // BONES - COPPER COIN - SILVER COIN - GOLD COIN - IRON KEY 15, 1, 1, 1, 2, // KEY OF B - SOLID KEY - SQUARE KEY - TOURQUOISE KEY - CROSS KEY diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h index 4a80d0e2d1..df2069f937 100644 --- a/engines/dm/dungeonman.h +++ b/engines/dm/dungeonman.h @@ -34,6 +34,23 @@ namespace DM { +enum ElementType { + kElementTypeChampion = -2, // @ CM2_ELEMENT_CHAMPION /* Values -2 and -1 are only used as projectile impact types */ + kElementTypeCreature = -1, // @ CM1_ELEMENT_CREATURE + kElementTypeWall = 0, // @ C00_ELEMENT_WALL /* Values 0-6 are used as square types and projectile impact types. Values 0-2 and 5-6 are also used for square aspect */ + kElementTypeCorridor = 1, // @ C01_ELEMENT_CORRIDOR + kElementTypePit = 2, // @ C02_ELEMENT_PIT + kElementTypeStairs = 3, // @ C03_ELEMENT_STAIRS + kElementTypeDoor = 4, // @ C04_ELEMENT_DOOR + kElementTypeTeleporter = 5, // @ C05_ELEMENT_TELEPORTER + kElementTypeFakeWall = 6, // @ C06_ELEMENT_FAKEWALL + kElementTypeDoorSide = 16, // @ C16_ELEMENT_DOOR_SIDE /* Values 16-19 are only used for square aspect */ + kElementTypeDoorFront = 17, // @ C17_ELEMENT_DOOR_FRONT + kElementTypeStairsSide = 18, // @ C18_ELEMENT_STAIRS_SIDE + kElementTypeStaisFront = 19 // @ C19_ELEMENT_STAIRS_FRONT +}; + + enum ObjectAllowedSlot { kObjectAllowedSlotMouth = 0x0001, // @ MASK0x0001_MOUTH kObjectAllowedSlotHead = 0x0002, // @ MASK0x0002_HEAD @@ -399,6 +416,7 @@ public: explicit Potion(uint16 *rawDat) : _nextThing(rawDat[0]), _attributes(rawDat[1]) {} PotionType getType() { return (PotionType)((_attributes >> 8) & 0x7F); } + void setType(PotionType val) { _attributes = (_attributes & ~(0x7F << 8)) | ((val & 0x7F) << 8); } Thing getNextThing() { return _nextThing; } }; // @ POTION @@ -435,6 +453,7 @@ public: JunkType getType() { return (JunkType)(_attributes & 0x7F); } uint16 getChargeCount() { return (_attributes >> 14) & 0x3; } + void setChargeCount(uint16 val) { _attributes = (_attributes & ~(0x3 << 14)) | ((val & 0x3) << 14); } Thing getNextThing() { return _nextThing; } }; // @ JUNK @@ -611,6 +630,7 @@ public: Thing getSquareFirstThing(int16 mapX, int16 mapY); // @ F0161_DUNGEON_GetSquareFirstThing Thing getNextThing(Thing thing); // @ F0159_DUNGEON_GetNextThing(THING P0280_T_Thing) uint16 *getThingData(Thing thing); // @ unsigned char* F0156_DUNGEON_GetThingData(register THING P0276_T_Thing) + uint16 *getSquareFirstThingData(int16 mapX, int16 mapY); // @ F0157_DUNGEON_GetSquareFirstThingData // TODO: this does stuff other than load the file! void loadDungeonFile(); // @ F0434_STARTEND_IsLoadDungeonSuccessful_CPSC @@ -639,10 +659,11 @@ public: Messages _messages; // @ NONE; int16 _currMapInscriptionWallOrnIndex; // @ G0265_i_CurrentMapInscriptionWallOrnamentIndex - uint16 _dungeonViewClickableBoxes[6][4]; // G0291_aauc_DungeonViewClickableBoxes + Box _dungeonViewClickableBoxes[6]; // G0291_aauc_DungeonViewClickableBoxes bool _isFacingAlcove; // @ G0286_B_FacingAlcove bool _isFacingViAltar; // @ G0287_B_FacingViAltar bool _isFacingFountain; // @ G0288_B_FacingFountain + ElementType _squareAheadElement; // @ G0285_i_SquareAheadElement }; } diff --git a/engines/dm/eventman.cpp b/engines/dm/eventman.cpp index 50fba849b8..fcfc975fca 100644 --- a/engines/dm/eventman.cpp +++ b/engines/dm/eventman.cpp @@ -31,12 +31,20 @@ #include "eventman.h" #include "dungeonman.h" #include "movesens.h" +#include "objectman.h" namespace DM { +Box gBoxObjectPiles[4] = { // @ G0462_as_Graphic561_Box_ObjectPiles + /* { X1, X2, Y1, Y2 } */ + Box(24, 111, 148, 168), /* Front left */ + Box(112, 199, 148, 168), /* Front right */ + Box(112, 183, 122, 147), /* Back right */ + Box(40, 111, 122, 147)}; /* Back left */ + MouseInput gPrimaryMouseInput_Entrance[4] = { // @ G0445_as_Graphic561_PrimaryMouseInput_Entrance[4] /* { Command, Box.X1, Box.X2, Box.Y1, Box.Y2, Button } */ MouseInput(kCommandEntranceEnterDungeon, 244, 298, 45, 58, kLeftMouseButton), @@ -390,7 +398,8 @@ void EventManager::processCommandQueue() { Command cmd = _commandQueue.pop(); - // MISSING CODE: for when movement is disabled + int16 commandX = cmd._pos.x; + int16 commandY = cmd._pos.y; _isCommandQueueLocked = false; processPendingClick(); @@ -406,7 +415,7 @@ void EventManager::processCommandQueue() { } if (cmd._type == kCommandClickInDungeonView) { - warning("DUMMY CODE, all of this"); + /*warning("DUMMY CODE, all of this"); DungeonMan &dunMan = *_vm->_dungeonMan; CurrMapData &currMap = dunMan._currMap; uint16 mapX = currMap._partyPosX; @@ -417,7 +426,8 @@ void EventManager::processCommandQueue() { Sensor sensor(dunMan.getThingData(squareFirstThing)); if (sensor.getType() == kSensorWallChampionPortrait) { _vm->_championMan->addCandidateChampionToParty(sensor.getData()); - } + }*/ + commandProcessType80ClickInDungeonView(commandX, commandY); } // MISSING CODE: the rest of the function @@ -510,4 +520,94 @@ void EventManager::commandProcessType80ClickInDungeonViewTouchFrontWall() { _vm->_stopWaitingForPlayerInput = _vm->_movsens->sensorIsTriggeredByClickOnWall(mapX, mapY, returnOppositeDir(currMap._partyDir)); } } + +void EventManager::commandProcessType80ClickInDungeonView(int16 posX, int16 posY) { + DungeonMan &dunMan = *_vm->_dungeonMan; + ChampionMan &champMan = *_vm->_championMan; + CurrMapData &currMap = _vm->_dungeonMan->_currMap; + + int16 mapX; + int16 mapY; + + + if (dunMan._squareAheadElement == kElementTypeDoorFront) { + if (champMan._leaderIndex == kChampionNone) { + return; + } + mapX = currMap._partyPosX; + mapY = currMap._partyPosY; + mapX += _dirIntoStepCountEast[currMap._partyDir]; + mapY += _dirIntoStepCountNorth[currMap._partyDir]; + + if (champMan._leaderEmptyHanded) { + if (Door(dunMan.getSquareFirstThingData(mapX, mapY)).hasButton() && + dunMan._dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn].isPointInside(Common::Point(posX, posY - 33))) { + _vm->_stopWaitingForPlayerInput = true; + warning("MISSING CODE: F0064_SOUND_RequestPlay_CPSD"); + warning("MISSING CODE: F0268_SENSOR_AddEvent"); + return; + } + + warning("MISSING CODE: F0375_COMMAND_ProcessType80_ClickInDungeonView_IsLeaderHandObjectThrown in elseif condition"); + } + } + + if (champMan._leaderEmptyHanded) { + for (int16 viewCell = kViewCellFronLeft; viewCell <= kViewCellDoorButtonOrWallOrn; viewCell++) { + if (dunMan._dungeonViewClickableBoxes[viewCell].isPointInside(Common::Point(posX, posY - 33))) { + if (viewCell == kViewCellDoorButtonOrWallOrn) { + if (!dunMan._isFacingAlcove) { + commandProcessType80ClickInDungeonViewTouchFrontWall(); + } + } else { + warning("MISSING CODE: F0373_COMMAND_ProcessType80_ClickInDungeonView_GrabLeaderHandObject"); + } + return; + } + } + } else { + Thing thing = champMan._leaderHand; + uint16 *rawThingPointer = dunMan.getThingData(thing); + if (dunMan._squareAheadElement == kElementTypeWall) { + for (int16 viewCell = kViewCellFronLeft; viewCell <= kViewCellFrontRight; ++viewCell) { + if (gBoxObjectPiles[viewCell].isPointInside(Common::Point(posX, posY))) { + warning("F0374_COMMAND_ProcessType80_ClickInDungeonView_DropLeaderHandObject"); + return; + } + } + + if (dunMan._dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn].isPointInside(Common::Point(posX, posY - 33))) { + if (dunMan._isFacingAlcove) { + warning("MISSING CODE: F0374_COMMAND_ProcessType80_ClickInDungeonView_DropLeaderHandObject"); + } else { + if (dunMan._isFacingFountain) { + uint16 iconIndex = _vm->_objectMan->getIconIndex(thing); + int16 weight = dunMan.getObjectWeight(thing); + if ((iconIndex >= kIconIndiceJunkWater) && (iconIndex <= kIconIndiceJunkWaterSkin)) { + ((Junk*)rawThingPointer)->setChargeCount(3); + } else if (iconIndex == kIconIndicePotionEmptyFlask) { + ((Potion*)rawThingPointer)->setType(kPotionTypeWaterFlask); + } else { + goto T0377019; + } + warning("MISSING CODE: F0296_CHAMPION_DrawChangedObjectIcons"); + champMan._champions[champMan._leaderIndex]._load += dunMan.getObjectWeight(thing) - weight; + } +T0377019: + commandProcessType80ClickInDungeonViewTouchFrontWall(); + } + } + + } else { + warning("MISSING CODE: F0375_COMMAND_ProcessType80_ClickInDungeonView_IsLeaderHandObjectThrown in if branch"); + for (int16 viewCell = kViewCellFronLeft; viewCell <= kViewCellBackLeft; viewCell++) { + if (gBoxObjectPiles[viewCell].isPointInside(Common::Point(posX, posY))) { + warning("MISSING CODE: F0374_COMMAND_ProcessType80_ClickInDungeonView_DropLeaderHandObject"); + return; + } + } + } + } +} + }; // end of namespace DM diff --git a/engines/dm/eventman.h b/engines/dm/eventman.h index e0e78f9465..1a4d663714 100644 --- a/engines/dm/eventman.h +++ b/engines/dm/eventman.h @@ -37,6 +37,8 @@ namespace DM { + + enum MouseButton { kNoneMouseButton = 0, // present only because of typesafety kLeftMouseButton = 1, @@ -245,6 +247,7 @@ public: void commandSetLeader(ChampionIndex index); // @ F0368_COMMAND_SetLeader void commandProcessType80ClickInDungeonViewTouchFrontWall(); // @ F0372_COMMAND_ProcessType80_ClickInDungeonView_TouchFrontWall + void commandProcessType80ClickInDungeonView(int16 posX, int16 posY); // @ F0377_COMMAND_ProcessType80_ClickInDungeonView }; } diff --git a/engines/dm/gfx.cpp b/engines/dm/gfx.cpp index 14324bdcd6..d9bb6af6fa 100644 --- a/engines/dm/gfx.cpp +++ b/engines/dm/gfx.cpp @@ -1146,9 +1146,11 @@ void DisplayMan::drawDungeon(direction dir, int16 posX, int16 posY) { byte *tmpBitmap = new byte[305 * 111]; clearBitmap(tmpBitmap, 305, 111, kColorBlack); - memset(_vm->_dungeonMan->_dungeonViewClickableBoxes, 0, sizeof(_vm->_dungeonMan->_dungeonViewClickableBoxes)); + for (int16 i = 0; i < 6; ++i) + _vm->_dungeonMan->_dungeonViewClickableBoxes[i].setToZero(); + for (uint16 i = 0; i < 6; ++i) { - _vm->_dungeonMan->_dungeonViewClickableBoxes[i][0] = 255; + _vm->_dungeonMan->_dungeonViewClickableBoxes[i]._x1 = 255 + 1; } if (flippedFloorCeiling) { @@ -1461,8 +1463,12 @@ bool DisplayMan::isDrawnWallOrnAnAlcove(int16 wallOrnOrd, ViewWall viewWallIndex return isAlcove; } nativeBitmapIndex++; - for (uint16 i = 0; i < 4; ++i) - _vm->_dungeonMan->_dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn][i] = coordinateSetA[i]; + + _vm->_dungeonMan->_dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn]._x1 = coordinateSetA[0]; + _vm->_dungeonMan->_dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn]._x2 = coordinateSetA[1]; + _vm->_dungeonMan->_dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn]._y1 = coordinateSetA[2]; + _vm->_dungeonMan->_dungeonViewClickableBoxes[kViewCellDoorButtonOrWallOrn]._y2 = coordinateSetA[3]; + _vm->_dungeonMan->_isFacingAlcove = isAlcove; _vm->_dungeonMan->_isFacingViAltar = (wallOrnIndex == _currMapViAltarIndex); _vm->_dungeonMan->_isFacingFountain = false; diff --git a/engines/dm/gfx.h b/engines/dm/gfx.h index 11679ef891..e73c44e697 100644 --- a/engines/dm/gfx.h +++ b/engines/dm/gfx.h @@ -91,6 +91,7 @@ public: bool isPointInside(Common::Point point) { return (_x1 <= point.x) && (point.x < _x2) && (_y1 <= point.y) && (point.y < _y2); } + void setToZero() { _x1 = _x2 = _y1 = _y2 = 0; } }; // @ BOX_BYTE, BOX_WORD extern Box gBoxMovementArrows; // G0002_s_Graphic562_Box_MovementArrows diff --git a/engines/dm/objectman.h b/engines/dm/objectman.h index 740ac0fd4e..fbf880db7e 100644 --- a/engines/dm/objectman.h +++ b/engines/dm/objectman.h @@ -43,7 +43,7 @@ public: SlotBox(int16 x, int16 y, int16 iconIndex): _x(x), _y(y), _iconIndex(iconIndex) {} }; // @ SLOT_BOX -extern SlotBox gSlotBoxes[46]; // @ G0030_as_Graphic562_SlotBoxes; +extern SlotBox gSlotBoxes[46]; // @ G0030_as_Graphic562_SlotBoxes class ObjectMan { DMEngine *_vm; |