diff --git a/build-tools/build-indexes b/build-tools/build-indexes index c9ffcc0f6..a44fdc585 100755 --- a/build-tools/build-indexes +++ b/build-tools/build-indexes @@ -1770,41 +1770,61 @@ function buildModSprites() { continue; } const ext = id.split(".")[1]; + //These are our supported file extensions, if missing we skip + if (!["png","gif","mp3"].includes(ext)) continue; id = toID(id.slice(0, id.length - 4)); - modSprites[id] ||= {}; - modSprites[id][modName] ||= []; - //TODO: Find a more space-efficient means of indicating which mons share certain resources in a given mod - modSprites[id][modName][subF] = null; + if (!modSprites[id]) modSprites[id] = {[modName]: [subF]}; + else if (!modSprites[id][modName]) modSprites[id][modName] = [subF]; + else modSprites[id][modName].push(subF); } + //We're not adding the .JSON extension outright because the other files would attempt to copypaste it and it would cause problems if (!inheritDataPresent) continue; try { - //We're not outright giving this file the .json suffix because the other files would attempt to copypaste it and it would cause problems const mappings = JSON.parse(fs.readFileSync(spritePath + "/reused")); for (const mon in mappings) { - //null is our indicator for the presence of a custom sprite already being uploaded + let inherited = mappings[mon]; + //null is not valid to inherit from //Also you can't inherit from yourself - if (mappings[mon] === null || mappings[mon] === mon) continue; - modSprites[mon] ||= {}; - modSprites[mon][modName] ||= {}; + if (inherited === null || inherited === mon) continue; //Skip if we already have custom data on this mon - if (modSprites[mon][modName].hasOwnProperty(subF)) continue; - let inherited = mappings[mon]; - if (modSprites[inherited] && modSprites[inherited][modName] && modSprites[inherited][modName].hasOwnProperty(subF)) { - //If we already decided that the inheritor inherits in of itself we inherit from that - //(cycles result in neither inheriting) - modSprites[mon][modName][subF] = modSprites[inherited][modName][subF]; + if (modSprites[mon] && modSprites[mon][modName] && modSprites[mon][modName].includes(subF)) continue; + if (!modSprites.ReusedResources[mon]) { + modSprites.ReusedResources[mon] = {[modName]: {}}; + } else if (!modSprites.ReusedResources[mon][modName]) { + modSprites.ReusedResources[mon][modName] = {}; + } else if (modSprites.ReusedResources[mon][modName].hasOwnProperty(subF)){ + //We already handled this, it was presumably caught in an inherit chain + continue; + } + //If we already decided that the inheritor inherits in of itself we inherit from that + //(cycles result in neither inheriting) + if (modSprites.ReusedResources[inherited] && modSprites.ReusedResources[inherited][modName] + && modSprites.ReusedResources[inherited][modName].hasOwnProperty(subF)) { + modSprites.ReusedResources[mon][modName][subF] = modSprites.ReusedResources[inherited][modName][subF]; } else { //We don't have inherit data for this mapping, so let us inherit - while (mappings.hasOwnProperty(inherited) && inherited !== mon) { - //If there is a chain of inheritance track it to the source + const inheritChain = [mon]; + //If there is a chain of inheritance track it to the source + //"inherited !== mon" breaks the loop if the inheritance is cyclic + while (mappings.hasOwnProperty(inherited) && inherited !== mon + //We're cutting off the inherit chain if we come across a preexisting element. + && !(modSprites.hasOwnProperty(inherited) && modSprites[inherited].hasOwnProperty(modName) + && modSprites[inherited][modName].contains(subF))) { + inheritChain.push(inherited); inherited = mappings[inherited]; } + //If there's a cycle none of these guys are inheriting if (inherited === mon) { - //CYCLE SPOTTED, DO NOT INHERIT - modSprites[mon][modName][subF] = null; + for (const chainInherit of inheritChain) { + modSprites[chainInherit] ||= {}; + if (!modSprites[chainInherit].hasOwnProperty(modName)) modSprites[chainInherit][modName] = [subF]; + else modSprites[chainInherit][modName].push(subF); + } } else { - //Now we inherit - modSprites[mon][modName][subF] = inherited; + //We're inheriting here + for (const chainInherit of inheritChain) { + modSprites.ReusedResources[chainInherit][modName][subF] = inherited; + } } } }