diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/AndPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/AndPredicate.java index 38b02e4b74e..e28fc909a7c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/AndPredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/AndPredicate.java @@ -12,31 +12,47 @@ public AndPredicate(List children, List predicate @Override protected boolean testGlobalMin(PredicateContext ctx) { + boolean result = true; for (BasePredicate predicate : predicates()) { if (!predicate.testGlobalMin(ctx)) { - return false; + result = false; + break; } } - for (MultiPredicate child : children()) { - if (!child.testGlobalMin(ctx)) { - return false; + if (result) { + for (MultiPredicate child : children()) { + if (!child.testGlobalMin(ctx)) { + result = false; + break; + } } } - return true; + if (result) { + result = !hasSettings() || TestType.GLOBAL_MIN.testSettings(this, ctx); + } + return result; } @Override protected boolean testSliceMin(PredicateContext ctx) { + boolean result = true; for (BasePredicate predicate : predicates()) { if (!predicate.testSliceMin(ctx)) { - return false; + result = false; + break; } } - for (MultiPredicate child : children()) { - if (!child.testSliceMin(ctx)) { - return false; + if (result) { + for (MultiPredicate child : children()) { + if (!child.testSliceMin(ctx)) { + result = false; + break; + } } } - return true; + if (result) { + result = !hasSettings() || TestType.SLICE_MIN.testSettings(this, ctx); + } + return result; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiPredicate.java index 9c989b9d977..1f7f7d21eae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiPredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiPredicate.java @@ -2,10 +2,14 @@ import com.gregtechceu.gtceu.api.multiblock.error.PatternStringError; import com.gregtechceu.gtceu.api.multiblock.predicates.BasePredicate; +import com.gregtechceu.gtceu.api.multiblock.predicates.PredicateSettings; +import com.gregtechceu.gtceu.api.multiblock.predicates.SettingsHolder; import com.gregtechceu.gtceu.api.multiblock.util.BlockInfo; import net.minecraft.network.chat.Component; +import dev.latvian.mods.rhino.util.RemapForJS; +import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -15,43 +19,57 @@ import java.util.*; import java.util.function.Consumer; +import java.util.function.UnaryOperator; -public abstract class MultiPredicate { +public abstract class MultiPredicate implements SettingsHolder { - private static final MultiPredicate EMPTY = of(Logic.OR, List.of()); + private static final MultiPredicate EMPTY = of(Logic.OR, List.of()).markImmutable(); - public static final MultiPredicate AIR = of(BasePredicate.AIR); + /// use {@link Predicates#air()} instead + @ApiStatus.Internal + public static final MultiPredicate AIR = of(BasePredicate.AIR) + .isAir(true).markImmutable(); - public static final MultiPredicate ANY = of(BasePredicate.ANY); + /// use {@link Predicates#any()} instead + @ApiStatus.Internal + public static final MultiPredicate ANY = of(BasePredicate.ANY) + .isAny(true).markImmutable(); private final List predicates; private final List children; private final boolean hasAir; + + @Accessors(fluent = true) + @Setter(AccessLevel.PRIVATE) + @Getter + private boolean isAir = false; + + @Accessors(fluent = true) + @Setter(AccessLevel.PRIVATE) + @Getter + private boolean isAny = false; + @Getter private final Logic type; + @Getter - @Setter @Accessors(chain = true) private boolean controller; + /// Nonnull by default, see {@link #recursive()} @Nullable @Getter - @Setter - private MultiPredicate parent; + private PredicateSettings settings; - public static MultiPredicate of(BasePredicate predicate) { - return Logic.OR.makePredicate(predicate, predicate == BasePredicate.AIR); - } - - /// @param predicates list must be modifiable - private static MultiPredicate of(Logic type, List predicates) { - return type.makePredicate(List.of(), predicates, predicates.stream().anyMatch(p -> p == BasePredicate.AIR)); - } + @Nullable + @Getter + private MultiPredicate parent; + private boolean mutable = true; /// @param children list of multi predicate children /// @param predicates list of testable predicates, should be sorted already - protected MultiPredicate(Logic type, List children, List predicates, - boolean hasAir) { + protected MultiPredicate(Logic type, List children, + List predicates, boolean hasAir) { predicates.forEach(p -> p.setParent(this)); children.forEach(mp -> mp.setParent(this)); this.predicates = Collections.unmodifiableList(predicates); @@ -113,10 +131,24 @@ public final boolean postSliceTest(PredicateContext ctx) { /// test against global/slice max counts public boolean testMaxCount(BasePredicate passedPredicate, PredicateContext context) { context.setStage(PredicateContext.PredicateStage.GLOBAL_MAX); - if (!passedPredicate.testGlobalMax(context)) + if (!(passedPredicate.testGlobalMax(context) && testParents(TestType.GLOBAL_MAX, passedPredicate, context))) { return false; + } context.setStage(PredicateContext.PredicateStage.SLICE_MAX); - return passedPredicate.testSliceMax(context); + return passedPredicate.testSliceMax(context) && testParents(TestType.SLICE_MAX, passedPredicate, context); + } + + // go up the parent chain to test settings of parents + + private boolean testParents(TestType type, BasePredicate passedPredicate, PredicateContext context) { + MultiPredicate parent = passedPredicate.getParent(); + while (parent != null) { + if (!type.testSettings(parent, context)) { + return false; + } + parent = parent.getParent(); + } + return true; } public List> getCandidates() { @@ -155,208 +187,251 @@ public boolean isEmpty() { return this == EMPTY; } - public boolean isAny() { - return this == ANY; + public boolean hasAir() { + return this.hasAir; } - public boolean isAir() { - return this == AIR; + /// @return {@code true} if this multi predicate has only one predicate, has no children, and has no parent + public boolean isSingle() { + return predicates.size() == 1 && isLeaf() && isRoot(); } - public boolean hasAir() { - return this.hasAir; + /// @return {@code true} if this multi predicate has no parent + public boolean isRoot() { + return getParent() == null; } - @CheckReturnValue - private MultiPredicate mutatedCopy(Consumer mutation) { - List copiedPredicates = new ArrayList<>(this.predicates.size()); - for (BasePredicate predicate : this.predicates) { - BasePredicate copy = predicate.copy(); - mutation.accept(copy); - copiedPredicates.add(copy); - } - List copiedChildren = new ArrayList<>(this.children.size()); - for (MultiPredicate child : this.children) { - copiedChildren.add(child.mutatedCopy(mutation)); - } - MultiPredicate copy = this.type.makePredicate(copiedChildren, copiedPredicates, this.hasAir); - copy.setController(this.controller); - return copy; + /// @return {@code true} if this multi predicate has children and is not a root predicate + public boolean isBranch() { + return !isLeaf() && !isRoot(); } - @CheckReturnValue - public MultiPredicate addTooltips(Component tooltip) { - return mutatedCopy(p -> p.addTooltips(tooltip)); + /// @return {@code true} if this multi predicate has no children multi predicates + public boolean isLeaf() { + return this.children.isEmpty(); } - @CheckReturnValue - public MultiPredicate setPriority(int priority) { - return mutatedCopy(p -> p.setPriority(priority)); + public List getDescriptiveContents() { + List list = new ArrayList<>(); + Component logicLine = switch (this.type) { + case OR -> Component.literal("any of:"); + case AND -> Component.literal("all of:"); + case XOR -> Component.literal("one of:"); + }; + list.add(logicLine); + for (BasePredicate predicate : predicates()) { + // todo prettier string? + list.add(Component.literal(predicate.toString())); + } + for (MultiPredicate child : children()) { + list.addAll(child.getDescriptiveContents()); + } + return list; } - @CheckReturnValue - public MultiPredicate setMinGlobalLimited(int min) { - return this.setMinCount(min); + protected void forEach(Consumer action) { + this.predicates.forEach(action); } - @CheckReturnValue - public MultiPredicate setMinGlobalLimited(int min, int previewCount) { - return this.setMinCount(min).setPreviewCount(previewCount); + public List predicates() { + return this.predicates; } - @CheckReturnValue - public MultiPredicate setMinCount(int min) { - return mutatedCopy(p -> p.setMinCount(min)); + public void forEachChild(Consumer action) { + this.children.forEach(action); } - @CheckReturnValue - public MultiPredicate setMaxGlobalLimited(int max) { - return this.setMaxCount(max); + public List children() { + return this.children; } - @CheckReturnValue - public MultiPredicate setMaxGlobalLimited(int max, int previewCount) { - return this.setMaxCount(max).setPreviewCount(previewCount); + /// @return a flattened list of all base predicates + public List expand() { + if (isLeaf()) return this.predicates; + List expanded = new ArrayList<>(this.predicates); + forEachChild(mp -> expanded.addAll(mp.expand())); + return expanded; } - @CheckReturnValue - public MultiPredicate setMaxCount(int max) { - return mutatedCopy(p -> p.setMaxCount(max)); + @Override + public boolean hasSettings() { + return this.settings != null; } - @CheckReturnValue - public MultiPredicate setGlobalMinMax(int min, int max) { - return this.setMinCount(min).setMaxCount(max); + /* + * MUTATE AND DO NOT COPY + */ + + @RemapForJS("addTooltip") + public MultiPredicate addTooltips(Component tooltip) { + var mutated = mutable ? this : deepCopy(); + mutated.forEach(p -> p.addTooltips(tooltip)); + mutated.forEachChild(mp -> mp.addTooltips(tooltip)); + return mutated; } @CheckReturnValue - public MultiPredicate setMinLayerLimited(int min) { - return this.setMinSliceCount(min); + public MultiPredicate addTooltips(Component... tooltip) { + var mutated = mutable ? this : deepCopy(); + mutated.forEach(p -> Collections.addAll(p.getAdditionalTooltips(), tooltip)); + mutated.forEachChild(mp -> mp.addTooltips(tooltip)); + return mutated; } - @CheckReturnValue - public MultiPredicate setMinLayerLimited(int min, int previewCount) { - return this.setMinSliceCount(min).setPreviewCount(previewCount); + @Override + public void updateSettings(UnaryOperator configurator) { + if (!mutable) return; + if (isSingle()) { + // the idea is that if we only have a single predicate, we mutate that predicate instead of ourselves + // as we're basically the same as that predicate + predicates().get(0).updateSettings(configurator); + onSettingsChanged(); + } else { + PredicateSettings settings = getSettings(); + if (settings != null) { + setSettings(Objects.requireNonNull(configurator.apply(settings))); + } else { + // update predicate settings + forEach(p -> p.updateSettings(configurator)); + // update children + // if they have settings, they should mutate themselves (non-recursive) + // otherwise they should mutate their predicates and children instead (recursive) + forEachChild(mp -> mp.updateSettings(configurator)); + onSettingsChanged(); + } + } } - @CheckReturnValue - public MultiPredicate setMinSliceCount(int min) { - return mutatedCopy(p -> p.setMinSliceCount(min)); + protected void onSettingsChanged() {} + + private MultiPredicate markImmutable() { + this.mutable = false; + return this; } - @CheckReturnValue - public MultiPredicate setMaxLayerLimited(int max) { - return this.setMaxSliceCount(max); + public void setSettings(@Nullable PredicateSettings settings) { + if (!mutable) return; + this.settings = settings == null ? null : settings.copy(); + onSettingsChanged(); } - @CheckReturnValue - public MultiPredicate setMaxLayerLimited(int max, int previewCount) { - return this.setMaxSliceCount(max).setPreviewCount(previewCount); + public void setParent(MultiPredicate parent) { + if (mutable) this.parent = parent; } - @CheckReturnValue - public MultiPredicate setMaxSliceCount(int max) { - return mutatedCopy(p -> p.setMaxSliceCount(max)); + public MultiPredicate setController(boolean controller) { + var mutated = mutable ? this : deepCopy(); + mutated.controller = controller; + return mutated; } + /* + * MUTATE AND COPY + */ + @CheckReturnValue - public MultiPredicate setPreviewCount(int previewCount) { - return mutatedCopy(p -> p.setPreviewCount(previewCount)); + protected MultiPredicate deepCopy() { + List copiedPredicates = predicates().stream() + .map(BasePredicate::copy) + // sort high to low (descending) + .sorted(Collections.reverseOrder(BasePredicate::compareTo)) + .toList(); + List copiedChildren = children().stream() + .map(MultiPredicate::deepCopy) + // sort high to low (descending) + .sorted(Collections.reverseOrder(MultiPredicate::compareTo)) + .toList(); + MultiPredicate copy = this.type.makePredicate(copiedChildren, copiedPredicates, this.hasAir); + copy.setSettings(this.settings); + copy.setController(this.controller); + return copy; } @CheckReturnValue - public MultiPredicate setLayerMinMax(int min, int max) { - return this.setMinSliceCount(min).setMaxSliceCount(max); + public MultiPredicate copyWith(Consumer configurator) { + MultiPredicate copy = deepCopy(); + configurator.accept(copy); + return copy; } - /** - * Sets the Minimum and Maximum limit to the passed value - * - * @param limit The Maximum and Minimum limit - */ + /// Mark this multipredicate as recursive (`this.settings = null`), + /// meaning that settings are applied to children instead of itself + /// @return a copy of this multipredicate with `this.settings = null` @CheckReturnValue - public MultiPredicate setExactLimit(int limit) { - return this.setGlobalMinMax(limit, limit); + public MultiPredicate recursive() { + return copyWith(mp -> mp.setSettings(null)); } + @Override @CheckReturnValue - public MultiPredicate disabledRenderFormed() { - return setDisableRenderFormed(true); + public MultiPredicate withSettings(UnaryOperator configurator) { + return copyWith(p -> p.updateSettings(configurator)); } @CheckReturnValue - public MultiPredicate setDisableRenderFormed(boolean disable) { - return mutatedCopy(p -> p.setDisableRenderFormed(disable)); + public MultiPredicate withMinGlobalLimited(int min) { + return this.withMinCount(min); } - /// @return a new multi predicate where any predicate may pass or be present in the multiblock - public MultiPredicate or(@Nullable MultiPredicate other) { - return combine(this, Logic.OR, other); + @CheckReturnValue + public MultiPredicate withMinGlobalLimited(int min, int previewCount) { + return withSettings(s -> s.withMinCount(min).withPreviewCount(previewCount)); } - /// @return a new multi predicate where every predicate must pass or be present in the multiblock - public MultiPredicate and(@Nullable MultiPredicate other) { - return combine(this, Logic.AND, other); + @CheckReturnValue + public MultiPredicate withMaxGlobalLimited(int max) { + return this.withMaxCount(max); } - /// @return a new multi predicate with every predicate exclusively
- /// OR-ed (only one predicate may be present in the multi) - public MultiPredicate xor(@Nullable MultiPredicate other) { - return combine(this, Logic.XOR, other); + @CheckReturnValue + public MultiPredicate withMaxGlobalLimited(int max, int previewCount) { + return withSettings(s -> s.withMaxCount(max).withPreviewCount(previewCount)); } - /// @return a new multi predicate where any predicate may pass or be present in the multiblock - public static MultiPredicate or(List predicates) { - return of(Logic.OR, predicates); + @CheckReturnValue + public MultiPredicate withGlobalMinMax(int min, int max) { + return withSettings(s -> s.withMinCount(min).withMaxCount(max)); } - /// @return a new multi predicate where every predicate must pass or be present in the multiblock - public static MultiPredicate and(List predicates) { - return of(Logic.AND, predicates); + @CheckReturnValue + public MultiPredicate withMinLayerLimited(int min) { + return this.withMinSliceCount(min); } - /// @return a new multi predicate with every predicate exclusively
- /// OR-ed (only one predicate may be present in the multi) - public static MultiPredicate xor(List predicates) { - return of(Logic.XOR, predicates); + @CheckReturnValue + public MultiPredicate withMinLayerLimited(int min, int previewCount) { + return withSettings(s -> s.withMinSliceCount(min).withPreviewCount(previewCount)); } - /// @return {@code true} if this multi predicate has only one predicate and has no children - public boolean isSingle() { - return predicates.size() == 1 && isLeaf(); + @CheckReturnValue + public MultiPredicate withMaxLayerLimited(int max) { + return this.withMaxSliceCount(max); } - /// @return {@code true} if this multi predicate has no parent - public boolean isRoot() { - return getParent() == null; + @CheckReturnValue + public MultiPredicate withMaxLayerLimited(int max, int previewCount) { + return withSettings(s -> s.withMaxSliceCount(max).withPreviewCount(previewCount)); } - /// @return {@code true} if this multi predicate has children and is not a root predicate - public boolean isBranch() { - return !isLeaf() && !isRoot(); + @CheckReturnValue + public MultiPredicate withLayerMinMax(int min, int max) { + return withSettings(s -> s.withMinSliceCount(min).withMaxSliceCount(max)); } - /// @return {@code true} if this multi predicate has no children multi predicates - public boolean isLeaf() { - return this.children.isEmpty(); + /** + * Sets the Minimum and Maximum limit to the passed value + * + * @param limit The Maximum and Minimum limit + */ + @CheckReturnValue + public MultiPredicate withExactLimit(int limit) { + return this.withGlobalMinMax(limit, limit); } - public List getDescriptiveContents() { - List list = new ArrayList<>(); - Component logicLine = switch (this.type) { - case OR -> Component.literal("any of:"); - case AND -> Component.literal("all of:"); - case XOR -> Component.literal("one of:"); - }; - list.add(logicLine); - for (BasePredicate predicate : this.predicates) { - // todo prettier string? - list.add(Component.literal(predicate.toString())); - } - for (MultiPredicate child : children()) { - list.addAll(child.getDescriptiveContents()); - } - return list; + /// @return a copy of this multi predicate with render formed disabled + @CheckReturnValue + public MultiPredicate disabledRenderFormed() { + return withDisableRenderFormed(true); } @Override @@ -373,64 +448,80 @@ public String toString() { builder.append('{'); StringJoiner joiner = new StringJoiner(", "); this.forEach(p -> joiner.add(p.toString())); + this.forEachChild(mp -> joiner.add(mp.toString())); builder.append(joiner); builder.append('}'); return builder.toString(); } - protected void forEach(Consumer action) { - this.predicates.forEach(action); + /* + * LOGIC AND COMBINATION + */ + + /// @return a new multi predicate where any predicate may pass or be present in the multiblock + public MultiPredicate or(@Nullable MultiPredicate other) { + return combine(this, Logic.OR, other); } - public List predicates() { - return this.predicates; + /// @return a new multi predicate where every predicate must pass or be present in the multiblock + public MultiPredicate and(@Nullable MultiPredicate other) { + return combine(this, Logic.AND, other); } - public void forEachChild(Consumer action) { - this.children.forEach(action); + /// @return a new multi predicate with every predicate exclusively
+ /// OR-ed (only one predicate may be present in the multi) + public MultiPredicate xor(@Nullable MultiPredicate other) { + return combine(this, Logic.XOR, other); } - public List children() { - return this.children; + /// @return a new multi predicate where any predicate may pass or be present in the multiblock + public static MultiPredicate or(List predicates) { + return of(Logic.OR, predicates); } - /// @return a flattened list of all base predicates - public List expand() { - if (isLeaf()) return this.predicates; - List expanded = new ArrayList<>(this.predicates); - forEachChild(mp -> expanded.addAll(mp.expand())); - return expanded; + /// @return a new multi predicate where every predicate must pass or be present in the multiblock + public static MultiPredicate and(List predicates) { + return of(Logic.AND, predicates); } - public static MultiPredicate empty() { - return EMPTY; + /// @return a new multi predicate with every predicate exclusively
+ /// OR-ed (only one predicate may be present in the multi) + public static MultiPredicate xor(List predicates) { + return of(Logic.XOR, predicates); } /// @param a left operand /// @param type logic of the new predicate /// @param b right operand, may be null - /// @return If {@code b == null}, returns {@code a}.
+ /// @return If {@code b == null || b == EMPTY}, returns {@code a}.
/// If {@code a == EMPTY}, returns {@code b}.
/// Otherwise, returns a new MultiPredicate that combines {@code a} and {@code b} private static MultiPredicate combine(MultiPredicate a, Logic type, @Nullable MultiPredicate b) { if (b == null || b.isEmpty()) return a; // no op if (a.isEmpty()) return b; - List predicates = new ArrayList<>(); - List children = new ArrayList<>(); - appendPredicates(type, a, predicates, children); - appendPredicates(type, b, predicates, children); - predicates.sort(BasePredicate::compareTo); - return type.makePredicate(children, predicates, a.hasAir || b.hasAir); - } - - private static void appendPredicates(Logic type, MultiPredicate multiPredicate, - List predicates, List children) { - if (multiPredicate.isSingle() || multiPredicate.isType(type)) { - predicates.addAll(multiPredicate.predicates()); - children.addAll(multiPredicate.children()); - } else { - children.add(multiPredicate); - } + + List children = List.of(a.deepCopy(), b.deepCopy()); + MultiPredicate combined = type.makePredicate(children, List.of(), a.hasAir || b.hasAir); + combined.setSettings(PredicateSettings.create()); + return combined; + } + + public static MultiPredicate empty() { + return EMPTY; + } + + public static MultiPredicate of(BasePredicate predicate) { + MultiPredicate multiPredicate = Logic.OR.makePredicate(predicate, predicate == BasePredicate.AIR); + multiPredicate.setSettings(PredicateSettings.create()); + return multiPredicate; + } + + /// @return A multi predicate with default settings + private static MultiPredicate of(Logic type, List predicates) { + MultiPredicate predicate = type.makePredicate(List.of(), predicates, predicates.stream() + .anyMatch(BasePredicate::isAir)); + predicate.setSettings(PredicateSettings.create()); + return predicate; } protected enum Logic { diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/OrPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/OrPredicate.java index 1cee4a452e2..2e4509f1299 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/OrPredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/OrPredicate.java @@ -12,31 +12,47 @@ public OrPredicate(List children, List predicates @Override protected boolean testGlobalMin(PredicateContext ctx) { + boolean result = false; for (BasePredicate predicate : predicates()) { if (predicate.testGlobalMin(ctx)) { - return true; + result = true; + break; } } - for (MultiPredicate child : children()) { - if (child.testGlobalMin(ctx)) { - return true; + if (!result) { + for (MultiPredicate child : children()) { + if (child.testGlobalMin(ctx)) { + result = true; + break; + } } } - return false; + if (result) { + result = TestType.GLOBAL_MIN.testSettings(this, ctx); + } + return result; } @Override protected boolean testSliceMin(PredicateContext ctx) { + boolean result = false; for (BasePredicate predicate : predicates()) { if (predicate.testSliceMin(ctx)) { - return true; + result = true; + break; } } - for (MultiPredicate child : children()) { - if (child.testSliceMin(ctx)) { - return true; + if (!result) { + for (MultiPredicate child : children()) { + if (child.testSliceMin(ctx)) { + result = true; + break; + } } } - return false; + if (result) { + result = TestType.SLICE_MIN.testSettings(this, ctx); + } + return result; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/PredicateContext.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/PredicateContext.java index f88dada6a89..1e4c30d55fa 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/PredicateContext.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/PredicateContext.java @@ -3,7 +3,7 @@ import com.gregtechceu.gtceu.api.multiblock.error.PatternError; import com.gregtechceu.gtceu.api.multiblock.pattern.CurrentBlockInfo; import com.gregtechceu.gtceu.api.multiblock.pattern.PatternState; -import com.gregtechceu.gtceu.api.multiblock.predicates.BasePredicate; +import com.gregtechceu.gtceu.api.multiblock.predicates.SettingsHolder; import com.gregtechceu.gtceu.api.multiblock.util.BlockInfo; import net.minecraft.core.BlockPos; @@ -29,8 +29,8 @@ public class PredicateContext { private final PatternState state; @Getter protected CurrentBlockInfo currentBlockInfo = new CurrentBlockInfo(); - protected final Object2IntMap globalCount = new Object2IntOpenHashMap<>(); - protected final Object2IntMap layerCount = new Object2IntOpenHashMap<>(); + protected final Object2IntMap> globalCount = new Object2IntOpenHashMap<>(); + protected final Object2IntMap> layerCount = new Object2IntOpenHashMap<>(); private final Int2ObjectMap> sliceErrors = new Int2ObjectAVLTreeMap<>( IntComparators.NATURAL_COMPARATOR); @@ -131,20 +131,20 @@ public void clearLayerCounts() { this.layerCount.clear(); } - public int incrementGlobalCount(BasePredicate predicate) { + public int incrementGlobalCount(SettingsHolder predicate) { return this.globalCount.mergeInt(predicate, 1, Integer::sum); } - public int incrementSliceCount(BasePredicate predicate) { + public int incrementSliceCount(SettingsHolder predicate) { if (!checkLayer) return 0; return this.layerCount.mergeInt(predicate, 1, Integer::sum); } - public int getGlobalCount(BasePredicate predicate) { + public int getGlobalCount(SettingsHolder predicate) { return this.globalCount.getInt(predicate); } - public int getSliceCount(BasePredicate predicate) { + public int getSliceCount(SettingsHolder predicate) { if (!checkLayer) return 0; return this.layerCount.getInt(predicate); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java index af3e9170d94..e2e40ce2eb4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java @@ -202,11 +202,11 @@ public static MultiPredicate fluidTag(TagKey tag) { } public static MultiPredicate any() { - return MultiPredicate.ANY; + return MultiPredicate.ANY.deepCopy(); } public static MultiPredicate air() { - return MultiPredicate.AIR; + return MultiPredicate.AIR.deepCopy(); } public static MultiPredicate abilities(PartAbility ability) { @@ -259,8 +259,8 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxInputs(EURecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.INPUT_ENERGY) - .setMinCount(1).setMaxCount(2) - .setPreviewCount(1).setPriority(1)); + .withGlobalMinMax(1, 2) + .withPreviewCount(1).withPriority(1)); break; } } @@ -269,8 +269,9 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxOutputs(EURecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.OUTPUT_ENERGY) - .setMinCount(1).setMaxCount(2) - .setPreviewCount(1).setPriority(1)); + .withGlobalMinMax(1, 2) + .withPreviewCount(1) + .withPriority(1)); break; } } @@ -279,7 +280,7 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxInputs(ItemRecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.IMPORT_ITEMS) - .setPreviewCount(1).setPriority(2)); + .withPreviewCount(1).withPriority(2)); break; } } @@ -288,7 +289,7 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxOutputs(ItemRecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.EXPORT_ITEMS) - .setPreviewCount(1).setPriority(2)); + .withPreviewCount(1).withPriority(2)); break; } } @@ -297,7 +298,7 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxInputs(FluidRecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.IMPORT_FLUIDS) - .setPreviewCount(1).setPriority(3)); + .withPreviewCount(1).withPriority(3)); break; } } @@ -306,7 +307,7 @@ public static MultiPredicate autoAbilities(GTRecipeType[] recipeType, for (var type : recipeType) { if (type.getMaxOutputs(FluidRecipeCapability.CAP) > 0) { predicate = predicate.and(abilities(PartAbility.EXPORT_FLUIDS) - .setPreviewCount(1).setPriority(3)); + .withPreviewCount(1).withPriority(3)); break; } } @@ -319,20 +320,19 @@ public static MultiPredicate autoAbilities(boolean checkMaintenance, boolean che MultiPredicate predicate = MultiPredicate.empty(); if (checkMaintenance) { predicate = predicate.and(abilities(PartAbility.MAINTENANCE) - .setMinCount(ConfigHolder.INSTANCE.machines.enableMaintenance ? 1 : 0) - .setMaxCount(1) - .setPriority(1)); + .withMinCount(ConfigHolder.INSTANCE.machines.enableMaintenance ? 1 : 0) + .withMaxCount(1) + .withPriority(1)); } if (checkMuffler) { predicate = predicate.and(abilities(PartAbility.MUFFLER) - .setExactLimit(1) - .setPriority(2)); + .withExactLimit(1) + .withPriority(2)); } if (checkParallel) { predicate = predicate.and(abilities(PartAbility.PARALLEL_HATCH) - .setMaxCount(1) - .setPreviewCount(1) - .setPriority(3)); + .withMaxGlobalLimited(1, 1) + .withPriority(3)); } return predicate; } @@ -345,7 +345,7 @@ public static MultiPredicate heatingCoils() { .sorted(Comparator.comparingInt(e -> e.getKey().getTier())) .map(e -> e.getValue().get())) .addTooltips(Component.translatable("gtceu.multiblock.pattern.error.coils")) - .setPriority(0); + .withPriority(0); } public static MultiPredicate cleanroomFilters() { @@ -373,8 +373,8 @@ public static MultiPredicate powerSubstationBatteries() { if (ConfigHolder.INSTANCE.machines.enableResearch) { return abilities(PartAbility.DATA_ACCESS) .xor(abilities(PartAbility.OPTICAL_DATA_RECEPTION)) - .setExactLimit(1) - .setPriority(1); + .withExactLimit(1) + .withPriority(1); } return null; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/XorPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/XorPredicate.java index f98b5b68cb1..01cf84ff2e6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/XorPredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/XorPredicate.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.api.multiblock.error.PatternStringError; import com.gregtechceu.gtceu.api.multiblock.predicates.BasePredicate; +import com.gregtechceu.gtceu.api.multiblock.predicates.PredicateSettings; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -21,8 +22,11 @@ public class XorPredicate extends MultiPredicate { public XorPredicate(List children, List predicates, boolean hasAir) { super(Logic.XOR, children, predicates, hasAir); - this.noneValid = expand().stream() - .anyMatch(p -> p.getMinCount() <= 0 && p.getMinSliceCount() <= 0); + } + + @Override + protected void onSettingsChanged() { + this.noneValid = isNoneValid(this); } @Override @@ -64,13 +68,21 @@ public XorPredicate(List children, List predicate @Override protected boolean testGlobalMin(PredicateContext ctx) { if (passedPredicate == null && noneValid) return true; - return passedPredicate != null && passedPredicate.testGlobalMin(ctx); + boolean passed = passedPredicate != null && passedPredicate.testGlobalMin(ctx); + if (passed) { + passed = TestType.GLOBAL_MIN.testSettings(this, ctx); + } + return passed; } @Override protected boolean testSliceMin(PredicateContext ctx) { if (passedPredicate == null && noneValid) return true; - return passedPredicate != null && passedPredicate.testSliceMin(ctx); + boolean passed = passedPredicate != null && passedPredicate.testSliceMin(ctx); + if (passed && hasSettings()) { + passed = TestType.SLICE_MIN.testSettings(this, ctx); + } + return passed; } @Override @@ -89,6 +101,23 @@ private static void xorError(PredicateContext context, BasePredicate predicate, context.skipFlipCheck(); } + private static boolean isNoneValid(MultiPredicate multiPredicate) { + PredicateSettings settings = multiPredicate.getSettings(); + if (settings != null && settings.isNoneValid()) return true; + + for (BasePredicate predicate : multiPredicate.predicates()) { + if (predicate.getSettings().isNoneValid()) { + return true; + } + } + for (MultiPredicate child : multiPredicate.children()) { + if (isNoneValid(child)) { + return true; + } + } + return false; + } + private static PassedPredicate ofPredicate(BasePredicate predicate) { return new PassedPredicate(predicate, null); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java index 3bc17c0bc5d..be1d661ca30 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/BasePredicate.java @@ -8,55 +8,57 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; +import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; +import lombok.experimental.Accessors; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.function.UnaryOperator; -public abstract class BasePredicate implements Comparable { +public abstract class BasePredicate implements SettingsHolder { + /// use {@link Predicates#air()} instead + @ApiStatus.Internal public static final BasePredicate AIR = new PredicateBuilder("Air") .predicate(ctx -> ctx.state().isAir()) - .build(); + .build() + .isAir(true) + .markImmutable(); + /// use {@link Predicates#any()} instead + @ApiStatus.Internal public static final BasePredicate ANY = new PredicateBuilder("Any") .predicate(ctx -> true) - .build(); + .build() + .isAny(true) + .markImmutable(); + + private boolean mutable = true; @Getter(lazy = true) private final List candidates = computeCandidates(); @Getter - @Setter - protected int priority = 0; - @Getter - @Setter - protected int minCount = -1; - @Getter - @Setter - protected int maxCount = -1; - @Getter - @Setter - protected int minSliceCount = -1; - @Getter - @Setter - protected int maxSliceCount = -1; - @Getter - @Setter - protected int previewCount = -1; - @Getter - @Setter - protected boolean disableRenderFormed = false; - @Getter - @Setter - private @Nullable String nbtParser; // unsure what this does - @Setter + protected PredicateSettings settings = PredicateSettings.create(); + private @Nullable MultiPredicate parent; @Getter private final List additionalTooltips = new ArrayList<>(); + @Accessors(fluent = true) + @Setter(AccessLevel.PRIVATE) + @Getter + private boolean isAir = false; + + @Accessors(fluent = true) + @Setter(AccessLevel.PRIVATE) + @Getter + private boolean isAny = false; + public MultiPredicate getParent() { return Objects.requireNonNull(this.parent); } @@ -70,24 +72,6 @@ public MultiPredicate getParent() { /// @return a list of components to be displayed while hovering over a block in the Multiblock Preview public abstract List getRecipeViewerTooltips(MultiPredicate root); - public abstract BasePredicate copy(); - - protected void copyTo(BasePredicate other) { - other.priority = this.priority; - other.minCount = this.minCount; - other.maxCount = this.maxCount; - other.minSliceCount = this.minSliceCount; - other.maxSliceCount = this.maxSliceCount; - other.previewCount = this.previewCount; - other.disableRenderFormed = this.disableRenderFormed; - other.nbtParser = this.nbtParser; - other.additionalTooltips.addAll(this.additionalTooltips); - } - - public void addTooltips(Component tooltip) { - this.additionalTooltips.add(tooltip); - } - /// delegates to {@link MultiPredicate#testMaxCount(BasePredicate, PredicateContext)}, /// with this predicate as the passing predicate public boolean checkMaxCount(PredicateContext context) { @@ -129,26 +113,6 @@ public boolean testSliceMin(PredicateContext ctx) { return false; } - /// simple test against global min count - public boolean testGlobalMin(int count) { - return minCount == -1 || count >= minCount; - } - - /// simple test against slice min count - public boolean testSliceMin(int count) { - return minSliceCount == -1 || count >= minSliceCount; - } - - /// simple test against global max count - public boolean testGlobalMax(int count) { - return maxCount == -1 || count <= maxCount; - } - - /// simple test against slice max count - public boolean testSliceMax(int count) { - return maxSliceCount == -1 || count <= maxSliceCount; - } - /// computes the candidates for this predicate public abstract List computeCandidates(); @@ -180,8 +144,46 @@ public String toString() { return builder.toString(); } + private BasePredicate markImmutable() { + this.mutable = false; + return this; + } + @Override - public int compareTo(BasePredicate o) { - return Integer.compare(this.priority, o.priority); + public boolean hasSettings() { + return true; + } + + public abstract BasePredicate copy(); + + protected void copyTo(BasePredicate other) { + other.setSettings(this.settings.copy()); + other.additionalTooltips.addAll(this.additionalTooltips); + other.isAir = this.isAir; + other.isAny = this.isAny; + } + + // COPY AND MUTATE + + @Override + public BasePredicate withSettings(UnaryOperator configurator) { + BasePredicate copy = copy(); + copy.updateSettings(configurator); + return copy; + } + + // MUTATE ONLY + + @Override + public void setSettings(PredicateSettings settings) { + if (mutable) this.settings = settings; + } + + public void setParent(@Nullable MultiPredicate parent) { + if (mutable) this.parent = parent; + } + + public void addTooltips(Component tooltip) { + if (mutable) this.additionalTooltips.add(tooltip); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/PredicateSettings.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/PredicateSettings.java new file mode 100644 index 00000000000..eef8b431e34 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/PredicateSettings.java @@ -0,0 +1,51 @@ +package com.gregtechceu.gtceu.api.multiblock.predicates; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import lombok.With; + +@With +public record PredicateSettings(int priority, + int minCount, int maxCount, + int minSliceCount, int maxSliceCount, + int previewCount, boolean disableRenderFormed) { + + // spotless:off + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("priority").forGetter(PredicateSettings::priority), + Codec.INT.fieldOf("min_count").forGetter(PredicateSettings::minCount), + Codec.INT.fieldOf("max_count").forGetter(PredicateSettings::maxCount), + Codec.INT.fieldOf("min_layer_count").forGetter(PredicateSettings::minSliceCount), + Codec.INT.fieldOf("max_layer_count").forGetter(PredicateSettings::maxSliceCount), + Codec.INT.fieldOf("preview_count").forGetter(PredicateSettings::previewCount), + Codec.BOOL.fieldOf("disable_render_formed").forGetter(PredicateSettings::disableRenderFormed) + ).apply(instance, PredicateSettings::new)); + // spotless:on + + public static final int MAX_PRIORITY = Integer.MAX_VALUE; + public static final int MIN_PRIORITY = Integer.MIN_VALUE; + + // helper for xor + public boolean isNoneValid() { + return minCount <= 0 && minSliceCount <= 0; + } + + public PredicateSettings copy() { + return new PredicateSettings( + this.priority, + this.minCount, + this.maxCount, + this.minSliceCount, + this.maxSliceCount, + this.previewCount, + this.disableRenderFormed); + } + + public static PredicateSettings create() { + return new PredicateSettings( + 0, + -1, -1, + -1, -1, + -1, false); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/SettingsHolder.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/SettingsHolder.java new file mode 100644 index 00000000000..d8b5940ce2a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/SettingsHolder.java @@ -0,0 +1,188 @@ +package com.gregtechceu.gtceu.api.multiblock.predicates; + +import com.gregtechceu.gtceu.api.multiblock.PredicateContext; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.CheckReturnValue; + +import java.util.function.UnaryOperator; + +public interface SettingsHolder> extends Comparable> { + + // getters + PredicateSettings getSettings(); + + boolean hasSettings(); + + default int getPriority() { + return hasSettings() ? getSettings().priority() : PredicateSettings.MIN_PRIORITY; + } + + default int getMinCount() { + return hasSettings() ? getSettings().minCount() : -1; + } + + default int getMaxCount() { + return hasSettings() ? getSettings().maxCount() : -1; + } + + default int getMinSliceCount() { + return hasSettings() ? getSettings().minSliceCount() : -1; + } + + default int getMaxSliceCount() { + return hasSettings() ? getSettings().maxSliceCount() : -1; + } + + default int getPreviewCount() { + return hasSettings() ? getSettings().previewCount() : -1; + } + + default boolean isRenderFormedDisabled() { + return hasSettings() && getSettings().disableRenderFormed(); + } + + // mutate only + @ApiStatus.Internal + void setSettings(PredicateSettings settings); + + /// mutates this object with the configured setting + @ApiStatus.Internal + default void updateSettings(UnaryOperator configurator) { + setSettings(configurator.apply(getSettings())); + } + + /// mutates this object with the given priority + @ApiStatus.Internal + default void setPriority(int priority) { + updateSettings(s -> s.withPriority(priority)); + } + + /// mutates this object with the given min global count + @ApiStatus.Internal + default void setMinCount(int minCount) { + updateSettings(s -> s.withMinCount(minCount)); + } + + /// mutates this object with the given max global count + @ApiStatus.Internal + default void setMaxCount(int maxCount) { + updateSettings(s -> s.withMaxCount(maxCount)); + } + + /// mutates this object with the given min slice count + @ApiStatus.Internal + default void setMinSliceCount(int minSliceCount) { + updateSettings(s -> s.withMinSliceCount(minSliceCount)); + } + + /// mutates this object with the given max slice count + @ApiStatus.Internal + default void setMaxSliceCount(int maxSliceCount) { + updateSettings(s -> s.withMaxSliceCount(maxSliceCount)); + } + + /// mutates this object with the given preview count + @ApiStatus.Internal + default void setPreviewCount(int previewCount) { + updateSettings(s -> s.withPreviewCount(previewCount)); + } + + /// mutates this object with the given render formed disabled + @ApiStatus.Internal + default void setDisableRenderFormed(boolean disableRenderFormed) { + updateSettings(s -> s.withDisableRenderFormed(disableRenderFormed)); + } + + // copy and mutate + /// @return a copy with these settings applied + S withSettings(UnaryOperator configurator); + + /// @return a copy of this object with the given priority + @CheckReturnValue + default S withPriority(int priority) { + return withSettings(s -> s.withPriority(priority)); + } + + /// @return a copy of this object with the given min global count + @CheckReturnValue + default S withMinCount(int minCount) { + return withSettings(s -> s.withMinCount(minCount)); + } + + /// @return a copy of this object with the given max global count + @CheckReturnValue + default S withMaxCount(int maxCount) { + return withSettings(s -> s.withMaxCount(maxCount)); + } + + /// @return a copy of this object with the given min slice count + @CheckReturnValue + default S withMinSliceCount(int minSliceCount) { + return withSettings(s -> s.withMinSliceCount(minSliceCount)); + } + + /// @return a copy of this object with the given max slice count + @CheckReturnValue + default S withMaxSliceCount(int maxSliceCount) { + return withSettings(s -> s.withMaxSliceCount(maxSliceCount)); + } + + /// @return a copy of this object with the given preview count + @CheckReturnValue + default S withPreviewCount(int previewCount) { + return withSettings(s -> s.withPreviewCount(previewCount)); + } + + /// @return a copy of this object with the given render form disabled + @CheckReturnValue + default S withDisableRenderFormed(boolean disableRenderFormed) { + return withSettings(s -> s.withDisableRenderFormed(disableRenderFormed)); + } + + // test methods + /// simple test against global min count + default boolean testGlobalMin(int count) { + return getMinCount() == -1 || count >= getMinCount(); + } + + /// simple test against slice min count + default boolean testSliceMin(int count) { + return getMinSliceCount() == -1 || count >= getMinSliceCount(); + } + + /// simple test against global max count + default boolean testGlobalMax(int count) { + return getMaxCount() == -1 || count <= getMaxCount(); + } + + /// simple test against slice max count + default boolean testSliceMax(int count) { + return getMaxSliceCount() == -1 || count <= getMaxSliceCount(); + } + + @Override + default int compareTo(SettingsHolder o) { + return Integer.compare(getPriority(), o.getPriority()); + } + + enum TestType { + + GLOBAL_MIN, + GLOBAL_MAX, + SLICE_MIN, + SLICE_MAX; + + // should return true if null settings + // otherwise test settings + public boolean testSettings(SettingsHolder holder, PredicateContext ctx) { + if (!holder.hasSettings()) return true; + return switch (this) { + case GLOBAL_MIN -> holder.testGlobalMin(ctx.getGlobalCount(holder)); + case GLOBAL_MAX -> holder.testGlobalMax(ctx.incrementGlobalCount(holder)); + case SLICE_MIN -> holder.testSliceMin(ctx.getSliceCount(holder)); + case SLICE_MAX -> holder.testSliceMax(ctx.incrementSliceCount(holder)); + }; + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/TestablePredicate.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/TestablePredicate.java index d3ab1de5f3d..e8862f177ca 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/TestablePredicate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/predicates/TestablePredicate.java @@ -55,9 +55,13 @@ class TestablePredicate extends BasePredicate { this.onError = onError; } + /// @param root the top-most multi predicate for this multi predicate + /// @return a list of components to be displayed while hovering over a block in the Multiblock Preview @Override public List getRecipeViewerTooltips(MultiPredicate root) { List tooltips = new ArrayList<>(this.getAdditionalTooltips()); + int minCount = getMinCount(); + int maxCount = getMaxCount(); if (minCount == maxCount && maxCount != -1) { tooltips.add(Component.translatable("gtceu.multiblock.pattern.exact_count", minCount)); } else if (minCount != maxCount && minCount != -1 && maxCount != -1) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java index c951e273b8e..9b4127ea787 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GCYMMachines.java @@ -95,7 +95,7 @@ public static void init() {} .slice("XXXXX", "XGGGX", "XGGGX", "XAAAX") .slice("XXXXX", "XXXXX", "XXSXX", "XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_SECURE_MACERATION.get()).setMinGlobalLimited(55) + .where('X', blocks(CASING_SECURE_MACERATION.get()).withMinGlobalLimited(55) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('G', Predicates.blocks(CRUSHING_WHEELS.get())) @@ -124,7 +124,7 @@ public static void init() {} .slice("XXXXX", "XTTTX", "X X") .slice("XXXXX", "XXSXX", "XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_WATERTIGHT.get()).setMinGlobalLimited(55) + .where('X', blocks(CASING_WATERTIGHT.get()).withMinGlobalLimited(55) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where(' ', Predicates.air()) @@ -154,7 +154,7 @@ public static void init() {} .slice("XXXXX", "XAPAX", "XXXXX") .slice("#XXX#", "XXSXX", "#XXX#") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_VIBRATION_SAFE.get()).setMinGlobalLimited(40) + .where('X', blocks(CASING_VIBRATION_SAFE.get()).withMinGlobalLimited(40) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('P', Predicates.blocks(CASING_STEEL_PIPE.get())) @@ -182,7 +182,7 @@ public static void init() {} .slice("XXXXX", "XAPAX", "XAAAX", "XAPAX", "XAAAX", "##F##") .slice("#XXX#", "#XSX#", "#XXX#", "#XXX#", "#XXX#", "##F##") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_REACTION_SAFE.get()).setMinGlobalLimited(50) + .where('X', blocks(CASING_REACTION_SAFE.get()).withMinGlobalLimited(50) .and(autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('F', frames(GTMaterials.HastelloyX)) @@ -214,7 +214,7 @@ public static void init() {} .slice("XXXXX", "XCCCX", "XCCCX") .slice("XXXXX", "XXSXX", "XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_NONCONDUCTING.get()).setMinGlobalLimited(30) + .where('X', blocks(CASING_NONCONDUCTING.get()).withMinGlobalLimited(30) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('C', blocks(ELECTROLYTIC_CELL.get())) @@ -240,7 +240,7 @@ public static void init() {} .slice("XCXCX", "XCXCX", "XCXCX") .slice("XXXXX", "XXSXX", "XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_NONCONDUCTING.get()).setMinGlobalLimited(35) + .where('X', blocks(CASING_NONCONDUCTING.get()).withMinGlobalLimited(35) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('C', blocks(ELECTROLYTIC_CELL.get())) @@ -267,7 +267,7 @@ public static void init() {} .slice("XXX", "XAX", "XXX") .slice("XXX", "XSX", "XXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_TUNGSTENSTEEL_ROBUST.get()).setMinGlobalLimited(30) + .where('X', blocks(CASING_TUNGSTENSTEEL_ROBUST.get()).withMinGlobalLimited(30) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('A', Predicates.air()) @@ -295,10 +295,10 @@ public static void init() {} .slice("XXXXXXXXX", "XAAAXAAAX", "XGGGXXXXX") .slice("XXXXXXXXX", "XGGGXXSXX", "XGGGX###X") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_LARGE_SCALE_ASSEMBLING.get()).setMinGlobalLimited(40) + .where('X', blocks(CASING_LARGE_SCALE_ASSEMBLING.get()).withMinGlobalLimited(40) .and(Predicates.autoAbilities(definition.getRecipeTypes(), false, false, true, true, true, true)) - .and(Predicates.abilities(INPUT_ENERGY).setExactLimit(1)) + .and(Predicates.abilities(INPUT_ENERGY).withExactLimit(1)) .and(Predicates.autoAbilities(true, false, true))) .where('G', Predicates.blocks(CASING_TEMPERED_GLASS.get())) .where('A', Predicates.air()) @@ -329,10 +329,10 @@ public static void init() {} .slice("XXXXXXX", "XTTTTXX", "XXXXXXX") .slice("#####XX", "#####SX", "#####XX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_LARGE_SCALE_ASSEMBLING.get()).setMinGlobalLimited(55) + .where('X', blocks(CASING_LARGE_SCALE_ASSEMBLING.get()).withMinGlobalLimited(55) .and(Predicates.autoAbilities(definition.getRecipeTypes(), false, false, true, true, true, true)) - .and(Predicates.abilities(INPUT_ENERGY).setExactLimit(1)) + .and(Predicates.abilities(INPUT_ENERGY).withExactLimit(1)) .and(Predicates.autoAbilities(true, false, true))) .where('T', Predicates.blocks(CASING_TEMPERED_GLASS.get())) .where('G', Predicates.blocks(CASING_GRATE.get())) @@ -361,7 +361,7 @@ public static void init() {} .slice("XXXXX", "XACAX", "XACAX", "XXXXX") .slice("#XXX#", "#XSX#", "#XXX#", "#XXX#") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).setMinGlobalLimited(45) + .where('X', blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).withMinGlobalLimited(45) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('C', Predicates.blocks(MOLYBDENUM_DISILICIDE_COIL_BLOCK.get())) @@ -394,7 +394,7 @@ public static void init() {} .slice("XXSXX", "XXGXX", "XXGXX", "XXXXX") .where('S', controller(blocks(definition.get()))) .where('C', blocks(CASING_TUNGSTENSTEEL_PIPE.get())) - .where('X', blocks(CASING_LASER_SAFE_ENGRAVING.get()).setMinGlobalLimited(50) + .where('X', blocks(CASING_LASER_SAFE_ENGRAVING.get()).withMinGlobalLimited(50) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('G', blocks(CASING_TEMPERED_GLASS.get())) @@ -422,7 +422,7 @@ public static void init() {} .slice("XXXXX", "XAXAX", "XKKKX", "XKKKX", "X###X") .slice("#X#X#", "#X#X#", "#XSX#", "XXXXX", "#XXX#") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_VIBRATION_SAFE.get()).setMinGlobalLimited(50) + .where('X', blocks(CASING_VIBRATION_SAFE.get()).withMinGlobalLimited(50) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('K', blocks(CASING_GRATE.get())) @@ -452,7 +452,7 @@ public static void init() {} .slice("XXXXX", "CAAAC", "GAAAG", "CAAAC", "XXXXX") .slice("#XSX#", "#CCC#", "#GGG#", "#CCC#", "#XXX#") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).setMinGlobalLimited(30) + .where('X', blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).withMinGlobalLimited(30) .and(autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, false))) .where('C', heatingCoils()) @@ -500,7 +500,7 @@ public static void init() {} .slice("XXX", "XTX", "XXX") .slice("XXX", "XSX", "XXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_WATERTIGHT.get()).setMinGlobalLimited(30) + .where('X', blocks(CASING_WATERTIGHT.get()).withMinGlobalLimited(30) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('T', blocks(CASING_STEEL_PIPE.get())) @@ -526,7 +526,7 @@ public static void init() {} .slice("XXXXXXX", "XAXGGGX", "XXXXXXX") .slice("XXXXXXX", "XSXCCCX", "XXXXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_STRESS_PROOF.get()).setMinGlobalLimited(40) + .where('X', blocks(CASING_STRESS_PROOF.get()).withMinGlobalLimited(40) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('G', blocks(CASING_STEEL_GEARBOX.get())) @@ -555,7 +555,7 @@ public static void init() {} .slice("XXXXX", "XCCCX", "XAAAX", "XXAXX", "##X##") .slice("#XXX#", "#XSX#", "#XXX#", "#XXX#", "#####") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_CORROSION_PROOF.get()).setMinGlobalLimited(50) + .where('X', blocks(CASING_CORROSION_PROOF.get()).withMinGlobalLimited(50) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('P', blocks(CASING_STEEL_PIPE.get())) @@ -583,7 +583,7 @@ public static void init() {} .slice("XXXXXXX", "XAXCCCX", "XXXAAAX", "##XXXXX") .slice("XXXXXXX", "XSXGGGX", "XXXGGGX", "##XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_SHOCK_PROOF.get()).setMinGlobalLimited(65) + .where('X', blocks(CASING_SHOCK_PROOF.get()).withMinGlobalLimited(65) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('G', blocks(CASING_TEMPERED_GLASS.get())) @@ -606,11 +606,11 @@ public static void init() {} .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, OC_NON_PERFECT_SUBTICK, BATCH_MODE) .appearanceBlock(CASING_WATERTIGHT) .pattern(definition -> { - MultiPredicate casingPredicate = blocks(CASING_WATERTIGHT.get()).setMinGlobalLimited(40); + MultiPredicate casingPredicate = blocks(CASING_WATERTIGHT.get()).withMinGlobalLimited(40); MultiPredicate exportPredicate = abilities(PartAbility.EXPORT_FLUIDS_1X); if (GTCEu.Mods.isAE2Loaded()) exportPredicate = exportPredicate.xor(blocks(GTAEMachines.FLUID_EXPORT_HATCH_ME.get())); - exportPredicate = exportPredicate.setMaxLayerLimited(1); + exportPredicate = exportPredicate.withMaxLayerLimited(1); return MultiblockPatternBuilder.start(UP, BACK, RIGHT) .slice("#YYY#", "YYYYY", "YYYYY", "YYYYY", "#YYY#") .slice("#YSY#", "YAAAY", "YAAAY", "YAAAY", "#YYY#") @@ -618,8 +618,8 @@ public static void init() {} .slice("#####", "#ZZZ#", "#ZZZ#", "#ZZZ#", "#####") .where('S', controller(blocks(definition.get()))) .where('Y', casingPredicate.and(abilities(IMPORT_ITEMS)) - .and(abilities(INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2)) - .and(abilities(IMPORT_FLUIDS).setMinGlobalLimited(1)) + .and(abilities(INPUT_ENERGY).withMinGlobalLimited(1).withMaxGlobalLimited(2)) + .and(abilities(IMPORT_FLUIDS).withMinGlobalLimited(1)) .and(abilities(EXPORT_ITEMS)) .and(autoAbilities(true, false, true))) .where('X', casingPredicate.and(exportPredicate)) @@ -650,7 +650,7 @@ public static void init() {} .slice("XXXXX", "XCACX", "XXXXX") .slice("XXXXX", "XXSXX", "XXXXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_WATERTIGHT.get()).setMinGlobalLimited(25) + .where('X', blocks(CASING_WATERTIGHT.get()).withMinGlobalLimited(25) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('C', blocks(CASING_STEEL_PIPE.get())) @@ -677,7 +677,7 @@ public static void init() {} .sliceRepeatable(2, 2, "##XXX", "##XPX", "##XGX") .slice("##XXX", "##XXX", "##XXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_STRESS_PROOF.get()).setMinGlobalLimited(40) + .where('X', blocks(CASING_STRESS_PROOF.get()).withMinGlobalLimited(40) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('P', blocks(CASING_TITANIUM_PIPE.get())) @@ -706,7 +706,7 @@ public static void init() {} .slice("XXXXX", "XCACX", "XCACX", "XXXXX") .slice("#XXX#", "#XSX#", "#XXX#", "#XXX#") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_WATERTIGHT.get()).setMinGlobalLimited(45) + .where('X', blocks(CASING_WATERTIGHT.get()).withMinGlobalLimited(45) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('C', blocks(CASING_STEEL_PIPE.get())) @@ -732,7 +732,7 @@ public static void init() {} .slice("XXXXX", "X#CCX", "XXXXX") .slice("XXXXX", "XSXXX", "XXX##") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_STRESS_PROOF.get()).setMinGlobalLimited(25) + .where('X', blocks(CASING_STRESS_PROOF.get()).withMinGlobalLimited(25) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, true))) .where('C', blocks(CASING_TITANIUM_GEARBOX.get())) @@ -757,7 +757,7 @@ public static void init() {} .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers::ebfOverclock, BATCH_MODE) .appearanceBlock(CASING_HIGH_TEMPERATURE_SMELTING) .pattern(definition -> { - MultiPredicate casing = blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).setMinGlobalLimited(360); + MultiPredicate casing = blocks(CASING_HIGH_TEMPERATURE_SMELTING.get()).withMinGlobalLimited(360); return MultiblockPatternBuilder.start(FRONT, UP, RIGHT) // spotless:off .slice("##XXXXXXXXX##", "##XXXXXXXXX##", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############", "#############") @@ -832,7 +832,7 @@ public static void init() {} .slice("#XXXXX#####", "#XXSXX#####", "#XGGGX#####", "#XGGGX#####", "#XGGGX#####", "#XXXXX#####", "###########") // spotless:on .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_ALUMINIUM_FROSTPROOF.get()).setMinGlobalLimited(140) + .where('X', blocks(CASING_ALUMINIUM_FROSTPROOF.get()).withMinGlobalLimited(140) .and(autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, true))) .where('G', blocks(CASING_TEMPERED_GLASS.get())) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java index 0bbef969da9..97b19c0dc01 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java @@ -546,7 +546,7 @@ public static MultiblockMachineDefinition registerMultiblockTank(GTRegistrate re .slice("CCC", "CSC", "CCC") .where('S', controller(blocks(definition.get()))) .where('C', blocks(casing.get()) - .and(blocks(valve.get()).setMaxGlobalLimited(2, 0))) + .and(blocks(valve.get()).withMaxGlobalLimited(2, 0))) .where('#', air()) .build()) .appearanceBlock(casing); @@ -604,15 +604,15 @@ public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate regis controller.getBlockPos().below().getY() == part.getBlockPos().getY() ? fireBox.get().defaultBlockState() : casing.get().defaultBlockState()) .pattern((definition) -> { - MultiPredicate fireboxPred = blocks(ALL_FIREBOXES.get(firebox).get()).setMinGlobalLimited(3) - .and(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setMinGlobalLimited(1) - .setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.IMPORT_ITEMS).setMaxGlobalLimited(1) - .setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1)); + MultiPredicate fireboxPred = blocks(ALL_FIREBOXES.get(firebox).get()).withMinGlobalLimited(3) + .and(Predicates.abilities(PartAbility.IMPORT_FLUIDS) + .withMinGlobalLimited(1, 1)) + .and(Predicates.abilities(PartAbility.IMPORT_ITEMS) + .withMaxGlobalLimited(1, 1)) + .and(Predicates.abilities(PartAbility.MUFFLER).withExactLimit(1)); if (ConfigHolder.INSTANCE.machines.enableMaintenance) { - fireboxPred = fireboxPred.and(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)); + fireboxPred = fireboxPred.and(Predicates.abilities(PartAbility.MAINTENANCE).withExactLimit(1)); } return MultiblockPatternBuilder.start(FRONT, UP, RIGHT) @@ -622,9 +622,9 @@ public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate regis .where('S', Predicates.controller(blocks(definition.getBlock()))) .where('P', blocks(pipe.get())) .where('X', fireboxPred) - .where('C', blocks(casing.get()).setMinGlobalLimited(20) - .and(Predicates.abilities(PartAbility.EXPORT_FLUIDS).setMinGlobalLimited(1) - .setPreviewCount(1))) + .where('C', blocks(casing.get()).withMinGlobalLimited(20) + .and(Predicates.abilities(PartAbility.EXPORT_FLUIDS) + .withMinGlobalLimited(1, 1))) .build(); }) .recoveryItems( @@ -665,7 +665,7 @@ public static MultiblockMachineDefinition registerLargeCombustionEngine(GTRegist .slice("AAA", "AYA", "AAA") .where('X', blocks(casing.get())) .where('G', blocks(gear.get())) - .where('C', blocks(casing.get()).setMinGlobalLimited(3) + .where('C', blocks(casing.get()).withMinGlobalLimited(3) .and(autoAbilities(definition.getRecipeTypes(), false, false, true, true, true, true)) .and(autoAbilities(true, true, false))) .where('D', @@ -727,8 +727,8 @@ public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate regi .where('S', controller(blocks(definition.getBlock()))) .where('G', blocks(gear.get())) .where('C', blocks(casing.get())) - .where('R', rotorHolder(tier).setExactLimit(1) - .and(abilities(PartAbility.OUTPUT_ENERGY).setExactLimit(1))) + .where('R', rotorHolder(tier).withExactLimit(1) + .and(abilities(PartAbility.OUTPUT_ENERGY).withExactLimit(1))) .where('H', blocks(casing.get()) .and(autoAbilities(definition.getRecipeTypes(), false, false, true, true, true, true)) .and(autoAbilities(true, needsMuffler, false))) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java index 90d6430d4ba..c2614da41d9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMultiMachines.java @@ -103,7 +103,7 @@ public class GTMultiMachines { .slice("XXX", "X#X", "XXX") .slice("XXX", "XYX", "XXX") .where('X', - blocks(CASING_COKE_BRICKS.get()).and(blocks(COKE_OVEN_HATCH.get()).setMaxGlobalLimited(5))) + blocks(CASING_COKE_BRICKS.get()).and(blocks(COKE_OVEN_HATCH.get()).withMaxGlobalLimited(5))) .where('#', Predicates.air()) .where('Y', Predicates.controller(blocks(definition.getBlock()))) .build()) @@ -149,7 +149,7 @@ public class GTMultiMachines { .slice("XXX", "C#C", "C#C", "XMX") .slice("XSX", "CCC", "CCC", "XXX") .where('S', controller(blocks(definition.getBlock()))) - .where('X', blocks(CASING_INVAR_HEATPROOF.get()).setMinGlobalLimited(9) + .where('X', blocks(CASING_INVAR_HEATPROOF.get()).withMinGlobalLimited(9) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, false))) .where('M', abilities(PartAbility.MUFFLER)) @@ -193,7 +193,7 @@ public class GTMultiMachines { .recipeModifiers(DEFAULT_ENVIRONMENT_REQUIREMENT, OC_PERFECT_SUBTICK, BATCH_MODE) .appearanceBlock(CASING_PTFE_INERT) .pattern(definition -> { - var casing = blocks(CASING_PTFE_INERT.get()).setMinGlobalLimited(10); + var casing = blocks(CASING_PTFE_INERT.get()).withMinGlobalLimited(10); var abilities = Predicates.autoAbilities(definition.getRecipeTypes()) .and(Predicates.autoAbilities(true, false, false)); return MultiblockPatternBuilder.start(FRONT, UP, RIGHT) @@ -203,7 +203,7 @@ public class GTMultiMachines { .where('S', Predicates.controller(blocks(definition.getBlock()))) .where('X', casing.and(abilities)) .where('P', blocks(CASING_POLYTETRAFLUOROETHYLENE_PIPE.get())) - .where('C', Predicates.heatingCoils().setExactLimit(1) + .where('C', Predicates.heatingCoils().withExactLimit(1) .and(abilities) .and(casing)) .build(); @@ -223,7 +223,7 @@ public class GTMultiMachines { .slice("XXX", "X#X", "XXX") .slice("XXX", "XSX", "XXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_STEEL_SOLID.get()).setMinGlobalLimited(14) + .where('X', blocks(CASING_STEEL_SOLID.get()).withMinGlobalLimited(14) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, true, false))) .where('#', Predicates.air()) @@ -245,7 +245,7 @@ public class GTMultiMachines { .slice("XXX", "XSX", "XXX") .where('S', Predicates.controller(blocks(definition.get()))) .where('X', - blocks(MACHINE_CASING_ULV.get()).setMinGlobalLimited(6) + blocks(MACHINE_CASING_ULV.get()).withMinGlobalLimited(6) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, true, false))) .where('C', Predicates.heatingCoils()) @@ -282,7 +282,7 @@ public class GTMultiMachines { .slice("XXX", "C#C", "XMX") .slice("XSX", "CCC", "XXX") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(CASING_INVAR_HEATPROOF.get()).setMinGlobalLimited(9) + .where('X', blocks(CASING_INVAR_HEATPROOF.get()).withMinGlobalLimited(9) .and(autoAbilities(definition.getRecipeTypes())) .and(autoAbilities(true, false, false))) .where('M', abilities(PartAbility.MUFFLER)) @@ -325,7 +325,7 @@ public class GTMultiMachines { .slice("HCHCH", "H###H", "HCHCH") .slice("HCHCH", "HCOCH", "HCHCH") .where('O', Predicates.controller(blocks(definition.get()))) - .where('H', blocks(CASING_STAINLESS_CLEAN.get()).setMinGlobalLimited(12) + .where('H', blocks(CASING_STAINLESS_CLEAN.get()).withMinGlobalLimited(12) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, true, false))) .where('#', Predicates.air()) @@ -360,9 +360,9 @@ public class GTMultiMachines { if (GTCEu.Mods.isAE2Loaded()) { exportPredicate = exportPredicate.xor(blocks(GTAEMachines.FLUID_EXPORT_HATCH_ME.get())); } - exportPredicate = exportPredicate.setMaxLayerLimited(1); + exportPredicate = exportPredicate.withMaxLayerLimited(1); MultiPredicate maint = autoAbilities(true, false, false) - .setMaxGlobalLimited(1); + .withMaxGlobalLimited(1); return MultiblockPatternBuilder.start(UP, BACK, RIGHT) .slice("YSY", "YYY", "YYY") .slice("ZZZ", "Z#Z", "ZZZ") @@ -370,10 +370,10 @@ public class GTMultiMachines { .slice("XXX", "XXX", "XXX") .where('S', Predicates.controller(blocks(definition.getBlock()))) .where('Y', blocks(CASING_STAINLESS_CLEAN.get()) - .and(Predicates.abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1)) - .and(Predicates.abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1) - .setMaxGlobalLimited(2)) - .and(Predicates.abilities(PartAbility.IMPORT_FLUIDS).setExactLimit(1)) + .and(Predicates.abilities(PartAbility.EXPORT_ITEMS).withMaxGlobalLimited(1)) + .and(Predicates.abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1) + .withMaxGlobalLimited(2)) + .and(Predicates.abilities(PartAbility.IMPORT_FLUIDS).withExactLimit(1)) .and(maint)) .where('Z', blocks(CASING_STAINLESS_CLEAN.get()) .and(exportPredicate) @@ -399,7 +399,7 @@ public class GTMultiMachines { .slice("XXX", "X#X", "XXX") .slice("XXX", "XSX", "XXX") .where('S', Predicates.controller(blocks(definition.getBlock()))) - .where('X', blocks(CASING_ALUMINIUM_FROSTPROOF.get()).setMinGlobalLimited(14) + .where('X', blocks(CASING_ALUMINIUM_FROSTPROOF.get()).withMinGlobalLimited(14) .and(Predicates.autoAbilities(definition.getRecipeTypes())) .and(Predicates.autoAbilities(true, false, false))) .where('#', Predicates.air()) @@ -424,13 +424,13 @@ public class GTMultiMachines { .and(!ConfigHolder.INSTANCE.machines.orderedAssemblyLineFluids ? Predicates.abilities(PartAbility.IMPORT_FLUIDS_1X, PartAbility.IMPORT_FLUIDS_4X, PartAbility.IMPORT_FLUIDS_9X) : - Predicates.abilities(PartAbility.IMPORT_FLUIDS_1X).setMaxGlobalLimited(4))) + Predicates.abilities(PartAbility.IMPORT_FLUIDS_1X).withMaxGlobalLimited(4))) .where('O', Predicates.abilities(PartAbility.EXPORT_ITEMS) .addTooltips(Component.translatable("gtceu.multiblock.pattern.location_end"))) .where('Y', blocks(CASING_STEEL_SOLID.get()).and(Predicates.abilities(PartAbility.INPUT_ENERGY) - .setMinGlobalLimited(1).setMaxGlobalLimited(2))) + .withMinGlobalLimited(1).withMaxGlobalLimited(2))) .where('I', blocks(ITEM_IMPORT_BUS[0].getBlock())) .where('G', blocks(CASING_GRATE.get())) .where('A', blocks(CASING_ASSEMBLY_CONTROL.get())) @@ -496,10 +496,10 @@ public class GTMultiMachines { .slice("XXX", "XSX", "XXX") .where('S', Predicates.controller(blocks(definition.getBlock()))) .where('#', Predicates.air()) - .where('X', blocks(CASING_BRONZE_BRICKS.get()).setMinGlobalLimited(14) - .and(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.STEAM).setExactLimit(1))) + .where('X', blocks(CASING_BRONZE_BRICKS.get()).withMinGlobalLimited(14) + .and(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).withPreviewCount(1)) + .and(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).withPreviewCount(1)) + .and(Predicates.abilities(PartAbility.STEAM).withExactLimit(1))) .build()) .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), GTCEu.id("block/multiblock/steam_grinder")) @@ -521,11 +521,11 @@ public class GTMultiMachines { .where('S', Predicates.controller(blocks(definition.getBlock()))) .where('#', Predicates.air()) .where(' ', Predicates.any()) - .where('X', blocks(CASING_BRONZE_BRICKS.get()).setMinGlobalLimited(6) - .and(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setPreviewCount(1))) + .where('X', blocks(CASING_BRONZE_BRICKS.get()).withMinGlobalLimited(6) + .and(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).withPreviewCount(1)) + .and(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).withPreviewCount(1))) .where('F', blocks(FIREBOX_BRONZE.get()) - .and(Predicates.abilities(PartAbility.STEAM).setExactLimit(1))) + .and(Predicates.abilities(PartAbility.STEAM).withExactLimit(1))) .build()) .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), @@ -572,12 +572,12 @@ public class GTMultiMachines { .where('G', blocks(FUSION_GLASS.get()).or(casing)) .where('E', casing.and( blocks(PartAbility.INPUT_ENERGY.getBlockRange(tier, UV).toArray(Block[]::new)) - .setMinGlobalLimited(1).setPreviewCount(16))) + .withMinGlobalLimited(1, 16))) .where('C', casing) .where('K', blocks(FusionReactorMachine.getCoilState(tier))) .where('O', casing.or(abilities(PartAbility.EXPORT_FLUIDS))) .where('A', air()) - .where('I', casing.and(abilities(PartAbility.IMPORT_FLUIDS).setMinGlobalLimited(2))) + .where('I', casing.and(abilities(PartAbility.IMPORT_FLUIDS).withMinGlobalLimited(2))) .where('#', any()) .build(); }) @@ -609,10 +609,10 @@ public class GTMultiMachines { .slice("XXX", "FCF", "FCF", "FCF", "#F#", "#F#", "#F#") .slice("XSX", "#F#", "#F#", "#F#", "###", "###", "###") .where('S', controller(blocks(definition.get()))) - .where('X', blocks(FluidDrillMachine.getCasingState(tier)).setMinGlobalLimited(3) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1) - .setMaxGlobalLimited(2)) - .and(abilities(PartAbility.EXPORT_FLUIDS).setMaxGlobalLimited(1))) + .where('X', blocks(FluidDrillMachine.getCasingState(tier)).withMinGlobalLimited(3) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1) + .withMaxGlobalLimited(2)) + .and(abilities(PartAbility.EXPORT_FLUIDS).withMaxGlobalLimited(1))) .where('C', blocks(FluidDrillMachine.getCasingState(tier))) .where('F', frames(FluidDrillMachine.getFrameMaterial(tier))) .where('#', any()) @@ -635,10 +635,10 @@ public class GTMultiMachines { .slice("XSX", "#F#", "#F#", "#F#", "###", "###", "###") .where('S', controller(blocks(definition.getBlock()))) .where('X', blocks(LargeMinerMachine.getCasingState(tier)) - .and(abilities(PartAbility.EXPORT_ITEMS).setExactLimit(1).setPreviewCount(1)) - .and(abilities(PartAbility.IMPORT_FLUIDS).setExactLimit(1).setPreviewCount(1)) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1) - .setMaxGlobalLimited(2).setPreviewCount(1))) + .and(abilities(PartAbility.EXPORT_ITEMS).withExactLimit(1).withPreviewCount(1)) + .and(abilities(PartAbility.IMPORT_FLUIDS).withExactLimit(1).withPreviewCount(1)) + .and(abilities(PartAbility.INPUT_ENERGY).withGlobalMinMax(1, 2) + .withPreviewCount(1))) .where('C', blocks(LargeMinerMachine.getCasingState(tier))) .where('F', frames(LargeMinerMachine.getMaterial(tier))) .where('#', any()) @@ -773,7 +773,7 @@ public class GTMultiMachines { .slice("XXX", "XCX", "XXX") .slice("XXX", "XSX", "XXX") .where('S', controller(blocks(definition.getBlock()))) - .where('X', blocks(GTBlocks.HIGH_POWER_CASING.get()).setMinGlobalLimited(12) + .where('X', blocks(GTBlocks.HIGH_POWER_CASING.get()).withMinGlobalLimited(12) .and(ActiveTransformerMachine.getHatchPredicates())) .where('C', blocks(GTBlocks.SUPERCONDUCTING_COIL.get())) .build()) @@ -808,12 +808,12 @@ public class GTMultiMachines { .where('C', blocks(CASING_PALLADIUM_SUBSTATION.get())) .where('X', blocks(CASING_PALLADIUM_SUBSTATION.get()) - .setMinGlobalLimited(PowerSubstationMachine.MIN_CASINGS) + .withMinGlobalLimited(PowerSubstationMachine.MIN_CASINGS) .and(autoAbilities(true, false, false)) .and(abilities(PartAbility.INPUT_ENERGY, PartAbility.SUBSTATION_INPUT_ENERGY, - PartAbility.INPUT_LASER).setMinGlobalLimited(1)) + PartAbility.INPUT_LASER).withMinGlobalLimited(1)) .and(abilities(PartAbility.OUTPUT_ENERGY, PartAbility.SUBSTATION_OUTPUT_ENERGY, - PartAbility.OUTPUT_LASER).setMinGlobalLimited(1))) + PartAbility.OUTPUT_LASER).withMinGlobalLimited(1))) .where('G', blocks(CASING_LAMINATED_GLASS.get())) .where('B', Predicates.powerSubstationBatteries()) .build()) @@ -860,10 +860,10 @@ public class GTMultiMachines { .slice("XSX", "#F#", "#F#", "#F#", "###", "###", "###") .where('S', controller(blocks(definition.get()))) .where('X', - blocks(BedrockOreMinerMachine.getCasingState(tier)).setMinGlobalLimited(3) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1) - .setMaxGlobalLimited(2)) - .and(abilities(PartAbility.EXPORT_ITEMS).setMaxGlobalLimited(1))) + blocks(BedrockOreMinerMachine.getCasingState(tier)).withMinGlobalLimited(3) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1) + .withMaxGlobalLimited(2)) + .and(abilities(PartAbility.EXPORT_ITEMS).withMaxGlobalLimited(1))) .where('C', blocks(BedrockOreMinerMachine.getCasingState(tier))) .where('F', frames(BedrockOreMinerMachine.getFrameMaterial(tier))) .where('#', any()) diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTResearchMachines.java b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTResearchMachines.java index eefb8023a7a..5d62e587dd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTResearchMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/machines/GTResearchMachines.java @@ -71,8 +71,8 @@ public class GTResearchMachines { .where('V', blocks(COMPUTER_HEAT_VENT.get())) .where('A', blocks(ADVANCED_COMPUTER_CASING.get())) .where('P', blocks(COMPUTER_CASING.get()) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2, 1)) - .and(abilities(PartAbility.COMPUTATION_DATA_RECEPTION).setExactLimit(1)) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1).withMaxGlobalLimited(2, 1)) + .and(abilities(PartAbility.COMPUTATION_DATA_RECEPTION).withExactLimit(1)) .and(autoAbilities(true, false, false))) .where('H', abilities(PartAbility.OBJECT_HOLDER)) .build()) @@ -109,13 +109,13 @@ public class GTResearchMachines { .slice("XCCCX", "XCSCX", "XCCCX") .where('S', controller(blocks(definition.getBlock()))) .where('X', blocks(COMPUTER_HEAT_VENT.get())) - .where('D', blocks(COMPUTER_CASING.get()).setMinGlobalLimited(3) - .and(abilities(PartAbility.DATA_ACCESS).setPreviewCount(3)) - .and(abilities(PartAbility.OPTICAL_DATA_TRANSMISSION).setMinGlobalLimited(1, 1)) - .and(abilities(PartAbility.OPTICAL_DATA_RECEPTION).setPreviewCount(1))) + .where('D', blocks(COMPUTER_CASING.get()).withMinGlobalLimited(3) + .and(abilities(PartAbility.DATA_ACCESS).withPreviewCount(3)) + .and(abilities(PartAbility.OPTICAL_DATA_TRANSMISSION).withMinGlobalLimited(1, 1)) + .and(abilities(PartAbility.OPTICAL_DATA_RECEPTION).withPreviewCount(1))) .where('A', blocks(COMPUTER_CASING.get())) - .where('C', blocks(HIGH_POWER_CASING.get()).setMinGlobalLimited(4) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2, 1)) + .where('C', blocks(HIGH_POWER_CASING.get()).withMinGlobalLimited(4) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1).withMaxGlobalLimited(2, 1)) .and(autoAbilities(true, false, false))) .build()) .workableCasingModel(GTCEu.id("block/casings/hpca/high_power_casing"), @@ -139,10 +139,10 @@ public class GTResearchMachines { .slice("XXX", "XSX", "XXX") .where('S', controller(blocks(definition.getBlock()))) .where('A', blocks(ADVANCED_COMPUTER_CASING.get())) - .where('X', blocks(COMPUTER_CASING.get()).setMinGlobalLimited(7) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2, 1)) - .and(abilities(PartAbility.COMPUTATION_DATA_TRANSMISSION).setMinGlobalLimited(1, 1)) - .and(abilities(PartAbility.COMPUTATION_DATA_RECEPTION).setMinGlobalLimited(1, 2)) + .where('X', blocks(COMPUTER_CASING.get()).withMinGlobalLimited(7) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1).withMaxGlobalLimited(2, 1)) + .and(abilities(PartAbility.COMPUTATION_DATA_TRANSMISSION).withMinGlobalLimited(1, 1)) + .and(abilities(PartAbility.COMPUTATION_DATA_RECEPTION).withMinGlobalLimited(1, 2)) .and(autoAbilities(true, false, false))) .build()) .sidedWorkableCasingModel(GTCEu.id("block/casings/hpca/computer_casing"), @@ -168,10 +168,10 @@ public class GTResearchMachines { .where('A', blocks(ADVANCED_COMPUTER_CASING.get())) .where('V', blocks(COMPUTER_HEAT_VENT.get())) .where('X', abilities(PartAbility.HPCA_COMPONENT)) - .where('C', blocks(COMPUTER_CASING.get()).setMinGlobalLimited(5) - .and(abilities(PartAbility.INPUT_ENERGY).setMinGlobalLimited(1).setMaxGlobalLimited(2, 1)) - .and(abilities(PartAbility.IMPORT_FLUIDS).setMaxGlobalLimited(1)) - .and(abilities(PartAbility.COMPUTATION_DATA_TRANSMISSION).setExactLimit(1)) + .where('C', blocks(COMPUTER_CASING.get()).withMinGlobalLimited(5) + .and(abilities(PartAbility.INPUT_ENERGY).withMinGlobalLimited(1).withMaxGlobalLimited(2, 1)) + .and(abilities(PartAbility.IMPORT_FLUIDS).withMaxGlobalLimited(1)) + .and(abilities(PartAbility.COMPUTATION_DATA_TRANSMISSION).withExactLimit(1)) .and(autoAbilities(true, false, false))) .build()) .sidedWorkableCasingModel(GTCEu.id("block/casings/hpca/computer_casing"), diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/ActiveTransformerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/ActiveTransformerMachine.java index 3391715c93b..fecb6149b96 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/ActiveTransformerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/ActiveTransformerMachine.java @@ -158,12 +158,12 @@ public void invalidateStructure(String name) { } public static MultiPredicate getHatchPredicates() { - return abilities(PartAbility.INPUT_ENERGY).setPreviewCount(1) - .or(abilities(PartAbility.OUTPUT_ENERGY).setPreviewCount(2)) - .or(abilities(PartAbility.SUBSTATION_INPUT_ENERGY).setPreviewCount(1)) - .or(abilities(PartAbility.SUBSTATION_OUTPUT_ENERGY).setPreviewCount(1)) - .or(abilities(PartAbility.INPUT_LASER).setPreviewCount(1)) - .or(abilities(PartAbility.OUTPUT_LASER).setPreviewCount(1)); + return abilities(PartAbility.INPUT_ENERGY).withPreviewCount(1) + .or(abilities(PartAbility.OUTPUT_ENERGY).withPreviewCount(2)) + .or(abilities(PartAbility.SUBSTATION_INPUT_ENERGY).withPreviewCount(1)) + .or(abilities(PartAbility.SUBSTATION_OUTPUT_ENERGY).withPreviewCount(1)) + .or(abilities(PartAbility.INPUT_LASER).withPreviewCount(1)) + .or(abilities(PartAbility.OUTPUT_LASER).withPreviewCount(1)); } public List getWidgetsForDisplay(PanelSyncManager syncManager) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java index 03ce28e1fce..db1e10b8005 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java @@ -75,12 +75,12 @@ public static MultiPredicate getMultiPredicate() { if (MULTI_PREDICATE == null) { MULTI_PREDICATE = Predicates.machines(GTMachines.MONITOR) .and(Predicates.abilities(PartAbility.INPUT_ENERGY) - .setMinGlobalLimited(1).setMaxGlobalLimited(2).setPreviewCount(1)) - .and(Predicates.abilities(PartAbility.DATA_ACCESS).setPreviewCount(1) - .or(Predicates.machines(GTMachines.BATTERY_BUFFER_4).setPreviewCount(0)) - .or(Predicates.machines(GTMachines.BATTERY_BUFFER_16).setPreviewCount(0)) - .setMaxGlobalLimited(4)) - .and(Predicates.machines(GTMachines.HULL).setPreviewCount(0)) + .withGlobalMinMax(1, 2).withPreviewCount(1)) + .and(Predicates.abilities(PartAbility.DATA_ACCESS).withPreviewCount(1) + .or(Predicates.machines(GTMachines.BATTERY_BUFFER_4).withPreviewCount(0)) + .or(Predicates.machines(GTMachines.BATTERY_BUFFER_16).withPreviewCount(0)) + .withMaxGlobalLimited(4)) + .and(Predicates.machines(GTMachines.HULL).withPreviewCount(0)) .and(Predicates.machines(GTMachines.ADVANCED_MONITOR)) .and(Predicates.blocks(GTBlocks.CASING_ALUMINIUM_FROSTPROOF.get())); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CleanroomMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CleanroomMachine.java index f2fc44eaf50..1b0d5b8360d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CleanroomMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CleanroomMachine.java @@ -316,12 +316,12 @@ public static Function getPattern() return (definition) -> { MultiPredicate wallPredicate = states(getCasingState(), getGlassState()).or(getValidFloorBlocks()); MultiPredicate energyPredicate = autoAbilities(true, false, false).and(abilities(PartAbility.INPUT_ENERGY) - .setMinGlobalLimited(1).setMaxGlobalLimited(3)); + .withMinGlobalLimited(1).withMaxGlobalLimited(3)); MultiPredicate edgePredicate = wallPredicate.and(energyPredicate); MultiPredicate facePredicate = wallPredicate.and(energyPredicate) - .and(doorPredicate().setMaxGlobalLimited(8)) - .and(abilities(PartAbility.PASSTHROUGH_HATCH).setMaxGlobalLimited(30)); + .and(doorPredicate().withMaxGlobalLimited(8)) + .and(abilities(PartAbility.PASSTHROUGH_HATCH).withMaxGlobalLimited(30)); MultiPredicate filterPredicate = cleanroomFilters(); MultiPredicate innerPredicate = innerPredicate(); MultiPredicate verticalEdgePredicate = edgePredicate.and(blocks(getGlassState().getBlock())); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/testmultis/PCBFactoryMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/testmultis/PCBFactoryMachine.java index c4ec9877989..84208ed3374 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/testmultis/PCBFactoryMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/testmultis/PCBFactoryMachine.java @@ -27,7 +27,7 @@ public IBlockPattern getDefaultStructurePattern() { .where('C', /* * Predicates.autoAbilities(true, false, false) * .or( - */Predicates.blocks(CASING_GRATE.get()).setMinGlobalLimited(12)) + */Predicates.blocks(CASING_GRATE.get()).withMinGlobalLimited(12)) .where('S', Predicates.controller(Predicates.blocks(getDefinition().getBlock()))) .where('B', Predicates.frames(GTMaterials.Steel)) .build();