diff options
author | Nicola Mettifogo | 2008-08-16 07:47:44 +0000 |
---|---|---|
committer | Nicola Mettifogo | 2008-08-16 07:47:44 +0000 |
commit | 5e912f6a900ced93b041059319fd9e57c258d2ef (patch) | |
tree | 5fbcb544db2d75cb9eb20499a95025f348d8645e | |
parent | 797a5e7035cf40025685f2bf3ffa4f6854783c89 (diff) | |
download | scummvm-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.cpp | 131 | ||||
-rw-r--r-- | engines/parallaction/parallaction.h | 2 |
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); |