From ada51dbdfb3111f309732e17abcbcc4fd1034fdc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 6 Jul 2015 20:26:37 -0400 Subject: SHERLOCK: RT: Fix characters walking off-screen --- engines/sherlock/people.cpp | 23 ++--------------------- engines/sherlock/people.h | 4 ++++ engines/sherlock/scalpel/scalpel_people.cpp | 27 +++++++++++++++++++++++++++ engines/sherlock/scalpel/scalpel_people.h | 14 +++++++++----- engines/sherlock/tattoo/tattoo_people.cpp | 25 +++++++++++++++++++++++++ engines/sherlock/tattoo/tattoo_people.h | 5 +++++ 6 files changed, 72 insertions(+), 26 deletions(-) (limited to 'engines') diff --git a/engines/sherlock/people.cpp b/engines/sherlock/people.cpp index 2317535640..46ae8e7051 100644 --- a/engines/sherlock/people.cpp +++ b/engines/sherlock/people.cpp @@ -84,27 +84,8 @@ void Person::goAllTheWay() { if (_destZone == -1) { _destZone = scene.closestZone(_walkDest); - // The destination isn't in a zone - if (_walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1)) - _walkDest.x = SHERLOCK_SCREEN_WIDTH - 2; - - // Trace a line between the centroid of the found closest zone to - // the destination, to find the point at which the zone will be left - const Common::Rect &destRect = scene._zones[_destZone]; - const Common::Point destCenter((destRect.left + destRect.right) / 2, - (destRect.top + destRect.bottom) / 2); - const Common::Point delta = _walkDest - destCenter; - Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER); - - // Move along the line until the zone is left - do { - pt += delta; - } while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER)); - - // Set the new walk destination to the last point that was in the - // zone just before it was left - _walkDest = Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER, - (pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER); + // Check for any restriction of final destination position + _walkDest = _vm->_people->restrictToZone(_destZone, _walkDest); } // Only do a walk if both zones are acceptable diff --git a/engines/sherlock/people.h b/engines/sherlock/people.h index 170f93589b..8210a54aed 100644 --- a/engines/sherlock/people.h +++ b/engines/sherlock/people.h @@ -156,6 +156,10 @@ public: */ virtual bool loadWalk() = 0; + /** + * Restrict passed point to zone using Sherlock's positioning rules + */ + virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos) = 0; }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_people.cpp b/engines/sherlock/scalpel/scalpel_people.cpp index db26bb8c0f..53876f8f1c 100644 --- a/engines/sherlock/scalpel/scalpel_people.cpp +++ b/engines/sherlock/scalpel/scalpel_people.cpp @@ -500,6 +500,33 @@ bool ScalpelPeople::loadWalk() { return result; } +const Common::Point ScalpelPeople::restrictToZone(int zoneId, const Common::Point &destPos) { + Scene &scene = *_vm->_scene; + Common::Point walkDest = destPos; + + // The destination isn't in a zone + if (walkDest.x >= (SHERLOCK_SCREEN_WIDTH - 1)) + walkDest.x = SHERLOCK_SCREEN_WIDTH - 2; + + // Trace a line between the centroid of the found closest zone to + // the destination, to find the point at which the zone will be left + const Common::Rect &destRect = scene._zones[zoneId]; + const Common::Point destCenter((destRect.left + destRect.right) / 2, + (destRect.top + destRect.bottom) / 2); + const Common::Point delta = walkDest - destCenter; + Point32 pt(destCenter.x * FIXED_INT_MULTIPLIER, destCenter.y * FIXED_INT_MULTIPLIER); + + // Move along the line until the zone is left + do { + pt += delta; + } while (destRect.contains(pt.x / FIXED_INT_MULTIPLIER, pt.y / FIXED_INT_MULTIPLIER)); + + // Set the new walk destination to the last point that was in the + // zone just before it was left + return Common::Point((pt.x - delta.x * 2) / FIXED_INT_MULTIPLIER, + (pt.y - delta.y * 2) / FIXED_INT_MULTIPLIER); +} + } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_people.h b/engines/sherlock/scalpel/scalpel_people.h index 0f8aa9dcc7..b53da2e6d8 100644 --- a/engines/sherlock/scalpel/scalpel_people.h +++ b/engines/sherlock/scalpel/scalpel_people.h @@ -42,11 +42,6 @@ enum ScalpelSequences { }; class ScalpelPerson : public Person { -protected: - /** - * Get the source position for a character potentially affected by scaling - */ - virtual Common::Point getSourcePoint() const; public: ScalpelPerson() : Person() {} virtual ~ScalpelPerson() {} @@ -72,6 +67,10 @@ public: */ virtual void walkToCoords(const Point32 &destPos, int destDir); + /** + * Get the source position for a character potentially affected by scaling + */ + virtual Common::Point getSourcePoint() const; }; class ScalpelPeople : public People { @@ -97,6 +96,11 @@ public: */ virtual void setTalkSequence(int speaker, int sequenceNum = 1); + /** + * Restrict passed point to zone using Sherlock's positioning rules + */ + virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos); + /** * Load the walking images for Sherlock */ diff --git a/engines/sherlock/tattoo/tattoo_people.cpp b/engines/sherlock/tattoo/tattoo_people.cpp index a7d7d2426c..81f68b46ae 100644 --- a/engines/sherlock/tattoo/tattoo_people.cpp +++ b/engines/sherlock/tattoo/tattoo_people.cpp @@ -1313,6 +1313,31 @@ void TattooPeople::pullNPCPaths() { } } +const Common::Point TattooPeople::restrictToZone(int zoneId, const Common::Point &destPos) { + Scene &scene = *_vm->_scene; + Screen &screen = *_vm->_screen; + Common::Rect &r = scene._zones[zoneId]; + + if (destPos.x < 0 || destPos.x > screen._backBuffer1.w()) + return destPos; + else if (destPos.y < r.top && r.left < destPos.x && destPos.x < r.right) + return Common::Point(destPos.x, r.top); + else if (destPos.y > r.bottom && r.left < destPos.x && destPos.x < r.right) + return Common::Point(destPos.x, r.bottom); + else if (destPos.x < r.left && r.top < destPos.y && destPos.y < r.bottom) + return Common::Point(r.left, destPos.y); + else if (destPos.x > r.right && r.top < destPos.y && destPos.y < r.bottom) + return Common::Point(r.bottom, destPos.y); + + // Find which corner of the zone the point is closet to + if (destPos.x <= r.left) { + return Common::Point(r.left, (destPos.y <= r.top) ? r.top : r.bottom); + } else { + return Common::Point(r.right, (destPos.y <= r.top) ? r.top : r.bottom); + } +} + + } // End of namespace Tattoo } // End of namespace Sherlock diff --git a/engines/sherlock/tattoo/tattoo_people.h b/engines/sherlock/tattoo/tattoo_people.h index 4b35998cb4..7cd73a10d6 100644 --- a/engines/sherlock/tattoo/tattoo_people.h +++ b/engines/sherlock/tattoo/tattoo_people.h @@ -251,6 +251,11 @@ public: * Load the walking images for Sherlock */ virtual bool loadWalk(); + + /** + * Restrict passed point to zone using Sherlock's positioning rules + */ + virtual const Common::Point restrictToZone(int zoneId, const Common::Point &destPos); }; } // End of namespace Scalpel -- cgit v1.2.3