scummvm/engines/dm/movesens.cpp

196 lines
7.7 KiB
C++
Raw Normal View History

2016-08-26 22:37:14 +02:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
/*
* Based on the Reverse Engineering work of Christophe Fontanel,
* maintainer of the Dungeon Master Encyclopaedia (http://dmweb.free.fr/)
*/
#include "movesens.h"
#include "champion.h"
#include "inventory.h"
#include "dungeonman.h"
#include "objectman.h"
2016-08-26 22:37:14 +02:00
namespace DM {
MovesensMan::MovesensMan(DMEngine* vm) : _vm(vm) {}
2016-08-26 22:47:44 +02:00
bool MovesensMan::f275_sensorIsTriggeredByClickOnWall(int16 mapX, int16 mapY, uint16 cellParam) {
ChampionMan &champMan = *_vm->_championMan;
DungeonMan &dunMan = *_vm->_dungeonMan;
ObjectMan &objMan = *_vm->_objectMan;
2016-08-26 22:37:14 +02:00
bool atLeastOneSensorWasTriggered = false;
2016-08-26 22:47:44 +02:00
Thing leaderHandObject = champMan._g414_leaderHandObject;
int16 sensorCountToProcessPerCell[4];
uint16 cell;
2016-08-26 22:43:17 +02:00
for (cell = k0_CellNorthWest; cell < k3_CellSouthWest; ++cell) {
sensorCountToProcessPerCell[cell] = 0;
}
Thing squareFirstThing;
2016-08-26 22:47:44 +02:00
Thing thingBeingProcessed = squareFirstThing = dunMan.f161_getSquareFirstThing(mapX, mapY);
ThingType thingType;
while (thingBeingProcessed != Thing::_endOfList) {
thingType = thingBeingProcessed.getType();
2016-08-26 22:43:17 +02:00
if (thingType == k3_SensorThingType) {
sensorCountToProcessPerCell[thingBeingProcessed.getCell()]++;
2016-08-26 22:43:17 +02:00
} else if (thingType >= k4_GroupThingType) {
break;
}
2016-08-26 22:47:44 +02:00
thingBeingProcessed = dunMan.f159_getNextThing(thingBeingProcessed);
}
Thing lastProcessedThing = thingBeingProcessed = squareFirstThing;
while (thingBeingProcessed != Thing::_endOfList) {
thingType = thingBeingProcessed.getType();
2016-08-26 22:43:17 +02:00
if (thingType == k3_SensorThingType) {
cell = thingBeingProcessed.getCell();
sensorCountToProcessPerCell[cell]--;
2016-08-26 22:47:44 +02:00
Sensor *sensor = (Sensor*)dunMan.f156_getThingData(thingBeingProcessed); // IF YOU CHECK ME, I'LL CALL THE COPS!
SensorType sensorType = sensor->getType();
2016-08-26 22:43:17 +02:00
if (sensorType == k0_SensorDisabled)
goto T0275058_ProceedToNextThing;
2016-08-26 22:43:17 +02:00
if ((champMan._g411_leaderIndex == kM1_ChampionNone) && (sensorType != k127_SensorWallChampionPortrait))
goto T0275058_ProceedToNextThing;
if (cell != cellParam)
goto T0275058_ProceedToNextThing;
int16 sensorData = sensor->getData();
int16 sensorEffect = sensor->getEffectA();
bool doNotTriggerSensor;
switch (sensorType) {
2016-08-26 22:43:17 +02:00
case k1_SensorWallOrnClick:
doNotTriggerSensor = false;
2016-08-26 22:43:17 +02:00
if (sensor->getEffectA() == k3_SensorEffHold) {
goto T0275058_ProceedToNextThing;
}
break;
2016-08-26 22:43:17 +02:00
case k2_SensorWallOrnClickWithAnyObj:
2016-07-02 01:55:48 +02:00
doNotTriggerSensor = (champMan._g415_leaderEmptyHanded != sensor->getRevertEffectA());
break;
2016-08-26 22:43:17 +02:00
case k17_SensorWallOrnClickWithSpecObjRemovedSensor:
case k11_SensorWallOrnClickWithSpecObjRemovedRotateSensors:
if (sensorCountToProcessPerCell[cell])
goto T0275058_ProceedToNextThing;
2016-08-26 22:43:17 +02:00
case k3_SensorWallOrnClickWithSpecObj:
case k4_SensorWallOrnClickWithSpecObjRemoved:
2016-08-26 22:47:44 +02:00
doNotTriggerSensor = ((sensorData == objMan.f32_getObjectType(leaderHandObject)) == sensor->getRevertEffectA());
2016-08-26 22:43:17 +02:00
if (!doNotTriggerSensor && (sensorType == k17_SensorWallOrnClickWithSpecObjRemovedSensor)) {
if (lastProcessedThing == thingBeingProcessed)
break;
2016-08-26 22:47:44 +02:00
((Sensor*)dunMan.f156_getThingData(lastProcessedThing))->setNextThing(sensor->getNextThing());
sensor->setNextThing(Thing::_none);
thingBeingProcessed = lastProcessedThing;
}
2016-08-26 22:43:17 +02:00
if (!doNotTriggerSensor && (sensorType == k11_SensorWallOrnClickWithSpecObjRemovedRotateSensors)) {
warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect");
}
break;
2016-08-26 22:43:17 +02:00
case k12_SensorWallObjGeneratorRotateSensors:
if (sensorCountToProcessPerCell[cell])
goto T0275058_ProceedToNextThing;
2016-07-02 01:55:48 +02:00
doNotTriggerSensor = !champMan._g415_leaderEmptyHanded;
if (!doNotTriggerSensor) {
warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect");
}
break;
2016-08-26 22:43:17 +02:00
case k13_SensorWallSingleObjStorageRotateSensors:
2016-07-02 01:55:48 +02:00
if (champMan._g415_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::_none;
}
warning("MISSING CODE: F0270_SENSOR_TriggerLocalEffect");
2016-08-26 22:43:17 +02:00
if ((sensorEffect == k3_SensorEffHold) && !champMan._g415_leaderEmptyHanded) {
doNotTriggerSensor = true;
} else {
doNotTriggerSensor = false;
}
break;
2016-08-26 22:43:17 +02:00
case k16_SensorWallObjExchanger: {
if (sensorCountToProcessPerCell[cell])
goto T0275058_ProceedToNextThing;
2016-08-26 22:47:44 +02:00
Thing thingOnSquare = dunMan.f161_getSquareFirstThing(mapX, mapY);
if ((objMan.f32_getObjectType(leaderHandObject) != sensorData) || (thingOnSquare == Thing::_none))
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;
}
2016-08-26 22:43:17 +02:00
case k127_SensorWallChampionPortrait:
2016-08-26 22:47:44 +02:00
champMan.f280_addCandidateChampionToParty(sensorData);
goto T0275058_ProceedToNextThing;
default:
goto T0275058_ProceedToNextThing;
}
2016-08-26 22:43:17 +02:00
if (sensorEffect == k3_SensorEffHold) {
sensorEffect = doNotTriggerSensor ? k1_SensorEffClear : k0_SensorEffSet;
doNotTriggerSensor = false;
}
if (!doNotTriggerSensor) {
atLeastOneSensorWasTriggered = true;
if (sensor->getAudibleA()) {
warning("MISSING CODE: F0064_SOUND_RequestPlay_CPSD");
}
2016-07-02 01:55:48 +02:00
if (!champMan._g415_leaderEmptyHanded &&
2016-08-26 22:43:17 +02:00
((sensorType == k4_SensorWallOrnClickWithSpecObjRemoved) ||
(sensorType == k11_SensorWallOrnClickWithSpecObjRemovedRotateSensors) ||
(sensorType == k17_SensorWallOrnClickWithSpecObjRemovedSensor))) {
2016-08-26 22:47:44 +02:00
*((Thing*)dunMan.f156_getThingData(leaderHandObject)) = Thing::_none;
warning("MISSING CODE: F0298_CHAMPION_GetObjectRemovedFromLeaderHand");
leaderHandObject = Thing::_none;
} else {
warning("MISSING CODE: (leaderHandObject = F0167_DUNGEON_GetObjectForProjectileLauncherOrObjectGenerator(sensorData)");
2016-08-26 22:43:17 +02:00
if (champMan._g415_leaderEmptyHanded && (sensorType == k12_SensorWallObjGeneratorRotateSensors) && (leaderHandObject != Thing::_none)) {
warning("MISSING CODE: F0297_CHAMPION_PutObjectInLeaderHand");
}
}
warning("MISSING CODE: F0272_SENSOR_TriggerEffect");
}
goto T0275058_ProceedToNextThing;
}
2016-08-26 22:43:17 +02:00
if (thingType >= k4_GroupThingType)
break;
T0275058_ProceedToNextThing:
lastProcessedThing = thingBeingProcessed;
2016-08-26 22:47:44 +02:00
thingBeingProcessed = dunMan.f159_getNextThing(thingBeingProcessed);
}
warning("MISSING CODE: F0271_SENSOR_ProcessRotationEffect");
return atLeastOneSensorWasTriggered;
}
}