diff options
Diffstat (limited to 'engines/parallaction')
-rw-r--r-- | engines/parallaction/inventory.h | 6 | ||||
-rw-r--r-- | engines/parallaction/zone.cpp | 20 |
2 files changed, 19 insertions, 7 deletions
diff --git a/engines/parallaction/inventory.h b/engines/parallaction/inventory.h index d08fa52813..8adf546529 100644 --- a/engines/parallaction/inventory.h +++ b/engines/parallaction/inventory.h @@ -27,13 +27,17 @@ namespace Parallaction { + struct Cnv; struct InventoryItem { - uint32 _id; + uint32 _id; // lowest 16 bits are always zero uint16 _index; }; +#define MAKE_INVENTORY_ID(x) (((x) & 0xFFFF) << 16) + + extern InventoryItem _inventory[]; void initInventory(); diff --git a/engines/parallaction/zone.cpp b/engines/parallaction/zone.cpp index e065fd849e..9d3c8de10a 100644 --- a/engines/parallaction/zone.cpp +++ b/engines/parallaction/zone.cpp @@ -128,9 +128,15 @@ void freeZones(Node *list) { for (; z; ) { - // TODO: understand and simplify this monster - if (((z->_limits._top == -1) || ((z->_limits._left == -2) && ((isItemInInventory(z->u.merge->_obj1) != 0) || (isItemInInventory(z->u.merge->_obj2) != 0)))) && - ((_engineFlags & kEngineQuit) == 0)) { + // WORKAROUND: this huge condition is needed because we made ZoneTypeData 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 hitZone. + if (((z->_limits._top == -1) || + ((z->_limits._left == -2) && ( + (((z->_type & 0xFFFF) == kZoneMerge) && ((isItemInInventory(MAKE_INVENTORY_ID(z->u.merge->_obj1)) != 0) || (isItemInInventory(MAKE_INVENTORY_ID(z->u.merge->_obj2)) != 0))) || + (((z->_type & 0xFFFF) == kZoneGet) && ((isItemInInventory(MAKE_INVENTORY_ID(z->u.get->_icon)) != 0))) + ))) && + ((_engineFlags & kEngineQuit) == 0)) { debugC(1, kDebugLocation, "freeZones preserving zone '%s'", z->_label._text); @@ -623,10 +629,12 @@ Zone *hitZone(uint32 type, uint16 x, uint16 y) { // out of Zone, so look for special values if ((z->_limits._left == -2) || (z->_limits._left == -3)) { - // only merge zones have _left == -2 or _left == -3 - if (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || - ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1))) { + // WORKAROUND: this huge condition is needed because we made ZoneTypeData 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 & 0xFFFF0000) == kZoneMerge) && (((_si == z->u.merge->_obj1) && (_di == z->u.merge->_obj2)) || ((_si == z->u.merge->_obj2) && (_di == z->u.merge->_obj1)))) || + (((z->_type & 0xFFFF0000) == kZoneGet) && ((_si == z->u.get->_icon) || (_di == z->u.get->_icon)))) { // special Zone if ((type == 0) && ((z->_type & 0xFFFF0000) == 0)) return z; |