aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicola Mettifogo2008-08-16 07:47:44 +0000
committerNicola Mettifogo2008-08-16 07:47:44 +0000
commit5e912f6a900ced93b041059319fd9e57c258d2ef (patch)
tree5fbcb544db2d75cb9eb20499a95025f348d8645e
parent797a5e7035cf40025685f2bf3ffa4f6854783c89 (diff)
downloadscummvm-rg350-5e912f6a900ced93b041059319fd9e57c258d2ef.tar.gz
scummvm-rg350-5e912f6a900ced93b041059319fd9e57c258d2ef.tar.bz2
scummvm-rg350-5e912f6a900ced93b041059319fd9e57c258d2ef.zip
Enabled interaction with movable zones - mainly NPCs - which are linked to animations.
svn-id: r33930
-rw-r--r--engines/parallaction/exec_ns.cpp131
-rw-r--r--engines/parallaction/parallaction.h2
2 files changed, 85 insertions, 48 deletions
diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp
index 4ea7d601e0..18ca1994bb 100644
--- a/engines/parallaction/exec_ns.cpp
+++ b/engines/parallaction/exec_ns.cpp
@@ -672,71 +672,106 @@ bool Parallaction::pickupItem(ZonePtr z) {
return (slot != -1);
}
+// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
+ if (z->_flags & kFlagsRemove)
+ return false;
+ debugC(5, kDebugExec, "checkZoneBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
-ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
-// printf("hitZone(%i, %i, %i)", type, x, y);
+ Common::Rect r;
+ z->getBox(r);
+ r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
+ r.bottom++;
- uint16 _di = y;
- uint16 _si = x;
+ r.grow(-1); // allows some tolerance for mouse click
- for (ZoneList::iterator it = _location._zones.begin(); it != _location._zones.end(); it++) {
-// printf("Zone name: %s", z->_name);
+ if (!r.contains(x, y)) {
- ZonePtr z = *it;
+ // out of Zone, so look for special values
+ if ((z->getX() == -2) || (z->getX() == -3)) {
- if (z->_flags & kFlagsRemove) continue;
+ // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
+ // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
+ // but we need to check it separately here. The same workaround is applied in freeZones.
+ if ((((z->_type & 0xFFFF) == kZoneMerge) && (((x == z->u.merge->_obj1) && (y == z->u.merge->_obj2)) || ((x == z->u.merge->_obj2) && (y == z->u.merge->_obj1)))) ||
+ (((z->_type & 0xFFFF) == kZoneGet) && ((x == z->u.get->_icon) || (y == z->u.get->_icon)))) {
- Common::Rect r;
- z->getBox(r);
- r.right++; // adjust border because Common::Rect doesn't include bottom-right edge
- r.bottom++;
+ // special Zone
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return true;
+ if (z->_type == type)
+ return true;
+ if ((z->_type & 0xFFFF0000) == type)
+ return true;
- r.grow(-1); // allows some tolerance for mouse click
+ }
+ }
- if (!r.contains(_si, _di)) {
+ if (z->getX() != -1)
+ return false;
+ if ((int)x < _char._ani->getFrameX())
+ return false;
+ if ((int)x > (_char._ani->getFrameX() + _char._ani->width()))
+ return false;
+ if ((int)y < _char._ani->getFrameY())
+ return false;
+ if ((int)y > (_char._ani->getFrameY() + _char._ani->height()))
+ return false;
- // out of Zone, so look for special values
- if ((z->getX() == -2) || (z->getX() == -3)) {
+ }
- // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
- // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
- // but we need to check it separately here. The same workaround is applied in freeZones.
- if ((((z->_type & 0xFFFF) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) ||
- (((z->_type & 0xFFFF) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) {
+ // normal Zone
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return true;
+ if (z->_type == type)
+ return true;
+ if ((z->_type & 0xFFFF0000) == type)
+ return true;
- // special Zone
- if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
- return z;
- if (z->_type == type)
- return z;
- if ((z->_type & 0xFFFF0000) == type)
- return z;
+ return false;
+}
- }
- }
+// FIXME: input coordinates must be offseted to handle scrolling!
+bool Parallaction::checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y) {
+ if (z->_flags & kFlagsRemove)
+ return false;
- if (z->getX() != -1)
- continue;
- if (_si < _char._ani->getFrameX())
- continue;
- if (_si > (_char._ani->getFrameX() + _char._ani->width()))
- continue;
- if (_di < _char._ani->getFrameY())
- continue;
- if (_di > (_char._ani->getFrameY() + _char._ani->height()))
- continue;
+ if ((z->_flags & kFlagsAnimLinked) == 0)
+ return false;
- }
+ debugC(5, kDebugExec, "checkLinkedAnimBox for %s (type = %x, x = %i, y = %i)", z->_name, type, x, y);
- // normal Zone
- if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
- return z;
- if (z->_type == type)
- return z;
- if ((z->_type & 0xFFFF0000) == type)
- return z;
+ AnimationPtr anim = z->_linkedAnim;
+ Common::Rect r(anim->getFrameX(), anim->getFrameY(), anim->getFrameX() + anim->width() + 1, anim->getFrameY() + anim->height() + 1);
+ if (!r.contains(x, y)) {
+ return false;
+ }
+
+ // NOTE: the implementation of the following lines is a different in the
+ // original... it is working so far, though
+ if ((type == 0) && ((z->_type & 0xFFFF0000) == 0))
+ return true;
+ if (z->_type == type)
+ return true;
+ if ((z->_type & 0xFFFF0000) == type)
+ return true;
+
+ return false;
+}
+
+ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
+ uint16 _di = y;
+ uint16 _si = x;
+
+ for (ZoneList::iterator it = _location._zones.begin(); it != _location._zones.end(); it++) {
+ if (checkLinkedAnimBox(*it, type, x, y)) {
+ return *it;
+ }
+ if (checkZoneBox(*it, type, x, y)) {
+ return *it;
+ }
}
diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h
index fb004a25b7..05dddd8ce0 100644
--- a/engines/parallaction/parallaction.h
+++ b/engines/parallaction/parallaction.h
@@ -261,6 +261,8 @@ public:
void pauseJobs();
void resumeJobs();
+ bool checkZoneBox(ZonePtr z, uint32 type, uint x, uint y);
+ bool checkLinkedAnimBox(ZonePtr z, uint32 type, uint x, uint y);
ZonePtr findZone(const char *name);
ZonePtr hitZone(uint32 type, uint16 x, uint16 y);
void runZone(ZonePtr z);