aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/shcm/shsupercm/fabric/citresewn/cit/ActiveCITs.java8
-rw-r--r--src/main/java/shcm/shsupercm/fabric/citresewn/cit/CIT.java8
-rw-r--r--src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/FallbackCondition.java79
-rw-r--r--src/main/java/shcm/shsupercm/fabric/citresewn/cit/builtin/conditions/core/WeightCondition.java20
-rw-r--r--src/main/java/shcm/shsupercm/fabric/citresewn/pack/PackParser.java7
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());
}
}