aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/dm/dm.h8
-rw-r--r--engines/dm/dungeonman.h6
-rw-r--r--engines/dm/movesens.cpp160
-rw-r--r--engines/dm/movesens.h1
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
};
}