diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/dm/dm.h | 8 | ||||
-rw-r--r-- | engines/dm/dungeonman.h | 6 | ||||
-rw-r--r-- | engines/dm/movesens.cpp | 160 | ||||
-rw-r--r-- | engines/dm/movesens.h | 1 |
4 files changed, 174 insertions, 1 deletions
diff --git a/engines/dm/dm.h b/engines/dm/dm.h index aa37776286..2c8ff1c1b9 100644 --- a/engines/dm/dm.h +++ b/engines/dm/dm.h @@ -83,6 +83,14 @@ enum ThingType { kThingTypeTotal = 16 // +1 than the last (explosionThingType) }; // @ C[00..15]_THING_TYPE_... +enum Cell { + kCellAny = -1, // @ CM1_CELL_ANY + kCellNorthWest = 0, // @ C00_CELL_NORTHWEST + kCellNorthEast = 1, // @ C01_CELL_NORTHEAST + kCellSouthEast = 2, // @ C02_CELL_SOUTHEAST + kCellSouthWest = 3 // @ C03_CELL_SOUTHWEST +}; + class Thing { uint16 _data; public: diff --git a/engines/dm/dungeonman.h b/engines/dm/dungeonman.h index 1ccb1d2c62..4a80d0e2d1 100644 --- a/engines/dm/dungeonman.h +++ b/engines/dm/dungeonman.h @@ -278,6 +278,7 @@ public: explicit Sensor(uint16 *rawDat) : _nextThing(rawDat[0]), _datAndType(rawDat[1]), _attributes(rawDat[2]), _action(rawDat[3]) {} Thing getNextThing() { return _nextThing; } + void setNextThing(Thing thing) { _nextThing = thing; } SensorType getType() { return (SensorType)(_datAndType & 0x7F); } // @ M39_TYPE uint16 getData() { return _datAndType >> 7; } // @ M40_DATA uint16 getDataMask1() { return (_datAndType >> 7) & 0xF; } // @ M42_MASK1 @@ -295,6 +296,11 @@ public: uint16 getRemoteMapX() { return (_action >> 6) & 0x1F; } direction getRemoteDir() { return (direction)((_action >> 4) & 3); } uint16 getLocalAction() { return (_action >> 4); } + uint16 getEffectA() { return (_attributes >> 3) & 0x3; } + bool getRevertEffectA() { return (_attributes >> 5) & 0x1; } + bool getAudibleA() { return (_attributes >> 6) & 0x1; } + + // some macros missing, i got bored }; // @ SENSOR diff --git a/engines/dm/movesens.cpp b/engines/dm/movesens.cpp index 9654d779b5..2c25251761 100644 --- a/engines/dm/movesens.cpp +++ b/engines/dm/movesens.cpp @@ -27,11 +27,169 @@ #include "movesens.h" +#include "champion.h" +#include "inventory.h" +#include "dungeonman.h" +#include "objectman.h" namespace DM { MovesensMan::MovesensMan(DMEngine* vm) : _vm(vm) {} +bool MovesensMan::sensorIsTriggeredByClickOnWall(int16 mapX, int16 mapY, uint16 cellParam) { + ChampionMan &champMan = *_vm->_championMan; + DungeonMan &dunMan = *_vm->_dungeonMan; + ObjectMan &objMan = *_vm->_objectMan; -}
\ No newline at end of file + + bool atLeastOneSensorWasTriggered = false; + Thing leaderHandObject = champMan._leaderHand; + int16 sensorCountToProcessPerCell[4]; + uint16 cell; + for (cell = kCellNorthWest; cell < kCellSouthWest; ++cell) { + sensorCountToProcessPerCell[cell] = 0; + } + Thing squareFirstThing; + Thing thingBeingProcessed = squareFirstThing = dunMan.getSquareFirstThing(mapX, mapY); + ThingType thingType; + while (thingBeingProcessed != Thing::_thingEndOfList) { + thingType = thingBeingProcessed.getType(); + if (thingType == kSensorThingType) { + sensorCountToProcessPerCell[thingBeingProcessed.getCell()]++; + } else if (thingType >= kGroupThingType) { + break; + } + thingBeingProcessed = dunMan.getNextThing(thingBeingProcessed); + } + Thing lastProcessedThing = thingBeingProcessed = squareFirstThing; + + while (thingBeingProcessed != Thing::_thingEndOfList) { + thingType = thingBeingProcessed.getType(); + if (thingType == kSensorThingType) { + cell = thingBeingProcessed.getCell(); + sensorCountToProcessPerCell[cell]--; + Sensor *sensor = (Sensor*)dunMan.getThingData(thingBeingProcessed); // IF YOU CHECK ME, I'LL CALL THE COPS! + SensorType sensorType = sensor->getType(); + if (sensorType == kSensorDisabled) + goto T0275058_ProceedToNextThing; + if ((champMan._leaderIndex == kChampionNone) && (sensorType != kSensorWallChampionPortrait)) + goto T0275058_ProceedToNextThing; + if (cell != cellParam) + goto T0275058_ProceedToNextThing; + int16 sensorData = sensor->getData(); + int16 sensorEffect = sensor->getEffectA(); + bool doNotTriggerSensor; + switch (sensorType) { + case kSensorWallOrnClick: + doNotTriggerSensor = false; + if (sensor->getEffectA() == kSensorEffHold) { + goto T0275058_ProceedToNextThing; + } + break; + case kSensorWallOrnClickWithAnyObj: + doNotTriggerSensor = (champMan._leaderEmptyHanded != sensor->getRevertEffectA()); + break; + case kSensorWallOrnClickWithSpecObjRemovedSensor: + case kSensorWallOrnClickWithSpecObjRemovedRotateSensors: + if (sensorCountToProcessPerCell[cell]) + goto T0275058_ProceedToNextThing; + case kSensorWallOrnClickWithSpecObj: + case kSensorWallOrnClickWithSpecObjRemoved: + doNotTriggerSensor = ((sensorData == objMan.getObjectType(leaderHandObject)) == sensor->getRevertEffectA()); + if (!doNotTriggerSensor && (sensorType == kSensorWallOrnClickWithSpecObjRemovedSensor)) { + if (lastProcessedThing == thingBeingProcessed) + break; + ((Sensor*)dunMan.getThingData(lastProcessedThing))->setNextThing(sensor->getNextThing()); + sensor->setNextThing(Thing::_thingNone); + thingBeingProcessed = lastProcessedThing; + } + if (!doNotTriggerSensor && (sensorType == kSensorWallOrnClickWithSpecObjRemovedRotateSensors)) { + warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect"); + } + break; + case kSensorWallObjGeneratorRotateSensors: + if (sensorCountToProcessPerCell[cell]) + goto T0275058_ProceedToNextThing; + doNotTriggerSensor = !champMan._leaderEmptyHanded; + if (!doNotTriggerSensor) { + warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect"); + } + break; + case kSensorWallSingleObjStorageRotateSensors: + if (champMan._leaderEmptyHanded) { + warning("MISSING CODE: F0273_SENSOR_GetObjectOfTypeInCell"); + warning("MISSING CODE: F0164_DUNGEON_UnlinkThingFromList"); + warning("MISSING CODE: F0297_CHAMPION_PutObjectInLeaderHand"); + } else { + warning("MISSING CODE: F0273_SENSOR_GetObjectOfTypeInCell"); + warning(("MISSING CODE: F0298_CHAMPION_GetObjectRemovedFromLeaderHand")); + warning("MISSING CODE: F0163_DUNGEON_LinkThingToList"); + leaderHandObject = Thing::_thingNone; + } + warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect"); + if ((sensorEffect == kSensorEffHold) && !champMan._leaderEmptyHanded) { + doNotTriggerSensor = true; + } else { + doNotTriggerSensor = false; + } + break; + case kSensorWallObjExchanger: { + if (sensorCountToProcessPerCell[cell]) + goto T0275058_ProceedToNextThing; + Thing thingOnSquare = dunMan.getSquareFirstThing(mapX, mapY); + if ((objMan.getObjectType(leaderHandObject) != sensorData) || (thingOnSquare == Thing::_thingNone)) + goto T0275058_ProceedToNextThing; + warning("MISSING CODE: F0164_DUNGEON_UnlinkThingFromList"); + warning("MISSING CODE: F0298_CHAMPION_GetObjectRemovedFromLeaderHand"); + warning("MISSING CODE: F0163_DUNGEON_LinkThingToList"); + warning("MISSING CODE: F0297_CHAMPION_PutObjectInLeaderHand"); + doNotTriggerSensor = false; + break; + } + case kSensorWallChampionPortrait: + champMan.addCandidateChampionToParty(sensorData); + goto T0275058_ProceedToNextThing; + default: + goto T0275058_ProceedToNextThing; + } + + if (sensorEffect == kSensorEffHold) { + sensorEffect = doNotTriggerSensor ? kSensorEffClear : kSensorEffSet; + doNotTriggerSensor = false; + } + + if (!doNotTriggerSensor) { + atLeastOneSensorWasTriggered = true; + if (sensor->getAudibleA()) { + warning("MISSING CODE: F0064_SOUND_RequestPlay_CPSD"); + } + if (!champMan._leaderEmptyHanded && + ((sensorType == kSensorWallOrnClickWithSpecObjRemoved) || + (sensorType == kSensorWallOrnClickWithSpecObjRemovedRotateSensors) || + (sensorType == kSensorWallOrnClickWithSpecObjRemovedSensor))) { + + *((Thing*)dunMan.getThingData(leaderHandObject)) = Thing::_thingNone; + warning("MISSING CODE: F0298_CHAMPION_GetObjectRemovedFromLeaderHand"); + leaderHandObject = Thing::_thingNone; + } else { + warning("MISSING CODE: (leaderHandObject = F0167_DUNGEON_GetObjectForProjectileLauncherOrObjectGenerator(sensorData)"); + if (champMan._leaderEmptyHanded && (sensorType == kSensorWallObjGeneratorRotateSensors) && (leaderHandObject != Thing::_thingNone)) { + warning("MISSING CODE: F0297_CHAMPION_PutObjectInLeaderHand"); + } + } + warning("MISSING CODE: F0272_SENSOR_TriggerEffect"); + } + goto T0275058_ProceedToNextThing; + } + if (thingType >= kGroupThingType) + break; +T0275058_ProceedToNextThing: + lastProcessedThing = thingBeingProcessed; + thingBeingProcessed = dunMan.getNextThing(thingBeingProcessed); + } + warning("MISSING CODE: F0271_SENSOR_ProcessRotationEffect"); + return atLeastOneSensorWasTriggered; +} + +} diff --git a/engines/dm/movesens.h b/engines/dm/movesens.h index e0f397df6d..b73f727f8b 100644 --- a/engines/dm/movesens.h +++ b/engines/dm/movesens.h @@ -37,6 +37,7 @@ class MovesensMan { DMEngine *_vm; public: explicit MovesensMan(DMEngine *vm); + bool sensorIsTriggeredByClickOnWall(int16 mapX, int16 mapY, uint16 cellParam); // @ F0275_SENSOR_IsTriggeredByClickOnWall }; } |