diff --git a/src/app/useOutfitState.js b/src/app/useOutfitState.js index 2c2345b..63b799b 100644 --- a/src/app/useOutfitState.js +++ b/src/app/useOutfitState.js @@ -218,28 +218,31 @@ function findItemConflicts(itemIdToAdd, state, apolloClient) { if (!itemToAdd.appearanceOn) { return []; } - const itemToAddZoneIds = [ - ...itemToAdd.appearanceOn.layers.map((l) => l.zone.id), - ...itemToAdd.appearanceOn.restrictedZones.map((z) => z.id), - ]; const wornItems = Array.from(wornItemIds).map((id) => items.find((i) => i.id === id) ); + const itemToAddZoneSets = getItemZones(itemToAdd); + const conflictingIds = []; for (const wornItem of wornItems) { if (!wornItem.appearanceOn) { continue; } - const wornItemZoneIds = [ - ...wornItem.appearanceOn.layers.map((l) => l.zone.id), - ...wornItem.appearanceOn.restrictedZones.map((z) => z.id), - ]; - const hasConflict = wornItemZoneIds.some((zid) => - itemToAddZoneIds.includes(zid) - ); - if (hasConflict) { + const wornItemZoneSets = getItemZones(wornItem); + + const itemsConflict = + setsIntersect( + itemToAddZoneSets.occupies, + wornItemZoneSets.occupiesOrRestricts + ) || + setsIntersect( + wornItemZoneSets.occupies, + itemToAddZoneSets.occupiesOrRestricts + ); + + if (itemsConflict) { conflictingIds.push(wornItem.id); } } @@ -247,6 +250,22 @@ function findItemConflicts(itemIdToAdd, state, apolloClient) { return conflictingIds; } +function getItemZones(item) { + const occupies = new Set(item.appearanceOn.layers.map((l) => l.zone.id)); + const restricts = new Set(item.appearanceOn.restrictedZones.map((z) => z.id)); + const occupiesOrRestricts = new Set([...occupies, ...restricts]); + return { occupies, occupiesOrRestricts }; +} + +function setsIntersect(a, b) { + for (const el of a) { + if (b.has(el)) { + return true; + } + } + return false; +} + // TODO: Get this out of here, tbh... function getZonesAndItems(itemsById, wornItemIds, closetedItemIds) { const wornItems = wornItemIds.map((id) => itemsById[id]).filter((i) => i);