aboutsummaryrefslogtreecommitdiff
path: root/engines/saga/actor_path.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/saga/actor_path.cpp')
-rw-r--r--engines/saga/actor_path.cpp51
1 files changed, 51 insertions, 0 deletions
diff --git a/engines/saga/actor_path.cpp b/engines/saga/actor_path.cpp
index 0fb072b201..d0f1cf2b5b 100644
--- a/engines/saga/actor_path.cpp
+++ b/engines/saga/actor_path.cpp
@@ -23,6 +23,7 @@
#include "saga/saga.h"
#include "saga/actor.h"
+#include "saga/objectmap.h"
#include "saga/scene.h"
namespace Saga {
@@ -99,6 +100,47 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point
_debugPointsCount = 0;
#endif
+ // WORKAROUND for bug #3360396. Path finding in IHNM is a bit buggy
+ // compared to the original, which occasionally leads to the player
+ // leaving the room instead of interacting with an object. So far, no
+ // one has figured out how to fix this properly. As a temporary [*]
+ // solution, we try to fix this on a case-by-case basis.
+ //
+ // The workaround is to assume that the player wants to stay in the
+ // room, unless he or she explicitly clicked on an exit zone.
+ //
+ // [*] And there is nothing more permanent than a temporary solution...
+
+ bool pathFindingWorkaround = false;
+
+ if (_vm->getGameId() == GID_IHNM) {
+ int chapter = _vm->_scene->currentChapterNumber();
+ int scene = _vm->_scene->currentSceneNumber();
+
+ // Ellen, in the room with the monitors.
+ if (chapter == 3 && scene == 54)
+ pathFindingWorkaround = true;
+
+ // Nimdok in the recovery room
+ if (chapter == 4 && scene == 71)
+ pathFindingWorkaround = true;
+ }
+
+ int hitZoneIndex;
+ const HitZone *hitZone;
+ bool restrictToRoom = false;
+
+ if (pathFindingWorkaround) {
+ restrictToRoom = true;
+ hitZoneIndex = _vm->_scene->_actionMap->hitTest(toPoint);
+ if (hitZoneIndex != -1) {
+ hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex);
+ if (hitZone->getFlags() & kHitZoneExit) {
+ restrictToRoom = false;
+ }
+ }
+ }
+
actor->_walkStepsCount = 0;
if (fromPoint == toPoint) {
actor->addWalkStepPoint(toPoint);
@@ -110,6 +152,15 @@ void Actor::findActorPath(ActorData *actor, const Point &fromPoint, const Point
if (_vm->_scene->validBGMaskPoint(iteratorPoint)) {
maskType = _vm->_scene->getBGMaskType(iteratorPoint);
setPathCell(iteratorPoint, _vm->_scene->getDoorState(maskType) ? kPathCellBarrier : kPathCellEmpty);
+ if (restrictToRoom) {
+ hitZoneIndex = _vm->_scene->_actionMap->hitTest(iteratorPoint);
+ if (hitZoneIndex != -1) {
+ hitZone = _vm->_scene->_actionMap->getHitZone(hitZoneIndex);
+ if (hitZone->getFlags() & kHitZoneExit) {
+ setPathCell(iteratorPoint, kPathCellBarrier);
+ }
+ }
+ }
} else {
setPathCell(iteratorPoint, kPathCellBarrier);
}