aboutsummaryrefslogtreecommitdiff
path: root/engines/parallaction
diff options
context:
space:
mode:
Diffstat (limited to 'engines/parallaction')
-rw-r--r--engines/parallaction/inventory.h6
-rw-r--r--engines/parallaction/zone.cpp20
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;