From b8730e64fb4891868f80a18da7e75aba8ee66ba7 Mon Sep 17 00:00:00 2001 From: Lean Mendoza Date: Sat, 28 Sep 2024 07:55:52 -0300 Subject: [PATCH] fix: add categories priority list for hiding/replacing (adr-239) (#116) * fix: add categories priority list for hiding/replacing (adr-239) * forceRender applied after computing hides (same as EA) --- src/lib/babylon/slots.ts | 71 +++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/src/lib/babylon/slots.ts b/src/lib/babylon/slots.ts index d5e332b..b33324f 100644 --- a/src/lib/babylon/slots.ts +++ b/src/lib/babylon/slots.ts @@ -22,6 +22,40 @@ const categoriesHiddenBySkin = [ BodyPartCategory.HANDS, ] +// based on https://adr.decentraland.org/adr/ADR-239 +const categoriesPriority = [ + WearableCategory.SKIN, + WearableCategory.UPPER_BODY, + WearableCategory.HANDS_WEAR, + WearableCategory.LOWER_BODY, + WearableCategory.FEET, + WearableCategory.HELMET, + WearableCategory.HAT, + WearableCategory.TOP_HEAD, + WearableCategory.MASK, + WearableCategory.EYEWEAR, + WearableCategory.EARRING, + WearableCategory.TIARA, + WearableCategory.HAIR, + WearableCategory.EYEBROWS, + WearableCategory.EYES, + WearableCategory.MOUTH, + WearableCategory.FACIAL_HAIR, + WearableCategory.BODY_SHAPE +] + +function getHides(wearable: WearableDefinition) { + const category = wearable.data.category + const replaced = wearable.data.replaces || [] + const hidden = wearable.data.hides || [] + if (category === WearableCategory.SKIN) { + hidden.push(...categoriesHiddenBySkin) + } + return Array.from(new Set([...replaced, ...hidden])).filter( + ($) => $ !== category + ) +} + export function getSlots(config: PreviewConfig) { const slots = new Map() @@ -63,35 +97,26 @@ export function getSlots(config: PreviewConfig) { slots.set(slot, wearable) } } - let hasSkin = false - // grab only the wearables that ended up in the map, and process in reverse order (last wearables can hide/replace the first ones) - wearables = wearables.filter((wearable) => slots.get(wearable.data.category) === wearable).reverse() + const forceRender = config.forceRender || [] const alreadyRemoved = new Set() - for (const wearable of wearables) { - const category = wearable.data.category - if (alreadyRemoved.has(category)) { + for (const category of categoriesPriority) { + const wearable = slots.get(category) + if (!wearable) { continue } - const replaced = wearable.data.replaces || [] - const hidden = wearable.data.hides || [] - const toRemove = Array.from(new Set([...replaced, ...hidden])).filter( - (category) => !config.forceRender?.includes(category) - ) - for (const slot of toRemove) { - if (slot !== category) { - slots.delete(slot) - alreadyRemoved.add(slot) - } + + if (alreadyRemoved.has(category)) { + continue } - if (wearable.data.category === WearableCategory.SKIN) { - hasSkin = true + + for (const slot of getHides(wearable)) { + alreadyRemoved.add(slot) } } - // skins hide all the following slots - if (hasSkin) { - for (const category of categoriesHiddenBySkin) { - slots.delete(category) - } + + const toHide = Array.from(alreadyRemoved).filter(category => !forceRender.includes(category)) + for (const category of toHide) { + slots.delete(category) } return slots