diff options
5 files changed, 117 insertions, 5 deletions
diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/ActiveCITs.java b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/ActiveCITs.java index 82f341f..379c94d 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/ActiveCITs.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/ActiveCITs.java @@ -5,6 +5,7 @@ import net.minecraft.resource.ResourceManager; import net.minecraft.util.profiler.Profiler; import shcm.shsupercm.fabric.citresewn.api.CITDisposable; import shcm.shsupercm.fabric.citresewn.api.CITTypeContainer; +import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core.*; import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; import shcm.shsupercm.fabric.citresewn.pack.GlobalProperties; import shcm.shsupercm.fabric.citresewn.pack.PackParser; @@ -87,10 +88,15 @@ public class ActiveCITs { private ActiveCITs() {} profiler.swap("citresewn:load_cits"); List<CIT<?>> cits = PackParser.parseCITs(resourceManager); + + FallbackCondition.apply(cits); + for (CIT<?> cit : cits) active.cits.computeIfAbsent(cit.type.getClass(), type -> new ArrayList<>()).add(cit); + for (Map.Entry<Class<? extends CITType>, List<CIT<?>>> entry : active.cits.entrySet()) { - entry.getValue().sort(Comparator.<CIT<?>>comparingInt(cit -> cit.weight).reversed().thenComparing(cit -> cit.propertiesIdentifier.toString())); + WeightCondition.apply(entry.getValue()); + for (CITTypeContainer<? extends CITType> typeContainer : CITRegistry.TYPES.values()) if (typeContainer.type == entry.getKey()) { typeContainer.loadUntyped(entry.getValue()); diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/CIT.java b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/CIT.java index 7c7ba5b..fa00c08 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/CIT.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/CIT.java @@ -32,12 +32,18 @@ public class CIT<T extends CITType> { */ public final int weight; - public CIT(Identifier propertiesIdentifier, String packName, T type, CITCondition[] conditions, int weight) { + /** + * Identifier of the cit to fallback to if this one doesn't load. + */ + public final Identifier fallback; + + public CIT(Identifier propertiesIdentifier, String packName, T type, CITCondition[] conditions, int weight, Identifier fallback) { this.propertiesIdentifier = propertiesIdentifier; this.packName = packName; this.type = type; this.conditions = conditions; this.weight = weight; + this.fallback = fallback; } /** diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/FallbackCondition.java b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/FallbackCondition.java new file mode 100644 index 0000000..5f8cdc3 --- /dev/null +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/FallbackCondition.java @@ -0,0 +1,79 @@ +package shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core; + +import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; +import net.minecraft.util.Identifier; +import shcm.shsupercm.fabric.citresewn.api.CITConditionContainer; +import shcm.shsupercm.fabric.citresewn.api.CITGlobalProperties; +import shcm.shsupercm.fabric.citresewn.cit.CIT; +import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.IdentifierCondition; +import shcm.shsupercm.fabric.citresewn.pack.format.PropertyValue; + +import java.util.*; + +/** + * Core property used to set the fallback of the CIT.<br> + * When a CIT loads successfully, its fallback CIT gets removed prior to activation.<br> + * If the main CIT fails to load(or if not loaded at all) the fallback loads as usual. + * @see #apply(List) + * @see #globalProperty(String, PropertyValue) + */ +public class FallbackCondition extends IdentifierCondition { + @Entrypoint(CITConditionContainer.ENTRYPOINT) + public static final CITConditionContainer<FallbackCondition> CONTAINER = new CITConditionContainer<>(FallbackCondition.class, FallbackCondition::new, + "cit_fallback", "citFallback"); + + public FallbackCondition() { + this.value = null; + } + + public Identifier getFallback() { + return this.value; + } + + public void setFallback(Identifier value) { + this.value = value; + } + + /** + * @see #globalProperty(String, PropertyValue) + */ + private static boolean fallbackCITResewnRoot = false; + + /** + * When the global property "citresewn:root_fallback" is set to true, all CITs in the "citresewn" + * root will automatically have the fallback to the same path in the other roots(optifine/mcpatcher).<br> + * This behavior is overridden if the CIT specifies a {@link FallbackCondition fallback} manually. + * @see #apply(List) + */ + @Entrypoint(CITGlobalProperties.ENTRYPOINT) + public static void globalProperty(String key, PropertyValue value) throws Exception { + if (key.equals("root_fallback")) + fallbackCITResewnRoot = value != null && Boolean.parseBoolean(value.value()); + } + + /** + * Removes fallback {@link CIT CITs} of all successfully loaded CITs in the given list.<br> + * @see #globalProperty(String, PropertyValue) + */ + public static void apply(List<CIT<?>> cits) { + Map<String, Set<Identifier>> removePacks = new HashMap<>(); + + for (CIT<?> cit : cits) { + Set<Identifier> remove = removePacks.computeIfAbsent(cit.packName, s -> new HashSet<>()); + if (cit.fallback == null) { + if (fallbackCITResewnRoot && cit.propertiesIdentifier.getPath().startsWith("citresewn/")) { + String subPath = cit.propertiesIdentifier.getPath().substring(10); + remove.add(new Identifier(cit.propertiesIdentifier.getNamespace(), "optifine/" + subPath)); + remove.add(new Identifier(cit.propertiesIdentifier.getNamespace(), "mcpatcher/" + subPath)); + } + } else { + remove.add(cit.fallback); + } + } + + cits.removeIf(cit -> { + Set<Identifier> remove = removePacks.get(cit.packName); + return remove != null && remove.contains(cit.propertiesIdentifier); + }); + } +} diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/WeightCondition.java b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/WeightCondition.java index cb728c9..60f97c4 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/WeightCondition.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/WeightCondition.java @@ -2,12 +2,17 @@ package shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core; import io.shcm.shsupercm.fabric.fletchingtable.api.Entrypoint; import shcm.shsupercm.fabric.citresewn.api.CITConditionContainer; +import shcm.shsupercm.fabric.citresewn.cit.CIT; import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.IntegerCondition; +import java.util.Comparator; +import java.util.List; + /** - * Internal condition used to determine the priority CITs get tested in.<br> + * Core property used to determine the priority CITs get tested in. * Weights default to 0 and higher weights get chosen over lower weights.<br> - * When two conflicting CITs have the same weight, their path in the resourcepack is used as a tie breaker. + * When two conflicting CITs have the same weight, their path in the + * resourcepack and the pack's name are used as a tie breaker. */ public class WeightCondition extends IntegerCondition { @Entrypoint(CITConditionContainer.ENTRYPOINT) @@ -16,6 +21,7 @@ public class WeightCondition extends IntegerCondition { public WeightCondition() { super(false, true, false); + this.min = 0; } public int getWeight() { @@ -25,4 +31,14 @@ public class WeightCondition extends IntegerCondition { public void setWeight(int weight) { this.min = weight; } + + /** + * Sorts the given {@link CIT} list by the CITs' weight and then by their path/pack name. + */ + public static void apply(List<CIT<?>> cits) { + cits.sort( + Comparator.<CIT<?>>comparingInt(cit -> cit.weight) + .reversed() + .thenComparing(cit -> cit.propertiesIdentifier.toString() + cit.packName)); + } } diff --git a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java index ad1b9ba..4b5d23a 100644 --- a/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java +++ b/src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java @@ -6,6 +6,7 @@ import net.minecraft.resource.ResourcePack; import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import shcm.shsupercm.fabric.citresewn.CITResewn; +import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core.FallbackCondition; import shcm.shsupercm.fabric.citresewn.cit.builtin.conditions.core.WeightCondition; import shcm.shsupercm.fabric.citresewn.ex.CITParsingException; import shcm.shsupercm.fabric.citresewn.cit.CIT; @@ -111,11 +112,15 @@ public final class PackParser { private PackParser() {} siblingCondition); WeightCondition weight = new WeightCondition(); + FallbackCondition fallback = new FallbackCondition(); conditions.removeIf(condition -> { if (condition instanceof WeightCondition weightCondition) { weight.setWeight(weightCondition.getWeight()); return true; + } else if (condition instanceof FallbackCondition fallbackCondition) { + fallback.setFallback(fallbackCondition.getFallback()); + return true; } return condition == null; @@ -123,6 +128,6 @@ public final class PackParser { private PackParser() {} citType.load(conditions, properties, resourceManager); - return new CIT<>(properties.identifier, properties.packName, citType, conditions.toArray(new CITCondition[0]), weight.getWeight()); + return new CIT<>(properties.identifier, properties.packName, citType, conditions.toArray(new CITCondition[0]), weight.getWeight(), fallback.getFallback()); } } |