From dec00eb49fe7c54a5097f611eb69894526eebea9 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Wed, 11 Dec 2024 03:03:54 -0700 Subject: [PATCH 01/29] refactor recipe handling functions outside of GTRecipe --- .../recipe/IRecipeCapabilityHolder.java | 2 +- .../api/capability/recipe/IRecipeHandler.java | 9 - .../gtceu/api/item/tool/ToolHelper.java | 8 +- .../machine/feature/IRecipeLogicMachine.java | 3 +- .../part/MultiblockPartMachine.java | 9 +- .../gtceu/api/machine/trait/RecipeLogic.java | 142 ++++--- .../gtceu/api/recipe/GTRecipe.java | 289 +-------------- .../gtceu/api/recipe/GTRecipeType.java | 22 +- .../gtceu/api/recipe/RecipeHandler.java | 349 ++++++++++++++++++ .../gtceu/api/recipe/RecipeRunner.java | 101 ++--- .../api/recipe/lookup/GTRecipeLookup.java | 3 +- .../gtceu/common/commands/GTCommands.java | 15 +- .../gtceu/common/data/GTRecipeModifiers.java | 3 +- .../electric/DistillationTowerMachine.java | 142 ++----- .../research/ResearchStationMachine.java | 67 ++-- .../LargeCombustionEngineMachine.java | 11 +- .../machine/trait/BedrockOreMinerLogic.java | 14 +- .../common/machine/trait/FluidDrillLogic.java | 14 +- .../machine/trait/miner/MinerLogic.java | 5 +- .../kjs/builders/GTRecipeTypeBuilder.java | 1 - 20 files changed, 554 insertions(+), 655 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 6213aa834a..b2af39f913 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -7,7 +7,7 @@ public interface IRecipeCapabilityHolder { - default boolean hasProxies() { + default boolean hasCapabilityProxies() { return !getCapabilitiesProxy().isEmpty(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java index c418f0f4f3..65067bc3d6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java @@ -7,7 +7,6 @@ import java.util.Comparator; import java.util.List; -import java.util.Set; /** * @author KilaBash @@ -43,14 +42,6 @@ public interface IRecipeHandler extends IFilteredHandler { */ List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, boolean simulate); - /** - * Slot name, it makes sense if recipe contents specify a slot name. - */ - @Nullable - default Set getSlotNames() { - return null; - } - /** * container size, if it has one. otherwise -1. */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index 7fb20b13da..e14e4832eb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.api.item.tool.aoe.AoESymmetrical; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.SizedIngredient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; @@ -423,10 +424,11 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It List.of(new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); be.getMetaMachine().reinitializeCapabilities(caps); - Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine); + Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, + r -> RecipeHandler.matchContents(be.metaMachine, r).isSuccess()); GTRecipe hammerRecipe = hammerRecipes == null || !hammerRecipes.hasNext() ? null : hammerRecipes.next(); - if (hammerRecipe != null && hammerRecipe.handleRecipeIO(IO.IN, be.metaMachine, - be.getMetaMachine().recipeLogic.getChanceCaches())) { + if (hammerRecipe != null && RecipeHandler.handleRecipeIO(IO.IN, be.metaMachine, hammerRecipe, + be.getMetaMachine().recipeLogic.getChanceCaches()).isSuccess()) { drops.clear(); TagPrefix prefix = ChemicalHelper.getPrefix(silktouchDrop.getItem()); if (prefix == null) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java index e7ea66e150..93368ba706 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -47,7 +48,7 @@ default void notifyStatusChanged(RecipeLogic.Status oldStatus, RecipeLogic.Statu RecipeLogic getRecipeLogic(); default GTRecipe fullModifyRecipe(GTRecipe recipe, @NotNull OCParams params, @NotNull OCResult result) { - return doModifyRecipe(recipe.trimRecipeOutputs(this.getOutputLimits()), params, result); + return doModifyRecipe(RecipeHandler.trimRecipeOutputs(recipe, this.getOutputLimits()), params, result); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index 89e82d16e9..fdb87925d8 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -37,9 +37,15 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { @RequireRerender protected final Set controllerPositions; + private final List recipeHandlerTraits; + public MultiblockPartMachine(IMachineBlockEntity holder) { super(holder); this.controllerPositions = new HashSet<>(); + + recipeHandlerTraits = traits.stream().filter(IRecipeHandlerTrait.class::isInstance) + .map(IRecipeHandlerTrait.class::cast) + .toList(); } ////////////////////////////////////// @@ -74,8 +80,7 @@ public List getControllers() { @Override public List getRecipeHandlers() { - return traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) - .toList(); + return recipeHandlerTraits; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index d3d96e9137..b556ff765c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -175,10 +176,6 @@ public double getProgressPercent() { return duration == 0 ? 0.0 : progress / (duration * 1.0); } - public boolean needFuel() { - return machine.getRecipeType().isFuelRecipeType(); - } - /** * it should be called on the server side restrictively. */ @@ -227,14 +224,21 @@ public void serverTick() { } } + protected RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { + var recipeConditions = RecipeHandler.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) + .findFirst(); + return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); + } + public boolean checkMatchedRecipeAvailable(GTRecipe match) { var matchCopy = match.copy(); var modified = machine.fullModifyRecipe(matchCopy, ocParams, ocResult); if (modified != null) { - if (modified.checkConditions(this).isSuccess() && - modified.matchRecipe(machine).isSuccess() && - modified.matchTickRecipe(machine).isSuccess()) { + var recipeMatch = checkRecipe(modified); + if (recipeMatch.isSuccess()) { setupRecipe(modified); + } else { + setWaiting(recipeMatch.getReason()); } if (lastRecipe != null && getStatus() == Status.WORKING) { lastOriginRecipe = match; @@ -248,34 +252,32 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { public void handleRecipeWorking() { Status last = this.status; assert lastRecipe != null; - var result = lastRecipe.checkConditions(this); - if (result.isSuccess()) { - if (handleFuelRecipe()) { - result = handleTickRecipe(lastRecipe); - if (result.isSuccess()) { - setStatus(Status.WORKING); - if (!machine.onWorking()) { - this.interruptRecipe(); - return; - } - progress++; - totalContinuousRunningTime++; - } else { - setWaiting(result.reason().get()); + var conditionResults = RecipeHandler.checkConditions(lastRecipe, this).stream().filter(v -> !v.isSuccess()) + .findFirst(); + RecipeHandler.ActionResult result; + if (conditionResults.isEmpty()) { + result = handleTickRecipe(lastRecipe); + if (result.isSuccess()) { + setStatus(Status.WORKING); + if (!machine.onWorking()) { + this.interruptRecipe(); + return; } + progress++; + totalContinuousRunningTime++; } else { - setWaiting(Component.translatable("gtceu.recipe_logic.insufficient_fuel")); + setWaiting(result.reason().get()); } } else { - setWaiting(result.reason().get()); + setWaiting(conditionResults.get().getReason()); } if (isWaiting()) { doDamping(); } if (last == Status.WORKING && getStatus() != Status.WORKING) { - lastRecipe.postWorking(machine); + RecipeHandler.postWorking(machine, lastRecipe); } else if (last != Status.WORKING && getStatus() == Status.WORKING) { - lastRecipe.preWorking(machine); + RecipeHandler.preWorking(machine, lastRecipe); } } @@ -290,16 +292,14 @@ protected void doDamping() { } public Iterator searchRecipe() { - return machine.getRecipeType().searchRecipe(this.machine); + return machine.getRecipeType().searchRecipe(this.machine, + r -> RecipeHandler.matchContents(this.machine, r).isSuccess()); } public void findAndHandleRecipe() { lastFailedMatches = null; // try to execute last recipe if possible - if (!recipeDirty && lastRecipe != null && - lastRecipe.matchRecipe(this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { + if (!recipeDirty && lastRecipe != null && checkRecipe(lastRecipe).isSuccess()) { GTRecipe recipe = lastRecipe; lastRecipe = null; lastOriginRecipe = null; @@ -329,26 +329,9 @@ protected void handleSearchingRecipes(Iterator matches) { } } - public boolean handleFuelRecipe() { - if (!needFuel() || fuelTime > 0) return true; - Iterator iterator = machine.getRecipeType().searchFuelRecipe(machine); - - while (iterator != null && iterator.hasNext()) { - GTRecipe recipe = iterator.next(); - if (recipe == null) continue; - - if (recipe.checkConditions(this).isSuccess() && handleRecipeIO(recipe, IO.IN)) { - fuelMaxTime = recipe.duration; - fuelTime = fuelMaxTime; - } - if (fuelTime > 0) return true; - } - return false; - } - - public GTRecipe.ActionResult handleTickRecipe(GTRecipe recipe) { + public RecipeHandler.ActionResult handleTickRecipe(GTRecipe recipe) { if (recipe.hasTick()) { - var result = recipe.matchTickRecipe(this.machine); + var result = RecipeHandler.matchTickRecipe(this.machine, recipe); if (result.isSuccess()) { handleTickRecipeIO(recipe, IO.IN); handleTickRecipeIO(recipe, IO.OUT); @@ -356,31 +339,32 @@ public GTRecipe.ActionResult handleTickRecipe(GTRecipe recipe) { return result; } } - return GTRecipe.ActionResult.SUCCESS; + return RecipeHandler.ActionResult.SUCCESS; } public void setupRecipe(GTRecipe recipe) { - if (handleFuelRecipe()) { - if (!machine.beforeWorking(recipe)) { - setStatus(Status.IDLE); - progress = 0; - duration = 0; - isActive = false; - return; + if (!machine.beforeWorking(recipe)) { + setStatus(Status.IDLE); + progress = 0; + duration = 0; + isActive = false; + return; + } + RecipeHandler.preWorking(this.machine, recipe); + var handledIO = handleRecipeIO(recipe, IO.IN); + if (handledIO.isSuccess()) { + if (lastRecipe != null && !recipe.equals(lastRecipe)) { + chanceCaches.clear(); } - recipe.preWorking(this.machine); - if (handleRecipeIO(recipe, IO.IN)) { - if (lastRecipe != null && !recipe.equals(lastRecipe)) { - chanceCaches.clear(); - } - recipeDirty = false; - lastRecipe = recipe; - setStatus(Status.WORKING); - progress = 0; - duration = recipe.duration; - isActive = true; - } + recipeDirty = false; + lastRecipe = recipe; + setStatus(Status.WORKING); + progress = 0; + duration = recipe.duration; + isActive = true; + } else { + setWaiting(handledIO.getReason()); } } @@ -462,7 +446,7 @@ public boolean isHasNotEnoughEnergy() { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - lastRecipe.postWorking(this.machine); + RecipeHandler.postWorking(this.machine, lastRecipe); handleRecipeIO(lastRecipe, IO.OUT); if (machine.alwaysTryModifyRecipe()) { if (lastOriginRecipe != null) { @@ -477,10 +461,8 @@ public void onRecipeFinish() { } } // try it again - if (!recipeDirty && !suspendAfterFinish && - lastRecipe.matchRecipe(this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { + var recipeMatch = checkRecipe(lastRecipe); + if (!recipeDirty && !suspendAfterFinish && recipeMatch.isSuccess()) { setupRecipe(lastRecipe); } else { if (suspendAfterFinish) { @@ -496,12 +478,12 @@ public void onRecipeFinish() { } } - protected boolean handleRecipeIO(GTRecipe recipe, IO io) { - return recipe.handleRecipeIO(io, this.machine, this.chanceCaches); + protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + return RecipeHandler.handleRecipeIO(io, this.machine, recipe, this.chanceCaches); } - protected boolean handleTickRecipeIO(GTRecipe recipe, IO io) { - return recipe.handleTickRecipeIO(io, this.machine, this.chanceCaches); + protected RecipeHandler.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + return RecipeHandler.handleTickRecipeIO(io, this.machine, recipe, this.chanceCaches); } /** @@ -510,7 +492,7 @@ protected boolean handleTickRecipeIO(GTRecipe recipe, IO io) { public void interruptRecipe() { machine.afterWorking(); if (lastRecipe != null) { - lastRecipe.postWorking(this.machine); + RecipeHandler.postWorking(this.machine, lastRecipe); setStatus(Status.IDLE); progress = 0; duration = 0; @@ -520,7 +502,7 @@ public void interruptRecipe() { public void inValid() { if (lastRecipe != null && isWorking()) { - lastRecipe.postWorking(machine); + RecipeHandler.postWorking(this.machine, lastRecipe); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index b8f96e9807..27a469dfb2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -1,33 +1,26 @@ package com.gregtechceu.gtceu.api.recipe; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; -import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.level.Level; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.Supplier; import javax.annotation.ParametersAreNonnullByDefault; @@ -200,10 +193,6 @@ public ItemStack getResultItem(RegistryAccess registryManager) { return ItemStack.EMPTY; } - /////////////////////////////////////////////////////////////// - // **********************internal logic********************* // - /////////////////////////////////////////////////////////////// - public List getInputContents(RecipeCapability capability) { return inputs.getOrDefault(capability, Collections.emptyList()); } @@ -220,241 +209,13 @@ public List getTickOutputContents(RecipeCapability capability) { return tickOutputs.getOrDefault(capability, Collections.emptyList()); } - public ActionResult matchRecipe(IRecipeCapabilityHolder holder) { - return matchRecipe(holder, false); - } - - public ActionResult matchTickRecipe(IRecipeCapabilityHolder holder) { - return hasTick() ? matchRecipe(holder, true) : ActionResult.SUCCESS; - } - - private ActionResult matchRecipe(IRecipeCapabilityHolder holder, boolean tick) { - if (!holder.hasProxies()) return ActionResult.FAIL_NO_REASON; - - var result = matchRecipeContents(IO.IN, holder, tick ? tickInputs : inputs, tick); - if (!result.isSuccess()) return result; - - result = matchRecipeContents(IO.OUT, holder, tick ? tickOutputs : outputs, tick); - if (!result.isSuccess()) return result; - - return ActionResult.SUCCESS; - } - - public ActionResult matchRecipeContents(IO io, IRecipeCapabilityHolder holder, - Map, List> contents, - boolean isTick) { - RecipeRunner runner = new RecipeRunner(this, io, isTick, holder, Collections.emptyMap(), true); - for (Map.Entry, List> entry : contents.entrySet()) { - var result = runner.handle(entry); - if (result == null) - continue; - - if (result.result().content != null || !result.result().slots.isEmpty()) { - if (io == IO.IN) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_in") - .append(": ").append(result.capability().getName()), 0f); - } else if (io == IO.OUT) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") - .append(": ").append(result.capability().getName()), 0f); - } else { - return ActionResult.FAIL_NO_REASON; - } - } - } - return ActionResult.SUCCESS; - } - - public boolean handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, - Map, Object2IntMap> chanceCaches) { - if (!holder.hasProxies() || io == IO.BOTH) return false; - return handleRecipe(io, holder, true, io == IO.IN ? tickInputs : tickOutputs, chanceCaches); - } - - public boolean handleRecipeIO(IO io, IRecipeCapabilityHolder holder, - Map, Object2IntMap> chanceCaches) { - if (!holder.hasProxies() || io == IO.BOTH) return false; - return handleRecipe(io, holder, false, io == IO.IN ? inputs : outputs, chanceCaches); - } - - public boolean handleRecipe(IO io, IRecipeCapabilityHolder holder, boolean isTick, - Map, List> contents, - Map, Object2IntMap> chanceCaches) { - RecipeRunner runner = new RecipeRunner(this, io, isTick, holder, chanceCaches, false); - for (Map.Entry, List> entry : contents.entrySet()) { - var handled = runner.handle(entry); - if (handled == null) - continue; - - if (handled.result().content != null || !handled.result().slots.isEmpty()) { - GTCEu.LOGGER.warn("io error while handling a recipe {} outputs. holder: {}", id, holder); - return false; - } - } - return true; - } - public boolean hasTick() { return !tickInputs.isEmpty() || !tickOutputs.isEmpty(); } - public void preWorking(IRecipeCapabilityHolder holder) { - handlePre(inputs, holder, IO.IN); - handlePre(outputs, holder, IO.OUT); - } - - public void postWorking(IRecipeCapabilityHolder holder) { - handlePost(inputs, holder, IO.IN); - handlePost(outputs, holder, IO.OUT); - } - - public void handlePre(Map, List> contents, IRecipeCapabilityHolder holder, IO io) { - contents.forEach(((capability, tuples) -> { - if (holder.getCapabilitiesProxy().contains(io, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { - capabilityProxy.preWorking(holder, io, this); - } - } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { - capabilityProxy.preWorking(holder, io, this); - } - } - })); - } - - public void handlePost(Map, List> contents, IRecipeCapabilityHolder holder, IO io) { - contents.forEach(((capability, tuples) -> { - if (holder.getCapabilitiesProxy().contains(io, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { - capabilityProxy.postWorking(holder, io, this); - } - } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { - capabilityProxy.postWorking(holder, io, this); - } - } - })); - } - - public ActionResult checkConditions(@NotNull RecipeLogic recipeLogic) { - if (conditions.isEmpty()) return ActionResult.SUCCESS; - Map, List> or = new HashMap<>(); - for (RecipeCondition condition : conditions) { - if (condition.isOr()) { - or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); - } else if (condition.test(this, recipeLogic) == condition.isReverse()) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails").append(": ") - .append(condition.getTooltips())); - } - } - for (List conditions : or.values()) { - if (conditions.stream().allMatch(condition -> condition.test(this, recipeLogic) == condition.isReverse())) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails")); - } - } - return ActionResult.SUCCESS; - } - - /** - * Trims the recipe outputs, chanced outputs, and fluid outputs based on the performing Machine's trim limit. - */ - public GTRecipe trimRecipeOutputs(Map, Integer> trimLimits) { - // Fast return early if no trimming desired - if (trimLimits.isEmpty() || trimLimits.values().stream().allMatch(integer -> integer == -1)) { - return this; - } - - GTRecipe current = this.copy(); - - GTRecipeBuilder builder = new GTRecipeBuilder(current, this.recipeType); - - builder.output.clear(); - builder.tickOutput.clear(); - - Map, List> recipeOutputs = doTrim(current.outputs, trimLimits); - Map, List> recipeTickOutputs = doTrim(current.tickOutputs, trimLimits); - - builder.output.putAll(recipeOutputs); - builder.tickOutput.putAll(recipeTickOutputs); - - return builder.buildRawRecipe(); - } - - /** - * Returns the maximum possible recipe outputs from a recipe, divided into regular and chanced outputs - * Takes into account any specific output limiters, ie macerator slots, to trim down the output list - * Trims from chanced outputs first, then regular outputs - * - * @param trimLimits The limit(s) on the number of outputs, -1 for disabled. - * @return All recipe outputs, limited by some factor(s) - */ - public Map, List> doTrim(Map, List> current, - Map, Integer> trimLimits) { - Map, List> outputs = new HashMap<>(); - - Set> trimmed = new HashSet<>(); - for (Map.Entry, Integer> entry : trimLimits.entrySet()) { - RecipeCapability key = entry.getKey(); - - if (!current.containsKey(key)) continue; - List nonChanced = new ArrayList<>(); - List chanced = new ArrayList<>(); - for (Content content : current.getOrDefault(key, List.of())) { - if (content.chance <= 0 || content.chance >= content.maxChance) nonChanced.add(content); - else chanced.add(content); - } - - int outputLimit = entry.getValue(); - if (outputLimit == -1) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()).addAll(nonChanced); - } - // If just the regular outputs would satisfy the outputLimit - else if (nonChanced.size() >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream() - .map(cont -> cont.copy(key, null)) - .toList() - .subList(0, outputLimit)); - - chanced.clear(); - } - // If the regular outputs and chanced outputs are required to satisfy the outputLimit - else if (!nonChanced.isEmpty() && (nonChanced.size() + chanced.size()) >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - - // Calculate the number of chanced outputs after adding all the regular outputs - int numChanced = outputLimit - nonChanced.size(); - - chanced = chanced.subList(0, Math.min(numChanced, chanced.size())); - } - // There are only chanced outputs to satisfy the outputLimit - else if (nonChanced.isEmpty()) { - chanced = chanced.subList(0, Math.min(outputLimit, chanced.size())); - } - // The number of outputs + chanced outputs is lower than the trim number, so just add everything - else { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - // Chanced outputs are taken care of in the original copy - } - - if (!chanced.isEmpty()) - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(chanced.stream().map(cont -> cont.copy(key, null)).toList()); - - trimmed.add(key); - } - for (Map.Entry, List> entry : current.entrySet()) { - if (trimmed.contains(entry.getKey())) continue; - outputs.computeIfAbsent(entry.getKey(), $ -> new ArrayList<>()).addAll(entry.getValue()); - } - - return outputs; - } - /** * Get the chance logic for a recipe capability + io + tick io combination - * + * * @param cap the recipe capability to get the chance logic for * @param io the {@link IO} of the chanche per-tick logic or the normal one * @return the chance logic for the aforementioned combination. Defaults to {@link ChanceLogic#OR}. @@ -476,54 +237,6 @@ public ChanceLogic getChanceLogicForCapability(RecipeCapability cap, IO io, b return ChanceLogic.OR; } - /** - * - * @param isSuccess is action success - * @param reason if fail, fail reason - * @param expectingRate if recipe matching fail, the expecting rate of one cap. - *
- * For example, recipe require 300eu and 10 apples, and left 100eu and 5 apples after recipe - * searching. - *
- * EU Missing Rate : 300 / (300 - 100) = 1.5 - *
- * Item Missing Rate : 10 / (10 - 5) = 2 - *
- * return max expecting rate --- 2 - */ - public static record ActionResult(boolean isSuccess, @Nullable Supplier reason, float expectingRate) { - - public final static ActionResult SUCCESS = new ActionResult(true, null, 0); - public final static ActionResult FAIL_NO_REASON = new ActionResult(true, null, 0); - - public static ActionResult fail(@Nullable Supplier component) { - return new ActionResult(false, component, 0); - } - - public static ActionResult fail(@Nullable Supplier component, float expectingRate) { - return new ActionResult(false, component, expectingRate); - } - } - - public boolean checkRecipeValid() { - return checkItemValid(inputs, "input") && checkItemValid(outputs, "output") && - checkItemValid(tickInputs, "tickInput") && checkItemValid(tickOutputs, "tickOutput"); - } - - private boolean checkItemValid(Map, List> contents, String name) { - for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { - var items = ItemRecipeCapability.CAP.of(content.content).getItems(); - if (items.length == 0) { - GTCEu.LOGGER.error("recipe {} {} item length is 0", id, name); - return false; - } else if (Arrays.stream(items).anyMatch(ItemStack::isEmpty)) { - GTCEu.LOGGER.error("recipe {} {} item is empty", id, name); - return false; - } - } - return true; - } - // Just check id as there *should* only ever be 1 instance of a recipe with this id. // If this doesn't work, fix. @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java index a07a2a6983..a361ec3498 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java @@ -40,10 +40,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; +import java.util.function.*; /** * @author KilaBash @@ -80,9 +77,6 @@ public class GTRecipeType implements RecipeType { protected SoundEntry sound; @Getter protected List> dataInfos = new ArrayList<>(); - @Setter - @Getter - protected boolean isFuelRecipeType; @Getter @Setter protected boolean isScanner; @@ -214,17 +208,9 @@ public GTRecipe getRecipe(RecipeManager recipeManager, ResourceLocation id) { return null; } - @Nullable - public Iterator searchFuelRecipe(IRecipeCapabilityHolder holder) { - if (!holder.hasProxies() || !isFuelRecipeType()) return null; - return getLookup().getRecipeIterator(holder, recipe -> recipe.isFuel && - recipe.matchRecipe(holder).isSuccess() && recipe.matchTickRecipe(holder).isSuccess()); - } - - public Iterator searchRecipe(IRecipeCapabilityHolder holder) { - if (!holder.hasProxies()) return null; - var iterator = getLookup().getRecipeIterator(holder, recipe -> !recipe.isFuel && - recipe.matchRecipe(holder).isSuccess() && recipe.matchTickRecipe(holder).isSuccess()); + public Iterator searchRecipe(IRecipeCapabilityHolder holder, Predicate canHandle) { + if (!holder.hasCapabilityProxies()) return null; + var iterator = getLookup().getRecipeIterator(holder, canHandle); boolean any = false; while (iterator.hasNext()) { GTRecipe recipe = iterator.next(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java new file mode 100644 index 0000000000..78d646d8bf --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java @@ -0,0 +1,349 @@ +package com.gregtechceu.gtceu.api.recipe; + +import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; +import com.gregtechceu.gtceu.api.recipe.content.Content; +import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.Supplier; + +public class RecipeHandler { + + /////////////////////////////////////////////////////////////// + // **********************internal logic********************* // + /////////////////////////////////////////////////////////////// + + public static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { + return matchRecipe(holder, recipe, false); + } + + public static ActionResult matchTickRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { + return recipe.hasTick() ? matchRecipe(holder, recipe, true) : ActionResult.SUCCESS; + } + + private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, boolean tick) { + if (!holder.hasCapabilityProxies()) + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + + var result = handleRecipe(IO.IN, holder, recipe, tick ? recipe.tickInputs : recipe.inputs, + Collections.emptyMap(), tick, true); + if (!result.isSuccess()) return result; + + result = handleRecipe(IO.OUT, holder, recipe, tick ? recipe.tickOutputs : recipe.outputs, + Collections.emptyMap(), tick, true); + return result; + } + + public static ActionResult handleRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, Object2IntMap> chanceCaches) { + if (!holder.hasCapabilityProxies() || io == IO.BOTH) + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_capability_proxies")); + return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, + false); + } + + public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, Object2IntMap> chanceCaches) { + if (!holder.hasCapabilityProxies() || io == IO.BOTH) + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_tick_capability_proxies")); + return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, + true, false); + } + + /** + * Checks if all the contents of the recipe are located in the holder. + * + * @param isTick + * @param simulated checks that the recipe ingredients are in the holder if true, + * process the recipe contents if false + */ + public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, List> contents, + Map, Object2IntMap> chanceCaches, + boolean isTick, boolean simulated) { + RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); + for (Map.Entry, List> entry : contents.entrySet()) { + var handle = runner.handle(entry); + if (handle == null) + continue; + + if (handle.content() != null) { + String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); + return ActionResult.fail(() -> Component.translatable(key) + .append(": ").append(handle.capability().getName())); + } + return handle.result(); + } + return ActionResult.SUCCESS; + + /* + * RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, false); + * for (Map.Entry, List> entry : contents.entrySet()) { + * var handled = runner.handle(entry); + * if (handled == null) + * continue; + * + * if (handled.content() != null) { + * GTCEu.LOGGER.warn("io error while handling a recipe {} outputs. holder: {}", recipe.id, holder); + * return false; + * } + * } + * return true; + */ + } + + public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { + var match = matchRecipe(holder, recipe); + if (!match.isSuccess) + return match; + return matchTickRecipe(holder, recipe); + } + + public static void preWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { + handlePre(holder, recipe, IO.IN); + handlePre(holder, recipe, IO.OUT); + } + + public static void postWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { + handlePost(holder, recipe, IO.IN); + handlePost(holder, recipe, IO.OUT); + } + + public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { + (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + if (holder.getCapabilitiesProxy().contains(io, capability)) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { + capabilityProxy.preWorking(holder, io, recipe); + } + } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { + capabilityProxy.preWorking(holder, io, recipe); + } + } + })); + } + + public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { + (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + if (holder.getCapabilitiesProxy().contains(io, capability)) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { + capabilityProxy.postWorking(holder, io, recipe); + } + } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { + capabilityProxy.postWorking(holder, io, recipe); + } + } + })); + } + + /** + * Check whether all conditions of a recipe are valid + * + * @param recipe the recipe to test + * @param recipeLogic the logic to test against the conditions + * @return the list of failed conditions, or success if all conditions are satisfied + */ + public static List checkConditions(GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + if (recipe.conditions.isEmpty()) return List.of(ActionResult.SUCCESS); + Map, List> or = new HashMap<>(); + List failures = new ArrayList<>(); + for (RecipeCondition condition : recipe.conditions) { + if (condition.isOr()) { + or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); + } else if (condition.test(recipe, recipeLogic) == condition.isReverse()) { + failures.add(ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails").append(": ") + .append(condition.getTooltips()))); + } + } + + for (List conditions : or.values()) { + if (conditions.stream() + .allMatch(condition -> condition.test(recipe, recipeLogic) == condition.isReverse())) { + failures.add(ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails"))); + } + } + if (!failures.isEmpty()) + return failures; + return List.of(ActionResult.SUCCESS); + } + + /** + * Trims the recipe outputs and tick outputs based on the performing Machine's trim limit. + */ + public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Map, Integer> trimLimits) { + // Fast return early if no trimming desired + if (trimLimits.isEmpty() || trimLimits.values().stream().allMatch(integer -> integer == -1)) { + return recipe; + } + + GTRecipe current = recipe.copy(); + + GTRecipeBuilder builder = new GTRecipeBuilder(current, recipe.recipeType); + + builder.output.clear(); + builder.tickOutput.clear(); + + Map, List> recipeOutputs = doTrim(current.outputs, trimLimits); + Map, List> recipeTickOutputs = doTrim(current.tickOutputs, trimLimits); + + builder.output.putAll(recipeOutputs); + builder.tickOutput.putAll(recipeTickOutputs); + + return builder.buildRawRecipe(); + } + + /** + * Returns the maximum possible recipe outputs from a recipe, divided into regular and chanced outputs + * Takes into account any specific output limiters, ie macerator slots, to trim down the output list + * Trims from chanced outputs first, then regular outputs + * + * @param trimLimits The limit(s) on the number of outputs, -1 for disabled. + * @return All recipe outputs, limited by some factor(s) + */ + public static Map, List> doTrim(Map, List> current, + Map, Integer> trimLimits) { + Map, List> outputs = new HashMap<>(); + + Set> trimmed = new HashSet<>(); + for (Map.Entry, Integer> entry : trimLimits.entrySet()) { + RecipeCapability key = entry.getKey(); + + if (!current.containsKey(key)) continue; + List nonChanced = new ArrayList<>(); + List chanced = new ArrayList<>(); + for (Content content : current.getOrDefault(key, List.of())) { + if (content.chance <= 0 || content.chance >= content.maxChance) nonChanced.add(content); + else chanced.add(content); + } + + int outputLimit = entry.getValue(); + if (outputLimit == -1) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()).addAll(nonChanced); + } + // If just the regular outputs would satisfy the outputLimit + else if (nonChanced.size() >= outputLimit) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream() + .map(cont -> cont.copy(key, null)) + .toList() + .subList(0, outputLimit)); + + chanced.clear(); + } + // If the regular outputs and chanced outputs are required to satisfy the outputLimit + else if (!nonChanced.isEmpty() && (nonChanced.size() + chanced.size()) >= outputLimit) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); + + // Calculate the number of chanced outputs after adding all the regular outputs + int numChanced = outputLimit - nonChanced.size(); + + chanced = chanced.subList(0, Math.min(numChanced, chanced.size())); + } + // There are only chanced outputs to satisfy the outputLimit + else if (nonChanced.isEmpty()) { + chanced = chanced.subList(0, Math.min(outputLimit, chanced.size())); + } + // The number of outputs + chanced outputs is lower than the trim number, so just add everything + else { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); + // Chanced outputs are taken care of in the original copy + } + + if (!chanced.isEmpty()) + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(chanced.stream().map(cont -> cont.copy(key, null)).toList()); + + trimmed.add(key); + } + for (Map.Entry, List> entry : current.entrySet()) { + if (trimmed.contains(entry.getKey())) continue; + outputs.computeIfAbsent(entry.getKey(), $ -> new ArrayList<>()).addAll(entry.getValue()); + } + + return outputs; + } + + public static List checkRecipeValidity(GTRecipe recipe) { + List results = new ArrayList<>(); + var result = checkItemValid(recipe.inputs, "input"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.outputs, "output"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.tickInputs, "tickInput"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.outputs, "tickOutput"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + if (!results.isEmpty()) + return results; + return List.of(ActionResult.SUCCESS); + } + + private static ActionResult checkItemValid(Map, List> contents, String name) { + for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { + var items = ItemRecipeCapability.CAP.of(content.content).getItems(); + if (items.length == 0) { + return ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + } else if (Arrays.stream(items).anyMatch(ItemStack::isEmpty)) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + } + } + return ActionResult.SUCCESS; + } + + private static ActionResult checkFluidValid(Map, List> contents, String name) { + for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { + var fluids = FluidRecipeCapability.CAP.of(content.content).getStacks(); + if (fluids.length == 0) { + return ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + } else if (Arrays.stream(fluids).anyMatch(FluidStack::isEmpty)) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + } + } + return ActionResult.SUCCESS; + } + + /** + * @param isSuccess is action success + * @param reason if fail, fail reason + */ + public record ActionResult(boolean isSuccess, @Nullable Supplier reason) { + + public final static ActionResult SUCCESS = new ActionResult(true, null); + public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); + + public static ActionResult fail(@Nullable Supplier component) { + return new ActionResult(false, component); + } + + public Component getReason() { + if (reason() == null) { + return Component.empty(); + } + return reason().get(); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index f30f06f875..30664fc536 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -10,7 +10,7 @@ import com.google.common.collect.Table; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import org.jetbrains.annotations.NotNull; +import lombok.Getter; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; @@ -22,13 +22,8 @@ @SuppressWarnings({ "rawtypes", "unchecked" }) class RecipeRunner { - static class ContentSlots { - - public @UnknownNullability List content = new ArrayList<>(); - public @NotNull Map slots = new HashMap<>(); - } - - record RecipeHandlingResult(RecipeCapability capability, ContentSlots result) {} + record RecipeHandlingResult(RecipeCapability capability, @UnknownNullability List content, + RecipeHandler.ActionResult result) {} // -------------------------------------------------------------------------------------------------------- @@ -43,8 +38,9 @@ record RecipeHandlingResult(RecipeCapability capability, ContentSlots result) // These are only used to store mutable state during each invocation of handle() private RecipeCapability capability; private Set> used; - private ContentSlots content; - private ContentSlots search; + @Getter + private @UnknownNullability List content; + private @UnknownNullability List search; public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -72,13 +68,13 @@ public RecipeHandlingResult handle(Map.Entry, List> if (result == null) return null; - return new RecipeHandlingResult(capability, result); + return new RecipeHandlingResult(capability, result, RecipeHandler.ActionResult.SUCCESS); } private void initState() { used = new HashSet<>(); - content = new ContentSlots(); - search = simulated ? content : new ContentSlots(); + content = new ArrayList<>(); + search = simulated ? content : new ArrayList<>(); } private void fillContent(IRecipeCapabilityHolder holder, Map.Entry, List> entry) { @@ -88,21 +84,13 @@ private void fillContent(IRecipeCapabilityHolder holder, Map.Entry chancedContents = new ArrayList<>(); for (Content cont : entry.getValue()) { // For simulated handling, search/content are the same instance, so there's no need to switch between them - if (cont.slotName == null) { - this.search.content.add(cont.content); - } else { - this.search.slots.computeIfAbsent(cont.slotName, s -> new ArrayList<>()).add(cont.content); - } + this.search.add(cont.content); // When simulating the recipe handling (used for recipe matching), chanced contents are ignored. if (simulated) continue; if (cont.chance >= cont.maxChance) { - if (cont.slotName == null) { - this.content.content.add(cont.content); - } else { - this.content.slots.computeIfAbsent(cont.slotName, s -> new ArrayList<>()).add(cont.content); - } + this.content.add(cont.content); } else { chancedContents.add(cont); } @@ -116,11 +104,7 @@ private void fillContent(IRecipeCapabilityHolder holder, Map.Entry new ArrayList<>()).add(cont.content); - } + this.content.add(cont.content); } } } @@ -131,17 +115,19 @@ private RecipeCapability resolveCapability(Map.Entry, Lis return null; } - content.content = this.content.content.stream().map(capability::copyContent).toList(); - if (this.content.content.isEmpty() && this.content.slots.isEmpty()) return null; - if (this.content.content.isEmpty()) content.content = null; + content = this.content.stream().map(capability::copyContent).toList(); + if (this.content.isEmpty()) { + content = null; + return null; + } return capability; } @Nullable - private ContentSlots handleContents() { + private List handleContents() { handleContentsInternal(io); - if (content.content == null && content.slots.isEmpty()) return null; + if (content == null) return null; handleContentsInternal(IO.BOTH); return content; @@ -158,57 +144,26 @@ private void handleContentsInternal(IO capIO) { // handle distinct first for (IRecipeHandler handler : handlers) { if (!handler.isDistinct()) continue; - var result = handler.handleRecipe(io, recipe, search.content, null, true); + var result = handler.handleRecipe(io, recipe, search, null, true); if (result == null) { - // check distint slot handler - if (handler.getSlotNames() != null && handler.getSlotNames().containsAll(search.slots.keySet())) { - boolean success = true; - for (var entry : search.slots.entrySet()) { - List left = handler.handleRecipe(io, recipe, entry.getValue(), entry.getKey(), true); - if (left != null) { - success = false; - break; - } - } - if (success) { - if (!simulated) { - for (var entry : content.slots.entrySet()) { - handler.handleRecipe(io, recipe, entry.getValue(), entry.getKey(), false); - } - } - content.slots.clear(); - } - } - if (content.slots.isEmpty()) { - if (!simulated) { - handler.handleRecipe(io, recipe, content.content, null, false); - } - content.content = null; + if (!simulated) { + handler.handleRecipe(io, recipe, content, null, false); } + content = null; } - if (content.content == null && content.slots.isEmpty()) { + if (content == null) { break; } } - if (content.content != null || !content.slots.isEmpty()) { + if (content != null) { // handle undistinct later for (IRecipeHandler proxy : handlers) { if (used.contains(proxy) || proxy.isDistinct()) continue; used.add(proxy); - if (content.content != null) { - content.content = proxy.handleRecipe(io, recipe, content.content, null, simulated); - } - if (proxy.getSlotNames() != null) { - Iterator iterator = content.slots.keySet().iterator(); - while (iterator.hasNext()) { - String key = iterator.next(); - if (proxy.getSlotNames().contains(key)) { - List left = proxy.handleRecipe(io, recipe, content.slots.get(key), key, simulated); - if (left == null) iterator.remove(); - } - } + if (content != null) { + content = proxy.handleRecipe(io, recipe, content, null, simulated); } - if (content.content == null && content.slots.isEmpty()) break; + if (content == null) break; } } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 626acd6ba1..06bafe7974 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; @@ -45,7 +46,7 @@ public class GTRecipeLookup { */ @Nullable public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { - return find(holder, recipe -> recipe.matchRecipe(holder).isSuccess()); + return find(holder, recipe -> RecipeHandler.matchRecipe(holder, recipe).isSuccess()); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java index 13d213bd4c..c1ca75abfe 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java +++ b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.ores.OrePlacer; import com.gregtechceu.gtceu.api.gui.factory.GTUIEditorFactory; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.registry.GTRegistry; import com.gregtechceu.gtceu.common.commands.arguments.GTRegistryArgument; @@ -65,11 +66,15 @@ public static void register(CommandDispatcher dispatcher, Co .executes(context -> { for (Recipe recipe : context.getSource().getServer().getRecipeManager() .getRecipes()) { - if (recipe instanceof GTRecipe gtRecipe && !gtRecipe.checkRecipeValid()) { - context.getSource().sendSuccess( - () -> Component - .literal("recipe %s is invalid".formatted(gtRecipe.id)), - false); + if (recipe instanceof GTRecipe gtRecipe) { + var recipeValid = RecipeHandler.checkRecipeValidity(gtRecipe).stream() + .filter(v -> !v.isSuccess()).findAny(); + if (recipeValid.isPresent()) { + context.getSource().sendSuccess( + () -> Component + .literal("Recipe %s is invalid".formatted(gtRecipe.id)), + false); + } } } return 1; diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java index 00274822ea..e1fbcd3069 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.OverclockingLogic; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; @@ -130,7 +131,7 @@ public static Pair fastParallel(MetaMachine machine, @NotNull if (machine instanceof IRecipeCapabilityHolder holder) { while (maxParallel > 0) { var copied = recipe.copy(ContentModifier.multiplier(maxParallel), modifyDuration); - if (copied.matchRecipe(holder).isSuccess() && copied.matchTickRecipe(holder).isSuccess()) { + if (RecipeHandler.matchContents(holder, copied).isSuccess()) { return Pair.of(copied, maxParallel); } maxParallel /= 2; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 2af5038cb0..b344406e38 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.modifier.ParallelLogic; @@ -173,128 +173,26 @@ public DistillationTowerMachine getMachine() { } @Override - @Nullable - public Iterator searchRecipe() { - var recipeType = machine.getRecipeType(); - if (recipeType == GTRecipeTypes.DISTILLERY_RECIPES) return super.searchRecipe(); - - // Do recipe searching ourselves so we can match the outputs how we want - IRecipeCapabilityHolder holder = this.machine; - if (!holder.hasProxies()) return null; - var iterator = recipeType.getLookup().getRecipeIterator(holder, recipe -> !recipe.isFuel && - this.matchDTRecipe(recipe, holder).isSuccess() && recipe.matchTickRecipe(holder).isSuccess()); - - boolean any = false; - while (iterator.hasNext()) { - GTRecipe recipe = iterator.next(); - if (recipe == null) continue; - any = true; - break; - } - - if (any) { - iterator.reset(); - return iterator; - } - - for (GTRecipeType.ICustomRecipeLogic logic : recipeType.getCustomRecipeLogicRunners()) { - GTRecipe recipe = logic.createCustomRecipe(holder); - if (recipe != null) return Collections.singleton(recipe).iterator(); - } - return Collections.emptyIterator(); - } - - @Override - public void findAndHandleRecipe() { - lastFailedMatches = null; - if (!recipeDirty && lastRecipe != null && - matchDTRecipe(lastRecipe, this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { - var recipe = lastRecipe; - lastRecipe = null; - lastOriginRecipe = null; - setupRecipe(recipe); - } else { - workingRecipe = null; - lastRecipe = null; - lastOriginRecipe = null; - handleSearchingRecipes(searchRecipe()); - } - } - - @Override - public boolean checkMatchedRecipeAvailable(GTRecipe match) { - var matchCopy = match.copy(); - var modified = machine.fullModifyRecipe(matchCopy, ocParams, ocResult); - if (modified != null) { - if (modified.checkConditions(this).isSuccess() && - matchDTRecipe(modified, machine).isSuccess() && - modified.matchTickRecipe(machine).isSuccess()) { - setupRecipe(modified); - } - if (lastRecipe != null && getStatus() == Status.WORKING) { - lastOriginRecipe = match; - lastFailedMatches = null; - return true; - } - } - return false; - } - - @Override - public void onRecipeFinish() { - machine.afterWorking(); - if (lastRecipe != null) { - lastRecipe.postWorking(machine); - handleRecipeIO(lastRecipe, IO.OUT); - if (machine.alwaysTryModifyRecipe()) { - if (lastOriginRecipe != null) { - var modified = machine.fullModifyRecipe(lastOriginRecipe.copy(), ocParams, ocResult); - if (modified == null) markLastRecipeDirty(); - else lastRecipe = modified; - } else { - markLastRecipeDirty(); - } - } - - if (!recipeDirty && !suspendAfterFinish && - matchDTRecipe(lastRecipe, this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { - setupRecipe(lastRecipe); - } else { - if (suspendAfterFinish) { - setStatus(Status.SUSPEND); - suspendAfterFinish = false; - } else { - setStatus(Status.IDLE); - } - progress = 0; - duration = 0; - isActive = false; - } - } - } - - private GTRecipe.ActionResult matchDTRecipe(GTRecipe recipe, IRecipeCapabilityHolder holder) { - var result = recipe.matchRecipeContents(IO.IN, holder, recipe.inputs, false); + public RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { + var result = RecipeHandler.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), + false, true); if (!result.isSuccess()) return result; var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - result = recipe.matchRecipeContents(IO.OUT, holder, out, false); + result = RecipeHandler.handleRecipe(IO.OUT, machine, recipe, out, Collections.emptyMap(), false, true); if (!result.isSuccess()) return result; } if (!applyFluidOutputs(recipe, FluidAction.SIMULATE)) { - return GTRecipe.ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") - .append(": ") - .append(FluidRecipeCapability.CAP.getName())); + return RecipeHandler.ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + .append(": ") + .append(FluidRecipeCapability.CAP.getName())); } - return GTRecipe.ActionResult.SUCCESS; + return RecipeHandler.ActionResult.SUCCESS; } private void updateWorkingRecipe(GTRecipe recipe) { @@ -314,21 +212,27 @@ private void updateWorkingRecipe(GTRecipe recipe) { } @Override - protected boolean handleRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { - if (super.handleRecipeIO(recipe, io)) { + var handleIO = super.handleRecipeIO(recipe, io); + if (handleIO.isSuccess()) { updateWorkingRecipe(recipe); - return true; + } else { + this.workingRecipe = null; } - this.workingRecipe = null; - return false; + return handleIO; } var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - recipe.handleRecipe(io, this.machine, false, out, chanceCaches); + RecipeHandler.handleRecipe(io, this.machine, recipe, out, chanceCaches, false, false); + } + if (applyFluidOutputs(recipe, FluidAction.EXECUTE)) { + return RecipeHandler.ActionResult.SUCCESS; } - return applyFluidOutputs(recipe, FluidAction.EXECUTE); + return RecipeHandler.ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + .append(": ") + .append(FluidRecipeCapability.CAP.getName())); } private boolean applyFluidOutputs(GTRecipe recipe, FluidAction action) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index c1e9329964..54ccc62782 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -16,6 +16,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.network.chat.Component; @@ -136,14 +137,16 @@ public ResearchStationMachine getMachine() { @Override public Iterator searchRecipe() { IRecipeCapabilityHolder holder = this.machine; - if (!holder.hasProxies()) return null; + if (!holder.hasCapabilityProxies()) return null; var iterator = machine.getRecipeType().getLookup().getRecipeIterator(holder, recipe -> { if (recipe.isFuel) return false; - if (!holder.hasProxies()) return false; - var result = recipe.matchRecipeContents(IO.IN, holder, recipe.inputs, false); + if (!holder.hasCapabilityProxies()) return false; + var result = RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), + false, false); if (!result.isSuccess()) return false; if (recipe.hasTick()) { - result = recipe.matchRecipeContents(IO.IN, holder, recipe.tickInputs, true); + result = RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, + Collections.emptyMap(), false, false); return result.isSuccess(); } return true; @@ -176,7 +179,9 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { return true; } // skip "can fit" checks, it can always fit - if (modified.checkConditions(this).isSuccess() && + var conditions = RecipeHandler.checkConditions(modified, this).stream().filter(v -> !v.isSuccess()) + .findFirst(); + if (conditions.isEmpty() && this.matchRecipeNoOutput(modified, machine).isSuccess() && this.matchTickRecipeNoOutput(modified, machine).isSuccess()) { setupRecipe(modified); @@ -190,20 +195,22 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { return false; } - public GTRecipe.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { - if (!holder.hasProxies()) return GTRecipe.ActionResult.FAIL_NO_REASON; - var result = recipe.matchRecipeContents(IO.IN, holder, recipe.inputs, false); - if (!result.isSuccess()) return result; - return GTRecipe.ActionResult.SUCCESS; + public RecipeHandler.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { + if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, + true); } - public GTRecipe.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { + public RecipeHandler.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { if (recipe.hasTick()) { - if (!holder.hasProxies()) return GTRecipe.ActionResult.FAIL_NO_REASON; - var result = recipe.matchRecipeContents(IO.IN, holder, recipe.tickInputs, true); - if (!result.isSuccess()) return result; + if (!holder.hasCapabilityProxies()) + return RecipeHandler.ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), + false, true); } - return GTRecipe.ActionResult.SUCCESS; + return RecipeHandler.ActionResult.SUCCESS; } @Override @@ -213,19 +220,17 @@ public void setupRecipe(GTRecipe recipe) { holder.setLocked(true); // Do RecipeLogic#setupRecipe but without any i/o - if (handleFuelRecipe()) { - if (!machine.beforeWorking(recipe)) { - return; - } - recipe.preWorking(this.machine); - - // do not consume inputs here, consume them on completion - recipeDirty = false; - lastRecipe = recipe; - setStatus(Status.WORKING); - progress = 0; - duration = recipe.duration; + if (!machine.beforeWorking(recipe)) { + return; } + RecipeHandler.preWorking(this.machine, recipe); + + // do not consume inputs here, consume them on completion + recipeDirty = false; + lastRecipe = recipe; + setStatus(Status.WORKING); + progress = 0; + duration = recipe.duration; } // "replace" the items in the slots rather than outputting elsewhere @@ -246,19 +251,19 @@ public void onRecipeFinish() { } @Override - protected boolean handleRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { return super.handleRecipeIO(recipe, io); } - return true; + return RecipeHandler.ActionResult.SUCCESS; } @Override - protected boolean handleTickRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHandler.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { return super.handleTickRecipeIO(recipe, io); } - return true; + return RecipeHandler.ActionResult.SUCCESS; } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java index ba7f3b0035..07e96a78b3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; @@ -122,7 +123,7 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec if (machine instanceof LargeCombustionEngineMachine engineMachine) { var EUt = RecipeHelper.getOutputEUt(recipe); // has lubricant - if (EUt > 0 && engineMachine.getLubricantRecipe().matchRecipe(engineMachine).isSuccess() && + if (EUt > 0 && RecipeHandler.matchRecipe(engineMachine, engineMachine.getLubricantRecipe()).isSuccess() && !engineMachine.isIntakesObstructed()) { var maxParallel = (int) (engineMachine.getOverclockVoltage() / EUt); // get maximum parallel var parallelResult = GTRecipeModifiers.accurateParallel(engineMachine, recipe, maxParallel, false); @@ -154,7 +155,8 @@ public boolean onWorking() { if (runningTimer % 72 == 0) { // insufficient lubricant - if (!getLubricantRecipe().handleRecipeIO(IO.IN, this, this.recipeLogic.getChanceCaches())) { + if (RecipeHandler.handleRecipeIO(IO.IN, this, getLubricantRecipe(), this.recipeLogic.getChanceCaches()) + .isSuccess()) { recipeLogic.interruptRecipe(); return false; } @@ -162,8 +164,9 @@ public boolean onWorking() { // check boost fluid if (isBoostAllowed()) { var boosterRecipe = getBoostRecipe(); - this.isOxygenBoosted = boosterRecipe.matchRecipe(this).isSuccess() && - boosterRecipe.handleRecipeIO(IO.IN, this, this.recipeLogic.getChanceCaches()); + this.isOxygenBoosted = RecipeHandler.matchRecipe(this, boosterRecipe).isSuccess() && + RecipeHandler.handleRecipeIO(IO.IN, this, boosterRecipe, this.recipeLogic.getChanceCaches()) + .isSuccess(); } runningTimer++; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java index 7c99368e8f..bbba5bc193 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.bedrockore.OreVeinWorldEntry; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.common.machine.multiblock.electric.BedrockOreMinerMachine; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; @@ -64,8 +64,7 @@ public void findAndHandleRecipe() { } var match = getOreMinerRecipe(); if (match != null) { - var copied = match.copy(new ContentModifier(match.duration, 0)); - if (match.matchRecipe(this.machine).isSuccess() && copied.matchTickRecipe(this.machine).isSuccess()) { + if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); } } @@ -107,7 +106,7 @@ private GTRecipe getOreMinerRecipe() { .EUt(GTValues.VA[getMachine().getEnergyTier()]) .outputItems(stack) .buildRawRecipe(); - if (recipe.matchRecipe(getMachine()).isSuccess() && recipe.matchTickRecipe(getMachine()).isSuccess()) { + if (RecipeHandler.matchContents(getMachine(), recipe).isSuccess()) { return recipe; } } @@ -146,15 +145,14 @@ public int getOreToProduce() { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - lastRecipe.postWorking(this.machine); - lastRecipe.handleRecipeIO(IO.OUT, this.machine, this.chanceCaches); + RecipeHandler.postWorking(this.machine, lastRecipe); + RecipeHandler.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); } depleteVein(); // try it again var match = getOreMinerRecipe(); if (match != null) { - var copied = match.copy(new ContentModifier(match.duration, 0)); - if (match.matchRecipe(this.machine).isSuccess() && copied.matchTickRecipe(this.machine).isSuccess()) { + if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); return; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java index dd93f651da..d30b197508 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java @@ -6,7 +6,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.bedrockfluid.FluidVeinWorldEntry; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FluidDrillMachine; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; @@ -57,8 +57,7 @@ public void findAndHandleRecipe() { } var match = getFluidDrillRecipe(); if (match != null) { - var copied = match.copy(new ContentModifier(match.duration, 0)); - if (match.matchRecipe(this.machine).isSuccess() && match.matchTickRecipe(this.machine).isSuccess()) { + if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); } } @@ -75,7 +74,7 @@ private GTRecipe getFluidDrillRecipe() { .outputFluids(new FluidStack(veinFluid, getFluidToProduce(data.getFluidVeinWorldEntry(getChunkX(), getChunkZ())))) .buildRawRecipe(); - if (recipe.matchRecipe(getMachine()).isSuccess() && recipe.matchTickRecipe(getMachine()).isSuccess()) { + if (RecipeHandler.matchContents(getMachine(), recipe).isSuccess()) { return recipe; } } @@ -114,15 +113,14 @@ private int getFluidToProduce(FluidVeinWorldEntry entry) { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - lastRecipe.postWorking(this.machine); - lastRecipe.handleRecipeIO(IO.OUT, this.machine, this.chanceCaches); + RecipeHandler.postWorking(this.machine, lastRecipe); + RecipeHandler.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); } depleteVein(); // try it again var match = getFluidDrillRecipe(); if (match != null) { - var copied = match.copy(new ContentModifier(match.duration, 0)); - if (match.matchRecipe(this.machine).isSuccess() && match.matchTickRecipe(this.machine).isSuccess()) { + if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); return; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 8a3589df12..0f92f856ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.api.misc.IgnoreEnergyRecipeHandler; import com.gregtechceu.gtceu.api.misc.ItemRecipeHandler; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.transfer.item.NotifiableAccountedInvWrapper; import com.gregtechceu.gtceu.common.data.GTBlocks; @@ -347,7 +348,7 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState inputItemHandler.storage.setStackInSlot(0, oreDrop); outputItemHandler.storage.clear(); - var matches = machine.getRecipeType().searchRecipe(this); + var matches = machine.getRecipeType().searchRecipe(this, r -> RecipeHandler.matchContents(this, r).isSuccess()); while (matches != null && matches.hasNext()) { GTRecipe match = matches.next(); @@ -355,7 +356,7 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState var eut = RecipeHelper.getInputEUt(match); if (GTUtil.getTierByVoltage(eut) <= getVoltageTier()) { - if (match.handleRecipeIO(IO.OUT, this, this.chanceCaches)) { + if (RecipeHandler.handleRecipeIO(IO.OUT, this, match, this.chanceCaches).isSuccess()) { blockDrops.clear(); var result = new ArrayList(); for (int i = 0; i < outputItemHandler.storage.getSlots(); ++i) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java index 4a93e80963..44d344fa8d 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java @@ -177,7 +177,6 @@ public GTRecipeType register() { type.setSound(sound); type.setHasResearchSlot(hasResearchSlot); type.setMaxTooltips(maxTooltips); - type.setFuelRecipeType(isFuelRecipeType); type.setSmallRecipeMap(smallRecipeMap); type.setIconSupplier(iconSupplier); type.setUiBuilder(uiBuilder); From f111ae8c45a155fbe0b70f1520ce2b50fddd08a8 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Wed, 11 Dec 2024 23:51:52 -0700 Subject: [PATCH 02/29] tables tables tables tables tables tables tables tables tables tables tables tables tables tables tables tables --- .../recipe/FluidRecipeCapability.java | 11 +- .../recipe/IRecipeCapabilityHolder.java | 10 +- .../api/capability/recipe/IRecipeHandler.java | 7 +- .../recipe/ItemRecipeCapability.java | 9 +- .../api/machine/WorkableTieredMachine.java | 21 +- .../feature/multiblock/IMultiPart.java | 3 +- .../multiblock/WorkableMultiblockMachine.java | 38 +- .../part/MultiblockPartMachine.java | 22 +- .../steam/SteamEnergyRecipeHandler.java | 4 +- .../machine/steam/SteamWorkableMachine.java | 23 +- .../trait/FluidHandlerProxyRecipeTrait.java | 4 +- .../trait/ItemHandlerProxyRecipeTrait.java | 4 +- .../trait/NotifiableComputationContainer.java | 14 +- .../trait/NotifiableEnergyContainer.java | 3 +- .../machine/trait/NotifiableFluidTank.java | 2 +- .../trait/NotifiableItemStackHandler.java | 3 +- .../api/machine/trait/RecipeHandlerList.java | 80 ++++ .../api/misc/IgnoreEnergyRecipeHandler.java | 2 +- .../gtceu/api/misc/ItemRecipeHandler.java | 2 +- .../gtceu/api/recipe/RecipeHandler.java | 20 +- .../gtceu/api/recipe/RecipeRunner.java | 174 ++++---- .../api/recipe/lookup/GTRecipeLookup.java | 1 + .../electric/ActiveTransformerMachine.java | 9 + .../electric/AssemblyLineMachine.java | 10 +- .../electric/BedrockOreMinerMachine.java | 2 +- .../electric/FusionReactorMachine.java | 16 +- .../research/ResearchStationMachine.java | 5 +- .../multiblock/steam/LargeBoilerMachine.java | 23 +- .../machine/trait/NotifiableStressTrait.java | 2 +- .../trait/customlogic/CannerLogic.java | 10 +- .../trait/customlogic/FormingPressLogic.java | 5 +- .../machine/trait/miner/MinerLogic.java | 22 +- .../ae2/machine/MEOutputHatchPartMachine.java | 2 +- .../MEPatternBufferProxyRecipeHandler.java | 4 +- .../trait/MEPatternBufferRecipeHandler.java | 16 +- .../ae2/slot/ExportOnlyAEItemList.java | 2 +- .../gregtechceu/gtceu/test/GTGameTests.java | 62 --- .../api/machine/trait/ParallelLogicTest.java | 139 ------ .../api/machine/trait/RecipeLogicTest.java | 129 ------ .../multiblock/PowerSubstationTest.java | 414 ------------------ .../gtceu/test/forge/GTGameTestsImpl.java | 17 - .../gtceu/utils/ResearchManager.java | 2 +- 42 files changed, 341 insertions(+), 1007 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/ParallelLogicTest.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/RecipeLogicTest.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/common/machine/multiblock/PowerSubstationTest.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/forge/GTGameTestsImpl.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java index af4421acd2..be3598145a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java @@ -152,10 +152,7 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu int maxMultiplier = multiplier; OverlayedTankHandler overlayedFluidHandler = new OverlayedTankHandler( - Objects.requireNonNullElseGet( - holder.getCapabilitiesProxy().get(IO.OUT, FluidRecipeCapability.CAP), - Collections::emptyList) - .stream() + holder.getCapabilitiesFlat(IO.OUT, FluidRecipeCapability.CAP).stream() .filter(NotifiableFluidTank.class::isInstance) .map(NotifiableFluidTank.class::cast) .toList()); @@ -200,10 +197,8 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu @Override public int getMaxParallelRatio(IRecipeCapabilityHolder holder, GTRecipe recipe, int parallelAmount) { // Find all the fluids in the combined Fluid Input inventories and create oversized FluidStacks - Map fluidStacks = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP), - Collections::>emptyList) - .stream() + Map fluidStacks = holder. + getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() .map(container -> container.getContents().stream().filter(FluidStack.class::isInstance) .map(FluidStack.class::cast).toList()) .flatMap(container -> GTHashMaps.fromFluidCollection(container).entrySet().stream()) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index b2af39f913..e7d9fa6264 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -1,9 +1,12 @@ package com.gregtechceu.gtceu.api.capability.recipe; import com.google.common.collect.Table; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import org.jetbrains.annotations.NotNull; +import java.util.Collections; import java.util.List; +import java.util.Map; public interface IRecipeCapabilityHolder { @@ -12,5 +15,10 @@ default boolean hasCapabilityProxies() { } @NotNull - Table, List>> getCapabilitiesProxy(); + Map> getCapabilitiesProxy(); + + default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { + return getCapabilitiesProxy().getOrDefault(io, Collections.emptyList()) + .stream().flatMap(rhl -> rhl.getCapability(cap).stream()).map(i -> (IRecipeHandler)i).toList(); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java index 65067bc3d6..6e44ec59eb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java @@ -34,13 +34,12 @@ public interface IRecipeHandler extends IFilteredHandler { * @param io the IO type of this recipe. always be one of the {@link IO#IN} or {@link IO#OUT} * @param recipe recipe. * @param left left contents for to be handled. - * @param slotName specific slot name. * @param simulate simulate. * @return left contents for continue handling by other proxies. *
* null - nothing left. handling successful/finish. you should always return null as a handling-done mark. */ - List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, boolean simulate); + List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate); /** * container size, if it has one. otherwise -1. @@ -71,12 +70,12 @@ default K copyContent(Object content) { return getCapability().copyInner((K) content); } - default List handleRecipe(IO io, GTRecipe recipe, List left, @Nullable String slotName, boolean simulate) { + default List handleRecipe(IO io, GTRecipe recipe, List left, boolean simulate) { List contents = new ObjectArrayList<>(left.size()); for (Object leftObj : left) { contents.add(copyContent(leftObj)); } - return handleRecipeInner(io, recipe, contents, slotName, simulate); + return handleRecipeInner(io, recipe, contents, simulate); } default void preWorking(IRecipeCapabilityHolder holder, IO io, GTRecipe recipe) {} diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java index f8ac38a7a9..1bb4816265 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java @@ -249,9 +249,7 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu int maxMultiplier = multiplier; OverlayedItemHandler itemHandler = new OverlayedItemHandler(new CombinedInvWrapper( - Objects.requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP), - Collections::emptyList) - .stream() + holder.getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).stream() .filter(IItemHandlerModifiable.class::isInstance) .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new))); @@ -386,10 +384,7 @@ private Object2IntMap getIngredientStacks(IRecipeCapabilityHolder hol ItemStackHashStrategy.comparingAllButCount()); Object2IntMap result = new Object2IntOpenHashMap<>(); - List> recipeHandlerList = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - Collections::>emptyList) - .stream() + List> recipeHandlerList = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(handler -> !handler.isProxy()).toList(); for (IRecipeHandler container : recipeHandlerList) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 3040d5ab01..7cbd626df2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -16,6 +16,7 @@ import com.google.common.collect.Tables; import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.ints.Int2IntFunction; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -67,7 +68,7 @@ public abstract class WorkableTieredMachine extends TieredEnergyMachine implemen @Persisted public final NotifiableComputationContainer exportComputation; @Getter - protected final Table, List>> capabilitiesProxy; + protected final Map> capabilitiesProxy; @Persisted @Getter protected int overclockTier; @@ -86,7 +87,7 @@ public WorkableTieredMachine(IMachineBlockEntity holder, int tier, Int2IntFuncti this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.tankScalingFunction = tankScalingFunction; - this.capabilitiesProxy = Tables.newCustomTable(new EnumMap<>(IO.class), IdentityHashMap::new); + this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); this.recipeLogic = createRecipeLogic(args); this.importItems = createImportItemHandler(args); @@ -162,15 +163,21 @@ protected RecipeLogic createRecipeLogic(Object... args) { @Override public void onLoad() { super.onLoad(); + // attach self traits + Map>> ioTraits = new Object2ObjectOpenHashMap<>(); + for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { - if (!capabilitiesProxy.contains(handlerTrait.getHandlerIO(), handlerTrait.getCapability())) { - capabilitiesProxy.put(handlerTrait.getHandlerIO(), handlerTrait.getCapability(), new ArrayList<>()); - } - capabilitiesProxy.get(handlerTrait.getHandlerIO(), handlerTrait.getCapability()).add(handlerTrait); - traitSubscriptions.add(handlerTrait.addChangedListener(recipeLogic::updateTickSubscription)); + ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); } } + + for(var entry : ioTraits.entrySet()) { + RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); + handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); + capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + } } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java index fd65c979f5..643a2875c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java @@ -5,6 +5,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IMachineFeature; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; @@ -59,7 +60,7 @@ default boolean canShared() { /** * Get all available traits for recipe logic. */ - List getRecipeHandlers(); + RecipeHandlerList getRecipeHandlers(); /** * whether its base model can be replaced by controller when it is formed. diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 1026d24106..818b64f9ad 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IWorkableMultiController; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; @@ -22,6 +23,7 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; @@ -66,7 +68,7 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach @Persisted private int activeRecipeType; @Getter - protected final Table, List>> capabilitiesProxy; + protected final Map> capabilitiesProxy; protected final List traitSubscriptions; @Getter @Setter @@ -83,7 +85,7 @@ public WorkableMultiblockMachine(IMachineBlockEntity holder, Object... args) { this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); - this.capabilitiesProxy = Tables.newCustomTable(new EnumMap<>(IO.class), IdentityHashMap::new); + this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); } @@ -123,27 +125,29 @@ public void onStructureFormed() { for (IMultiPart part : getParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - var handlerIO = io == IO.BOTH ? handler.getHandlerIO() : io; - if (!capabilitiesProxy.contains(handlerIO, handler.getCapability())) { - capabilitiesProxy.put(handlerIO, handler.getCapability(), new ArrayList<>()); - } - capabilitiesProxy.get(handlerIO, handler.getCapability()).add(handler); - traitSubscriptions.add(handler.addChangedListener(recipeLogic::updateTickSubscription)); - } + + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + capabilitiesProxy.computeIfAbsent(handlerList.getHandlerIO(), i -> new ArrayList<>()).add(handlerList); + traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } + // attach self traits + Map>> ioTraits = new Object2ObjectOpenHashMap<>(); + for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { - if (!capabilitiesProxy.contains(handlerTrait.getHandlerIO(), handlerTrait.getCapability())) { - capabilitiesProxy.put(handlerTrait.getHandlerIO(), handlerTrait.getCapability(), new ArrayList<>()); - } - capabilitiesProxy.get(handlerTrait.getHandlerIO(), handlerTrait.getCapability()).add(handlerTrait); - traitSubscriptions.add(handlerTrait.addChangedListener(recipeLogic::updateTickSubscription)); + ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); } } + + for(var entry : ioTraits.entrySet()) { + RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); + handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); + capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + } // schedule recipe logic recipeLogic.updateTickSubscription(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index fdb87925d8..21e7e6dfef 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -1,15 +1,19 @@ package com.gregtechceu.gtceu.api.machine.multiblock.part; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import lombok.Getter; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -37,15 +41,9 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { @RequireRerender protected final Set controllerPositions; - private final List recipeHandlerTraits; - public MultiblockPartMachine(IMachineBlockEntity holder) { super(holder); this.controllerPositions = new HashSet<>(); - - recipeHandlerTraits = traits.stream().filter(IRecipeHandlerTrait.class::isInstance) - .map(IRecipeHandlerTrait.class::cast) - .toList(); } ////////////////////////////////////// @@ -78,9 +76,15 @@ public List getControllers() { return result; } - @Override - public List getRecipeHandlers() { - return recipeHandlerTraits; + public RecipeHandlerList getRecipeHandlers() { + var a = traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) + .toList(); + if(a.isEmpty()) { + return new RecipeHandlerList(IO.NONE); + } + var l = new RecipeHandlerList(a.get(0).getHandlerIO()); + l.addHandler(a.toArray(new IRecipeHandler[0])); + return l; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java index c5526ee8a8..ccec3c65d3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java @@ -34,7 +34,7 @@ public SteamEnergyRecipeHandler(NotifiableFluidTank steamTank, double conversion } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { long sum = left.stream().reduce(0L, Long::sum); int realSum = GTMath.saturatedCast((long) Math.ceil(sum * conversionRate)); @@ -43,7 +43,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nu FluidIngredient.of(GTMaterials.Steam.getFluid(realSum)); var list = new ArrayList(); list.add(steam); - var leftSteam = steamTank.handleRecipeInner(io, recipe, list, slotName, simulate); + var leftSteam = steamTank.handleRecipeInner(io, recipe, list, simulate); if (leftSteam == null || leftSteam.isEmpty()) return null; sum = (long) (leftSteam.get(0).getAmount() / conversionRate); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index 87cff593bd..6f9d92cbfa 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; @@ -22,6 +23,7 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -79,7 +81,7 @@ public abstract class SteamWorkableMachine extends SteamMachine protected boolean isMuffled; protected boolean previouslyMuffled = true; @Getter - protected final Table, List>> capabilitiesProxy; + protected final Map> capabilitiesProxy; protected final List traitSubscriptions; public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, Object... args) { @@ -87,7 +89,7 @@ public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); - this.capabilitiesProxy = Tables.newCustomTable(new EnumMap<>(IO.class), IdentityHashMap::new); + this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); this.outputFacing = hasFrontFacing() ? getFrontFacing().getOpposite() : Direction.UP; } @@ -103,16 +105,21 @@ public ManagedFieldHolder getFieldHolder() { @Override public void onLoad() { super.onLoad(); + // attach self traits + Map>> ioTraits = new Object2ObjectOpenHashMap<>(); + for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { - if (!capabilitiesProxy.contains(handlerTrait.getHandlerIO(), handlerTrait.getCapability())) { - capabilitiesProxy.put(handlerTrait.getHandlerIO(), handlerTrait.getCapability(), new ArrayList<>()); - } - var handlers = capabilitiesProxy.get(handlerTrait.getHandlerIO(), handlerTrait.getCapability()); - if (handlers != null) handlers.add(handlerTrait); - traitSubscriptions.add(handlerTrait.addChangedListener(recipeLogic::updateTickSubscription)); + ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); } } + + for(var entry : ioTraits.entrySet()) { + RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); + handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); + capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + } } protected RecipeLogic createRecipeLogic(@SuppressWarnings("unused") Object... args) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java index 78913405fe..5897162905 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java @@ -44,10 +44,10 @@ public FluidHandlerProxyRecipeTrait(MetaMachine machine, @Override public List handleRecipeInner(IO io, GTRecipe recipe, List left, - @Nullable String slotName, boolean simulate) { + boolean simulate) { if (!enabled) return left; for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, slotName, simulate); + handler.handleRecipeInner(io, recipe, left, simulate); if (left.isEmpty()) return null; } return left; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java index 3053a12746..681f8bef9a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java @@ -42,11 +42,11 @@ public ItemHandlerProxyRecipeTrait(MetaMachine machine, } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { if (!enabled) return left; for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, slotName, simulate); + handler.handleRecipeInner(io, recipe, left, simulate); if (left.isEmpty()) return null; } return left; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableComputationContainer.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableComputationContainer.java index adc57c3006..d6a5e2b9bc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableComputationContainer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableComputationContainer.java @@ -5,10 +5,7 @@ import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; import com.gregtechceu.gtceu.api.capability.IOpticalComputationReceiver; import com.gregtechceu.gtceu.api.capability.forge.GTCapability; -import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; @@ -182,7 +179,7 @@ public boolean canBridge(@NotNull Collection seen) } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { IOpticalComputationProvider provider = getOpticalNetProvider(); if (provider == null) return left; @@ -248,10 +245,9 @@ public IOpticalComputationProvider getComputationProvider() { } else if (machine instanceof IOpticalComputationProvider provider) { return provider; } else if (machine instanceof IRecipeCapabilityHolder recipeCapabilityHolder) { - if (recipeCapabilityHolder.getCapabilitiesProxy().contains(IO.IN, CWURecipeCapability.CAP) && - !recipeCapabilityHolder.getCapabilitiesProxy().get(IO.IN, CWURecipeCapability.CAP).isEmpty()) { - var provider = (IOpticalComputationProvider) recipeCapabilityHolder.getCapabilitiesProxy() - .get(IO.IN, CWURecipeCapability.CAP).get(0); + var cwuCap = recipeCapabilityHolder.getCapabilitiesFlat(IO.IN, CWURecipeCapability.CAP); + if (!cwuCap.isEmpty()) { + var provider = (IOpticalComputationProvider) cwuCap.get(0); if (provider != this) { return provider; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableEnergyContainer.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableEnergyContainer.java index 3ccf38e7c8..483cdac107 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableEnergyContainer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableEnergyContainer.java @@ -302,8 +302,7 @@ public long changeEnergy(long energyToAdd) { } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, - boolean simulate) { + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { IEnergyContainer capability = this; long sum = left.stream().reduce(0L, Long::sum); if (io == IO.IN) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java index 9785867242..fe05568226 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java @@ -98,7 +98,7 @@ public ManagedFieldHolder getFieldHolder() { @Override public List handleRecipeInner(IO io, GTRecipe recipe, List left, - @Nullable String slotName, boolean simulate) { + boolean simulate) { if (io != handlerIO) return left; if (io != IO.IN && io != IO.OUT) return left.isEmpty() ? null : left; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java index eb43aeb94d..33436f06b6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java @@ -81,8 +81,7 @@ public ManagedFieldHolder getFieldHolder() { } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, - boolean simulate) { + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { return handleRecipe(io, recipe, left, simulate, handlerIO, storage); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java new file mode 100644 index 0000000000..25e635cfd2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -0,0 +1,80 @@ +package com.gregtechceu.gtceu.api.machine.trait; + +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; +import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.content.Content; +import com.lowdragmc.lowdraglib.syncdata.ISubscription; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import lombok.Getter; +import lombok.Setter; + +import java.util.*; + +public class RecipeHandlerList { + public Map, List>> handlerMap = new Object2ObjectOpenHashMap<>(); + private IO io; + @Setter + @Getter + private boolean isDistinct = false; + + public RecipeHandlerList(IO io) { + this.io = io; + } + + public static RecipeHandlerList of(IO io, IRecipeHandler handler) { + RecipeHandlerList rhl = new RecipeHandlerList(io); + rhl.addHandler(handler); + return rhl; + } + + public List> getCapability(RecipeCapability cap) { + return handlerMap.getOrDefault(cap, Collections.emptyList()); + } + + public void addHandler(IRecipeHandler... handlers) { + for(var handler : handlers) { + handlerMap.computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); + } + } + + public boolean hasCapability(RecipeCapability cap) { + return handlerMap.containsKey(cap); + } + + public IO getHandlerIO() { + return io; + } + + public List addChangeListeners(Runnable listener) { + List ret = new ArrayList<>(); + for(var handlerList : handlerMap.values()) { + for(var handler : handlerList) { + if(handler instanceof IRecipeHandlerTrait handlerTrait) { + ret.add(handlerTrait.addChangedListener(listener)); + } + } + } + return ret; + } + + public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { + var copy = new IdentityHashMap<>(contents); + var it = copy.entrySet().iterator(); + while(it.hasNext()) { + var entry = it.next(); + for(var handler : handlerMap.get(entry.getKey())) { + var left = handler.handleRecipe(io, recipe, entry.getValue(), simulate); + if(left == null) { + it.remove(); + break; + } else { + entry.setValue(left); + } + } + } + return copy; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java index cabc3721b2..d0df34e3c8 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java @@ -13,7 +13,7 @@ public class IgnoreEnergyRecipeHandler implements IRecipeHandler { @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { return null; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java index da98dfa54c..71866335d6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java @@ -35,7 +35,7 @@ public ItemRecipeHandler(IO handlerIO, int slots) { } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { return NotifiableItemStackHandler.handleRecipe(io, recipe, left, simulate, this.handlerIO, storage); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java index 78d646d8bf..3cb72ec74b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java @@ -73,7 +73,7 @@ public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, G boolean isTick, boolean simulated) { RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); for (Map.Entry, List> entry : contents.entrySet()) { - var handle = runner.handle(entry); + var handle = runner.handle(contents); if (handle == null) continue; @@ -121,12 +121,13 @@ public static void postWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { - if (holder.getCapabilitiesProxy().contains(io, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { + var capFlatMap = holder.getCapabilitiesFlat(io, capability); + if (!capFlatMap.isEmpty()) { + for (IRecipeHandler capabilityProxy : capFlatMap) { capabilityProxy.preWorking(holder, io, recipe); } - } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { + } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { capabilityProxy.preWorking(holder, io, recipe); } } @@ -135,12 +136,13 @@ public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { - if (holder.getCapabilitiesProxy().contains(io, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(io, capability)) { + var capFlatMap = holder.getCapabilitiesFlat(io, capability); + if (!capFlatMap.isEmpty()) { + for (IRecipeHandler capabilityProxy : capFlatMap) { capabilityProxy.postWorking(holder, io, recipe); } - } else if (holder.getCapabilitiesProxy().contains(IO.BOTH, capability)) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesProxy().get(IO.BOTH, capability)) { + } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { capabilityProxy.postWorking(holder, io, recipe); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 30664fc536..442976f05a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; @@ -22,7 +23,7 @@ @SuppressWarnings({ "rawtypes", "unchecked" }) class RecipeRunner { - record RecipeHandlingResult(RecipeCapability capability, @UnknownNullability List content, + record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, RecipeHandler.ActionResult result) {} // -------------------------------------------------------------------------------------------------------- @@ -32,15 +33,17 @@ record RecipeHandlingResult(RecipeCapability capability, @UnknownNullability private final boolean isTick; private final IRecipeCapabilityHolder holder; private final Map, Object2IntMap> chanceCaches; - private final Table, List>> capabilityProxies; + private final Map> capabilityProxies; private final boolean simulated; // These are only used to store mutable state during each invocation of handle() private RecipeCapability capability; private Set> used; - @Getter - private @UnknownNullability List content; - private @UnknownNullability List search; + private Map, List> recipeContents; + private Map, List> searchRecipeContents; + /*@Getter + private Map contentMatchList; + private @UnknownNullability List searchingMatchList;*/ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -51,120 +54,131 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.holder = holder; this.chanceCaches = chanceCaches; this.capabilityProxies = holder.getCapabilitiesProxy(); + this.recipeContents = new IdentityHashMap<>(); + this.searchRecipeContents = new IdentityHashMap<>(); this.simulated = simulated; } @Nullable - public RecipeHandlingResult handle(Map.Entry, List> entry) { + public RecipeHandlingResult handle(Map, List> entries) { initState(); - this.fillContent(holder, entry); - this.capability = this.resolveCapability(entry); - if (capability == null) - return null; - var result = this.handleContents(); - if (result == null) + fillContentMatchList(entries); + + if (capability == null) return null; - return new RecipeHandlingResult(capability, result, RecipeHandler.ActionResult.SUCCESS); + return this.handleContents(); } private void initState() { used = new HashSet<>(); - content = new ArrayList<>(); - search = simulated ? content : new ArrayList<>(); + //contentMatchList = new ArrayList<>(); + //searchingMatchList = simulated ? contentMatchList : new ArrayList<>(); } - private void fillContent(IRecipeCapabilityHolder holder, Map.Entry, List> entry) { - RecipeCapability cap = entry.getKey(); + /** + * Populates the content match list to know if conditions are satisfied. + */ + private void fillContentMatchList(Map, List> entries) { ChanceBoostFunction function = recipe.getType().getChanceFunction(); - ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick); - List chancedContents = new ArrayList<>(); - for (Content cont : entry.getValue()) { - // For simulated handling, search/content are the same instance, so there's no need to switch between them - this.search.add(cont.content); - - // When simulating the recipe handling (used for recipe matching), chanced contents are ignored. - if (simulated) continue; - - if (cont.chance >= cont.maxChance) { - this.content.add(cont.content); - } else { - chancedContents.add(cont); + for(var entry : entries.entrySet()) { + RecipeCapability cap = entry.getKey(); + if (!cap.doMatchInRecipe()) { + continue; + } + ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick); + List chancedContents = new ArrayList<>(); + if(entry.getValue().isEmpty()) continue; + this.recipeContents.putIfAbsent(cap, new ArrayList<>()); + for (Content cont : entry.getValue()) { + this.searchRecipeContents.computeIfAbsent(cap, c -> new ArrayList<>()).add(cont.content); + + // When simulating the recipe handling (used for recipe matching), chanced contents are ignored. + if (simulated) continue; + + if (cont.chance >= cont.maxChance) { + this.recipeContents.get(cap).add(cont.content); + } else { + chancedContents.add(cont); + } } - } - // Only roll if there's anything to roll for - if (!chancedContents.isEmpty()) { - int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); - int chanceTier = recipeTier + recipe.ocLevel; - var cache = this.chanceCaches.get(cap); - chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, recipe.parallels); + if (!chancedContents.isEmpty()) { + int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); + int chanceTier = recipeTier + recipe.ocLevel; + var cache = this.chanceCaches.get(cap); + chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, recipe.parallels); - for (Content cont : chancedContents) { - this.content.add(cont.content); + for (Content cont : chancedContents) { + this.recipeContents.get(cap).add(cont.content); + } } - } - } - private RecipeCapability resolveCapability(Map.Entry, List> entry) { - RecipeCapability capability = entry.getKey(); - if (!capability.doMatchInRecipe()) { - return null; - } - - content = this.content.stream().map(capability::copyContent).toList(); - if (this.content.isEmpty()) { - content = null; - return null; + if(!recipeContents.get(cap).isEmpty()) {} + //recipeContents.put(cap, recipeContents.get(cap).stream().map(cap::copyContent).toList()); + else + recipeContents.remove(cap); } - - return capability; } @Nullable - private List handleContents() { - handleContentsInternal(io); - if (content == null) return null; - handleContentsInternal(IO.BOTH); - - return content; + private RecipeHandlingResult handleContents() { + var result = handleContentsInternal(io); + if (!result.result.isSuccess()) { + return result; + } + if(recipeContents.isEmpty()) { + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + } + return handleContentsInternal(IO.BOTH); } - private void handleContentsInternal(IO capIO) { - if (!capabilityProxies.contains(capIO, capability)) - return; + private RecipeHandlingResult handleContentsInternal(IO capIO) { // noinspection DataFlowIssue checked above. - var handlers = new ArrayList<>(capabilityProxies.get(capIO, capability)); - handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); + var handlers = new ArrayList<>(capabilityProxies.get(capIO)); + + //handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); // handle distinct first - for (IRecipeHandler handler : handlers) { + boolean handled = false; + for (var handler : handlers) { if (!handler.isDistinct()) continue; - var result = handler.handleRecipe(io, recipe, search, null, true); - if (result == null) { - if (!simulated) { - handler.handleRecipe(io, recipe, content, null, false); + var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); + if (res.isEmpty()) { + if(!simulated) { + handler.handleRecipe(io, recipe, recipeContents, false); } - content = null; - } - if (content == null) { + handled = true; break; } } - if (content != null) { - // handle undistinct later - for (IRecipeHandler proxy : handlers) { - if (used.contains(proxy) || proxy.isDistinct()) continue; - used.add(proxy); - if (content != null) { - content = proxy.handleRecipe(io, recipe, content, null, simulated); + + if(!handled) { + for(var handler : handlers) { + if(!recipeContents.isEmpty()) { + recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); + } + if(recipeContents.isEmpty()) { + handled = true; + break; } - if (content == null) break; } } + + if(handled) { + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + } + + for(var entry : recipeContents.entrySet()) { + if(entry.getValue() != null && !entry.getValue().isEmpty()) { + return new RecipeHandlingResult(entry.getKey(), entry.getValue(), RecipeHandler.ActionResult.FAIL_NO_REASON); + } + } + + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.FAIL_NO_REASON); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 06bafe7974..3050b23f24 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -427,6 +427,7 @@ protected List> fromRecipe(@NotNull GTRecipe r) { */ @NotNull protected List> fromHolder(@NotNull IRecipeCapabilityHolder r) { + List> list = new ObjectArrayList<>( r.getCapabilitiesProxy().row(IO.IN).values().size()); r.getCapabilitiesProxy().row(IO.IN).forEach((cap, handlers) -> { 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 efdeed95fa..4abe67ef8f 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 @@ -89,6 +89,15 @@ public void onStructureFormed() { for (IMultiPart part : getPrioritySortedParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> { + if() + }); + for (var handler : part.getRecipeHandlers()) { var handlerIO = handler.getHandlerIO(); // If IO not compatible diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java index 2717f9eedc..1bb515e8e2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java @@ -32,10 +32,7 @@ public boolean beforeWorking(@Nullable GTRecipe recipe) { if (ConfigHolder.INSTANCE.machines.orderedAssemblyLineItems) { var recipeInputs = recipe.inputs.get(ItemRecipeCapability.CAP); - var itemInputInventory = Objects - .requireNonNullElseGet(getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - Collections::>emptyList) - .stream() + var itemInputInventory = getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(handler -> !handler.isProxy()) .map(container -> container.getContents().stream().filter(ItemStack.class::isInstance) .map(ItemStack.class::cast).toList()) @@ -54,10 +51,7 @@ public boolean beforeWorking(@Nullable GTRecipe recipe) { if (ConfigHolder.INSTANCE.machines.orderedAssemblyLineFluids) { recipeInputs = recipe.inputs.get(FluidRecipeCapability.CAP); - var itemFluidInventory = Objects - .requireNonNullElseGet(getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP), - Collections::>emptyList) - .stream() + var itemFluidInventory = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() .map(container -> container.getContents().stream().filter(FluidStack.class::isInstance) .map(FluidStack.class::cast).toList()) .filter(container -> !container.isEmpty()) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/BedrockOreMinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/BedrockOreMinerMachine.java index c7e6660fde..f0519da6b4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/BedrockOreMinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/BedrockOreMinerMachine.java @@ -61,7 +61,7 @@ public BedrockOreMinerLogic getRecipeLogic() { } public int getEnergyTier() { - var energyContainer = this.getCapabilitiesProxy().get(IO.IN, EURecipeCapability.CAP); + var energyContainer = this.getCapabilitiesFlat(IO.IN, EURecipeCapability.CAP); if (energyContainer == null) return this.tier; var energyCont = new EnergyContainerList(energyContainer.stream().filter(IEnergyContainer.class::isInstance) .map(IEnergyContainer.class::cast).toList()); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java index 85485711e7..fc29b7953b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java @@ -107,15 +107,13 @@ public void onStructureFormed() { for (IMultiPart part : getParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE || io == IO.OUT) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - traitSubscriptions.add(handler.addChangedListener(this::updatePreHeatSubscription)); - } - } + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer)v)); + traitSubscriptions.addAll(handlerList.addChangeListeners(this::updatePreHeatSubscription)); } this.inputEnergyContainers = new EnergyContainerList(energyContainers); energyContainer.resetBasicInfo(calculateEnergyStorageFactor(getTier(), energyContainers.size()), 0, 0, 0, 0); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 54ccc62782..6aab715ab9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockDisplayText; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; @@ -66,9 +67,7 @@ public void onStructureFormed() { this.computationProvider = provider; } if (part instanceof IObjectHolder objectHolder) { - this.objectHolder = objectHolder; - this.getCapabilitiesProxy().put(IO.IN, ItemRecipeCapability.CAP, - Collections.singletonList(objectHolder.getAsHandler())); + this.getCapabilitiesProxy().put(IO.IN, List.of(RecipeHandlerList.of(IO.IN, objectHolder.getAsHandler()))); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java index 1299ff9d52..be72c770af 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java @@ -120,15 +120,10 @@ protected void updateCurrentTemperature() { (ConfigHolder.INSTANCE.machines.largeBoilers.steamPerWater * 100); var drainWater = List.of(FluidIngredient.of(maxDrain, Fluids.WATER)); List> inputTanks = new ArrayList<>(); - if (getCapabilitiesProxy().contains(IO.IN, FluidRecipeCapability.CAP)) { - inputTanks.addAll(Objects.requireNonNull(getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP))); - } - if (getCapabilitiesProxy().contains(IO.BOTH, FluidRecipeCapability.CAP)) { - inputTanks - .addAll(Objects.requireNonNull(getCapabilitiesProxy().get(IO.BOTH, FluidRecipeCapability.CAP))); - } + inputTanks.addAll(getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP)); + inputTanks.addAll(getCapabilitiesFlat(IO.BOTH, FluidRecipeCapability.CAP)); for (IRecipeHandler tank : inputTanks) { - drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, null, false); + drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, false); if (drainWater == null) break; } var drained = (drainWater == null || drainWater.isEmpty()) ? maxDrain : @@ -141,16 +136,10 @@ protected void updateCurrentTemperature() { // fill steam var fillSteam = List.of(FluidIngredient.of(GTMaterials.Steam.getFluid(steamGenerated))); List> outputTanks = new ArrayList<>(); - if (getCapabilitiesProxy().contains(IO.OUT, FluidRecipeCapability.CAP)) { - outputTanks.addAll( - Objects.requireNonNull(getCapabilitiesProxy().get(IO.OUT, FluidRecipeCapability.CAP))); - } - if (getCapabilitiesProxy().contains(IO.BOTH, FluidRecipeCapability.CAP)) { - outputTanks.addAll( - Objects.requireNonNull(getCapabilitiesProxy().get(IO.BOTH, FluidRecipeCapability.CAP))); - } + outputTanks.addAll(getCapabilitiesFlat(IO.OUT, FluidRecipeCapability.CAP)); + outputTanks.addAll(getCapabilitiesFlat(IO.BOTH, FluidRecipeCapability.CAP)); for (IRecipeHandler tank : outputTanks) { - fillSteam = (List) tank.handleRecipe(IO.OUT, null, fillSteam, null, false); + fillSteam = (List) tank.handleRecipe(IO.OUT, null, fillSteam, false); if (fillSteam == null) break; } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java index a8b00997f1..4b966c7f22 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java @@ -62,7 +62,7 @@ public void onMachineLoad() { } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { if (machine instanceof IKineticMachine kineticMachine) { float sum = left.stream().reduce(0f, Float::sum); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java index fb78d48116..562d167511 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java @@ -26,18 +26,12 @@ public class CannerLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var itemInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - ArrayList::new) - .stream() + var itemInputs = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(IItemHandlerModifiable.class::isInstance) .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new); - var fluidInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP), - ArrayList::new) - .stream() + var fluidInputs = holder.getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() .filter(IFluidHandler.class::isInstance).map(IFluidHandler.class::cast) .toArray(IFluidHandler[]::new); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java index bb7dc1c8c1..97abb269c2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java @@ -26,10 +26,7 @@ public class FormingPressLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var handlers = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - Collections::emptyList) - .stream() + var handlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(NotifiableItemStackHandler.class::isInstance) .map(NotifiableItemStackHandler.class::cast) .filter(i -> i.getSlots() > 1) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 0f92f856ce..34a6a52f0f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.misc.IgnoreEnergyRecipeHandler; import com.gregtechceu.gtceu.api.misc.ItemRecipeHandler; @@ -23,6 +24,7 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -118,7 +120,7 @@ public class MinerLogic extends RecipeLogic implements IRecipeCapabilityHolder { @Getter private boolean isInventoryFull; @Getter - private final Table, List>> capabilitiesProxy; + private final Map> capabilitiesProxy; private final ItemRecipeHandler inputItemHandler, outputItemHandler; private final IgnoreEnergyRecipeHandler inputEnergyHandler; @Setter @@ -143,15 +145,21 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, this.isDone = false; this.pickaxeTool = GTItems.TOOL_ITEMS.get(GTMaterials.Neutronium, GTToolType.PICKAXE).get().get(); this.pickaxeTool.enchant(Enchantments.BLOCK_FORTUNE, fortune); - this.capabilitiesProxy = Tables.newCustomTable(new EnumMap<>(IO.class), IdentityHashMap::new); + this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); this.inputItemHandler = new ItemRecipeHandler(IO.IN, machine.getRecipeType().getMaxInputs(ItemRecipeCapability.CAP)); this.outputItemHandler = new ItemRecipeHandler(IO.OUT, machine.getRecipeType().getMaxOutputs(ItemRecipeCapability.CAP)); this.inputEnergyHandler = new IgnoreEnergyRecipeHandler(); - this.capabilitiesProxy.put(IO.IN, inputItemHandler.getCapability(), List.of(inputItemHandler)); - this.capabilitiesProxy.put(IO.IN, inputEnergyHandler.getCapability(), List.of(inputEnergyHandler)); - this.capabilitiesProxy.put(IO.OUT, outputItemHandler.getCapability(), List.of(outputItemHandler)); + + RecipeHandlerList inHandlers = new RecipeHandlerList(IO.IN); + RecipeHandlerList outHandlers = new RecipeHandlerList(IO.OUT); + + inHandlers.addHandler(inputItemHandler, inputEnergyHandler); + outHandlers.addHandler(outputItemHandler); + + this.capabilitiesProxy.put(IO.IN, List.of(inHandlers)); + this.capabilitiesProxy.put(IO.OUT, List.of(outHandlers)); } @Override @@ -390,8 +398,8 @@ protected void getSilkTouchDrops(NonNullList blockDrops, BlockState b protected NotifiableAccountedInvWrapper getCachedItemHandler() { if (cachedItemHandler == null) { - cachedItemHandler = new NotifiableAccountedInvWrapper(machine.getCapabilitiesProxy() - .get(IO.OUT, ItemRecipeCapability.CAP).stream() + cachedItemHandler = new NotifiableAccountedInvWrapper(machine + .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).stream() .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new)); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java index bcba4a445e..a11bfaf779 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java @@ -149,7 +149,7 @@ public boolean isFluidValid(int tank, @NotNull FluidStack stack) { @Override @Nullable public List handleRecipeInner(IO io, GTRecipe recipe, List left, - @Nullable String slotName, boolean simulate) { + boolean simulate) { if (io != IO.OUT) return left; FluidAction action = simulate ? FluidAction.SIMULATE : FluidAction.EXECUTE; for (var it = left.iterator(); it.hasNext();) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java index 2ec56d8a66..449f411841 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java @@ -31,10 +31,10 @@ public MEPatternBufferProxyRecipeHandler(MetaMachine machine, IO handlerIO, Reci } @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, @Nullable String slotName, + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, slotName, simulate); + handler.handleRecipeInner(io, recipe, left, simulate); if (left.isEmpty()) return null; } return left; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java index 7230bf63ea..c910393aa0 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java @@ -137,11 +137,11 @@ public ISubscription addChangedListener(Runnable listener) { @Override public List handleRecipeInner(IO io, GTRecipe recipe, List left, - @Nullable String slotName, boolean simulate) { + boolean simulate) { if (io != IO.IN) return left; var machine = getMachine(); - machine.getCircuitInventorySimulated().handleRecipeInner(io, recipe, left, slotName, simulate); - machine.getShareInventory().handleRecipeInner(io, recipe, left, slotName, simulate); + machine.getCircuitInventorySimulated().handleRecipeInner(io, recipe, left, simulate); + machine.getShareInventory().handleRecipeInner(io, recipe, left, simulate); return handleItemInner(recipe, left, simulate); } @@ -206,14 +206,10 @@ public ISubscription addChangedListener(Runnable listener) { } @Override - public List handleRecipeInner( - IO io, - GTRecipe recipe, - List left, - @Nullable String slotName, - boolean simulate) { + public List handleRecipeInner(IO io, GTRecipe recipe, + List left, boolean simulate) { if (io != IO.IN) return left; - getMachine().getShareTank().handleRecipeInner(io, recipe, left, slotName, simulate); + getMachine().getShareTank().handleRecipeInner(io, recipe, left, simulate); return handleFluidInner(recipe, left, simulate); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java index 2544910063..4338782171 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java @@ -93,7 +93,7 @@ public ItemStack extractItem(int slot, int amount, boolean simulate) { @Override public List handleRecipeInner(IO io, GTRecipe recipe, List left, - @Nullable String slotName, boolean simulate) { + boolean simulate) { return NotifiableItemStackHandler.handleRecipe(io, recipe, left, simulate, this.handlerIO, getHandler()); } diff --git a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java b/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java deleted file mode 100644 index 09b88ed06c..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.gregtechceu.gtceu.test; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.test.api.machine.trait.ParallelLogicTest; -import com.gregtechceu.gtceu.test.api.machine.trait.RecipeLogicTest; - -import net.minecraft.gametest.framework.GameTest; -import net.minecraft.gametest.framework.GameTestGenerator; -import net.minecraft.gametest.framework.TestFunction; -import net.minecraft.world.level.block.Rotation; - -import com.mojang.datafixers.util.Pair; - -import java.lang.reflect.Modifier; -import java.util.Collection; -import java.util.Comparator; -import java.util.stream.Stream; - -public class GTGameTests { - - private static final Class[] testHolders = { - RecipeLogicTest.class, - ParallelLogicTest.class - }; - - @GameTestGenerator - public static Collection generateTests() { - return getTestsFrom(testHolders); - } - - public static Collection getTestsFrom(Class... classes) { - return Stream.of(classes) - .map(Class::getDeclaredMethods) - .flatMap(Stream::of) - .filter(method -> !method.isSynthetic() && method.getAnnotation(GameTest.class) != null) - .map(method -> Pair.of(method, method.getAnnotation(GameTest.class))) - .map(method -> new TestFunction( - "gtceu", - GTCEu.MOD_ID + "." + method.getFirst().getDeclaringClass().getSimpleName() + "." + - method.getFirst().getName(), - method.getSecond().template(), - Rotation.NONE, - method.getSecond().timeoutTicks(), - method.getSecond().setupTicks(), - method.getSecond().required(), - method.getSecond().requiredSuccesses(), - method.getSecond().attempts(), - gameTestHelper -> { - try { - Object object = null; - if (!Modifier.isStatic(method.getFirst().getModifiers())) { - object = method.getFirst().getDeclaringClass().getConstructor().newInstance(); - } - method.getFirst().invoke(object, gameTestHelper); - } catch (ReflectiveOperationException e) { - throw new RuntimeException(e); - } - })) - .sorted(Comparator.comparing(TestFunction::getTestName)) - .toList(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/ParallelLogicTest.java b/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/ParallelLogicTest.java deleted file mode 100644 index 86fd638bd9..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/ParallelLogicTest.java +++ /dev/null @@ -1,139 +0,0 @@ -package com.gregtechceu.gtceu.test.api.machine.trait; - -import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.common.data.GTMaterials; -import com.gregtechceu.gtceu.common.data.GTRecipeModifiers; -import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; - -import com.lowdragmc.lowdraglib.side.item.IItemTransfer; - -import net.minecraft.core.BlockPos; -import net.minecraft.gametest.framework.GameTest; -import net.minecraft.gametest.framework.GameTestHelper; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.fluids.capability.IFluidHandler; - -public class ParallelLogicTest { - - @GameTest(template = "gtceu:ebf") - public void getMaxRecipeMultiplier_FluidLimitTest(GameTestHelper helper) { - BlockEntity holder = helper.getBlockEntity(new BlockPos(1, 1, 0)); - if (!(holder instanceof MetaMachineBlockEntity atte)) { - helper.fail("wrong block at relative pos [1,1,0]!"); - return; - } - MetaMachine machine = atte.getMetaMachine(); - if (!(machine instanceof IRecipeLogicMachine rlm)) { - helper.fail("wrong machine in MetaMachineBlockEntity!"); - return; - } - - int parallelLimit = 4; - - // Create a simple recipe to be used for testing - GTRecipe recipe = GTRecipeBuilder.ofRaw() - .inputItems(new ItemStack(Blocks.COBBLESTONE)) - .inputFluids(GTMaterials.Acetone.getFluid(4000)) - .outputItems(new ItemStack(Blocks.STONE)) - .blastFurnaceTemp(1000) - .EUt(30).duration(100) - .buildRawRecipe(); - - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP)).insertItem(0, - new ItemStack(Blocks.COBBLESTONE, 16), false); - ((IFluidHandler) rlm.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP)) - .fill(GTMaterials.Acetone.getFluid(8000), IFluidHandler.FluidAction.EXECUTE); - - var paralleled = GTRecipeModifiers.accurateParallel(machine, recipe, parallelLimit, false); - - helper.assertTrue(paralleled.getSecond() == 2, - "Expected Parallel amount to be 2, is %s.".formatted(paralleled.getSecond())); - - helper.succeed(); - } - - @GameTest(template = "gtceu:ebf") - public void getMaxRecipeMultiplier_LimitFailureTest(GameTestHelper helper) { - BlockEntity holder = helper.getBlockEntity(new BlockPos(1, 1, 0)); - if (!(holder instanceof MetaMachineBlockEntity atte)) { - helper.fail("wrong block at relative pos [1,1,0]!"); - return; - } - MetaMachine machine = atte.getMetaMachine(); - if (!(machine instanceof IRecipeLogicMachine rlm)) { - helper.fail("wrong machine in MetaMachineBlockEntity!"); - return; - } - - int parallelLimit = 4; - - // Create a simple recipe to be used for testing - GTRecipe recipe = GTRecipeBuilder.ofRaw() - .inputItems(new ItemStack(Blocks.COBBLESTONE)) - .inputFluids(GTMaterials.Acetone.getFluid(1000)) - .outputItems(new ItemStack(Blocks.STONE)) - .blastFurnaceTemp(1000) - .EUt(30).duration(100) - .buildRawRecipe(); - - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP)).insertItem(0, - new ItemStack(Blocks.COBBLESTONE, 16), false); - ((IFluidHandler) rlm.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP)) - .fill(GTMaterials.Acetone.getFluid(8000), IFluidHandler.FluidAction.EXECUTE); - - var paralleled = GTRecipeModifiers.accurateParallel(machine, recipe, parallelLimit, false); - - helper.assertTrue(paralleled == null || paralleled.getSecond() == 0, - "Parallel is too high, should be 0, is %s.".formatted(paralleled.getSecond())); - - helper.succeed(); - } - - @GameTest(template = "gtceu:ebf") - public void getMaxRecipeMultiplier_ItemFailureTest(GameTestHelper helper) { - BlockEntity holder = helper.getBlockEntity(new BlockPos(1, 1, 0)); - if (!(holder instanceof MetaMachineBlockEntity atte)) { - helper.fail("wrong block at relative pos [1,1,0]!"); - return; - } - MetaMachine machine = atte.getMetaMachine(); - if (!(machine instanceof IRecipeLogicMachine rlm)) { - helper.fail("wrong machine in MetaMachineBlockEntity!"); - return; - } - - int parallelLimit = 4; - - // Create a simple recipe to be used for testing - GTRecipe recipe = GTRecipeBuilder.ofRaw() - .inputItems(new ItemStack(Blocks.COBBLESTONE)) - .inputFluids(GTMaterials.Acetone.getFluid(100)) - .outputItems(new ItemStack(Blocks.STONE)) - .blastFurnaceTemp(1000) - .EUt(30).duration(100) - .buildRawRecipe(); - - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP)).insertItem(0, - new ItemStack(Blocks.COBBLESTONE, 16), false); - ((IFluidHandler) rlm.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP)) - .fill(GTMaterials.Naphtha.getFluid(8000), IFluidHandler.FluidAction.EXECUTE); - - var paralleled = GTRecipeModifiers.accurateParallel(machine, recipe, parallelLimit, false); - - helper.assertTrue(paralleled == null || paralleled.getSecond() == 0, - "Parallel is too high, should be 0, is %s.".formatted(paralleled.getSecond())); - - helper.succeed(); - } - - // TODO add the rest of - // https://github.com/GregTechCEu/GregTech/blob/master/src/test/java/gregtech/api/recipes/logic/ParallelLogicTest.java. -} diff --git a/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/RecipeLogicTest.java b/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/RecipeLogicTest.java deleted file mode 100644 index 7d9847c43d..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/api/machine/trait/RecipeLogicTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.gregtechceu.gtceu.test.api.machine.trait; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.common.data.GTRecipeTypes; -import com.gregtechceu.gtceu.core.mixins.RecipeManagerAccessor; -import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; - -import com.lowdragmc.lowdraglib.side.item.IItemTransfer; - -import net.minecraft.core.BlockPos; -import net.minecraft.gametest.framework.BeforeBatch; -import net.minecraft.gametest.framework.GameTest; -import net.minecraft.gametest.framework.GameTestHelper; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.entity.BlockEntity; - -import java.util.HashMap; - -public class RecipeLogicTest { - - private static boolean hasInjectedRecipe = false; - - @BeforeBatch(batch = GTCEu.MOD_ID) - public static void replaceRecipeManagerEntries(ServerLevel level) { - if (hasInjectedRecipe) return; - var recipes = new HashMap<>(((RecipeManagerAccessor) level.getRecipeManager()).getRawRecipes()); - ((RecipeManagerAccessor) level.getRecipeManager()).setRawRecipes(recipes); - recipes.replaceAll((k, v) -> new HashMap<>(v)); - } - - @GameTest(template = "gtceu:recipelogic") - public static void recipeLogicTest(GameTestHelper helper) { - // oops the BeforeBatch isn't registered. - RecipeLogicTest.replaceRecipeManagerEntries(helper.getLevel()); - - BlockEntity holder = helper.getBlockEntity(new BlockPos(0, 2, 0)); - if (!(holder instanceof MetaMachineBlockEntity atte)) { - helper.fail("wrong block at relative pos [0,1,0]!"); - return; - } - MetaMachine machine = atte.getMetaMachine(); - if (!(machine instanceof IRecipeLogicMachine rlm)) { - helper.fail("wrong machine in MetaMachineBlockEntity!"); - return; - } - - GTRecipe recipe = GTRecipeBuilder.ofRaw() - .id(GTCEu.id("test")) - .inputItems(new ItemStack(Blocks.COBBLESTONE)) - .outputItems(new ItemStack(Blocks.STONE)) - .EUt(1).duration(1) - .buildRawRecipe(); - // force insert the recipe into the manager. - - if (!hasInjectedRecipe) { - ((RecipeManagerAccessor) helper.getLevel().getRecipeManager()).getRawRecipes() - .get(GTRecipeTypes.CHEMICAL_RECIPES).put(GTCEu.id("test"), recipe); - hasInjectedRecipe = true; - } - - RecipeLogic arl = rlm.getRecipeLogic(); - - arl.findAndHandleRecipe(); - - // no recipe found - helper.assertFalse(arl.isActive(), "Recipe logic is active, even when it shouldn't be"); - helper.assertTrue(arl.getLastRecipe() == null, - "Recipe logic has somehow found a recipe, when there should be none"); - - // put an item in the inventory that will trigger recipe recheck - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP).get(0)).insertItem(0, - new ItemStack(Blocks.COBBLESTONE, 16), false); - // Inputs change. did we detect it ? - // helper.assertTrue(arl.isRecipeDirty(), "Recipe is not dirty"); - arl.findAndHandleRecipe(); - helper.assertFalse(arl.getLastRecipe() == null, - "Last recipe is empty, even though recipe logic should've found a recipe."); - helper.assertTrue(arl.isActive(), "Recipelogic is inactive, when it should be active."); - int stackCount = ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP).get(0)) - .getStackInSlot(0).getCount(); - helper.assertTrue(stackCount == 15, "Count is wrong (should be 15, when it's %s".formatted(stackCount)); - - // Save a reference to the old recipe so we can make sure it's getting reused - GTRecipe prev = arl.getLastRecipe(); - - // Finish the recipe, the output should generate, and the next iteration should begin - arl.serverTick(); - helper.assertTrue(arl.getLastRecipe() == prev, "lastRecipe is wrong"); - helper.assertTrue(ItemStack.isSameItem( - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP).get(0)) - .getStackInSlot(0), - new ItemStack(Blocks.STONE, 1)), "wrong output stack."); - helper.assertTrue(arl.isActive(), "RecipeLogic is not active, when it should be."); - - // Complete the second iteration, but the machine stops because its output is now full - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP).get(0)).setStackInSlot(0, - new ItemStack(Blocks.STONE, 63)); - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP).get(0)).setStackInSlot(1, - new ItemStack(Blocks.STONE, 64)); - arl.serverTick(); - helper.assertFalse(arl.isActive(), "RecipeLogic is active, when it shouldn't be."); - - // Try to process again and get failed out because of full buffer. - arl.serverTick(); - helper.assertFalse(arl.isActive(), "Recipelogic is active, when it shouldn't be."); - - // Some room is freed in the output bus, so we can continue now. - ((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP).get(0)).setStackInSlot(1, - ItemStack.EMPTY); - arl.serverTick(); - // helper.assertTrue(arl.isActive(), "Recipelogic is inactive."); - helper.assertTrue(ItemStack - .isSameItem(((IItemTransfer) rlm.getCapabilitiesProxy().get(IO.OUT, ItemRecipeCapability.CAP).get(0)) - .getStackInSlot(0), new ItemStack(Blocks.STONE, 1)), - "Wrong stack."); - - // Finish. - helper.succeed(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/test/common/machine/multiblock/PowerSubstationTest.java b/src/main/java/com/gregtechceu/gtceu/test/common/machine/multiblock/PowerSubstationTest.java deleted file mode 100644 index 6c0960d4eb..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/common/machine/multiblock/PowerSubstationTest.java +++ /dev/null @@ -1,414 +0,0 @@ -/* - * package com.gregtechceu.gtceu.test.common.machine.multiblock; - * - * - * public class PowerSubstationTest { - * - * @GameTest(template = "gtceu:pss") - * public void Test_1_Slot(GameTestHelper helper) { - * BlockEntity be = helper.getBlockEntity(new BlockPos(2, 2, 0)); - * if (!(be instanceof IMachineBlockEntity mbe)) { - * helper.fail("wrong block at pos [2, 2, 0]! (not a machine block entity)"); - * return; - * } - * if (!(mbe.getMetaMachine() instanceof PowerSubstationMachine pss)) { - * helper.fail("wrong machine at pos [2, 2, 0]! (not a Power Substation)"); - * return; - * } - * - * PowerSubstationMachine.PowerStationEnergyBank storage = createStorage(pss, 100); - * helper.assertTrue(storage.getCapacity().equals(BigInteger.valueOf(100)), "Wrong max storage! was" + - * storage.getCapacity() + ", expected 100"); - * - * // Random fill and drain tests - * long filled = storage.fill(50); - * helper.assertTrue(filled == 50, "Expected `fill` to return 50, was" + filled); - * helper.assertTrue(storage.getStored().equals(BigInteger.valueOf(50)), "Expected stored energy amount to be 50, was" + - * storage.getStored()); - * filled = storage.fill(100); - * helper.assertTrue(filled == 50, "Expected `fill` to return 50, was" + filled); - * helper.assertTrue(storage.getStored().equals(BigInteger.valueOf(100)), "Expected stored energy amount to be 100, was" - * + storage.getStored()); - * filled = storage.fill(100); - * helper.assertTrue(filled == 0, "Expected `fill` to return 0, was" + filled); - * helper.assertTrue(storage.getStored().equals(BigInteger.valueOf(100)), "Expected stored energy amount to be 100, was" - * + storage.getStored()); - * MatcherAssert.assertThat(storage.drain(50), is(50L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(50)); - * MatcherAssert.assertThat(storage.drain(100), is(50L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Fully fill and drain - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * MatcherAssert.assertThat(storage.fill(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Try to overfill and overdrain - * MatcherAssert.assertThat(storage.fill(1000), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * - * MatcherAssert.assertThat(storage.drain(1000), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * } - * - * @Test - * public void Test_4_Slot_Equal_Sizes() { - * PowerStationEnergyBank storage = createStorage(100, 100, 100, 100); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(400)); - * - * // No overlap of slots - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * MatcherAssert.assertThat(storage.fill(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Overlap slots - * MatcherAssert.assertThat(storage.fill(150), is(150L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(150)); - * MatcherAssert.assertThat(storage.fill(50), is(50L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.fill(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * MatcherAssert.assertThat(storage.fill(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * - * MatcherAssert.assertThat(storage.drain(150), is(150L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(250)); - * MatcherAssert.assertThat(storage.drain(50), is(50L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.drain(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Fully fill and drain - * MatcherAssert.assertThat(storage.fill(400), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * MatcherAssert.assertThat(storage.fill(400), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * - * MatcherAssert.assertThat(storage.drain(400), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(400), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Try to overfill and overdrain - * MatcherAssert.assertThat(storage.fill(1000), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(400)); - * - * MatcherAssert.assertThat(storage.drain(1000), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * } - * - * @Test - * public void Test_4_Slot_Different_Sizes() { - * PowerStationEnergyBank storage = createStorage(100, 200, 300, 400); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(1000)); - * - * // No overlap of slots - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * MatcherAssert.assertThat(storage.fill(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.fill(300), is(300L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(600)); - * MatcherAssert.assertThat(storage.fill(400), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * MatcherAssert.assertThat(storage.fill(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * - * MatcherAssert.assertThat(storage.drain(400), is(400L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(600)); - * MatcherAssert.assertThat(storage.drain(300), is(300L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.drain(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(100)); - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Overlap slots - * MatcherAssert.assertThat(storage.fill(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.fill(600), is(600L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(900)); - * MatcherAssert.assertThat(storage.fill(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * MatcherAssert.assertThat(storage.fill(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(900)); - * MatcherAssert.assertThat(storage.drain(600), is(600L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(300)); - * MatcherAssert.assertThat(storage.drain(100), is(100L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(200)); - * MatcherAssert.assertThat(storage.drain(200), is(200L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(100), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Fully fill and drain - * MatcherAssert.assertThat(storage.fill(1000), is(1000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * MatcherAssert.assertThat(storage.fill(1000), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * - * MatcherAssert.assertThat(storage.drain(1000), is(1000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * MatcherAssert.assertThat(storage.drain(1000), is(0L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Try to overfill and overdrain - * MatcherAssert.assertThat(storage.fill(10000), is(1000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1000)); - * - * MatcherAssert.assertThat(storage.drain(10000), is(1000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * } - * - * @SuppressWarnings("NumericOverflow") - * - * @Test - * public void Test_Over_Long() { - * PowerStationEnergyBank storage = createStorage(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(Long.MAX_VALUE, Long.MAX_VALUE, Long.MAX_VALUE)); - * - * long halfLong = Long.MAX_VALUE / 2; - * - * MatcherAssert.assertThat(storage.fill(halfLong), is(halfLong)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(halfLong)); - * MatcherAssert.assertThat(storage.fill(Long.MAX_VALUE), is(Long.MAX_VALUE)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(halfLong, Long.MAX_VALUE)); - * - * MatcherAssert.assertThat(storage.drain(halfLong), is(halfLong)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(Long.MAX_VALUE)); - * MatcherAssert.assertThat(storage.drain(Long.MAX_VALUE), is(Long.MAX_VALUE)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(0)); - * - * // Test overflow - * Assertions.assertThrows(IllegalArgumentException.class, () -> storage.fill(Long.MAX_VALUE + 1000)); - * Assertions.assertThrows(IllegalArgumentException.class, () -> storage.drain(Long.MAX_VALUE + 1000)); - * } - * - * @Test - * public void Test_Rebuild_Storage() { - * PowerStationEnergyBank storage = createStorage(100, 500, 4000); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(4600)); - * - * // Set up the storage with some amount of energy - * MatcherAssert.assertThat(storage.fill(3000), is(3000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(3000)); - * - * // Rebuild with more storage than needed - * storage = rebuildStorage(storage, 1000, 4000, 4000); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(9000)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(3000)); - * - * // Reset - * storage = createStorage(100, 500, 4000); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(4600)); - * - * // Set up storage with energy again - * MatcherAssert.assertThat(storage.fill(3000), is(3000L)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(3000)); - * - * // Rebuild with less storage than needed - * storage = rebuildStorage(storage, 100, 100, 400, 500); - * MatcherAssert.assertThat(storage.getCapacity(), isBigInt(1100)); - * MatcherAssert.assertThat(storage.getStored(), isBigInt(1100)); - * } - * - * @Test - * public void Test_Optimized_Big_Integer_Summarize() { - * Consumer testRunner = r -> { - * BigInteger summation = BigInteger.ZERO; - * long[] storageValues = new long[9 * MAX_BATTERY_LAYERS]; - * for (int i = 0; i < storageValues.length; i++) { - * long randomLong = Math.abs(r.nextLong()); - * storageValues[i] = randomLong; - * summation = summation.add(BigInteger.valueOf(randomLong)); - * } - * - * PowerStationEnergyBank storage = createStorage(storageValues); - * MatcherAssert.assertThat(storage.getCapacity(), is(summation)); - * }; - * - * for (int i = 0; i < 100; i++) { - * testRunner.accept(new Random()); - * } - * } - * - * @Test - * public void Test_Passive_Drain_Calculation() { - * // 100kEU/t per storage block "too large" (like max long) - * PowerStationEnergyBank storage = createStorage(Long.MAX_VALUE, Long.MAX_VALUE); - * MatcherAssert.assertThat(storage.getPassiveDrainPerTick(), - * is(2 * PASSIVE_DRAIN_MAX_PER_STORAGE)); - * - * Consumer testRunner = r -> { - * int numTruncated = 0; - * BigInteger nonTruncated = BigInteger.ZERO; - * - * long[] storageValues = new long[9 * MAX_BATTERY_LAYERS]; - * for (int i = 0; i < storageValues.length; i++) { - * long randomLong = Math.abs(r.nextLong()); - * storageValues[i] = randomLong; - * if (randomLong / PASSIVE_DRAIN_DIVISOR >= PASSIVE_DRAIN_MAX_PER_STORAGE) { - * numTruncated++; - * } else { - * nonTruncated = nonTruncated.add(BigInteger.valueOf(randomLong)); - * } - * } - * - * PowerStationEnergyBank testStorage = createStorage(storageValues); - * MatcherAssert.assertThat(testStorage.getPassiveDrainPerTick(), - * is(nonTruncated.divide(BigInteger.valueOf(PASSIVE_DRAIN_DIVISOR)) - * .add(BigInteger.valueOf(numTruncated * PASSIVE_DRAIN_MAX_PER_STORAGE)) - * .longValue())); - * }; - * - * for (int i = 0; i < 100; i++) { - * testRunner.accept(new Random()); - * } - * } - * - * @Test - * public void Test_Fill_Drain_Randomized() { - * Consumer testRunner = r -> { - * BigInteger totalStorage = BigInteger.ZERO; - * long[] storageValues = new long[9 * MAX_BATTERY_LAYERS]; - * for (int i = 0; i < storageValues.length; i++) { - * long randomLong = Math.abs(r.nextLong()); - * storageValues[i] = randomLong; - * totalStorage = totalStorage.add(BigInteger.valueOf(randomLong)); - * } - * - * PowerStationEnergyBank storage = createStorage(storageValues); - * - * // test capacity - * MatcherAssert.assertThat(storage.getCapacity(), is(totalStorage)); - * - * // test fill - * BigInteger amountToFill = totalStorage; - * do { - * long randomLong = Math.abs(r.nextLong()); - * BigInteger randomBigInt = BigInteger.valueOf(randomLong); - * - * if (amountToFill.compareTo(randomBigInt) <= 0) { - * MatcherAssert.assertThat(storage.fill(randomLong), is(amountToFill.longValue())); - * amountToFill = BigInteger.ZERO; - * } else { - * MatcherAssert.assertThat(storage.fill(randomLong), is(randomLong)); - * amountToFill = amountToFill.subtract(randomBigInt); - * } - * } while (!amountToFill.equals(BigInteger.ZERO)); - * - * // test drain - * BigInteger amountToDrain = totalStorage; - * do { - * long randomLong = Math.abs(r.nextLong()); - * BigInteger randomBigInt = BigInteger.valueOf(randomLong); - * - * if (amountToDrain.compareTo(randomBigInt) <= 0) { - * MatcherAssert.assertThat(storage.drain(randomLong), is(amountToDrain.longValue())); - * amountToDrain = BigInteger.ZERO; - * } else { - * MatcherAssert.assertThat(storage.drain(randomLong), is(randomLong)); - * amountToDrain = amountToDrain.subtract(randomBigInt); - * } - * } while (!amountToDrain.equals(BigInteger.ZERO)); - * }; - * - * for (int i = 0; i < 100; i++) { - * testRunner.accept(new Random()); - * } - * } - * - * private static Matcher isBigInt(long value, long... additional) { - * BigInteger retVal = BigInteger.valueOf(value); - * if (additional != null) { - * for (long l : additional) { - * retVal = retVal.add(BigInteger.valueOf(l)); - * } - * } - * return is(retVal); - * } - * - * private static PowerSubstationMachine.PowerStationEnergyBank createStorage(MetaMachine machine, long... - * storageValues) { - * List batteries = new ArrayList<>(); - * for (long value : storageValues) { - * batteries.add(new TestBattery(value)); - * } - * return new PowerSubstationMachine.PowerStationEnergyBank(machine, batteries); - * } - * - * private static PowerSubstationMachine.PowerStationEnergyBank - * rebuildStorage(PowerSubstationMachine.PowerStationEnergyBank storage, long... storageValues) { - * List batteries = new ArrayList<>(); - * for (long value : storageValues) { - * batteries.add(new TestBattery(value)); - * } - * return storage.rebuild(batteries); - * } - * - * private static class TestBattery implements IBatteryData { - * - * private final long capacity; - * - * private TestBattery(long capacity) { - * this.capacity = capacity; - * } - * - * @Override - * public long getCapacity() { - * return capacity; - * } - * - * // not used in this test - * - * @Override - * public int getTier() { - * return 0; - * } - * - * // not used in this test - * - * @NotNull - * - * @Override - * public String getBatteryName() { - * return ""; - * } - * } - * } - */ diff --git a/src/main/java/com/gregtechceu/gtceu/test/forge/GTGameTestsImpl.java b/src/main/java/com/gregtechceu/gtceu/test/forge/GTGameTestsImpl.java deleted file mode 100644 index f1963914c4..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/forge/GTGameTestsImpl.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gregtechceu.gtceu.test.forge; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.test.GTGameTests; - -import net.minecraftforge.event.RegisterGameTestsEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; - -@Mod.EventBusSubscriber(modid = GTCEu.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) -public class GTGameTestsImpl { - - @SubscribeEvent - public static void registerGameTests(RegisterGameTestsEvent event) { - event.register(GTGameTests.class); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java b/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java index 378ca529cb..6d2ddb57cf 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java @@ -163,7 +163,7 @@ public static class DataStickCopyScannerLogic implements GTRecipeType.ICustomRec @Override public GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var itemInputs = holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP).stream() + var itemInputs = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(IItemHandlerModifiable.class::isInstance) .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new); From d644eda091a62ebde633d51569380395d72b9509 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Thu, 12 Dec 2024 02:21:58 -0700 Subject: [PATCH 03/29] stuff kinda works --- .../gtceu/api/item/tool/ToolHelper.java | 11 ++--- .../WorkableElectricMultiblockMachine.java | 8 ++-- .../api/machine/steam/SimpleSteamMachine.java | 5 +- .../gtceu/api/recipe/RecipeRunner.java | 2 - .../api/recipe/lookup/GTRecipeLookup.java | 46 +++++++++++-------- .../electric/ActiveTransformerMachine.java | 28 ++++------- .../multiblock/electric/CleanroomMachine.java | 15 +++--- .../electric/DistillationTowerMachine.java | 18 +++++++- .../electric/FluidDrillMachine.java | 2 +- .../electric/LargeMinerMachine.java | 22 ++++----- .../electric/PowerSubstationMachine.java | 27 +++++------ .../electric/research/DataBankMachine.java | 14 +++--- .../electric/research/HPCAMachine.java | 20 ++++---- .../research/NetworkSwitchMachine.java | 12 +++-- .../primitive/PrimitivePumpMachine.java | 27 +++++------ .../steam/SteamParallelMultiblockMachine.java | 16 ++++--- .../machine/MEPatternBufferPartMachine.java | 19 +++++--- .../MEPatternBufferProxyPartMachine.java | 19 ++++---- .../gtceu/utils/DummyMachineBlockEntity.java | 4 +- .../gtceu/utils/DummyRecipeLogicMachine.java | 7 ++- 20 files changed, 174 insertions(+), 148 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index e14e4832eb..ec30040d4e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.item.IGTTool; import com.gregtechceu.gtceu.api.item.tool.aoe.AoESymmetrical; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.content.Content; @@ -412,16 +413,14 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It // Stack lists can be immutable going into Recipe#matches barring no rewrites // Search for forge hammer recipes from all drops individually (only LV or under) - Table, List>> caps = Tables - .newCustomTable(new EnumMap<>(IO.class), IdentityHashMap::new); + Map> caps = new IdentityHashMap<>(); DummyMachineBlockEntity be = new DummyMachineBlockEntity(GTValues.LV, GTRecipeTypes.FORGE_HAMMER_RECIPES, GTMachines.defaultTankSizeFunction, caps); - caps.put(IO.IN, EURecipeCapability.CAP, List.of(new InfiniteEnergyContainer(be.getMetaMachine(), + caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new InfiniteEnergyContainer(be.getMetaMachine(), GTValues.V[GTValues.LV], GTValues.V[GTValues.LV], 1, GTValues.V[GTValues.LV], 1))); - caps.put(IO.IN, ItemRecipeCapability.CAP, List.of(new NotifiableItemStackHandler(be.getMetaMachine(), 1, + caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 1, IO.IN, IO.IN, (slots) -> new CustomItemStackHandler(silktouchDrop)))); - caps.put(IO.OUT, ItemRecipeCapability.CAP, - List.of(new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); + caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); be.getMetaMachine().reinitializeCapabilities(caps); Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java index e248549e6e..8e902f6616 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java @@ -189,16 +189,16 @@ public long getOverclockVoltage() { public EnergyContainerList getEnergyContainer() { List containers = new ArrayList<>(); - var capabilities = capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP); - if (capabilities != null) { + var capabilities = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + if (!capabilities.isEmpty()) { for (IRecipeHandler handler : capabilities) { if (handler instanceof IEnergyContainer container) { containers.add(container); } } } else { - capabilities = capabilitiesProxy.get(IO.OUT, EURecipeCapability.CAP); - if (capabilities != null) { + capabilities = capabilitiesProxy.get(IO.OUT).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + if (!capabilities.isEmpty()) { for (IRecipeHandler handler : capabilities) { if (handler instanceof IEnergyContainer container) { containers.add(container); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java index 18fec5a333..d0d1da96c2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java @@ -14,6 +14,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; @@ -88,8 +89,8 @@ protected NotifiableItemStackHandler createExportItemHandler(@SuppressWarnings(" public void onLoad() { super.onLoad(); // Fine, we use it to provide eu cap for recipe, simulating an EU machine. - capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, - List.of(new SteamEnergyRecipeHandler(steamTank, 1d))); + capabilitiesProxy.computeIfAbsent(IO.IN, i -> new ArrayList<>()) + .add(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(steamTank, 1d))); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 442976f05a..28bb794ed1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -67,8 +67,6 @@ public RecipeHandlingResult handle(Map, List> entri fillContentMatchList(entries); - if (capability == null) - return null; return this.handleContents(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 3050b23f24..981488b3ff 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -59,24 +59,27 @@ public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { protected List> prepareRecipeFind(@NotNull IRecipeCapabilityHolder holder) { // First, check if items and fluids are valid. int totalSize = 0; - for (Map.Entry, List>> entries : holder.getCapabilitiesProxy().row(IO.IN) - .entrySet()) { - int size = 0; - if (!entries.getKey().isRecipeSearchFilter()) { - continue; - } - for (IRecipeHandler entry : entries.getValue()) { - if (entry.getSize() != -1) { - size += entry.getSize(); + var recipeList = holder.getCapabilitiesProxy().get(IO.IN).stream().toList(); + + for(var handler : recipeList) { + for (Map.Entry, List>> entries : handler.handlerMap.entrySet()) { + int size = 0; + if (!entries.getKey().isRecipeSearchFilter()) { + continue; + } + for (IRecipeHandler entry : entries.getValue()) { + if (entry.getSize() != -1) { + size += entry.getSize(); + } } + if (size == Integer.MAX_VALUE) { + return null; + } + totalSize += size; } - if (size == Integer.MAX_VALUE) { + if (totalSize == 0) { return null; } - totalSize += size; - } - if (totalSize == 0) { - return null; } // Build input. @@ -428,9 +431,16 @@ protected List> fromRecipe(@NotNull GTRecipe r) { @NotNull protected List> fromHolder(@NotNull IRecipeCapabilityHolder r) { - List> list = new ObjectArrayList<>( - r.getCapabilitiesProxy().row(IO.IN).values().size()); - r.getCapabilitiesProxy().row(IO.IN).forEach((cap, handlers) -> { + var recipeList = r.getCapabilitiesProxy().get(IO.IN).stream().toList(); + int size = 0; + for(var handler : recipeList) { + for(var entry : handler.handlerMap.entrySet()) { + size += entry.getValue().size(); + } + } + + List> list = new ObjectArrayList<>(size); + r.getCapabilitiesProxy().get(IO.IN).forEach(v -> v.handlerMap.forEach((cap, handlers) -> { if (cap.isRecipeSearchFilter() && !handlers.isEmpty()) { for (IRecipeHandler handler : handlers) { if (handler.isProxy()) { @@ -442,7 +452,7 @@ protected List> fromHolder(@NotNull IRecipeCapabilit } } } - }); + })); return list; } 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 4abe67ef8f..ef4118c4f0 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 @@ -92,26 +92,18 @@ public void onStructureFormed() { var handlerList = part.getRecipeHandlers(); if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - handlerList.getCapability(EURecipeCapability.CAP).stream() + var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> { - if() - }); - - for (var handler : part.getRecipeHandlers()) { - var handlerIO = handler.getHandlerIO(); - // If IO not compatible - if (io != IO.BOTH && handlerIO != IO.BOTH && io != handlerIO) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - if (handlerIO == IO.IN) { - powerInput.add(container); - } else if (handlerIO == IO.OUT) { - powerOutput.add(container); - } - traitSubscriptions.add(handler.addChangedListener(converterSubscription::updateSubscription)); - } + .map(v -> (IEnergyContainer)v) + .toList(); + + if(handlerList.getHandlerIO() == IO.IN) { + powerInput.addAll(containers); + } else if(handlerList.getHandlerIO() == IO.OUT) { + powerOutput.addAll(containers); } + + traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription)); } // Invalidate the structure if there is not at least one output and one input 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 267b6be956..c2157aced0 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 @@ -184,14 +184,13 @@ protected void initializeAbilities() { if (isPartIgnored(part)) continue; IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE || io == IO.OUT) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - } - } + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer)v)); + if (part instanceof IMaintenanceMachine maintenanceMachine) { getRecipeLogic().setMaintenanceMachine(maintenanceMachine); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index b344406e38..543a97d7bd 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -93,14 +93,28 @@ public void onStructureFormed() { var part = parts.get(outputIndex); if (part.self().getPos().getY() == y) { - part.getRecipeHandlers().stream() + part.getRecipeHandlers().handlerMap.forEach((cap, handler) -> { + boolean found = false; + if(handler instanceof IFluidHandler fluidHandler) { + found = true; + fluidOutputs.add(fluidHandler); + if(firstValid == null) { + firstValid = fluidHandler; + } + } else { + fluidOutputs.add(VoidFluidHandler.INSTANCE); + } + }); + + /*part.getRecipeHandlers().stream() .filter(IFluidHandler.class::isInstance) .findFirst() .ifPresentOrElse(h -> { fluidOutputs.add((IFluidHandler) h); if (firstValid == null) firstValid = (IFluidHandler) h; }, - () -> fluidOutputs.add(VoidFluidHandler.INSTANCE)); + () -> fluidOutputs.add(VoidFluidHandler.INSTANCE));*/ + outputIndex++; } else if (part.self().getPos().getY() > y) { fluidOutputs.add(VoidFluidHandler.INSTANCE); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FluidDrillMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FluidDrillMachine.java index 9ee7a09b0d..946e9e230e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FluidDrillMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FluidDrillMachine.java @@ -62,7 +62,7 @@ public FluidDrillLogic getRecipeLogic() { } public int getEnergyTier() { - var energyContainer = this.getCapabilitiesProxy().get(IO.IN, EURecipeCapability.CAP); + var energyContainer = this.getCapabilitiesFlat(IO.IN, EURecipeCapability.CAP); if (energyContainer == null) return this.tier; var energyCont = new EnergyContainerList(energyContainer.stream().filter(IEnergyContainer.class::isInstance) .map(IEnergyContainer.class::cast).toList()); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java index 3f16efe5f8..7b2f84ebce 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java @@ -139,18 +139,16 @@ private void initializeAbilities() { for (IMultiPart part : getParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - var handlerIO = io == IO.BOTH ? handler.getHandlerIO() : io; - if (handlerIO == IO.IN && handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - } else if (handlerIO == IO.IN && handler.getCapability() == FluidRecipeCapability.CAP && - handler instanceof IFluidHandler fluidHandler) { - fluidTanks.add(fluidHandler); - } - } + + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer)v)); + handlerList.getCapability(FluidRecipeCapability.CAP).stream() + .filter(v -> v instanceof IFluidHandler) + .forEach(v -> fluidTanks.add((IFluidHandler)v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.inputFluidInventory = new FluidHandlerList(fluidTanks); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java index 2bf3899227..ac2046906b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java @@ -101,20 +101,21 @@ public void onStructureFormed() { if (part instanceof IMaintenanceMachine maintenanceMachine) { this.maintenance = maintenanceMachine; } - for (var handler : part.getRecipeHandlers()) { - var handlerIO = handler.getHandlerIO(); - // If IO not compatible - if (io != IO.BOTH && handlerIO != IO.BOTH && io != handlerIO) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - if (handlerIO == IO.IN) { - inputs.add(container); - } else if (handlerIO == IO.OUT) { - outputs.add(container); - } - traitSubscriptions.add(handler.addChangedListener(tickSubscription::updateSubscription)); - } + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .map(v -> (IEnergyContainer)v) + .toList(); + + if(handlerList.getHandlerIO() == IO.IN) { + inputs.addAll(containers); + } else if(handlerList.getHandlerIO() == IO.OUT) { + outputs.addAll(containers); } + + traitSubscriptions.addAll(handlerList.addChangeListeners(tickSubscription::updateSubscription)); } this.inputHatches = new EnergyContainerList(inputs); this.outputHatches = new EnergyContainerList(outputs); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java index 8d6ffb8339..f5c656680e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java @@ -67,14 +67,12 @@ public void onStructureFormed() { this.maintenance = maintenanceMachine; } if (io == IO.NONE || io == IO.OUT) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - } - } + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer)v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.energyUsage = calculateEnergyUsage(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index e0d55da620..433679f408 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -111,17 +111,15 @@ public void onStructureFormed() { this.maintenance = maintenanceMachine; } if (io == IO.NONE || io == IO.OUT) continue; - for (var handler : part.getRecipeHandlers()) { - // If IO not compatible - if (io != IO.BOTH && handler.getHandlerIO() != IO.BOTH && io != handler.getHandlerIO()) continue; - if (handler.getCapability() == EURecipeCapability.CAP && - handler instanceof IEnergyContainer container) { - energyContainers.add(container); - } else if (handler.getCapability() == FluidRecipeCapability.CAP && - handler instanceof IFluidHandler fluidHandler) { - coolantContainers.add(fluidHandler); - } - } + var handlerList = part.getRecipeHandlers(); + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer)v)); + handlerList.getCapability(FluidRecipeCapability.CAP).stream() + .filter(v -> v instanceof IFluidHandler) + .forEach(v -> coolantContainers.add((IFluidHandler)v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.coolantHandler = new FluidHandlerList(coolantContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java index f402658b8a..5288bc05e6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.IOpticalComputationHatch; import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; +import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; @@ -60,6 +61,7 @@ public void onStructureFormed() { List receivers = new ArrayList<>(); List transmitters = new ArrayList<>(); for (var part : this.getParts()) { + var handlerList = part.getRecipeHandlers(); if (part instanceof IOpticalComputationHatch hatch) { Block block = part.self().getBlockState().getBlock(); if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { @@ -68,10 +70,10 @@ public void onStructureFormed() { if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { transmitters.add(hatch); } - } else if (part.getRecipeHandlers().stream().anyMatch(IOpticalComputationHatch.class::isInstance)) { - var hatch = part.getRecipeHandlers().stream().filter(IOpticalComputationHatch.class::isInstance) - .map(IOpticalComputationHatch.class::cast).findFirst().orElse(null); - if (hatch != null) { + } else if (false/*|| part.getRecipeHandlers().getCapability(CWURecipeCapability.CAP).stream().anyMatch(IOpticalComputationHatch.class::isInstance)*/) { + /*var hatch = part.getRecipeHandlers().stream().filter(IOpticalComputationHatch.class::isInstance) + .map(IOpticalComputationHatch.class::cast).findFirst().orElse(null);*/ + /*if (hatch != null) { Block block = part.self().getBlockState().getBlock(); if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { receivers.add(hatch); @@ -79,7 +81,7 @@ public void onStructureFormed() { if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { transmitters.add(hatch); } - } + }*/ } } computationHandler.onStructureForm(receivers, transmitters); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java index 567c7a98c0..721eb9d544 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java @@ -52,19 +52,20 @@ public void onStructureFormed() { private void initializeTank() { for (IMultiPart part : getParts()) { - for (var handler : part.getRecipeHandlers()) { - if (handler.getHandlerIO() == IO.OUT && handler.getCapability() == FluidRecipeCapability.CAP) { - fluidTank = (NotifiableFluidTank) handler; - long tankCapacity = fluidTank.getTankCapacity(0); - if (tankCapacity == FluidType.BUCKET_VOLUME) { - hatchModifier = 1; - } else if (tankCapacity == FluidType.BUCKET_VOLUME * 8) { - hatchModifier = 2; - } else { - hatchModifier = 4; - } - return; + var handlerList = part.getRecipeHandlers(); + + var recipeCap = handlerList.getCapability(FluidRecipeCapability.CAP); + if (handlerList.getHandlerIO() == IO.OUT && !recipeCap.isEmpty()) { + fluidTank = (NotifiableFluidTank) recipeCap.get(0); + long tankCapacity = fluidTank.getTankCapacity(0); + if (tankCapacity == FluidType.BUCKET_VOLUME) { + hatchModifier = 1; + } else if (tankCapacity == FluidType.BUCKET_VOLUME * 8) { + hatchModifier = 2; + } else { + hatchModifier = 4; } + return; } } } @@ -101,7 +102,7 @@ private void produceWater() { if (fluidTank == null) initializeTank(); if (fluidTank != null) { fluidTank.handleRecipe(IO.OUT, null, - List.of(FluidIngredient.of(GTMaterials.Water.getFluid(getFluidProduction()))), null, false); + List.of(FluidIngredient.of(GTMaterials.Water.getFluid(getFluidProduction()))), false); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index baf3459537..3a782ad86b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamEnergyRecipeHandler; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; @@ -59,19 +60,21 @@ public SteamParallelMultiblockMachine(IMachineBlockEntity holder, Object... args @Override public void onStructureFormed() { super.onStructureFormed(); - var handlers = capabilitiesProxy.get(IO.IN, FluidRecipeCapability.CAP); - if (handlers == null) return; + var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).toList(); + if (handlers.isEmpty()) return; var itr = handlers.iterator(); while (itr.hasNext()) { var handler = itr.next(); if (handler instanceof NotifiableFluidTank tank) { if (tank.isFluidValid(0, GTMaterials.Steam.getFluid(1))) { itr.remove(); - if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { + capabilitiesProxy.computeIfAbsent(IO.IN, c -> new ArrayList<>()) + .add(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, CONVERSION_RATE))); + /*if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, new ArrayList<>()); } capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP) - .add(new SteamEnergyRecipeHandler(tank, CONVERSION_RATE)); + .add(new SteamEnergyRecipeHandler(tank, CONVERSION_RATE));*/ return; } } @@ -102,9 +105,8 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec public void addDisplayText(List textList) { IDisplayUIMachine.super.addDisplayText(textList); if (isFormed()) { - var handlers = capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP); - if (handlers != null && handlers.size() > 0 && - handlers.get(0) instanceof SteamEnergyRecipeHandler steamHandler) { + var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + if (!handlers.isEmpty() && handlers.get(0) instanceof SteamEnergyRecipeHandler steamHandler) { if (steamHandler.getCapacity() > 0) { long steamStored = steamHandler.getStored(); textList.add(Component.translatable("gtceu.multiblock.steam.steam_stored", steamStored, diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index 22556ec766..e168a57714 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.integration.ae2.machine; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -15,6 +16,7 @@ import com.gregtechceu.gtceu.api.machine.fancyconfigurator.FancyTankConfigurator; import com.gregtechceu.gtceu.api.machine.feature.IHasCircuitSlot; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; +import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; @@ -184,13 +186,16 @@ public void onLoad() { } })); } - getRecipeHandlers().forEach(handler -> handler.addChangedListener(() -> getProxies().forEach(proxy -> { - if (handler.getCapability() == ItemRecipeCapability.CAP) { - proxy.itemProxyHandler.notifyListeners(); - } else { - proxy.fluidProxyHandler.notifyListeners(); - } - }))); + getRecipeHandlers().handlerMap.forEach((cap,handler) -> handler.stream() + .filter(v -> v instanceof IRecipeHandlerTrait) + .forEach(u -> ((IRecipeHandlerTrait) u).addChangedListener(() -> getProxies().forEach(proxy -> { + if(cap == ItemRecipeCapability.CAP) { + proxy.itemProxyHandler.notifyListeners(); + } else if(cap == FluidRecipeCapability.CAP) { + proxy.fluidProxyHandler.notifyListeners(); + } + }))) + ); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java index 953f8f5475..a1c03e6288 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java @@ -75,15 +75,18 @@ public boolean setBuffer(@Nullable BlockPos pos) { List> itemHandlers = new ArrayList<>(); List> fluidHandlers = new ArrayList<>(); - for (var handler : machine.getRecipeHandlers()) { - if (handler.isProxy()) continue; - - if (handler.getCapability() == ItemRecipeCapability.CAP) { - itemHandlers.add((NotifiableRecipeHandlerTrait) handler); - } else { - fluidHandlers.add((NotifiableRecipeHandlerTrait) handler); + var handlerList = machine.getRecipeHandlers(); + handlerList.handlerMap.forEach((cap, handlers) -> { + for(var handler : handlers) { + if (handler.isProxy()) continue; + + if (handler.getCapability() == ItemRecipeCapability.CAP) { + itemHandlers.add((NotifiableRecipeHandlerTrait) handler); + } else { + fluidHandlers.add((NotifiableRecipeHandlerTrait) handler); + } } - } + }); itemProxyHandler.setHandlers(itemHandlers); fluidProxyHandler.setHandlers(fluidHandlers); diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java index 6f5d7f28e9..0127e97bd6 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.lowdragmc.lowdraglib.syncdata.managed.MultiManagedStorage; @@ -15,6 +16,7 @@ import lombok.Getter; import java.util.List; +import java.util.Map; /** * Dummy machine BE used for wrapping {@link DummyRecipeLogicMachine}s @@ -27,7 +29,7 @@ public class DummyMachineBlockEntity implements IMachineBlockEntity { private final MachineDefinition definition; public DummyMachineBlockEntity(int tier, GTRecipeType type, Int2IntFunction tankScalingFunction, - Table, List>> capabilitiesProxy, + Map> capabilitiesProxy, Object... args) { this.definition = MachineDefinition.createDefinition(GTCEu.id("dummy")); this.definition.setRecipeTypes(new GTRecipeType[] { type }); diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java index f52d413db5..acaf04c79e 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java @@ -8,9 +8,11 @@ import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.google.common.collect.Table; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.List; +import java.util.Map; /** * Dummy machine used for searching recipes outside of a machine. @@ -18,14 +20,15 @@ public class DummyRecipeLogicMachine extends WorkableTieredMachine implements IRecipeLogicMachine { public DummyRecipeLogicMachine(IMachineBlockEntity be, int tier, Int2IntFunction tankScalingFunction, - Table, List>> capabilitiesProxy, + Map> capabilitiesProxy, Object... args) { super(be, tier, tankScalingFunction, args); reinitializeCapabilities(capabilitiesProxy); } - public void reinitializeCapabilities(Table, List>> caps) { + public void reinitializeCapabilities(Map> caps) { this.capabilitiesProxy.clear(); + this.capabilitiesProxy.putAll(caps); } } From c7db522cbeaebc764f90d7b283e3c53920c9e29d Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Thu, 12 Dec 2024 17:08:29 -0700 Subject: [PATCH 04/29] some recipe action stuff, gotta fix handler map still --- .../gtceu/api/machine/trait/RecipeLogic.java | 12 ++++++++- .../gtceu/api/recipe/RecipeHandler.java | 27 +++++++++---------- .../gtceu/api/recipe/RecipeRunner.java | 5 ++-- .../api/recipe/lookup/GTRecipeLookup.java | 9 ++++--- .../research/ResearchStationMachine.java | 4 +-- .../steam/SteamParallelMultiblockMachine.java | 3 ++- 6 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index b556ff765c..db977f88b5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -227,7 +227,17 @@ public void serverTick() { protected RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { var recipeConditions = RecipeHandler.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) .findFirst(); - return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); + if(recipeConditions.isPresent()) { + return recipeConditions.get(); + } + var match = RecipeHandler.matchRecipe(this.machine, recipe); + var matchTick = RecipeHandler.matchTickRecipe(this.machine, recipe); + if(!match.isSuccess()) + return match; + if(!matchTick.isSuccess()) + return matchTick; + return RecipeHandler.ActionResult.SUCCESS; + //return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); } public boolean checkMatchedRecipeAvailable(GTRecipe match) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java index 3cb72ec74b..d616c182e8 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java @@ -33,7 +33,7 @@ public static ActionResult matchTickRecipe(IRecipeCapabilityHolder holder, GTRec private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, boolean tick) { if (!holder.hasCapabilityProxies()) - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + return ActionResult.FAIL_NO_CAPABILITIES; var result = handleRecipe(IO.IN, holder, recipe, tick ? recipe.tickInputs : recipe.inputs, Collections.emptyMap(), tick, true); @@ -47,7 +47,7 @@ private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe public static ActionResult handleRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, Map, Object2IntMap> chanceCaches) { if (!holder.hasCapabilityProxies() || io == IO.BOTH) - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_capability_proxies")); + return ActionResult.FAIL_NO_CAPABILITIES; return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, false); } @@ -55,7 +55,7 @@ public static ActionResult handleRecipeIO(IO io, IRecipeCapabilityHolder holder, public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, Map, Object2IntMap> chanceCaches) { if (!holder.hasCapabilityProxies() || io == IO.BOTH) - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.no_tick_capability_proxies")); + return ActionResult.FAIL_NO_CAPABILITIES; return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, true, false); } @@ -72,19 +72,14 @@ public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, G Map, Object2IntMap> chanceCaches, boolean isTick, boolean simulated) { RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); - for (Map.Entry, List> entry : contents.entrySet()) { - var handle = runner.handle(contents); - if (handle == null) - continue; - - if (handle.content() != null) { - String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); - return ActionResult.fail(() -> Component.translatable(key) - .append(": ").append(handle.capability().getName())); - } - return handle.result(); + var handle = runner.handle(contents); + + if (handle == null || handle.content() != null) { + String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); + return ActionResult.fail(() -> Component.translatable(key) + .append(": ").append(handle.capability().getName())); } - return ActionResult.SUCCESS; + return handle.result(); /* * RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, false); @@ -336,6 +331,8 @@ public record ActionResult(boolean isSuccess, @Nullable Supplier reas public final static ActionResult SUCCESS = new ActionResult(true, null); public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); + public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, () -> Component.translatable("gtceu.recipe_logic.no_contents")); + public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); public static ActionResult fail(@Nullable Supplier component) { return new ActionResult(false, component); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 28bb794ed1..b0b5321f81 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -55,7 +55,7 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.chanceCaches = chanceCaches; this.capabilityProxies = holder.getCapabilitiesProxy(); this.recipeContents = new IdentityHashMap<>(); - this.searchRecipeContents = new IdentityHashMap<>(); + this.searchRecipeContents = simulated ? recipeContents : new IdentityHashMap<>(); this.simulated = simulated; } @@ -67,6 +67,8 @@ public RecipeHandlingResult handle(Map, List> entri fillContentMatchList(entries); + if(searchRecipeContents.isEmpty()) + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.PASS_NO_CONTENTS); return this.handleContents(); } @@ -135,7 +137,6 @@ private RecipeHandlingResult handleContents() { } private RecipeHandlingResult handleContentsInternal(IO capIO) { - // noinspection DataFlowIssue checked above. var handlers = new ArrayList<>(capabilityProxies.get(capIO)); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 981488b3ff..1858c6f8df 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -62,7 +62,7 @@ protected List> prepareRecipeFind(@NotNull IRecipeCa var recipeList = holder.getCapabilitiesProxy().get(IO.IN).stream().toList(); for(var handler : recipeList) { - for (Map.Entry, List>> entries : handler.handlerMap.entrySet()) { + for (var entries : handler.handlerMap.entrySet()) { int size = 0; if (!entries.getKey().isRecipeSearchFilter()) { continue; @@ -77,9 +77,10 @@ protected List> prepareRecipeFind(@NotNull IRecipeCa } totalSize += size; } - if (totalSize == 0) { - return null; - } + } + + if (totalSize == 0) { + return null; } // Build input. diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 6aab715ab9..9643501a7f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -196,7 +196,7 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { public RecipeHandler.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + .FAIL_NO_CAPABILITIES; return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, true); } @@ -205,7 +205,7 @@ public RecipeHandler.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IReci if (recipe.hasTick()) { if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + .FAIL_NO_CAPABILITIES; return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), false, true); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index 3a782ad86b..d2834e0be4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.ParametersAreNonnullByDefault; @@ -60,7 +61,7 @@ public SteamParallelMultiblockMachine(IMachineBlockEntity holder, Object... args @Override public void onStructureFormed() { super.onStructureFormed(); - var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).toList(); + var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).collect(Collectors.toList()); if (handlers.isEmpty()) return; var itr = handlers.iterator(); while (itr.hasNext()) { From 8a613b609b36809ea65193c9ea450e367a2c71ae Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 01:41:43 -0700 Subject: [PATCH 05/29] distinctness works in item and dual hatches :lets: --- .../recipe/IRecipeCapabilityHolder.java | 11 ++++++++--- .../recipe/ItemRecipeCapability.java | 2 +- .../api/machine/WorkableTieredMachine.java | 7 +++++++ .../multiblock/WorkableMultiblockMachine.java | 16 ++++++++++++++++ .../part/MultiblockPartMachine.java | 19 ++++++++++++------- .../machine/steam/SteamWorkableMachine.java | 7 +++++++ .../api/machine/trait/RecipeHandlerList.java | 6 +++++- .../gtceu/api/recipe/RecipeRunner.java | 10 +++++++--- .../multiblock/part/DualHatchPartMachine.java | 1 + .../multiblock/part/ItemBusPartMachine.java | 1 + .../machine/trait/miner/MinerLogic.java | 8 ++++++++ .../trait/MEPatternBufferRecipeHandler.java | 1 + 12 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index e7d9fa6264..d96a55c77a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.capability.recipe; import com.google.common.collect.Table; +import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import org.jetbrains.annotations.NotNull; @@ -17,8 +18,12 @@ default boolean hasCapabilityProxies() { @NotNull Map> getCapabilitiesProxy(); - default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { - return getCapabilitiesProxy().getOrDefault(io, Collections.emptyList()) - .stream().flatMap(rhl -> rhl.getCapability(cap).stream()).map(i -> (IRecipeHandler)i).toList(); + Map, List>>> getCapabilitiesFlat(); + + default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { + if(getCapabilitiesProxy().get(io) == null) { + return Collections.emptyList(); + } + return getCapabilitiesFlat().get(io).get(cap); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java index 1bb4816265..f7b1c997c5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java @@ -384,7 +384,7 @@ private Object2IntMap getIngredientStacks(IRecipeCapabilityHolder hol ItemStackHashStrategy.comparingAllButCount()); Object2IntMap result = new Object2IntOpenHashMap<>(); - List> recipeHandlerList = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() + var recipeHandlerList = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(handler -> !handler.isProxy()).toList(); for (IRecipeHandler container : recipeHandlerList) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 7cbd626df2..2c7259c7d9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -69,6 +69,8 @@ public abstract class WorkableTieredMachine extends TieredEnergyMachine implemen public final NotifiableComputationContainer exportComputation; @Getter protected final Map> capabilitiesProxy; + @Getter + protected Map, List>>> capabilitiesFlat; @Persisted @Getter protected int overclockTier; @@ -88,6 +90,7 @@ public WorkableTieredMachine(IMachineBlockEntity holder, int tier, Int2IntFuncti this.activeRecipeType = 0; this.tankScalingFunction = tankScalingFunction; this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); + this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); this.recipeLogic = createRecipeLogic(args); this.importItems = createImportItemHandler(args); @@ -169,6 +172,8 @@ public void onLoad() { for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); + capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) + .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } @@ -185,6 +190,8 @@ public void onUnload() { super.onUnload(); traitSubscriptions.forEach(ISubscription::unsubscribe); traitSubscriptions.clear(); + capabilitiesProxy.clear(); + capabilitiesFlat.clear(); recipeLogic.inValid(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 818b64f9ad..e0b3527811 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -69,6 +69,8 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach private int activeRecipeType; @Getter protected final Map> capabilitiesProxy; + @Getter + protected Map, List>>> capabilitiesFlat; protected final List traitSubscriptions; @Getter @Setter @@ -86,6 +88,7 @@ public WorkableMultiblockMachine(IMachineBlockEntity holder, Object... args) { this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); + this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); } @@ -119,6 +122,7 @@ public void onStructureFormed() { // attach parts' traits activeBlocks = getMultiblockState().getMatchContext().getOrDefault("vaBlocks", LongSets.emptySet()); capabilitiesProxy.clear(); + capabilitiesFlat.clear(); traitSubscriptions.forEach(ISubscription::unsubscribe); traitSubscriptions.clear(); Map ioMap = getMultiblockState().getMatchContext().getOrCreate("ioMap", Long2ObjectMaps::emptyMap); @@ -130,6 +134,10 @@ public void onStructureFormed() { if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; capabilitiesProxy.computeIfAbsent(handlerList.getHandlerIO(), i -> new ArrayList<>()).add(handlerList); + var inner = capabilitiesFlat.computeIfAbsent(handlerList.getHandlerIO(), i -> new Object2ObjectOpenHashMap<>()); + for(var cap : handlerList.handlerMap.entrySet()) { + inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); + } traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } @@ -139,6 +147,8 @@ public void onStructureFormed() { for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); + capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) + .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } @@ -146,6 +156,10 @@ public void onStructureFormed() { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + var inner = capabilitiesFlat.computeIfAbsent(entry.getKey(), i -> new Object2ObjectOpenHashMap<>()); + for(var cap : handlerList.handlerMap.entrySet()) { + inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); + } traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } // schedule recipe logic @@ -158,6 +172,7 @@ public void onStructureInvalid() { updateActiveBlocks(false); activeBlocks = null; capabilitiesProxy.clear(); + capabilitiesFlat.clear(); traitSubscriptions.forEach(ISubscription::unsubscribe); traitSubscriptions.clear(); // reset recipe Logic @@ -170,6 +185,7 @@ public void onPartUnload() { updateActiveBlocks(false); activeBlocks = null; capabilitiesProxy.clear(); + capabilitiesFlat.clear(); traitSubscriptions.forEach(ISubscription::unsubscribe); traitSubscriptions.clear(); // fine some parts invalid now. diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index 21e7e6dfef..d18688280a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -41,6 +41,8 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { @RequireRerender protected final Set controllerPositions; + protected RecipeHandlerList handlerList; + public MultiblockPartMachine(IMachineBlockEntity holder) { super(holder); this.controllerPositions = new HashSet<>(); @@ -77,14 +79,17 @@ public List getControllers() { } public RecipeHandlerList getRecipeHandlers() { - var a = traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) - .toList(); - if(a.isEmpty()) { - return new RecipeHandlerList(IO.NONE); + if(handlerList == null) { + var a = traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) + .toList(); + if (a.isEmpty()) { + handlerList = new RecipeHandlerList(IO.NONE); + return handlerList; + } + handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); + handlerList.addHandler(a.toArray(new IRecipeHandler[0])); } - var l = new RecipeHandlerList(a.get(0).getHandlerIO()); - l.addHandler(a.toArray(new IRecipeHandler[0])); - return l; + return handlerList; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index 6f9d92cbfa..36e41e1b91 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -82,6 +82,8 @@ public abstract class SteamWorkableMachine extends SteamMachine protected boolean previouslyMuffled = true; @Getter protected final Map> capabilitiesProxy; + @Getter + protected Map, List>>> capabilitiesFlat; protected final List traitSubscriptions; public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, Object... args) { @@ -90,6 +92,7 @@ public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); + this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); this.traitSubscriptions = new ArrayList<>(); this.outputFacing = hasFrontFacing() ? getFrontFacing().getOpposite() : Direction.UP; } @@ -111,6 +114,8 @@ public void onLoad() { for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); + capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) + .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } @@ -131,6 +136,8 @@ public void onUnload() { super.onUnload(); traitSubscriptions.forEach(ISubscription::unsubscribe); traitSubscriptions.clear(); + capabilitiesProxy.clear(); + capabilitiesFlat.clear(); recipeLogic.inValid(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index 25e635cfd2..a94bbdf68f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -61,11 +61,15 @@ public List addChangeListeners(Runnable listener) { } public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { + if(handlerMap.isEmpty()) return contents; var copy = new IdentityHashMap<>(contents); var it = copy.entrySet().iterator(); while(it.hasNext()) { var entry = it.next(); - for(var handler : handlerMap.get(entry.getKey())) { + var handlerList = handlerMap.get(entry.getKey()); + if(handlerList == null) + continue; + for(var handler : handlerList) { var left = handler.handleRecipe(io, recipe, entry.getValue(), simulate); if(left == null) { it.remove(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index b0b5321f81..46c1428298 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -126,17 +126,20 @@ private void fillContentMatchList(Map, List> entrie @Nullable private RecipeHandlingResult handleContents() { + if(recipeContents.isEmpty()) { + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + } var result = handleContentsInternal(io); if (!result.result.isSuccess()) { return result; } - if(recipeContents.isEmpty()) { - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); - } return handleContentsInternal(IO.BOTH); } private RecipeHandlingResult handleContentsInternal(IO capIO) { + if(!capabilityProxies.containsKey(capIO)) + return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + // noinspection DataFlowIssue checked above. var handlers = new ArrayList<>(capabilityProxies.get(capIO)); @@ -158,6 +161,7 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { if(!handled) { for(var handler : handlers) { + if(handler.isDistinct()) continue; if(!recipeContents.isEmpty()) { recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java index 3219e93ade..ff8d449453 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java @@ -166,6 +166,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { super.setDistinct(isDistinct); tank.setDistinct(isDistinct); + getRecipeHandlers().setDistinct(true); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java index 47499de668..542a5b3ba3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java @@ -142,6 +142,7 @@ public void setDistinct(boolean isDistinct) { getInventory().setDistinct(isDistinct); circuitInventory.setDistinct(isDistinct); combinedInventory.setDistinct(isDistinct); + getRecipeHandlers().setDistinct(isDistinct); } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 34a6a52f0f..cf08403072 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -121,6 +121,8 @@ public class MinerLogic extends RecipeLogic implements IRecipeCapabilityHolder { private boolean isInventoryFull; @Getter private final Map> capabilitiesProxy; + @Getter + protected Map, List>>> capabilitiesFlat; private final ItemRecipeHandler inputItemHandler, outputItemHandler; private final IgnoreEnergyRecipeHandler inputEnergyHandler; @Setter @@ -146,6 +148,7 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, this.pickaxeTool = GTItems.TOOL_ITEMS.get(GTMaterials.Neutronium, GTToolType.PICKAXE).get().get(); this.pickaxeTool.enchant(Enchantments.BLOCK_FORTUNE, fortune); this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); + this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); this.inputItemHandler = new ItemRecipeHandler(IO.IN, machine.getRecipeType().getMaxInputs(ItemRecipeCapability.CAP)); this.outputItemHandler = new ItemRecipeHandler(IO.OUT, @@ -160,6 +163,11 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, this.capabilitiesProxy.put(IO.IN, List.of(inHandlers)); this.capabilitiesProxy.put(IO.OUT, List.of(outHandlers)); + var inMap = this.capabilitiesFlat.put(IO.IN, new Object2ObjectOpenHashMap<>()); + var outMap = this.capabilitiesFlat.put(IO.OUT, new Object2ObjectOpenHashMap<>()); + inMap.put(ItemRecipeCapability.CAP, List.of(inputItemHandler)); + inMap.put(EURecipeCapability.CAP, List.of(inputEnergyHandler)); + outMap.put(ItemRecipeCapability.CAP, List.of(outputItemHandler)); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java index c910393aa0..8f0e30ab3a 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java @@ -169,6 +169,7 @@ public int getPriority() { @Override public boolean isDistinct() { + super.setDistinct(true); return true; } From 9ffec46485cc28b9df695c4a6a0a9a7f2758b0ee Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 02:49:37 -0700 Subject: [PATCH 06/29] add back non distinct searching --- .../gtceu/api/recipe/RecipeRunner.java | 27 +++++++++++++++---- .../multiblock/part/DualHatchPartMachine.java | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 46c1428298..1943988417 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -38,7 +38,7 @@ record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNu // These are only used to store mutable state during each invocation of handle() private RecipeCapability capability; - private Set> used; + private Set used; private Map, List> recipeContents; private Map, List> searchRecipeContents; /*@Getter @@ -142,13 +142,19 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { // noinspection DataFlowIssue checked above. var handlers = new ArrayList<>(capabilityProxies.get(capIO)); + List distinct = new ArrayList<>(), nondistinct = new ArrayList<>(); + for(var handler : handlers) { + if(handler.isDistinct()) + distinct.add(handler); + else + nondistinct.add(handler); + } //handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); // handle distinct first boolean handled = false; - for (var handler : handlers) { - if (!handler.isDistinct()) continue; + for (var handler : distinct) { var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); if (res.isEmpty()) { if(!simulated) { @@ -160,8 +166,7 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } if(!handled) { - for(var handler : handlers) { - if(handler.isDistinct()) continue; + for(var handler : nondistinct) { if(!recipeContents.isEmpty()) { recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); } @@ -172,6 +177,18 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } } + if(!handled) { + for (var handler : distinct) { + if (!recipeContents.isEmpty()) { + var res = handler.handleRecipe(io, recipe, recipeContents, simulated); + if (res.isEmpty()) { + handled = true; + break; + } + } + } + } + if(handled) { return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java index ff8d449453..caa37522c2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java @@ -166,7 +166,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { super.setDistinct(isDistinct); tank.setDistinct(isDistinct); - getRecipeHandlers().setDistinct(true); + getRecipeHandlers().setDistinct(isDistinct); } @Override From dd8f671e73ed088f47e0aca778d69f45702e4403 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 02:53:17 -0700 Subject: [PATCH 07/29] spotless --- .../recipe/FluidRecipeCapability.java | 5 +- .../recipe/IRecipeCapabilityHolder.java | 5 +- .../api/capability/recipe/IRecipeHandler.java | 1 - .../gtceu/api/item/tool/ToolHelper.java | 15 ++--- .../api/machine/WorkableTieredMachine.java | 4 +- .../feature/multiblock/IMultiPart.java | 1 - .../WorkableElectricMultiblockMachine.java | 6 +- .../multiblock/WorkableMultiblockMachine.java | 13 ++-- .../part/MultiblockPartMachine.java | 5 +- .../api/machine/steam/SimpleSteamMachine.java | 1 - .../steam/SteamEnergyRecipeHandler.java | 2 - .../machine/steam/SteamWorkableMachine.java | 6 +- .../trait/FluidHandlerProxyRecipeTrait.java | 1 - .../trait/ItemHandlerProxyRecipeTrait.java | 1 - .../machine/trait/NotifiableFluidTank.java | 1 - .../api/machine/trait/RecipeHandlerList.java | 26 ++++---- .../gtceu/api/machine/trait/RecipeLogic.java | 8 +-- .../api/misc/IgnoreEnergyRecipeHandler.java | 2 - .../gtceu/api/misc/ItemRecipeHandler.java | 1 - .../gtceu/api/recipe/RecipeHandler.java | 6 +- .../gtceu/api/recipe/RecipeRunner.java | 61 +++++++++---------- .../api/recipe/lookup/GTRecipeLookup.java | 7 +-- .../electric/ActiveTransformerMachine.java | 6 +- .../electric/AssemblyLineMachine.java | 1 - .../multiblock/electric/CleanroomMachine.java | 2 +- .../electric/DistillationTowerMachine.java | 22 ++++--- .../electric/FusionReactorMachine.java | 2 +- .../electric/LargeMinerMachine.java | 4 +- .../electric/PowerSubstationMachine.java | 6 +- .../electric/research/DataBankMachine.java | 2 +- .../electric/research/HPCAMachine.java | 4 +- .../research/NetworkSwitchMachine.java | 32 ++++++---- .../research/ResearchStationMachine.java | 9 ++- .../multiblock/steam/LargeBoilerMachine.java | 1 - .../steam/SteamParallelMultiblockMachine.java | 18 +++--- .../machine/trait/NotifiableStressTrait.java | 1 - .../trait/customlogic/CannerLogic.java | 3 - .../trait/customlogic/FormingPressLogic.java | 1 - .../machine/trait/miner/MinerLogic.java | 4 +- .../machine/MEPatternBufferPartMachine.java | 15 +++-- .../MEPatternBufferProxyPartMachine.java | 2 +- .../MEPatternBufferProxyRecipeHandler.java | 1 - .../trait/MEPatternBufferRecipeHandler.java | 1 - .../ae2/slot/ExportOnlyAEItemList.java | 1 - .../gtceu/utils/DummyMachineBlockEntity.java | 3 - .../gtceu/utils/DummyRecipeLogicMachine.java | 5 +- 46 files changed, 151 insertions(+), 173 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java index be3598145a..8ae17e3d28 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/FluidRecipeCapability.java @@ -152,7 +152,7 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu int maxMultiplier = multiplier; OverlayedTankHandler overlayedFluidHandler = new OverlayedTankHandler( - holder.getCapabilitiesFlat(IO.OUT, FluidRecipeCapability.CAP).stream() + holder.getCapabilitiesFlat(IO.OUT, FluidRecipeCapability.CAP).stream() .filter(NotifiableFluidTank.class::isInstance) .map(NotifiableFluidTank.class::cast) .toList()); @@ -197,8 +197,7 @@ public int limitParallel(GTRecipe recipe, IRecipeCapabilityHolder holder, int mu @Override public int getMaxParallelRatio(IRecipeCapabilityHolder holder, GTRecipe recipe, int parallelAmount) { // Find all the fluids in the combined Fluid Input inventories and create oversized FluidStacks - Map fluidStacks = holder. - getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() + Map fluidStacks = holder.getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() .map(container -> container.getContents().stream().filter(FluidStack.class::isInstance) .map(FluidStack.class::cast).toList()) .flatMap(container -> GTHashMaps.fromFluidCollection(container).entrySet().stream()) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index d96a55c77a..09af339acb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -1,8 +1,7 @@ package com.gregtechceu.gtceu.api.capability.recipe; -import com.google.common.collect.Table; -import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; + import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -21,7 +20,7 @@ default boolean hasCapabilityProxies() { Map, List>>> getCapabilitiesFlat(); default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { - if(getCapabilitiesProxy().get(io) == null) { + if (getCapabilitiesProxy().get(io) == null) { return Collections.emptyList(); } return getCapabilitiesFlat().get(io).get(cap); diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java index 6e44ec59eb..d4c702f821 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeHandler.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.api.recipe.GTRecipe; import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import org.jetbrains.annotations.Nullable; import java.util.Comparator; import java.util.List; diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index ec30040d4e..29adff550f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -65,8 +65,6 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -416,11 +414,14 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It Map> caps = new IdentityHashMap<>(); DummyMachineBlockEntity be = new DummyMachineBlockEntity(GTValues.LV, GTRecipeTypes.FORGE_HAMMER_RECIPES, GTMachines.defaultTankSizeFunction, caps); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new InfiniteEnergyContainer(be.getMetaMachine(), - GTValues.V[GTValues.LV], GTValues.V[GTValues.LV], 1, GTValues.V[GTValues.LV], 1))); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 1, - IO.IN, IO.IN, (slots) -> new CustomItemStackHandler(silktouchDrop)))); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); + caps.computeIfAbsent(IO.IN, i -> new ArrayList()) + .add(RecipeHandlerList.of(IO.IN, new InfiniteEnergyContainer(be.getMetaMachine(), + GTValues.V[GTValues.LV], GTValues.V[GTValues.LV], 1, GTValues.V[GTValues.LV], 1))); + caps.computeIfAbsent(IO.IN, i -> new ArrayList()) + .add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 1, + IO.IN, IO.IN, (slots) -> new CustomItemStackHandler(silktouchDrop)))); + caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add( + RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); be.getMetaMachine().reinitializeCapabilities(caps); Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 2c7259c7d9..cf7763bd7f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -12,8 +12,6 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; @@ -177,7 +175,7 @@ public void onLoad() { } } - for(var entry : ioTraits.entrySet()) { + for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java index 643a2875c3..6404e0c2ae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java @@ -4,7 +4,6 @@ import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineFeature; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; -import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java index 8e902f6616..31ec1e06f5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java @@ -189,7 +189,8 @@ public long getOverclockVoltage() { public EnergyContainerList getEnergyContainer() { List containers = new ArrayList<>(); - var capabilities = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + var capabilities = capabilitiesProxy.get(IO.IN).stream() + .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); if (!capabilities.isEmpty()) { for (IRecipeHandler handler : capabilities) { if (handler instanceof IEnergyContainer container) { @@ -197,7 +198,8 @@ public EnergyContainerList getEnergyContainer() { } } } else { - capabilities = capabilitiesProxy.get(IO.OUT).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + capabilities = capabilitiesProxy.get(IO.OUT).stream() + .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); if (!capabilities.isEmpty()) { for (IRecipeHandler handler : capabilities) { if (handler instanceof IEnergyContainer container) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index e0b3527811..a491baab0c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -23,15 +23,13 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.longs.LongSets; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -134,8 +132,9 @@ public void onStructureFormed() { if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; capabilitiesProxy.computeIfAbsent(handlerList.getHandlerIO(), i -> new ArrayList<>()).add(handlerList); - var inner = capabilitiesFlat.computeIfAbsent(handlerList.getHandlerIO(), i -> new Object2ObjectOpenHashMap<>()); - for(var cap : handlerList.handlerMap.entrySet()) { + var inner = capabilitiesFlat.computeIfAbsent(handlerList.getHandlerIO(), + i -> new Object2ObjectOpenHashMap<>()); + for (var cap : handlerList.handlerMap.entrySet()) { inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); } traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); @@ -152,12 +151,12 @@ public void onStructureFormed() { } } - for(var entry : ioTraits.entrySet()) { + for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); var inner = capabilitiesFlat.computeIfAbsent(entry.getKey(), i -> new Object2ObjectOpenHashMap<>()); - for(var cap : handlerList.handlerMap.entrySet()) { + for (var cap : handlerList.handlerMap.entrySet()) { inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); } traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index d18688280a..3181370751 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -7,13 +7,12 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; - import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; + import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; -import lombok.Getter; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -79,7 +78,7 @@ public List getControllers() { } public RecipeHandlerList getRecipeHandlers() { - if(handlerList == null) { + if (handlerList == null) { var a = traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) .toList(); if (a.isEmpty()) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java index d0d1da96c2..5867680624 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.api.machine.steam; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java index ccec3c65d3..0ff0d08a5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java @@ -12,8 +12,6 @@ import net.minecraftforge.fluids.FluidStack; -import org.jetbrains.annotations.Nullable; - import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index 36e41e1b91..c8ee8e18dc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -23,7 +23,6 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -33,8 +32,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -119,7 +117,7 @@ public void onLoad() { } } - for(var entry : ioTraits.entrySet()) { + for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java index 5897162905..a0e2f523e1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java @@ -11,7 +11,6 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Getter; import lombok.Setter; -import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java index 681f8bef9a..8dd407a975 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java @@ -12,7 +12,6 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Getter; import lombok.Setter; -import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.List; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java index fe05568226..4be0502b02 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java @@ -20,7 +20,6 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.function.Predicate; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index a94bbdf68f..79bfa956b6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -4,9 +4,9 @@ import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; -import com.gregtechceu.gtceu.api.recipe.content.Content; + import com.lowdragmc.lowdraglib.syncdata.ISubscription; + import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; @@ -14,6 +14,7 @@ import java.util.*; public class RecipeHandlerList { + public Map, List>> handlerMap = new Object2ObjectOpenHashMap<>(); private IO io; @Setter @@ -35,7 +36,7 @@ public List> getCapability(RecipeCapability cap) { } public void addHandler(IRecipeHandler... handlers) { - for(var handler : handlers) { + for (var handler : handlers) { handlerMap.computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); } } @@ -50,9 +51,9 @@ public IO getHandlerIO() { public List addChangeListeners(Runnable listener) { List ret = new ArrayList<>(); - for(var handlerList : handlerMap.values()) { - for(var handler : handlerList) { - if(handler instanceof IRecipeHandlerTrait handlerTrait) { + for (var handlerList : handlerMap.values()) { + for (var handler : handlerList) { + if (handler instanceof IRecipeHandlerTrait handlerTrait) { ret.add(handlerTrait.addChangedListener(listener)); } } @@ -60,18 +61,19 @@ public List addChangeListeners(Runnable listener) { return ret; } - public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { - if(handlerMap.isEmpty()) return contents; + public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, + boolean simulate) { + if (handlerMap.isEmpty()) return contents; var copy = new IdentityHashMap<>(contents); var it = copy.entrySet().iterator(); - while(it.hasNext()) { + while (it.hasNext()) { var entry = it.next(); var handlerList = handlerMap.get(entry.getKey()); - if(handlerList == null) + if (handlerList == null) continue; - for(var handler : handlerList) { + for (var handler : handlerList) { var left = handler.handleRecipe(io, recipe, entry.getValue(), simulate); - if(left == null) { + if (left == null) { it.remove(); break; } else { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index db977f88b5..b7d8418703 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -227,17 +227,17 @@ public void serverTick() { protected RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { var recipeConditions = RecipeHandler.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) .findFirst(); - if(recipeConditions.isPresent()) { + if (recipeConditions.isPresent()) { return recipeConditions.get(); } var match = RecipeHandler.matchRecipe(this.machine, recipe); var matchTick = RecipeHandler.matchTickRecipe(this.machine, recipe); - if(!match.isSuccess()) + if (!match.isSuccess()) return match; - if(!matchTick.isSuccess()) + if (!matchTick.isSuccess()) return matchTick; return RecipeHandler.ActionResult.SUCCESS; - //return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); + // return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); } public boolean checkMatchedRecipeAvailable(GTRecipe match) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java index d0df34e3c8..afb42b47bc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/IgnoreEnergyRecipeHandler.java @@ -6,8 +6,6 @@ import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import org.jetbrains.annotations.Nullable; - import java.util.List; public class IgnoreEnergyRecipeHandler implements IRecipeHandler { diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java index 71866335d6..4b31639e03 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/ItemRecipeHandler.java @@ -12,7 +12,6 @@ import net.minecraft.world.item.crafting.Ingredient; import lombok.Getter; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java index d616c182e8..5cc7939b5b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java @@ -331,8 +331,10 @@ public record ActionResult(boolean isSuccess, @Nullable Supplier reas public final static ActionResult SUCCESS = new ActionResult(true, null); public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); - public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, () -> Component.translatable("gtceu.recipe_logic.no_contents")); - public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, + () -> Component.translatable("gtceu.recipe_logic.no_contents")); + public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, + () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); public static ActionResult fail(@Nullable Supplier component) { return new ActionResult(false, component); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 1943988417..9ffd6f3f1a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -2,16 +2,13 @@ import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; -import com.google.common.collect.Table; import it.unimi.dsi.fastutil.objects.Object2IntMap; -import lombok.Getter; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; @@ -41,9 +38,11 @@ record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNu private Set used; private Map, List> recipeContents; private Map, List> searchRecipeContents; - /*@Getter - private Map contentMatchList; - private @UnknownNullability List searchingMatchList;*/ + /* + * @Getter + * private Map contentMatchList; + * private @UnknownNullability List searchingMatchList; + */ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -63,11 +62,9 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, public RecipeHandlingResult handle(Map, List> entries) { initState(); - - fillContentMatchList(entries); - if(searchRecipeContents.isEmpty()) + if (searchRecipeContents.isEmpty()) return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.PASS_NO_CONTENTS); return this.handleContents(); @@ -75,8 +72,8 @@ public RecipeHandlingResult handle(Map, List> entri private void initState() { used = new HashSet<>(); - //contentMatchList = new ArrayList<>(); - //searchingMatchList = simulated ? contentMatchList : new ArrayList<>(); + // contentMatchList = new ArrayList<>(); + // searchingMatchList = simulated ? contentMatchList : new ArrayList<>(); } /** @@ -84,14 +81,14 @@ private void initState() { */ private void fillContentMatchList(Map, List> entries) { ChanceBoostFunction function = recipe.getType().getChanceFunction(); - for(var entry : entries.entrySet()) { + for (var entry : entries.entrySet()) { RecipeCapability cap = entry.getKey(); if (!cap.doMatchInRecipe()) { continue; } ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick); List chancedContents = new ArrayList<>(); - if(entry.getValue().isEmpty()) continue; + if (entry.getValue().isEmpty()) continue; this.recipeContents.putIfAbsent(cap, new ArrayList<>()); for (Content cont : entry.getValue()) { this.searchRecipeContents.computeIfAbsent(cap, c -> new ArrayList<>()).add(cont.content); @@ -110,15 +107,16 @@ private void fillContentMatchList(Map, List> entrie int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); int chanceTier = recipeTier + recipe.ocLevel; var cache = this.chanceCaches.get(cap); - chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, recipe.parallels); + chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, + recipe.parallels); for (Content cont : chancedContents) { this.recipeContents.get(cap).add(cont.content); } } - if(!recipeContents.get(cap).isEmpty()) {} - //recipeContents.put(cap, recipeContents.get(cap).stream().map(cap::copyContent).toList()); + if (!recipeContents.get(cap).isEmpty()) {} + // recipeContents.put(cap, recipeContents.get(cap).stream().map(cap::copyContent).toList()); else recipeContents.remove(cap); } @@ -126,7 +124,7 @@ private void fillContentMatchList(Map, List> entrie @Nullable private RecipeHandlingResult handleContents() { - if(recipeContents.isEmpty()) { + if (recipeContents.isEmpty()) { return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); } var result = handleContentsInternal(io); @@ -137,27 +135,27 @@ private RecipeHandlingResult handleContents() { } private RecipeHandlingResult handleContentsInternal(IO capIO) { - if(!capabilityProxies.containsKey(capIO)) + if (!capabilityProxies.containsKey(capIO)) return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); // noinspection DataFlowIssue checked above. var handlers = new ArrayList<>(capabilityProxies.get(capIO)); List distinct = new ArrayList<>(), nondistinct = new ArrayList<>(); - for(var handler : handlers) { - if(handler.isDistinct()) + for (var handler : handlers) { + if (handler.isDistinct()) distinct.add(handler); else nondistinct.add(handler); } - //handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); + // handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); // handle distinct first boolean handled = false; for (var handler : distinct) { var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); if (res.isEmpty()) { - if(!simulated) { + if (!simulated) { handler.handleRecipe(io, recipe, recipeContents, false); } handled = true; @@ -165,19 +163,19 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } } - if(!handled) { - for(var handler : nondistinct) { - if(!recipeContents.isEmpty()) { + if (!handled) { + for (var handler : nondistinct) { + if (!recipeContents.isEmpty()) { recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); } - if(recipeContents.isEmpty()) { + if (recipeContents.isEmpty()) { handled = true; break; } } } - if(!handled) { + if (!handled) { for (var handler : distinct) { if (!recipeContents.isEmpty()) { var res = handler.handleRecipe(io, recipe, recipeContents, simulated); @@ -189,13 +187,14 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } } - if(handled) { + if (handled) { return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); } - for(var entry : recipeContents.entrySet()) { - if(entry.getValue() != null && !entry.getValue().isEmpty()) { - return new RecipeHandlingResult(entry.getKey(), entry.getValue(), RecipeHandler.ActionResult.FAIL_NO_REASON); + for (var entry : recipeContents.entrySet()) { + if (entry.getValue() != null && !entry.getValue().isEmpty()) { + return new RecipeHandlingResult(entry.getKey(), entry.getValue(), + RecipeHandler.ActionResult.FAIL_NO_REASON); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 1858c6f8df..a057f6aef4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -61,7 +61,7 @@ protected List> prepareRecipeFind(@NotNull IRecipeCa int totalSize = 0; var recipeList = holder.getCapabilitiesProxy().get(IO.IN).stream().toList(); - for(var handler : recipeList) { + for (var handler : recipeList) { for (var entries : handler.handlerMap.entrySet()) { int size = 0; if (!entries.getKey().isRecipeSearchFilter()) { @@ -431,11 +431,10 @@ protected List> fromRecipe(@NotNull GTRecipe r) { */ @NotNull protected List> fromHolder(@NotNull IRecipeCapabilityHolder r) { - var recipeList = r.getCapabilitiesProxy().get(IO.IN).stream().toList(); int size = 0; - for(var handler : recipeList) { - for(var entry : handler.handlerMap.entrySet()) { + for (var handler : recipeList) { + for (var entry : handler.handlerMap.entrySet()) { size += entry.getValue().size(); } } 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 ef4118c4f0..384b5d7033 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 @@ -94,12 +94,12 @@ public void onStructureFormed() { var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer)v) + .map(v -> (IEnergyContainer) v) .toList(); - if(handlerList.getHandlerIO() == IO.IN) { + if (handlerList.getHandlerIO() == IO.IN) { powerInput.addAll(containers); - } else if(handlerList.getHandlerIO() == IO.OUT) { + } else if (handlerList.getHandlerIO() == IO.OUT) { powerOutput.addAll(containers); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java index 1bb515e8e2..1e8db776fa 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java @@ -2,7 +2,6 @@ import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; 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 c2157aced0..4542952ffe 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 @@ -189,7 +189,7 @@ protected void initializeAbilities() { handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer)v)); + .forEach(v -> energyContainers.add((IEnergyContainer) v)); if (part instanceof IMaintenanceMachine maintenanceMachine) { getRecipeLogic().setMaintenanceMachine(maintenanceMachine); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 543a97d7bd..f506f2adda 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -95,10 +95,10 @@ public void onStructureFormed() { if (part.self().getPos().getY() == y) { part.getRecipeHandlers().handlerMap.forEach((cap, handler) -> { boolean found = false; - if(handler instanceof IFluidHandler fluidHandler) { + if (handler instanceof IFluidHandler fluidHandler) { found = true; fluidOutputs.add(fluidHandler); - if(firstValid == null) { + if (firstValid == null) { firstValid = fluidHandler; } } else { @@ -106,14 +106,16 @@ public void onStructureFormed() { } }); - /*part.getRecipeHandlers().stream() - .filter(IFluidHandler.class::isInstance) - .findFirst() - .ifPresentOrElse(h -> { - fluidOutputs.add((IFluidHandler) h); - if (firstValid == null) firstValid = (IFluidHandler) h; - }, - () -> fluidOutputs.add(VoidFluidHandler.INSTANCE));*/ + /* + * part.getRecipeHandlers().stream() + * .filter(IFluidHandler.class::isInstance) + * .findFirst() + * .ifPresentOrElse(h -> { + * fluidOutputs.add((IFluidHandler) h); + * if (firstValid == null) firstValid = (IFluidHandler) h; + * }, + * () -> fluidOutputs.add(VoidFluidHandler.INSTANCE)); + */ outputIndex++; } else if (part.self().getPos().getY() > y) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java index fc29b7953b..ce67c481e0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java @@ -112,7 +112,7 @@ public void onStructureFormed() { handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer)v)); + .forEach(v -> energyContainers.add((IEnergyContainer) v)); traitSubscriptions.addAll(handlerList.addChangeListeners(this::updatePreHeatSubscription)); } this.inputEnergyContainers = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java index 7b2f84ebce..390497cc26 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java @@ -145,10 +145,10 @@ private void initializeAbilities() { handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer)v)); + .forEach(v -> energyContainers.add((IEnergyContainer) v)); handlerList.getCapability(FluidRecipeCapability.CAP).stream() .filter(v -> v instanceof IFluidHandler) - .forEach(v -> fluidTanks.add((IFluidHandler)v)); + .forEach(v -> fluidTanks.add((IFluidHandler) v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.inputFluidInventory = new FluidHandlerList(fluidTanks); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java index ac2046906b..e3fe94af1e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java @@ -106,12 +106,12 @@ public void onStructureFormed() { var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer)v) + .map(v -> (IEnergyContainer) v) .toList(); - if(handlerList.getHandlerIO() == IO.IN) { + if (handlerList.getHandlerIO() == IO.IN) { inputs.addAll(containers); - } else if(handlerList.getHandlerIO() == IO.OUT) { + } else if (handlerList.getHandlerIO() == IO.OUT) { outputs.addAll(containers); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java index f5c656680e..e2b297129c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java @@ -72,7 +72,7 @@ public void onStructureFormed() { handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer)v)); + .forEach(v -> energyContainers.add((IEnergyContainer) v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.energyUsage = calculateEnergyUsage(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index 433679f408..f9c986eb4e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -116,10 +116,10 @@ public void onStructureFormed() { handlerList.getCapability(EURecipeCapability.CAP).stream() .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer)v)); + .forEach(v -> energyContainers.add((IEnergyContainer) v)); handlerList.getCapability(FluidRecipeCapability.CAP).stream() .filter(v -> v instanceof IFluidHandler) - .forEach(v -> coolantContainers.add((IFluidHandler)v)); + .forEach(v -> coolantContainers.add((IFluidHandler) v)); } this.energyContainer = new EnergyContainerList(energyContainers); this.coolantHandler = new FluidHandlerList(coolantContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java index 5288bc05e6..948a86ed7d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.IOpticalComputationHatch; import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; -import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; @@ -70,18 +69,25 @@ public void onStructureFormed() { if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { transmitters.add(hatch); } - } else if (false/*|| part.getRecipeHandlers().getCapability(CWURecipeCapability.CAP).stream().anyMatch(IOpticalComputationHatch.class::isInstance)*/) { - /*var hatch = part.getRecipeHandlers().stream().filter(IOpticalComputationHatch.class::isInstance) - .map(IOpticalComputationHatch.class::cast).findFirst().orElse(null);*/ - /*if (hatch != null) { - Block block = part.self().getBlockState().getBlock(); - if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { - receivers.add(hatch); - } - if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { - transmitters.add(hatch); - } - }*/ + } else if (false/* + * || part.getRecipeHandlers().getCapability(CWURecipeCapability.CAP).stream().anyMatch( + * IOpticalComputationHatch.class::isInstance) + */) { + /* + * var hatch = part.getRecipeHandlers().stream().filter(IOpticalComputationHatch.class::isInstance) + * .map(IOpticalComputationHatch.class::cast).findFirst().orElse(null); + */ + /* + * if (hatch != null) { + * Block block = part.self().getBlockState().getBlock(); + * if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { + * receivers.add(hatch); + * } + * if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { + * transmitters.add(hatch); + * } + * } + */ } } computationHandler.onStructureForm(receivers, transmitters); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 9643501a7f..bdec551ae2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -67,7 +67,8 @@ public void onStructureFormed() { this.computationProvider = provider; } if (part instanceof IObjectHolder objectHolder) { - this.getCapabilitiesProxy().put(IO.IN, List.of(RecipeHandlerList.of(IO.IN, objectHolder.getAsHandler()))); + this.getCapabilitiesProxy().put(IO.IN, + List.of(RecipeHandlerList.of(IO.IN, objectHolder.getAsHandler()))); } } @@ -195,8 +196,7 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { } public RecipeHandler.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { - if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult - .FAIL_NO_CAPABILITIES; + if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult.FAIL_NO_CAPABILITIES; return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, true); } @@ -204,8 +204,7 @@ public RecipeHandler.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCa public RecipeHandler.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { if (recipe.hasTick()) { if (!holder.hasCapabilityProxies()) - return RecipeHandler.ActionResult - .FAIL_NO_CAPABILITIES; + return RecipeHandler.ActionResult.FAIL_NO_CAPABILITIES; return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), false, true); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java index be72c770af..02d40fe166 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java @@ -41,7 +41,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index d2834e0be4..56ee374a37 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -61,7 +61,8 @@ public SteamParallelMultiblockMachine(IMachineBlockEntity holder, Object... args @Override public void onStructureFormed() { super.onStructureFormed(); - var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).collect(Collectors.toList()); + var handlers = capabilitiesProxy.get(IO.IN).stream() + .flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).collect(Collectors.toList()); if (handlers.isEmpty()) return; var itr = handlers.iterator(); while (itr.hasNext()) { @@ -71,11 +72,13 @@ public void onStructureFormed() { itr.remove(); capabilitiesProxy.computeIfAbsent(IO.IN, c -> new ArrayList<>()) .add(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, CONVERSION_RATE))); - /*if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { - capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, new ArrayList<>()); - } - capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP) - .add(new SteamEnergyRecipeHandler(tank, CONVERSION_RATE));*/ + /* + * if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { + * capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, new ArrayList<>()); + * } + * capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP) + * .add(new SteamEnergyRecipeHandler(tank, CONVERSION_RATE)); + */ return; } } @@ -106,7 +109,8 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec public void addDisplayText(List textList) { IDisplayUIMachine.super.addDisplayText(textList); if (isFormed()) { - var handlers = capabilitiesProxy.get(IO.IN).stream().flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + var handlers = capabilitiesProxy.get(IO.IN).stream() + .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); if (!handlers.isEmpty() && handlers.get(0) instanceof SteamEnergyRecipeHandler steamHandler) { if (steamHandler.getCapacity() > 0) { long steamStored = steamHandler.getStored(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java index 4b966c7f22..ebe158f255 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java @@ -16,7 +16,6 @@ import lombok.Getter; import lombok.Setter; -import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.List; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java index 562d167511..e07a13d926 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java @@ -19,9 +19,6 @@ import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Objects; - public class CannerLogic implements GTRecipeType.ICustomRecipeLogic { @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java index 97abb269c2..cde2d7f1de 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java @@ -19,7 +19,6 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; -import java.util.Objects; import java.util.stream.Collectors; public class FormingPressLogic implements GTRecipeType.ICustomRecipeLogic { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index cf08403072..cd45058c48 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -24,7 +24,6 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.commands.arguments.blocks.BlockStateParser; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -43,9 +42,8 @@ import net.minecraftforge.common.Tags; import net.minecraftforge.items.IItemHandlerModifiable; -import com.google.common.collect.Table; -import com.google.common.collect.Tables; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index e168a57714..50adec039a 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -186,16 +186,15 @@ public void onLoad() { } })); } - getRecipeHandlers().handlerMap.forEach((cap,handler) -> handler.stream() + getRecipeHandlers().handlerMap.forEach((cap, handler) -> handler.stream() .filter(v -> v instanceof IRecipeHandlerTrait) .forEach(u -> ((IRecipeHandlerTrait) u).addChangedListener(() -> getProxies().forEach(proxy -> { - if(cap == ItemRecipeCapability.CAP) { - proxy.itemProxyHandler.notifyListeners(); - } else if(cap == FluidRecipeCapability.CAP) { - proxy.fluidProxyHandler.notifyListeners(); - } - }))) - ); + if (cap == ItemRecipeCapability.CAP) { + proxy.itemProxyHandler.notifyListeners(); + } else if (cap == FluidRecipeCapability.CAP) { + proxy.fluidProxyHandler.notifyListeners(); + } + })))); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java index a1c03e6288..68da2e1a56 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java @@ -77,7 +77,7 @@ public boolean setBuffer(@Nullable BlockPos pos) { List> fluidHandlers = new ArrayList<>(); var handlerList = machine.getRecipeHandlers(); handlerList.handlerMap.forEach((cap, handlers) -> { - for(var handler : handlers) { + for (var handler : handlers) { if (handler.isProxy()) continue; if (handler.getCapability() == ItemRecipeCapability.CAP) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java index 449f411841..a40c5f3e82 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java @@ -10,7 +10,6 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import lombok.Setter; -import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java index 8f0e30ab3a..242175942e 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java @@ -23,7 +23,6 @@ import lombok.Getter; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java index 4338782171..85d23c7299 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/slot/ExportOnlyAEItemList.java @@ -14,7 +14,6 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.function.Supplier; diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java index 0127e97bd6..8d3f1c5ef0 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java @@ -2,8 +2,6 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; @@ -11,7 +9,6 @@ import com.lowdragmc.lowdraglib.syncdata.managed.MultiManagedStorage; -import com.google.common.collect.Table; import it.unimi.dsi.fastutil.ints.Int2IntFunction; import lombok.Getter; diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java index acaf04c79e..9759c00e63 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java @@ -1,14 +1,11 @@ package com.gregtechceu.gtceu.utils; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.WorkableTieredMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; - -import com.google.common.collect.Table; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; + import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.List; From b45c7a8e389bd24c7287d286e8f21c773e55ff5f Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 03:06:43 -0700 Subject: [PATCH 08/29] fix npe --- .../gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index a057f6aef4..c455261f84 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeHandler; @@ -59,7 +60,8 @@ public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { protected List> prepareRecipeFind(@NotNull IRecipeCapabilityHolder holder) { // First, check if items and fluids are valid. int totalSize = 0; - var recipeList = holder.getCapabilitiesProxy().get(IO.IN).stream().toList(); + List recipeList = new ArrayList<>( + holder.getCapabilitiesProxy().getOrDefault(IO.IN, new ArrayList<>())); for (var handler : recipeList) { for (var entries : handler.handlerMap.entrySet()) { From aa06ec49be96edf23f779a127760ee7f92b6f5a3 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 20:38:51 -0700 Subject: [PATCH 09/29] refactor the static recipe helper methods into recipe helper, also fix duplicate ingredient counting in buses and default distinct mode set on world --- .../gtceu/api/item/tool/ToolHelper.java | 6 +- .../machine/feature/IRecipeLogicMachine.java | 4 +- .../gtceu/api/machine/trait/RecipeLogic.java | 44 +-- .../gtceu/api/recipe/RecipeHandler.java | 350 ------------------ .../gtceu/api/recipe/RecipeHelper.java | 339 ++++++++++++++++- .../gtceu/api/recipe/RecipeRunner.java | 14 +- .../api/recipe/lookup/GTRecipeLookup.java | 4 +- .../gtceu/common/commands/GTCommands.java | 4 +- .../gtceu/common/data/GTRecipeModifiers.java | 3 +- .../electric/DistillationTowerMachine.java | 20 +- .../research/ResearchStationMachine.java | 32 +- .../LargeCombustionEngineMachine.java | 9 +- .../multiblock/part/ItemBusPartMachine.java | 7 +- .../machine/trait/BedrockOreMinerLogic.java | 12 +- .../common/machine/trait/FluidDrillLogic.java | 12 +- .../machine/trait/miner/MinerLogic.java | 5 +- 16 files changed, 417 insertions(+), 448 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index 29adff550f..eaa13dd508 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -14,7 +14,7 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.SizedIngredient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; @@ -425,9 +425,9 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It be.getMetaMachine().reinitializeCapabilities(caps); Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, - r -> RecipeHandler.matchContents(be.metaMachine, r).isSuccess()); + r -> RecipeHelper.matchContents(be.metaMachine, r).isSuccess()); GTRecipe hammerRecipe = hammerRecipes == null || !hammerRecipes.hasNext() ? null : hammerRecipes.next(); - if (hammerRecipe != null && RecipeHandler.handleRecipeIO(IO.IN, be.metaMachine, hammerRecipe, + if (hammerRecipe != null && RecipeHelper.handleRecipeIO(IO.IN, be.metaMachine, hammerRecipe, be.getMetaMachine().recipeLogic.getChanceCaches()).isSuccess()) { drops.clear(); TagPrefix prefix = ChemicalHelper.getPrefix(silktouchDrop.getItem()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java index 93368ba706..e04372c4af 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java @@ -6,7 +6,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -48,7 +48,7 @@ default void notifyStatusChanged(RecipeLogic.Status oldStatus, RecipeLogic.Statu RecipeLogic getRecipeLogic(); default GTRecipe fullModifyRecipe(GTRecipe recipe, @NotNull OCParams params, @NotNull OCResult result) { - return doModifyRecipe(RecipeHandler.trimRecipeOutputs(recipe, this.getOutputLimits()), params, result); + return doModifyRecipe(RecipeHelper.trimRecipeOutputs(recipe, this.getOutputLimits()), params, result); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index b7d8418703..86579c2fbf 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -224,19 +224,19 @@ public void serverTick() { } } - protected RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { - var recipeConditions = RecipeHandler.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) + protected RecipeHelper.ActionResult checkRecipe(GTRecipe recipe) { + var recipeConditions = RecipeHelper.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) .findFirst(); if (recipeConditions.isPresent()) { return recipeConditions.get(); } - var match = RecipeHandler.matchRecipe(this.machine, recipe); - var matchTick = RecipeHandler.matchTickRecipe(this.machine, recipe); + var match = RecipeHelper.matchRecipe(this.machine, recipe); + var matchTick = RecipeHelper.matchTickRecipe(this.machine, recipe); if (!match.isSuccess()) return match; if (!matchTick.isSuccess()) return matchTick; - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; // return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); } @@ -262,9 +262,9 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { public void handleRecipeWorking() { Status last = this.status; assert lastRecipe != null; - var conditionResults = RecipeHandler.checkConditions(lastRecipe, this).stream().filter(v -> !v.isSuccess()) + var conditionResults = RecipeHelper.checkConditions(lastRecipe, this).stream().filter(v -> !v.isSuccess()) .findFirst(); - RecipeHandler.ActionResult result; + RecipeHelper.ActionResult result; if (conditionResults.isEmpty()) { result = handleTickRecipe(lastRecipe); if (result.isSuccess()) { @@ -285,9 +285,9 @@ public void handleRecipeWorking() { doDamping(); } if (last == Status.WORKING && getStatus() != Status.WORKING) { - RecipeHandler.postWorking(machine, lastRecipe); + RecipeHelper.postWorking(machine, lastRecipe); } else if (last != Status.WORKING && getStatus() == Status.WORKING) { - RecipeHandler.preWorking(machine, lastRecipe); + RecipeHelper.preWorking(machine, lastRecipe); } } @@ -303,7 +303,7 @@ protected void doDamping() { public Iterator searchRecipe() { return machine.getRecipeType().searchRecipe(this.machine, - r -> RecipeHandler.matchContents(this.machine, r).isSuccess()); + r -> RecipeHelper.matchContents(this.machine, r).isSuccess()); } public void findAndHandleRecipe() { @@ -339,9 +339,9 @@ protected void handleSearchingRecipes(Iterator matches) { } } - public RecipeHandler.ActionResult handleTickRecipe(GTRecipe recipe) { + public RecipeHelper.ActionResult handleTickRecipe(GTRecipe recipe) { if (recipe.hasTick()) { - var result = RecipeHandler.matchTickRecipe(this.machine, recipe); + var result = RecipeHelper.matchTickRecipe(this.machine, recipe); if (result.isSuccess()) { handleTickRecipeIO(recipe, IO.IN); handleTickRecipeIO(recipe, IO.OUT); @@ -349,7 +349,7 @@ public RecipeHandler.ActionResult handleTickRecipe(GTRecipe recipe) { return result; } } - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } public void setupRecipe(GTRecipe recipe) { @@ -360,7 +360,7 @@ public void setupRecipe(GTRecipe recipe) { isActive = false; return; } - RecipeHandler.preWorking(this.machine, recipe); + RecipeHelper.preWorking(this.machine, recipe); var handledIO = handleRecipeIO(recipe, IO.IN); if (handledIO.isSuccess()) { if (lastRecipe != null && !recipe.equals(lastRecipe)) { @@ -456,7 +456,7 @@ public boolean isHasNotEnoughEnergy() { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - RecipeHandler.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(this.machine, lastRecipe); handleRecipeIO(lastRecipe, IO.OUT); if (machine.alwaysTryModifyRecipe()) { if (lastOriginRecipe != null) { @@ -488,12 +488,12 @@ public void onRecipeFinish() { } } - protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { - return RecipeHandler.handleRecipeIO(io, this.machine, recipe, this.chanceCaches); + protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + return RecipeHelper.handleRecipeIO(io, this.machine, recipe, this.chanceCaches); } - protected RecipeHandler.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { - return RecipeHandler.handleTickRecipeIO(io, this.machine, recipe, this.chanceCaches); + protected RecipeHelper.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + return RecipeHelper.handleTickRecipeIO(io, this.machine, recipe, this.chanceCaches); } /** @@ -502,7 +502,7 @@ protected RecipeHandler.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) public void interruptRecipe() { machine.afterWorking(); if (lastRecipe != null) { - RecipeHandler.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(this.machine, lastRecipe); setStatus(Status.IDLE); progress = 0; duration = 0; @@ -512,7 +512,7 @@ public void interruptRecipe() { public void inValid() { if (lastRecipe != null && isWorking()) { - RecipeHandler.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(this.machine, lastRecipe); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java deleted file mode 100644 index 5cc7939b5b..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHandler.java +++ /dev/null @@ -1,350 +0,0 @@ -package com.gregtechceu.gtceu.api.recipe; - -import com.gregtechceu.gtceu.api.capability.recipe.*; -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; -import com.gregtechceu.gtceu.api.recipe.content.Content; -import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; - -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.fluids.FluidStack; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.*; -import java.util.function.Supplier; - -public class RecipeHandler { - - /////////////////////////////////////////////////////////////// - // **********************internal logic********************* // - /////////////////////////////////////////////////////////////// - - public static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { - return matchRecipe(holder, recipe, false); - } - - public static ActionResult matchTickRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { - return recipe.hasTick() ? matchRecipe(holder, recipe, true) : ActionResult.SUCCESS; - } - - private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, boolean tick) { - if (!holder.hasCapabilityProxies()) - return ActionResult.FAIL_NO_CAPABILITIES; - - var result = handleRecipe(IO.IN, holder, recipe, tick ? recipe.tickInputs : recipe.inputs, - Collections.emptyMap(), tick, true); - if (!result.isSuccess()) return result; - - result = handleRecipe(IO.OUT, holder, recipe, tick ? recipe.tickOutputs : recipe.outputs, - Collections.emptyMap(), tick, true); - return result; - } - - public static ActionResult handleRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, - Map, Object2IntMap> chanceCaches) { - if (!holder.hasCapabilityProxies() || io == IO.BOTH) - return ActionResult.FAIL_NO_CAPABILITIES; - return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, - false); - } - - public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, - Map, Object2IntMap> chanceCaches) { - if (!holder.hasCapabilityProxies() || io == IO.BOTH) - return ActionResult.FAIL_NO_CAPABILITIES; - return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, - true, false); - } - - /** - * Checks if all the contents of the recipe are located in the holder. - * - * @param isTick - * @param simulated checks that the recipe ingredients are in the holder if true, - * process the recipe contents if false - */ - public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, - Map, List> contents, - Map, Object2IntMap> chanceCaches, - boolean isTick, boolean simulated) { - RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); - var handle = runner.handle(contents); - - if (handle == null || handle.content() != null) { - String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); - return ActionResult.fail(() -> Component.translatable(key) - .append(": ").append(handle.capability().getName())); - } - return handle.result(); - - /* - * RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, false); - * for (Map.Entry, List> entry : contents.entrySet()) { - * var handled = runner.handle(entry); - * if (handled == null) - * continue; - * - * if (handled.content() != null) { - * GTCEu.LOGGER.warn("io error while handling a recipe {} outputs. holder: {}", recipe.id, holder); - * return false; - * } - * } - * return true; - */ - } - - public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { - var match = matchRecipe(holder, recipe); - if (!match.isSuccess) - return match; - return matchTickRecipe(holder, recipe); - } - - public static void preWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { - handlePre(holder, recipe, IO.IN); - handlePre(holder, recipe, IO.OUT); - } - - public static void postWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { - handlePost(holder, recipe, IO.IN); - handlePost(holder, recipe, IO.OUT); - } - - public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { - (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { - var capFlatMap = holder.getCapabilitiesFlat(io, capability); - if (!capFlatMap.isEmpty()) { - for (IRecipeHandler capabilityProxy : capFlatMap) { - capabilityProxy.preWorking(holder, io, recipe); - } - } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { - capabilityProxy.preWorking(holder, io, recipe); - } - } - })); - } - - public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { - (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { - var capFlatMap = holder.getCapabilitiesFlat(io, capability); - if (!capFlatMap.isEmpty()) { - for (IRecipeHandler capabilityProxy : capFlatMap) { - capabilityProxy.postWorking(holder, io, recipe); - } - } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { - for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { - capabilityProxy.postWorking(holder, io, recipe); - } - } - })); - } - - /** - * Check whether all conditions of a recipe are valid - * - * @param recipe the recipe to test - * @param recipeLogic the logic to test against the conditions - * @return the list of failed conditions, or success if all conditions are satisfied - */ - public static List checkConditions(GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { - if (recipe.conditions.isEmpty()) return List.of(ActionResult.SUCCESS); - Map, List> or = new HashMap<>(); - List failures = new ArrayList<>(); - for (RecipeCondition condition : recipe.conditions) { - if (condition.isOr()) { - or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); - } else if (condition.test(recipe, recipeLogic) == condition.isReverse()) { - failures.add(ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails").append(": ") - .append(condition.getTooltips()))); - } - } - - for (List conditions : or.values()) { - if (conditions.stream() - .allMatch(condition -> condition.test(recipe, recipeLogic) == condition.isReverse())) { - failures.add(ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails"))); - } - } - if (!failures.isEmpty()) - return failures; - return List.of(ActionResult.SUCCESS); - } - - /** - * Trims the recipe outputs and tick outputs based on the performing Machine's trim limit. - */ - public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Map, Integer> trimLimits) { - // Fast return early if no trimming desired - if (trimLimits.isEmpty() || trimLimits.values().stream().allMatch(integer -> integer == -1)) { - return recipe; - } - - GTRecipe current = recipe.copy(); - - GTRecipeBuilder builder = new GTRecipeBuilder(current, recipe.recipeType); - - builder.output.clear(); - builder.tickOutput.clear(); - - Map, List> recipeOutputs = doTrim(current.outputs, trimLimits); - Map, List> recipeTickOutputs = doTrim(current.tickOutputs, trimLimits); - - builder.output.putAll(recipeOutputs); - builder.tickOutput.putAll(recipeTickOutputs); - - return builder.buildRawRecipe(); - } - - /** - * Returns the maximum possible recipe outputs from a recipe, divided into regular and chanced outputs - * Takes into account any specific output limiters, ie macerator slots, to trim down the output list - * Trims from chanced outputs first, then regular outputs - * - * @param trimLimits The limit(s) on the number of outputs, -1 for disabled. - * @return All recipe outputs, limited by some factor(s) - */ - public static Map, List> doTrim(Map, List> current, - Map, Integer> trimLimits) { - Map, List> outputs = new HashMap<>(); - - Set> trimmed = new HashSet<>(); - for (Map.Entry, Integer> entry : trimLimits.entrySet()) { - RecipeCapability key = entry.getKey(); - - if (!current.containsKey(key)) continue; - List nonChanced = new ArrayList<>(); - List chanced = new ArrayList<>(); - for (Content content : current.getOrDefault(key, List.of())) { - if (content.chance <= 0 || content.chance >= content.maxChance) nonChanced.add(content); - else chanced.add(content); - } - - int outputLimit = entry.getValue(); - if (outputLimit == -1) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()).addAll(nonChanced); - } - // If just the regular outputs would satisfy the outputLimit - else if (nonChanced.size() >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream() - .map(cont -> cont.copy(key, null)) - .toList() - .subList(0, outputLimit)); - - chanced.clear(); - } - // If the regular outputs and chanced outputs are required to satisfy the outputLimit - else if (!nonChanced.isEmpty() && (nonChanced.size() + chanced.size()) >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - - // Calculate the number of chanced outputs after adding all the regular outputs - int numChanced = outputLimit - nonChanced.size(); - - chanced = chanced.subList(0, Math.min(numChanced, chanced.size())); - } - // There are only chanced outputs to satisfy the outputLimit - else if (nonChanced.isEmpty()) { - chanced = chanced.subList(0, Math.min(outputLimit, chanced.size())); - } - // The number of outputs + chanced outputs is lower than the trim number, so just add everything - else { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - // Chanced outputs are taken care of in the original copy - } - - if (!chanced.isEmpty()) - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(chanced.stream().map(cont -> cont.copy(key, null)).toList()); - - trimmed.add(key); - } - for (Map.Entry, List> entry : current.entrySet()) { - if (trimmed.contains(entry.getKey())) continue; - outputs.computeIfAbsent(entry.getKey(), $ -> new ArrayList<>()).addAll(entry.getValue()); - } - - return outputs; - } - - public static List checkRecipeValidity(GTRecipe recipe) { - List results = new ArrayList<>(); - var result = checkItemValid(recipe.inputs, "input"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } - result = checkItemValid(recipe.outputs, "output"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } - result = checkItemValid(recipe.tickInputs, "tickInput"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } - result = checkItemValid(recipe.outputs, "tickOutput"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } - if (!results.isEmpty()) - return results; - return List.of(ActionResult.SUCCESS); - } - - private static ActionResult checkItemValid(Map, List> contents, String name) { - for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { - var items = ItemRecipeCapability.CAP.of(content.content).getItems(); - if (items.length == 0) { - return ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); - } else if (Arrays.stream(items).anyMatch(ItemStack::isEmpty)) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); - } - } - return ActionResult.SUCCESS; - } - - private static ActionResult checkFluidValid(Map, List> contents, String name) { - for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { - var fluids = FluidRecipeCapability.CAP.of(content.content).getStacks(); - if (fluids.length == 0) { - return ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); - } else if (Arrays.stream(fluids).anyMatch(FluidStack::isEmpty)) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); - } - } - return ActionResult.SUCCESS; - } - - /** - * @param isSuccess is action success - * @param reason if fail, fail reason - */ - public record ActionResult(boolean isSuccess, @Nullable Supplier reason) { - - public final static ActionResult SUCCESS = new ActionResult(true, null); - public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); - public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, - () -> Component.translatable("gtceu.recipe_logic.no_contents")); - public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, - () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); - - public static ActionResult fail(@Nullable Supplier component) { - return new ActionResult(false, component); - } - - public Component getReason() { - if (reason() == null) { - return Component.empty(); - } - return reason().get(); - } - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index f237b0261e..68b641336a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -1,23 +1,25 @@ package com.gregtechceu.gtceu.api.recipe; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; import com.gregtechceu.gtceu.api.recipe.logic.OCResult; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.utils.GTUtil; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -import java.util.Collections; -import java.util.List; +import java.util.*; +import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -221,4 +223,329 @@ public static List getOutputFluids(GTRecipeBuilder builder) { .map(ingredient -> ingredient.getStacks()[0]) .collect(Collectors.toList()); } + + public static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { + return matchRecipe(holder, recipe, false); + } + + public static ActionResult matchTickRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe) { + return recipe.hasTick() ? matchRecipe(holder, recipe, true) : ActionResult.SUCCESS; + } + + private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, boolean tick) { + if (!holder.hasCapabilityProxies()) + return ActionResult.FAIL_NO_CAPABILITIES; + + var result = handleRecipe(IO.IN, holder, recipe, tick ? recipe.tickInputs : recipe.inputs, + Collections.emptyMap(), tick, true); + if (!result.isSuccess()) return result; + + result = handleRecipe(IO.OUT, holder, recipe, tick ? recipe.tickOutputs : recipe.outputs, + Collections.emptyMap(), tick, true); + return result; + } + + public static ActionResult handleRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, Object2IntMap> chanceCaches) { + if (!holder.hasCapabilityProxies() || io == IO.BOTH) + return ActionResult.FAIL_NO_CAPABILITIES; + return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, + false); + } + + public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, Object2IntMap> chanceCaches) { + if (!holder.hasCapabilityProxies() || io == IO.BOTH) + return ActionResult.FAIL_NO_CAPABILITIES; + return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, + true, false); + } + + /** + * Checks if all the contents of the recipe are located in the holder. + * + * @param isTick + * @param simulated checks that the recipe ingredients are in the holder if true, + * process the recipe contents if false + */ + public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + Map, List> contents, + Map, Object2IntMap> chanceCaches, + boolean isTick, boolean simulated) { + RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); + var handle = runner.handle(contents); + + if (handle == null || handle.content() != null) { + String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); + return ActionResult.fail(() -> Component.translatable(key) + .append(": ").append(handle.capability().getName())); + } + return handle.result(); + + /* + * RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, false); + * for (Map.Entry, List> entry : contents.entrySet()) { + * var handled = runner.handle(entry); + * if (handled == null) + * continue; + * + * if (handled.content() != null) { + * GTCEu.LOGGER.warn("io error while handling a recipe {} outputs. holder: {}", recipe.id, holder); + * return false; + * } + * } + * return true; + */ + } + + public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { + var match = matchRecipe(holder, recipe); + if (!match.isSuccess()) + return match; + return matchTickRecipe(holder, recipe); + } + + public static void preWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { + handlePre(holder, recipe, IO.IN); + handlePre(holder, recipe, IO.OUT); + } + + public static void postWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) { + handlePost(holder, recipe, IO.IN); + handlePost(holder, recipe, IO.OUT); + } + + public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { + (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + var capFlatMap = holder.getCapabilitiesFlat(io, capability); + if (!capFlatMap.isEmpty()) { + for (IRecipeHandler capabilityProxy : capFlatMap) { + capabilityProxy.preWorking(holder, io, recipe); + } + } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { + capabilityProxy.preWorking(holder, io, recipe); + } + } + })); + } + + public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { + (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + var capFlatMap = holder.getCapabilitiesFlat(io, capability); + if (!capFlatMap.isEmpty()) { + for (IRecipeHandler capabilityProxy : capFlatMap) { + capabilityProxy.postWorking(holder, io, recipe); + } + } else if (!holder.getCapabilitiesFlat(IO.BOTH, capability).isEmpty()) { + for (IRecipeHandler capabilityProxy : holder.getCapabilitiesFlat(IO.BOTH, capability)) { + capabilityProxy.postWorking(holder, io, recipe); + } + } + })); + } + + /** + * Check whether all conditions of a recipe are valid + * + * @param recipe the recipe to test + * @param recipeLogic the logic to test against the conditions + * @return the list of failed conditions, or success if all conditions are satisfied + */ + public static List checkConditions(GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + if (recipe.conditions.isEmpty()) return List.of(ActionResult.SUCCESS); + Map, List> or = new HashMap<>(); + List failures = new ArrayList<>(); + for (RecipeCondition condition : recipe.conditions) { + if (condition.isOr()) { + or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); + } else if (condition.test(recipe, recipeLogic) == condition.isReverse()) { + failures.add(ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails").append(": ") + .append(condition.getTooltips()))); + } + } + + for (List conditions : or.values()) { + if (conditions.stream() + .allMatch(condition -> condition.test(recipe, recipeLogic) == condition.isReverse())) { + failures.add(ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails"))); + } + } + if (!failures.isEmpty()) + return failures; + return List.of(ActionResult.SUCCESS); + } + + /** + * Trims the recipe outputs and tick outputs based on the performing Machine's trim limit. + */ + public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Map, Integer> trimLimits) { + // Fast return early if no trimming desired + if (trimLimits.isEmpty() || trimLimits.values().stream().allMatch(integer -> integer == -1)) { + return recipe; + } + + GTRecipe current = recipe.copy(); + + GTRecipeBuilder builder = new GTRecipeBuilder(current, recipe.recipeType); + + builder.output.clear(); + builder.tickOutput.clear(); + + Map, List> recipeOutputs = doTrim(current.outputs, trimLimits); + Map, List> recipeTickOutputs = doTrim(current.tickOutputs, trimLimits); + + builder.output.putAll(recipeOutputs); + builder.tickOutput.putAll(recipeTickOutputs); + + return builder.buildRawRecipe(); + } + + /** + * Returns the maximum possible recipe outputs from a recipe, divided into regular and chanced outputs + * Takes into account any specific output limiters, ie macerator slots, to trim down the output list + * Trims from chanced outputs first, then regular outputs + * + * @param trimLimits The limit(s) on the number of outputs, -1 for disabled. + * @return All recipe outputs, limited by some factor(s) + */ + public static Map, List> doTrim(Map, List> current, + Map, Integer> trimLimits) { + Map, List> outputs = new HashMap<>(); + + Set> trimmed = new HashSet<>(); + for (Map.Entry, Integer> entry : trimLimits.entrySet()) { + RecipeCapability key = entry.getKey(); + + if (!current.containsKey(key)) continue; + List nonChanced = new ArrayList<>(); + List chanced = new ArrayList<>(); + for (Content content : current.getOrDefault(key, List.of())) { + if (content.chance <= 0 || content.chance >= content.maxChance) nonChanced.add(content); + else chanced.add(content); + } + + int outputLimit = entry.getValue(); + if (outputLimit == -1) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()).addAll(nonChanced); + } + // If just the regular outputs would satisfy the outputLimit + else if (nonChanced.size() >= outputLimit) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream() + .map(cont -> cont.copy(key, null)) + .toList() + .subList(0, outputLimit)); + + chanced.clear(); + } + // If the regular outputs and chanced outputs are required to satisfy the outputLimit + else if (!nonChanced.isEmpty() && (nonChanced.size() + chanced.size()) >= outputLimit) { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); + + // Calculate the number of chanced outputs after adding all the regular outputs + int numChanced = outputLimit - nonChanced.size(); + + chanced = chanced.subList(0, Math.min(numChanced, chanced.size())); + } + // There are only chanced outputs to satisfy the outputLimit + else if (nonChanced.isEmpty()) { + chanced = chanced.subList(0, Math.min(outputLimit, chanced.size())); + } + // The number of outputs + chanced outputs is lower than the trim number, so just add everything + else { + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); + // Chanced outputs are taken care of in the original copy + } + + if (!chanced.isEmpty()) + outputs.computeIfAbsent(key, $ -> new ArrayList<>()) + .addAll(chanced.stream().map(cont -> cont.copy(key, null)).toList()); + + trimmed.add(key); + } + for (Map.Entry, List> entry : current.entrySet()) { + if (trimmed.contains(entry.getKey())) continue; + outputs.computeIfAbsent(entry.getKey(), $ -> new ArrayList<>()).addAll(entry.getValue()); + } + + return outputs; + } + + public static List checkRecipeValidity(GTRecipe recipe) { + List results = new ArrayList<>(); + var result = checkItemValid(recipe.inputs, "input"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.outputs, "output"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.tickInputs, "tickInput"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + result = checkItemValid(recipe.outputs, "tickOutput"); + if (result != ActionResult.SUCCESS) { + results.add(result); + } + if (!results.isEmpty()) + return results; + return List.of(ActionResult.SUCCESS); + } + + private static ActionResult checkItemValid(Map, List> contents, String name) { + for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { + var items = ItemRecipeCapability.CAP.of(content.content).getItems(); + if (items.length == 0) { + return ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + } else if (Arrays.stream(items).anyMatch(ItemStack::isEmpty)) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + } + } + return ActionResult.SUCCESS; + } + + private static ActionResult checkFluidValid(Map, List> contents, String name) { + for (Content content : contents.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList())) { + var fluids = FluidRecipeCapability.CAP.of(content.content).getStacks(); + if (fluids.length == 0) { + return ActionResult + .fail(() -> Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + } else if (Arrays.stream(fluids).anyMatch(FluidStack::isEmpty)) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + } + } + return ActionResult.SUCCESS; + } + + /** + * @param isSuccess is action success + * @param reason if fail, fail reason + */ + public record ActionResult(boolean isSuccess, @Nullable Supplier reason) { + + public final static ActionResult SUCCESS = new ActionResult(true, null); + public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); + public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, + () -> Component.translatable("gtceu.recipe_logic.no_contents")); + public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, + () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + + public static ActionResult fail(@Nullable Supplier component) { + return new ActionResult(false, component); + } + + public Component getReason() { + if (reason() == null) { + return Component.empty(); + } + return reason().get(); + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 9ffd6f3f1a..a54606bfbb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -21,7 +21,7 @@ class RecipeRunner { record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, - RecipeHandler.ActionResult result) {} + RecipeHelper.ActionResult result) {} // -------------------------------------------------------------------------------------------------------- @@ -65,7 +65,7 @@ public RecipeHandlingResult handle(Map, List> entri fillContentMatchList(entries); if (searchRecipeContents.isEmpty()) - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.PASS_NO_CONTENTS); + return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.PASS_NO_CONTENTS); return this.handleContents(); } @@ -125,7 +125,7 @@ private void fillContentMatchList(Map, List> entrie @Nullable private RecipeHandlingResult handleContents() { if (recipeContents.isEmpty()) { - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); } var result = handleContentsInternal(io); if (!result.result.isSuccess()) { @@ -136,7 +136,7 @@ private RecipeHandlingResult handleContents() { private RecipeHandlingResult handleContentsInternal(IO capIO) { if (!capabilityProxies.containsKey(capIO)) - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); // noinspection DataFlowIssue checked above. var handlers = new ArrayList<>(capabilityProxies.get(capIO)); @@ -188,16 +188,16 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } if (handled) { - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); } for (var entry : recipeContents.entrySet()) { if (entry.getValue() != null && !entry.getValue().isEmpty()) { return new RecipeHandlingResult(entry.getKey(), entry.getValue(), - RecipeHandler.ActionResult.FAIL_NO_REASON); + RecipeHelper.ActionResult.FAIL_NO_REASON); } } - return new RecipeHandlingResult(null, null, RecipeHandler.ActionResult.FAIL_NO_REASON); + return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.FAIL_NO_REASON); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index c455261f84..9825d0e9f2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -5,7 +5,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; @@ -47,7 +47,7 @@ public class GTRecipeLookup { */ @Nullable public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { - return find(holder, recipe -> RecipeHandler.matchRecipe(holder, recipe).isSuccess()); + return find(holder, recipe -> RecipeHelper.matchRecipe(holder, recipe).isSuccess()); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java index c1ca75abfe..916d017caf 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java +++ b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.ores.OrePlacer; import com.gregtechceu.gtceu.api.gui.factory.GTUIEditorFactory; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.registry.GTRegistry; import com.gregtechceu.gtceu.common.commands.arguments.GTRegistryArgument; @@ -67,7 +67,7 @@ public static void register(CommandDispatcher dispatcher, Co for (Recipe recipe : context.getSource().getServer().getRecipeManager() .getRecipes()) { if (recipe instanceof GTRecipe gtRecipe) { - var recipeValid = RecipeHandler.checkRecipeValidity(gtRecipe).stream() + var recipeValid = RecipeHelper.checkRecipeValidity(gtRecipe).stream() .filter(v -> !v.isSuccess()).findAny(); if (recipeValid.isPresent()) { context.getSource().sendSuccess( diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java index e1fbcd3069..76a7643f36 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java @@ -12,7 +12,6 @@ import com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.OverclockingLogic; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.content.Content; @@ -131,7 +130,7 @@ public static Pair fastParallel(MetaMachine machine, @NotNull if (machine instanceof IRecipeCapabilityHolder holder) { while (maxParallel > 0) { var copied = recipe.copy(ContentModifier.multiplier(maxParallel), modifyDuration); - if (RecipeHandler.matchContents(holder, copied).isSuccess()) { + if (RecipeHelper.matchContents(holder, copied).isSuccess()) { return Pair.of(copied, maxParallel); } maxParallel /= 2; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index f506f2adda..07b2d4c3ca 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.modifier.ParallelLogic; @@ -189,26 +189,26 @@ public DistillationTowerMachine getMachine() { } @Override - public RecipeHandler.ActionResult checkRecipe(GTRecipe recipe) { - var result = RecipeHandler.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), + public RecipeHelper.ActionResult checkRecipe(GTRecipe recipe) { + var result = RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), false, true); if (!result.isSuccess()) return result; var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - result = RecipeHandler.handleRecipe(IO.OUT, machine, recipe, out, Collections.emptyMap(), false, true); + result = RecipeHelper.handleRecipe(IO.OUT, machine, recipe, out, Collections.emptyMap(), false, true); if (!result.isSuccess()) return result; } if (!applyFluidOutputs(recipe, FluidAction.SIMULATE)) { - return RecipeHandler.ActionResult + return RecipeHelper.ActionResult .fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } private void updateWorkingRecipe(GTRecipe recipe) { @@ -228,7 +228,7 @@ private void updateWorkingRecipe(GTRecipe recipe) { } @Override - protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { var handleIO = super.handleRecipeIO(recipe, io); if (handleIO.isSuccess()) { @@ -241,12 +241,12 @@ protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - RecipeHandler.handleRecipe(io, this.machine, recipe, out, chanceCaches, false, false); + RecipeHelper.handleRecipe(io, this.machine, recipe, out, chanceCaches, false, false); } if (applyFluidOutputs(recipe, FluidAction.EXECUTE)) { - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } - return RecipeHandler.ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + return RecipeHelper.ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index bdec551ae2..4c2f206d07 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -17,8 +17,8 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; @@ -141,11 +141,11 @@ public Iterator searchRecipe() { var iterator = machine.getRecipeType().getLookup().getRecipeIterator(holder, recipe -> { if (recipe.isFuel) return false; if (!holder.hasCapabilityProxies()) return false; - var result = RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), + var result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, false); if (!result.isSuccess()) return false; if (recipe.hasTick()) { - result = RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, + result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), false, false); return result.isSuccess(); } @@ -179,7 +179,7 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { return true; } // skip "can fit" checks, it can always fit - var conditions = RecipeHandler.checkConditions(modified, this).stream().filter(v -> !v.isSuccess()) + var conditions = RecipeHelper.checkConditions(modified, this).stream().filter(v -> !v.isSuccess()) .findFirst(); if (conditions.isEmpty() && this.matchRecipeNoOutput(modified, machine).isSuccess() && @@ -195,20 +195,20 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { return false; } - public RecipeHandler.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { - if (!holder.hasCapabilityProxies()) return RecipeHandler.ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, + public RecipeHelper.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { + if (!holder.hasCapabilityProxies()) return RecipeHelper.ActionResult.FAIL_NO_CAPABILITIES; + return RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, true); } - public RecipeHandler.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { + public RecipeHelper.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { if (recipe.hasTick()) { if (!holder.hasCapabilityProxies()) - return RecipeHandler.ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHandler.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), + return RecipeHelper.ActionResult.FAIL_NO_CAPABILITIES; + return RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), false, true); } - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } @Override @@ -221,7 +221,7 @@ public void setupRecipe(GTRecipe recipe) { if (!machine.beforeWorking(recipe)) { return; } - RecipeHandler.preWorking(this.machine, recipe); + RecipeHelper.preWorking(this.machine, recipe); // do not consume inputs here, consume them on completion recipeDirty = false; @@ -249,19 +249,19 @@ public void onRecipeFinish() { } @Override - protected RecipeHandler.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { return super.handleRecipeIO(recipe, io); } - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } @Override - protected RecipeHandler.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + protected RecipeHelper.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { return super.handleTickRecipeIO(recipe, io); } - return RecipeHandler.ActionResult.SUCCESS; + return RecipeHelper.ActionResult.SUCCESS; } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java index 07e96a78b3..d57cbf5edc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java @@ -13,7 +13,6 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.logic.OCParams; @@ -123,7 +122,7 @@ public static GTRecipe recipeModifier(MetaMachine machine, @NotNull GTRecipe rec if (machine instanceof LargeCombustionEngineMachine engineMachine) { var EUt = RecipeHelper.getOutputEUt(recipe); // has lubricant - if (EUt > 0 && RecipeHandler.matchRecipe(engineMachine, engineMachine.getLubricantRecipe()).isSuccess() && + if (EUt > 0 && RecipeHelper.matchRecipe(engineMachine, engineMachine.getLubricantRecipe()).isSuccess() && !engineMachine.isIntakesObstructed()) { var maxParallel = (int) (engineMachine.getOverclockVoltage() / EUt); // get maximum parallel var parallelResult = GTRecipeModifiers.accurateParallel(engineMachine, recipe, maxParallel, false); @@ -155,7 +154,7 @@ public boolean onWorking() { if (runningTimer % 72 == 0) { // insufficient lubricant - if (RecipeHandler.handleRecipeIO(IO.IN, this, getLubricantRecipe(), this.recipeLogic.getChanceCaches()) + if (RecipeHelper.handleRecipeIO(IO.IN, this, getLubricantRecipe(), this.recipeLogic.getChanceCaches()) .isSuccess()) { recipeLogic.interruptRecipe(); return false; @@ -164,8 +163,8 @@ public boolean onWorking() { // check boost fluid if (isBoostAllowed()) { var boosterRecipe = getBoostRecipe(); - this.isOxygenBoosted = RecipeHandler.matchRecipe(this, boosterRecipe).isSuccess() && - RecipeHandler.handleRecipeIO(IO.IN, this, boosterRecipe, this.recipeLogic.getChanceCaches()) + this.isOxygenBoosted = RecipeHelper.matchRecipe(this, boosterRecipe).isSuccess() && + RecipeHelper.handleRecipeIO(IO.IN, this, boosterRecipe, this.recipeLogic.getChanceCaches()) .isSuccess(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java index 542a5b3ba3..12aed38bfb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java @@ -59,14 +59,11 @@ public class ItemBusPartMachine extends TieredIOPartMachine implements IDistinct @Getter @Persisted protected final NotifiableItemStackHandler circuitInventory; - @Getter - protected final ItemHandlerProxyRecipeTrait combinedInventory; public ItemBusPartMachine(IMachineBlockEntity holder, int tier, IO io, Object... args) { super(holder, tier, io); this.inventory = createInventory(args); this.circuitInventory = createCircuitItemHandler(io); - this.combinedInventory = createCombinedItemHandler(io); } ////////////////////////////////////// @@ -119,8 +116,7 @@ public void onLoad() { serverLevel.getServer().tell(new TickTask(0, this::updateInventorySubscription)); } inventorySubs = getInventory().addChangedListener(this::updateInventorySubscription); - - combinedInventory.recomputeEnabledState(); + getRecipeHandlers().setDistinct(getInventory().isDistinct()); } @Override @@ -141,7 +137,6 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { getInventory().setDistinct(isDistinct); circuitInventory.setDistinct(isDistinct); - combinedInventory.setDistinct(isDistinct); getRecipeHandlers().setDistinct(isDistinct); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java index bbba5bc193..3979349702 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java @@ -9,7 +9,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.bedrockore.OreVeinWorldEntry; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.common.machine.multiblock.electric.BedrockOreMinerMachine; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; @@ -64,7 +64,7 @@ public void findAndHandleRecipe() { } var match = getOreMinerRecipe(); if (match != null) { - if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { + if (RecipeHelper.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); } } @@ -106,7 +106,7 @@ private GTRecipe getOreMinerRecipe() { .EUt(GTValues.VA[getMachine().getEnergyTier()]) .outputItems(stack) .buildRawRecipe(); - if (RecipeHandler.matchContents(getMachine(), recipe).isSuccess()) { + if (RecipeHelper.matchContents(getMachine(), recipe).isSuccess()) { return recipe; } } @@ -145,14 +145,14 @@ public int getOreToProduce() { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - RecipeHandler.postWorking(this.machine, lastRecipe); - RecipeHandler.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); + RecipeHelper.postWorking(this.machine, lastRecipe); + RecipeHelper.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); } depleteVein(); // try it again var match = getOreMinerRecipe(); if (match != null) { - if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { + if (RecipeHelper.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); return; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java index d30b197508..a04f6135e8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java @@ -6,7 +6,7 @@ import com.gregtechceu.gtceu.api.data.worldgen.bedrockfluid.FluidVeinWorldEntry; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FluidDrillMachine; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; @@ -57,7 +57,7 @@ public void findAndHandleRecipe() { } var match = getFluidDrillRecipe(); if (match != null) { - if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { + if (RecipeHelper.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); } } @@ -74,7 +74,7 @@ private GTRecipe getFluidDrillRecipe() { .outputFluids(new FluidStack(veinFluid, getFluidToProduce(data.getFluidVeinWorldEntry(getChunkX(), getChunkZ())))) .buildRawRecipe(); - if (RecipeHandler.matchContents(getMachine(), recipe).isSuccess()) { + if (RecipeHelper.matchContents(getMachine(), recipe).isSuccess()) { return recipe; } } @@ -113,14 +113,14 @@ private int getFluidToProduce(FluidVeinWorldEntry entry) { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - RecipeHandler.postWorking(this.machine, lastRecipe); - RecipeHandler.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); + RecipeHelper.postWorking(this.machine, lastRecipe); + RecipeHelper.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); } depleteVein(); // try it again var match = getFluidDrillRecipe(); if (match != null) { - if (RecipeHandler.matchContents(this.machine, match).isSuccess()) { + if (RecipeHelper.matchContents(this.machine, match).isSuccess()) { setupRecipe(match); return; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index cd45058c48..8d6395fcfb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -11,7 +11,6 @@ import com.gregtechceu.gtceu.api.misc.IgnoreEnergyRecipeHandler; import com.gregtechceu.gtceu.api.misc.ItemRecipeHandler; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.RecipeHandler; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.transfer.item.NotifiableAccountedInvWrapper; import com.gregtechceu.gtceu.common.data.GTBlocks; @@ -362,7 +361,7 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState inputItemHandler.storage.setStackInSlot(0, oreDrop); outputItemHandler.storage.clear(); - var matches = machine.getRecipeType().searchRecipe(this, r -> RecipeHandler.matchContents(this, r).isSuccess()); + var matches = machine.getRecipeType().searchRecipe(this, r -> RecipeHelper.matchContents(this, r).isSuccess()); while (matches != null && matches.hasNext()) { GTRecipe match = matches.next(); @@ -370,7 +369,7 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState var eut = RecipeHelper.getInputEUt(match); if (GTUtil.getTierByVoltage(eut) <= getVoltageTier()) { - if (RecipeHandler.handleRecipeIO(IO.OUT, this, match, this.chanceCaches).isSuccess()) { + if (RecipeHelper.handleRecipeIO(IO.OUT, this, match, this.chanceCaches).isSuccess()) { blockDrops.clear(); var result = new ArrayList(); for (int i = 0; i < outputItemHandler.storage.getSlots(); ++i) { From b03f3b0839fae89d675f95ed55f692a2160de1da Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 20:39:12 -0700 Subject: [PATCH 10/29] mfw glue sticks --- .../java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java | 2 +- .../multiblock/electric/research/ResearchStationMachine.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 68b641336a..e88f7fb72f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -10,11 +10,11 @@ import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.utils.GTUtil; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 4c2f206d07..5270b89af1 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -17,8 +17,8 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; - import com.gregtechceu.gtceu.api.recipe.RecipeHelper; + import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; From 6d56c730775da332f798c6f7b6804452ab76a354 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:13:10 -0700 Subject: [PATCH 11/29] removal of ui names and slot names from content --- .../resources/assets/gtceu/lang/en_ud.json | 47 ------------------- .../resources/assets/gtceu/lang/en_us.json | 47 ------------------- .../gtceu/api/recipe/content/Content.java | 23 ++------- .../recipe/content/IContentSerializer.java | 26 +--------- .../recipe/modifier/RecipeModifierList.java | 4 +- .../gtceu/common/data/GTRecipeModifiers.java | 4 +- .../data/recipe/builder/GTRecipeBuilder.java | 22 ++++----- .../kjs/recipe/GTRecipeSchema.java | 4 +- .../kjs/recipe/components/ContentJS.java | 14 ++---- .../xei/widgets/GTOreByProduct.java | 2 +- 10 files changed, 25 insertions(+), 168 deletions(-) diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 4a42d3925e..d931a4427f 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -218,10 +218,6 @@ "block.gtceu.ev_diode": "ǝpoıᗡ ΛƎϛ§", "block.gtceu.ev_distillery": "ɹ§III ʎɹǝןןıʇsıᗡ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_electric_furnace": "ɹ§III ǝɔɐuɹnℲ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_electric_gear_box_16a": "ɹ§III Ɐ9Ɩ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_electric_gear_box_2a": "ɹ§III Ɐᄅ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_electric_gear_box_32a": "ɹ§III ⱯᄅƐ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_electric_gear_box_8a": "ɹ§III Ɐ8 xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_electrolyzer": "ɹ§III ɹǝzʎןoɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_electromagnetic_separator": "ɹ§III ɹoʇɐɹɐdǝS ɔıʇǝubɐɯoɹʇɔǝןƎ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_energy_input_hatch": "ɥɔʇɐH ʎbɹǝuƎ ΛƎϛ§", @@ -248,9 +244,6 @@ "block.gtceu.ev_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛƎϛ§", "block.gtceu.ev_item_collector": "ɹ§III ɹoʇɔǝןןoƆ ɯǝʇI pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛƎϛ§", - "block.gtceu.ev_kinetic_input_box": "ɹ§III xoᗺ ʇnduI ɔıʇǝuıʞ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_kinetic_mixer": "ɹ§III ɹǝxıW ɔıʇǝuıʞ pǝɔuɐʌpⱯϛ§", - "block.gtceu.ev_kinetic_output_box": "ɹ§III xoᗺ ʇndʇnO ɔıʇǝuıʞ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_lapotronic_battery": "ɹoʇıɔɐdɐƆ ɔıuoɹʇodɐꞀ ΛƎ", "block.gtceu.ev_large_miner": "ɹ§III ɹǝuıW ǝbɹɐꞀ pǝɔuɐʌpⱯϛ§", "block.gtceu.ev_laser_engraver": "ɹ§III ɹǝʌɐɹbuƎ ɹǝsɐꞀ pǝɔuɐʌpⱯϛ§", @@ -369,10 +362,6 @@ "block.gtceu.hv_diode": "ǝpoıᗡ ΛH9§", "block.gtceu.hv_distillery": "ɹ§II ʎɹǝןןıʇsıᗡ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_electric_furnace": "ɹ§II ǝɔɐuɹnℲ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_electric_gear_box_16a": "ɹ§II Ɐ9Ɩ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_electric_gear_box_2a": "ɹ§II Ɐᄅ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_electric_gear_box_32a": "ɹ§II ⱯᄅƐ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_electric_gear_box_8a": "ɹ§II Ɐ8 xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_electrolyzer": "ɹ§II ɹǝzʎןoɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_electromagnetic_separator": "ɹ§II ɹoʇɐɹɐdǝS ɔıʇǝubɐɯoɹʇɔǝןƎ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_energy_input_hatch": "ɥɔʇɐH ʎbɹǝuƎ ΛH9§", @@ -394,9 +383,6 @@ "block.gtceu.hv_input_hatch": "ɥɔʇɐH ʇnduI ΛH9§", "block.gtceu.hv_item_collector": "ɹ§II ɹoʇɔǝןןoƆ ɯǝʇI pǝɔuɐʌpⱯ9§", "block.gtceu.hv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛH9§", - "block.gtceu.hv_kinetic_input_box": "ɹ§II xoᗺ ʇnduI ɔıʇǝuıʞ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_kinetic_mixer": "ɹ§II ɹǝxıW ɔıʇǝuıʞ pǝɔuɐʌpⱯ9§", - "block.gtceu.hv_kinetic_output_box": "ɹ§II xoᗺ ʇndʇnO ɔıʇǝuıʞ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_laser_engraver": "ɹ§II ɹǝʌɐɹbuƎ ɹǝsɐꞀ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_lathe": "ɹ§II ǝɥʇɐꞀ pǝɔuɐʌpⱯ9§", "block.gtceu.hv_macerator": "ɹ§II ɹoʇɐɹǝɔɐW pǝɔuɐʌpⱯ9§", @@ -484,8 +470,6 @@ "block.gtceu.iv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛI6§", "block.gtceu.iv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛI6§", "block.gtceu.iv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛI6§", - "block.gtceu.iv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ ǝʇıןƎ6§", - "block.gtceu.iv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ ǝʇıןƎ6§", "block.gtceu.iv_lapotronic_battery": "ɹoʇıɔɐdɐƆ ɔıuoɹʇodɐꞀ ΛI", "block.gtceu.iv_large_miner": "ɹ§ ɹǝuıW ǝbɹɐꞀ ǝʇıןƎ6§", "block.gtceu.iv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ ǝʇıןƎ6§", @@ -650,8 +634,6 @@ "block.gtceu.luv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛnꞀp§", "block.gtceu.luv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛnꞀp§", "block.gtceu.luv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛnꞀp§", - "block.gtceu.luv_kinetic_input_box": "ɹ§II xoᗺ ʇnduI ɔıʇǝuıʞ ǝʇıןƎp§", - "block.gtceu.luv_kinetic_output_box": "ɹ§II xoᗺ ʇndʇnO ɔıʇǝuıʞ ǝʇıןƎp§", "block.gtceu.luv_lapotronic_battery": "ɹoʇıɔɐdɐƆ ɔıuoɹʇodɐꞀ ΛnꞀ", "block.gtceu.luv_large_miner": "ɹ§II ɹǝuıW ǝbɹɐꞀ ǝʇıןƎp§", "block.gtceu.luv_laser_engraver": "ɹ§II ɹǝʌɐɹbuƎ ɹǝsɐꞀ ǝʇıןƎp§", @@ -712,10 +694,6 @@ "block.gtceu.lv_diode": "ǝpoıᗡ ΛꞀㄥ§", "block.gtceu.lv_distillery": "ɹ§ ʎɹǝןןıʇsıᗡ ɔısɐᗺ", "block.gtceu.lv_electric_furnace": "ɹ§ ǝɔɐuɹnℲ ɔıɹʇɔǝןƎ ɔısɐᗺ", - "block.gtceu.lv_electric_gear_box_16a": "ɹ§ Ɐ9Ɩ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ ɔısɐᗺ", - "block.gtceu.lv_electric_gear_box_2a": "ɹ§ Ɐᄅ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ ɔısɐᗺ", - "block.gtceu.lv_electric_gear_box_32a": "ɹ§ ⱯᄅƐ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ ɔısɐᗺ", - "block.gtceu.lv_electric_gear_box_8a": "ɹ§ Ɐ8 xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ ɔısɐᗺ", "block.gtceu.lv_electrolyzer": "ɹ§ ɹǝzʎןoɹʇɔǝןƎ ɔısɐᗺ", "block.gtceu.lv_electromagnetic_separator": "ɹ§ ɹoʇɐɹɐdǝS ɔıʇǝubɐɯoɹʇɔǝןƎ ɔısɐᗺ", "block.gtceu.lv_energy_input_hatch": "ɥɔʇɐH ʎbɹǝuƎ ΛꞀㄥ§", @@ -736,9 +714,6 @@ "block.gtceu.lv_input_hatch": "ɥɔʇɐH ʇnduI ΛꞀㄥ§", "block.gtceu.lv_item_collector": "ɹ§ ɹoʇɔǝןןoƆ ɯǝʇI ɔısɐᗺ", "block.gtceu.lv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛꞀㄥ§", - "block.gtceu.lv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ ɔısɐᗺ", - "block.gtceu.lv_kinetic_mixer": "ɹ§ ɹǝxıW ɔıʇǝuıʞ ɔısɐᗺ", - "block.gtceu.lv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ ɔısɐᗺ", "block.gtceu.lv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ ɔısɐᗺ", "block.gtceu.lv_lathe": "ɹ§ ǝɥʇɐꞀ ɔısɐᗺ", "block.gtceu.lv_macerator": "ɹ§ ɹoʇɐɹǝɔɐW ɔısɐᗺ", @@ -861,10 +836,6 @@ "block.gtceu.mv_diode": "ǝpoıᗡ ΛWq§", "block.gtceu.mv_distillery": "ɹ§ ʎɹǝןןıʇsıᗡ pǝɔuɐʌpⱯq§", "block.gtceu.mv_electric_furnace": "ɹ§ ǝɔɐuɹnℲ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_electric_gear_box_16a": "ɹ§ Ɐ9Ɩ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_electric_gear_box_2a": "ɹ§ Ɐᄅ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_electric_gear_box_32a": "ɹ§ ⱯᄅƐ xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_electric_gear_box_8a": "ɹ§ Ɐ8 xoqɹɐǝ⅁ ɔıɹʇɔǝןƎ pǝɔuɐʌpⱯq§", "block.gtceu.mv_electrolyzer": "ɹ§ ɹǝzʎןoɹʇɔǝןƎ pǝɔuɐʌpⱯq§", "block.gtceu.mv_electromagnetic_separator": "ɹ§ ɹoʇɐɹɐdǝS ɔıʇǝubɐɯoɹʇɔǝןƎ pǝɔuɐʌpⱯq§", "block.gtceu.mv_energy_input_hatch": "ɥɔʇɐH ʎbɹǝuƎ ΛWq§", @@ -886,9 +857,6 @@ "block.gtceu.mv_input_hatch": "ɥɔʇɐH ʇnduI ΛWq§", "block.gtceu.mv_item_collector": "ɹ§ ɹoʇɔǝןןoƆ ɯǝʇI pǝɔuɐʌpⱯq§", "block.gtceu.mv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛWq§", - "block.gtceu.mv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_kinetic_mixer": "ɹ§ ɹǝxıW ɔıʇǝuıʞ pǝɔuɐʌpⱯq§", - "block.gtceu.mv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ pǝɔuɐʌpⱯq§", "block.gtceu.mv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ pǝɔuɐʌpⱯq§", "block.gtceu.mv_lathe": "ɹ§ ǝɥʇɐꞀ pǝɔuɐʌpⱯq§", "block.gtceu.mv_macerator": "ɹ§ ɹoʇɐɹǝɔɐW pǝɔuɐʌpⱯq§", @@ -984,8 +952,6 @@ "block.gtceu.opv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛdOן§6§", "block.gtceu.opv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛdOן§6§", "block.gtceu.opv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛdOן§6§", - "block.gtceu.opv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ ʎɹɐpuǝbǝꞀן§6§", - "block.gtceu.opv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ ʎɹɐpuǝbǝꞀן§6§", "block.gtceu.opv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ ʎɹɐpuǝbǝꞀן§6§", "block.gtceu.opv_lathe": "ɹ§ ǝɥʇɐꞀ ʎɹɐpuǝbǝꞀן§6§", "block.gtceu.opv_macerator": "ɹ§ ɹoʇɐɹǝɔɐW ʎɹɐpuǝbǝꞀן§6§", @@ -1230,8 +1196,6 @@ "block.gtceu.uev_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛƎ∩ɐ§", "block.gtceu.uev_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛƎ∩ɐ§", "block.gtceu.uev_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛƎ∩ɐ§", - "block.gtceu.uev_kinetic_input_box": "ɹ§II xoᗺ ʇnduI ɔıʇǝuıʞ ɔıdƎɐ§", - "block.gtceu.uev_kinetic_output_box": "ɹ§II xoᗺ ʇndʇnO ɔıʇǝuıʞ ɔıdƎɐ§", "block.gtceu.uev_laser_engraver": "ɹ§II ɹǝʌɐɹbuƎ ɹǝsɐꞀ ɔıdƎɐ§", "block.gtceu.uev_lathe": "ɹ§II ǝɥʇɐꞀ ɔıdƎɐ§", "block.gtceu.uev_macerator": "ɹ§II ɹoʇɐɹǝɔɐW ɔıdƎɐ§", @@ -1315,8 +1279,6 @@ "block.gtceu.uhv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛH∩ㄣ§", "block.gtceu.uhv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛH∩ㄣ§", "block.gtceu.uhv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛH∩ㄣ§", - "block.gtceu.uhv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ ɔıdƎㄣ§", - "block.gtceu.uhv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ ɔıdƎㄣ§", "block.gtceu.uhv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ ɔıdƎㄣ§", "block.gtceu.uhv_lathe": "ɹ§ ǝɥʇɐꞀ ɔıdƎㄣ§", "block.gtceu.uhv_macerator": "ɹ§ ɹoʇɐɹǝɔɐW ɔıdƎㄣ§", @@ -1400,8 +1362,6 @@ "block.gtceu.uiv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛI∩ᄅ§", "block.gtceu.uiv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛI∩ᄅ§", "block.gtceu.uiv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛI∩ᄅ§", - "block.gtceu.uiv_kinetic_input_box": "ɹ§III xoᗺ ʇnduI ɔıʇǝuıʞ ɔıdƎᄅ§", - "block.gtceu.uiv_kinetic_output_box": "ɹ§III xoᗺ ʇndʇnO ɔıʇǝuıʞ ɔıdƎᄅ§", "block.gtceu.uiv_laser_engraver": "ɹ§III ɹǝʌɐɹbuƎ ɹǝsɐꞀ ɔıdƎᄅ§", "block.gtceu.uiv_lathe": "ɹ§III ǝɥʇɐꞀ ɔıdƎᄅ§", "block.gtceu.uiv_macerator": "ɹ§III ɹoʇɐɹǝɔɐW ɔıdƎᄅ§", @@ -1506,8 +1466,6 @@ "block.gtceu.uv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ Λ∩Ɛ§", "block.gtceu.uv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN Λ∩Ɛ§", "block.gtceu.uv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI Λ∩Ɛ§", - "block.gtceu.uv_kinetic_input_box": "ɹ§ xoᗺ ʇnduI ɔıʇǝuıʞ ǝʇɐɯıʇן∩Ɛ§", - "block.gtceu.uv_kinetic_output_box": "ɹ§ xoᗺ ʇndʇnO ɔıʇǝuıʞ ǝʇɐɯıʇן∩Ɛ§", "block.gtceu.uv_lapotronic_battery": "ɹoʇıɔɐdɐƆ ɔıuoɹʇodɐꞀ Λ∩", "block.gtceu.uv_laser_engraver": "ɹ§ ɹǝʌɐɹbuƎ ɹǝsɐꞀ ǝʇɐɯıʇן∩Ɛ§", "block.gtceu.uv_lathe": "ɹ§ ǝɥʇɐꞀ ǝʇɐɯıʇן∩Ɛ§", @@ -1593,8 +1551,6 @@ "block.gtceu.uxv_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ ΛX∩ǝ§", "block.gtceu.uxv_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN ΛX∩ǝ§", "block.gtceu.uxv_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI ΛX∩ǝ§", - "block.gtceu.uxv_kinetic_input_box": "ɹ§ΛI xoᗺ ʇnduI ɔıʇǝuıʞ ɔıdƎǝ§", - "block.gtceu.uxv_kinetic_output_box": "ɹ§ΛI xoᗺ ʇndʇnO ɔıʇǝuıʞ ɔıdƎǝ§", "block.gtceu.uxv_laser_engraver": "ɹ§ΛI ɹǝʌɐɹbuƎ ɹǝsɐꞀ ɔıdƎǝ§", "block.gtceu.uxv_lathe": "ɹ§ΛI ǝɥʇɐꞀ ɔıdƎǝ§", "block.gtceu.uxv_macerator": "ɹ§ΛI ɹoʇɐɹǝɔɐW ɔıdƎǝ§", @@ -1713,8 +1669,6 @@ "block.gtceu.zpm_input_hatch_4x": "ɥɔʇɐH ʇnduI ǝןdnɹpɐnὉ WԀZɔ§", "block.gtceu.zpm_input_hatch_9x": "ɥɔʇɐH ʇnduI ǝןdnuoN WԀZɔ§", "block.gtceu.zpm_item_passthrough_hatch": "ɥɔʇɐH ɥbnoɹɥʇssɐԀ ɯǝʇI WԀZɔ§", - "block.gtceu.zpm_kinetic_input_box": "ɹ§III xoᗺ ʇnduI ɔıʇǝuıʞ ǝʇıןƎɔ§", - "block.gtceu.zpm_kinetic_output_box": "ɹ§III xoᗺ ʇndʇnO ɔıʇǝuıʞ ǝʇıןƎɔ§", "block.gtceu.zpm_lapotronic_battery": "ɹoʇıɔɐdɐƆ ɔıuoɹʇodɐꞀ WԀZ", "block.gtceu.zpm_laser_engraver": "ɹ§III ɹǝʌɐɹbuƎ ɹǝsɐꞀ ǝʇıןƎɔ§", "block.gtceu.zpm_lathe": "ɹ§III ǝɥʇɐꞀ ǝʇıןƎɔ§", @@ -2233,7 +2187,6 @@ "gtceu.cover.item_detector.message_item_storage_inverted": "ǝbɐɹoʇS ɯǝʇI pǝʇɹǝʌuI buıɹoʇıuoW", "gtceu.cover.item_detector.message_item_storage_normal": "ǝbɐɹoʇS ɯǝʇI ןɐɯɹoN buıɹoʇıuoW", "gtceu.cracker": "ɹǝʞɔɐɹƆ", - "gtceu.create_mixer": "ɹǝxıW ǝʇɐǝɹƆ", "gtceu.creative.activity.off": "ǝʌıʇɔɐ ʇoN", "gtceu.creative.activity.on": "ǝʌıʇɔⱯ", "gtceu.creative.chest.ipc": "ǝןɔʎƆ ɹǝd sɯǝʇI", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 366f45806b..d81522d6e7 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -218,10 +218,6 @@ "block.gtceu.ev_diode": "§5EV Diode", "block.gtceu.ev_distillery": "§5Advanced Distillery III§r", "block.gtceu.ev_electric_furnace": "§5Advanced Electric Furnace III§r", - "block.gtceu.ev_electric_gear_box_16a": "§5Advanced Electric Gearbox 16A III§r", - "block.gtceu.ev_electric_gear_box_2a": "§5Advanced Electric Gearbox 2A III§r", - "block.gtceu.ev_electric_gear_box_32a": "§5Advanced Electric Gearbox 32A III§r", - "block.gtceu.ev_electric_gear_box_8a": "§5Advanced Electric Gearbox 8A III§r", "block.gtceu.ev_electrolyzer": "§5Advanced Electrolyzer III§r", "block.gtceu.ev_electromagnetic_separator": "§5Advanced Electromagnetic Separator III§r", "block.gtceu.ev_energy_input_hatch": "§5EV Energy Hatch", @@ -248,9 +244,6 @@ "block.gtceu.ev_input_hatch_9x": "§5EV Nonuple Input Hatch", "block.gtceu.ev_item_collector": "§5Advanced Item Collector III§r", "block.gtceu.ev_item_passthrough_hatch": "§5EV Item Passthrough Hatch", - "block.gtceu.ev_kinetic_input_box": "§5Advanced Kinetic Input Box III§r", - "block.gtceu.ev_kinetic_mixer": "§5Advanced Kinetic Mixer III§r", - "block.gtceu.ev_kinetic_output_box": "§5Advanced Kinetic Output Box III§r", "block.gtceu.ev_lapotronic_battery": "EV Lapotronic Capacitor", "block.gtceu.ev_large_miner": "§5Advanced Large Miner III§r", "block.gtceu.ev_laser_engraver": "§5Advanced Laser Engraver III§r", @@ -369,10 +362,6 @@ "block.gtceu.hv_diode": "§6HV Diode", "block.gtceu.hv_distillery": "§6Advanced Distillery II§r", "block.gtceu.hv_electric_furnace": "§6Advanced Electric Furnace II§r", - "block.gtceu.hv_electric_gear_box_16a": "§6Advanced Electric Gearbox 16A II§r", - "block.gtceu.hv_electric_gear_box_2a": "§6Advanced Electric Gearbox 2A II§r", - "block.gtceu.hv_electric_gear_box_32a": "§6Advanced Electric Gearbox 32A II§r", - "block.gtceu.hv_electric_gear_box_8a": "§6Advanced Electric Gearbox 8A II§r", "block.gtceu.hv_electrolyzer": "§6Advanced Electrolyzer II§r", "block.gtceu.hv_electromagnetic_separator": "§6Advanced Electromagnetic Separator II§r", "block.gtceu.hv_energy_input_hatch": "§6HV Energy Hatch", @@ -394,9 +383,6 @@ "block.gtceu.hv_input_hatch": "§6HV Input Hatch", "block.gtceu.hv_item_collector": "§6Advanced Item Collector II§r", "block.gtceu.hv_item_passthrough_hatch": "§6HV Item Passthrough Hatch", - "block.gtceu.hv_kinetic_input_box": "§6Advanced Kinetic Input Box II§r", - "block.gtceu.hv_kinetic_mixer": "§6Advanced Kinetic Mixer II§r", - "block.gtceu.hv_kinetic_output_box": "§6Advanced Kinetic Output Box II§r", "block.gtceu.hv_laser_engraver": "§6Advanced Laser Engraver II§r", "block.gtceu.hv_lathe": "§6Advanced Lathe II§r", "block.gtceu.hv_macerator": "§6Advanced Macerator II§r", @@ -484,8 +470,6 @@ "block.gtceu.iv_input_hatch_4x": "§9IV Quadruple Input Hatch", "block.gtceu.iv_input_hatch_9x": "§9IV Nonuple Input Hatch", "block.gtceu.iv_item_passthrough_hatch": "§9IV Item Passthrough Hatch", - "block.gtceu.iv_kinetic_input_box": "§9Elite Kinetic Input Box §r", - "block.gtceu.iv_kinetic_output_box": "§9Elite Kinetic Output Box §r", "block.gtceu.iv_lapotronic_battery": "IV Lapotronic Capacitor", "block.gtceu.iv_large_miner": "§9Elite Large Miner §r", "block.gtceu.iv_laser_engraver": "§9Elite Laser Engraver §r", @@ -650,8 +634,6 @@ "block.gtceu.luv_input_hatch_4x": "§dLuV Quadruple Input Hatch", "block.gtceu.luv_input_hatch_9x": "§dLuV Nonuple Input Hatch", "block.gtceu.luv_item_passthrough_hatch": "§dLuV Item Passthrough Hatch", - "block.gtceu.luv_kinetic_input_box": "§dElite Kinetic Input Box II§r", - "block.gtceu.luv_kinetic_output_box": "§dElite Kinetic Output Box II§r", "block.gtceu.luv_lapotronic_battery": "LuV Lapotronic Capacitor", "block.gtceu.luv_large_miner": "§dElite Large Miner II§r", "block.gtceu.luv_laser_engraver": "§dElite Laser Engraver II§r", @@ -712,10 +694,6 @@ "block.gtceu.lv_diode": "§7LV Diode", "block.gtceu.lv_distillery": "Basic Distillery §r", "block.gtceu.lv_electric_furnace": "Basic Electric Furnace §r", - "block.gtceu.lv_electric_gear_box_16a": "Basic Electric Gearbox 16A §r", - "block.gtceu.lv_electric_gear_box_2a": "Basic Electric Gearbox 2A §r", - "block.gtceu.lv_electric_gear_box_32a": "Basic Electric Gearbox 32A §r", - "block.gtceu.lv_electric_gear_box_8a": "Basic Electric Gearbox 8A §r", "block.gtceu.lv_electrolyzer": "Basic Electrolyzer §r", "block.gtceu.lv_electromagnetic_separator": "Basic Electromagnetic Separator §r", "block.gtceu.lv_energy_input_hatch": "§7LV Energy Hatch", @@ -736,9 +714,6 @@ "block.gtceu.lv_input_hatch": "§7LV Input Hatch", "block.gtceu.lv_item_collector": "Basic Item Collector §r", "block.gtceu.lv_item_passthrough_hatch": "§7LV Item Passthrough Hatch", - "block.gtceu.lv_kinetic_input_box": "Basic Kinetic Input Box §r", - "block.gtceu.lv_kinetic_mixer": "Basic Kinetic Mixer §r", - "block.gtceu.lv_kinetic_output_box": "Basic Kinetic Output Box §r", "block.gtceu.lv_laser_engraver": "Basic Laser Engraver §r", "block.gtceu.lv_lathe": "Basic Lathe §r", "block.gtceu.lv_macerator": "Basic Macerator §r", @@ -861,10 +836,6 @@ "block.gtceu.mv_diode": "§bMV Diode", "block.gtceu.mv_distillery": "§bAdvanced Distillery §r", "block.gtceu.mv_electric_furnace": "§bAdvanced Electric Furnace §r", - "block.gtceu.mv_electric_gear_box_16a": "§bAdvanced Electric Gearbox 16A §r", - "block.gtceu.mv_electric_gear_box_2a": "§bAdvanced Electric Gearbox 2A §r", - "block.gtceu.mv_electric_gear_box_32a": "§bAdvanced Electric Gearbox 32A §r", - "block.gtceu.mv_electric_gear_box_8a": "§bAdvanced Electric Gearbox 8A §r", "block.gtceu.mv_electrolyzer": "§bAdvanced Electrolyzer §r", "block.gtceu.mv_electromagnetic_separator": "§bAdvanced Electromagnetic Separator §r", "block.gtceu.mv_energy_input_hatch": "§bMV Energy Hatch", @@ -886,9 +857,6 @@ "block.gtceu.mv_input_hatch": "§bMV Input Hatch", "block.gtceu.mv_item_collector": "§bAdvanced Item Collector §r", "block.gtceu.mv_item_passthrough_hatch": "§bMV Item Passthrough Hatch", - "block.gtceu.mv_kinetic_input_box": "§bAdvanced Kinetic Input Box §r", - "block.gtceu.mv_kinetic_mixer": "§bAdvanced Kinetic Mixer §r", - "block.gtceu.mv_kinetic_output_box": "§bAdvanced Kinetic Output Box §r", "block.gtceu.mv_laser_engraver": "§bAdvanced Laser Engraver §r", "block.gtceu.mv_lathe": "§bAdvanced Lathe §r", "block.gtceu.mv_macerator": "§bAdvanced Macerator §r", @@ -984,8 +952,6 @@ "block.gtceu.opv_input_hatch_4x": "§9§lOpV Quadruple Input Hatch", "block.gtceu.opv_input_hatch_9x": "§9§lOpV Nonuple Input Hatch", "block.gtceu.opv_item_passthrough_hatch": "§9§lOpV Item Passthrough Hatch", - "block.gtceu.opv_kinetic_input_box": "§9§lLegendary Kinetic Input Box §r", - "block.gtceu.opv_kinetic_output_box": "§9§lLegendary Kinetic Output Box §r", "block.gtceu.opv_laser_engraver": "§9§lLegendary Laser Engraver §r", "block.gtceu.opv_lathe": "§9§lLegendary Lathe §r", "block.gtceu.opv_macerator": "§9§lLegendary Macerator §r", @@ -1230,8 +1196,6 @@ "block.gtceu.uev_input_hatch_4x": "§aUEV Quadruple Input Hatch", "block.gtceu.uev_input_hatch_9x": "§aUEV Nonuple Input Hatch", "block.gtceu.uev_item_passthrough_hatch": "§aUEV Item Passthrough Hatch", - "block.gtceu.uev_kinetic_input_box": "§aEpic Kinetic Input Box II§r", - "block.gtceu.uev_kinetic_output_box": "§aEpic Kinetic Output Box II§r", "block.gtceu.uev_laser_engraver": "§aEpic Laser Engraver II§r", "block.gtceu.uev_lathe": "§aEpic Lathe II§r", "block.gtceu.uev_macerator": "§aEpic Macerator II§r", @@ -1315,8 +1279,6 @@ "block.gtceu.uhv_input_hatch_4x": "§4UHV Quadruple Input Hatch", "block.gtceu.uhv_input_hatch_9x": "§4UHV Nonuple Input Hatch", "block.gtceu.uhv_item_passthrough_hatch": "§4UHV Item Passthrough Hatch", - "block.gtceu.uhv_kinetic_input_box": "§4Epic Kinetic Input Box §r", - "block.gtceu.uhv_kinetic_output_box": "§4Epic Kinetic Output Box §r", "block.gtceu.uhv_laser_engraver": "§4Epic Laser Engraver §r", "block.gtceu.uhv_lathe": "§4Epic Lathe §r", "block.gtceu.uhv_macerator": "§4Epic Macerator §r", @@ -1400,8 +1362,6 @@ "block.gtceu.uiv_input_hatch_4x": "§2UIV Quadruple Input Hatch", "block.gtceu.uiv_input_hatch_9x": "§2UIV Nonuple Input Hatch", "block.gtceu.uiv_item_passthrough_hatch": "§2UIV Item Passthrough Hatch", - "block.gtceu.uiv_kinetic_input_box": "§2Epic Kinetic Input Box III§r", - "block.gtceu.uiv_kinetic_output_box": "§2Epic Kinetic Output Box III§r", "block.gtceu.uiv_laser_engraver": "§2Epic Laser Engraver III§r", "block.gtceu.uiv_lathe": "§2Epic Lathe III§r", "block.gtceu.uiv_macerator": "§2Epic Macerator III§r", @@ -1506,8 +1466,6 @@ "block.gtceu.uv_input_hatch_4x": "§3UV Quadruple Input Hatch", "block.gtceu.uv_input_hatch_9x": "§3UV Nonuple Input Hatch", "block.gtceu.uv_item_passthrough_hatch": "§3UV Item Passthrough Hatch", - "block.gtceu.uv_kinetic_input_box": "§3Ultimate Kinetic Input Box §r", - "block.gtceu.uv_kinetic_output_box": "§3Ultimate Kinetic Output Box §r", "block.gtceu.uv_lapotronic_battery": "UV Lapotronic Capacitor", "block.gtceu.uv_laser_engraver": "§3Ultimate Laser Engraver §r", "block.gtceu.uv_lathe": "§3Ultimate Lathe §r", @@ -1593,8 +1551,6 @@ "block.gtceu.uxv_input_hatch_4x": "§eUXV Quadruple Input Hatch", "block.gtceu.uxv_input_hatch_9x": "§eUXV Nonuple Input Hatch", "block.gtceu.uxv_item_passthrough_hatch": "§eUXV Item Passthrough Hatch", - "block.gtceu.uxv_kinetic_input_box": "§eEpic Kinetic Input Box IV§r", - "block.gtceu.uxv_kinetic_output_box": "§eEpic Kinetic Output Box IV§r", "block.gtceu.uxv_laser_engraver": "§eEpic Laser Engraver IV§r", "block.gtceu.uxv_lathe": "§eEpic Lathe IV§r", "block.gtceu.uxv_macerator": "§eEpic Macerator IV§r", @@ -1713,8 +1669,6 @@ "block.gtceu.zpm_input_hatch_4x": "§cZPM Quadruple Input Hatch", "block.gtceu.zpm_input_hatch_9x": "§cZPM Nonuple Input Hatch", "block.gtceu.zpm_item_passthrough_hatch": "§cZPM Item Passthrough Hatch", - "block.gtceu.zpm_kinetic_input_box": "§cElite Kinetic Input Box III§r", - "block.gtceu.zpm_kinetic_output_box": "§cElite Kinetic Output Box III§r", "block.gtceu.zpm_lapotronic_battery": "ZPM Lapotronic Capacitor", "block.gtceu.zpm_laser_engraver": "§cElite Laser Engraver III§r", "block.gtceu.zpm_lathe": "§cElite Lathe III§r", @@ -2233,7 +2187,6 @@ "gtceu.cover.item_detector.message_item_storage_inverted": "Monitoring Inverted Item Storage", "gtceu.cover.item_detector.message_item_storage_normal": "Monitoring Normal Item Storage", "gtceu.cracker": "Cracker", - "gtceu.create_mixer": "Create Mixer", "gtceu.creative.activity.off": "Not active", "gtceu.creative.activity.on": "Active", "gtceu.creative.chest.ipc": "Items per Cycle", diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java index a2965b64d9..6b6a64c3ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java @@ -32,19 +32,12 @@ public class Content { public int chance; public int maxChance; public int tierChanceBoost; - @Nullable - public String slotName; - @Nullable - public String uiName; - public Content(Object content, int chance, int maxChance, int tierChanceBoost, @Nullable String slotName, - @Nullable String uiName) { + public Content(Object content, int chance, int maxChance, int tierChanceBoost) { this.content = content; this.chance = chance; this.maxChance = maxChance; this.tierChanceBoost = fixBoost(tierChanceBoost); - this.slotName = slotName == null || slotName.isEmpty() ? null : slotName; - this.uiName = uiName == null || uiName.isEmpty() ? null : uiName; } public static Codec codec(RecipeCapability capability) { @@ -55,24 +48,20 @@ public static Codec codec(RecipeCapability capability) { ExtraCodecs.NON_NEGATIVE_INT.optionalFieldOf("maxChance", ChanceLogic.getMaxChancedValue()) .forGetter(val -> val.maxChance), Codec.INT.optionalFieldOf("tierChanceBoost", 0) - .forGetter(val -> val.tierChanceBoost), - Codec.STRING.optionalFieldOf("slotName", "").forGetter(val -> val.slotName != null ? val.slotName : ""), - Codec.STRING.optionalFieldOf("uiName", "").forGetter(val -> val.uiName != null ? val.uiName : "")) + .forGetter(val -> val.tierChanceBoost)) .apply(instance, Content::new)); } public Content copy(RecipeCapability capability, @Nullable ContentModifier modifier) { if (modifier == null || chance < maxChance) { - return new Content(capability.copyContent(content), chance, maxChance, tierChanceBoost, slotName, uiName); + return new Content(capability.copyContent(content), chance, maxChance, tierChanceBoost); } else { - return new Content(capability.copyContent(content, modifier), chance, maxChance, tierChanceBoost, - slotName, uiName); + return new Content(capability.copyContent(content, modifier), chance, maxChance, tierChanceBoost); } } public Content copyExplicit(RecipeCapability capability, @Nullable ContentModifier modifier) { - return new Content(capability.copyContent(content, modifier), chance, maxChance, tierChanceBoost, - slotName, uiName); + return new Content(capability.copyContent(content, modifier), chance, maxChance, tierChanceBoost); } /** @@ -193,8 +182,6 @@ public String toString() { ", chance=" + chance + ", maxChance=" + maxChance + ", tierChanceBoost=" + tierChanceBoost + - ", slotName='" + slotName + '\'' + - ", uiName='" + uiName + '\'' + '}'; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/IContentSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/IContentSerializer.java index 5a145a06f4..1da1f14ab4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/IContentSerializer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/IContentSerializer.java @@ -45,14 +45,6 @@ default void toNetworkContent(FriendlyByteBuf buf, Content content) { buf.writeVarInt(content.chance); buf.writeVarInt(content.maxChance); buf.writeVarInt(content.tierChanceBoost); - buf.writeBoolean(content.slotName != null); - if (content.slotName != null) { - buf.writeUtf(content.slotName); - } - buf.writeBoolean(content.uiName != null); - if (content.uiName != null) { - buf.writeUtf(content.uiName); - } } default Content fromNetworkContent(FriendlyByteBuf buf) { @@ -60,15 +52,7 @@ default Content fromNetworkContent(FriendlyByteBuf buf) { int chance = buf.readVarInt(); int maxChance = buf.readVarInt(); int tierChanceBoost = buf.readVarInt(); - String slotName = null; - if (buf.readBoolean()) { - slotName = buf.readUtf(); - } - String uiName = null; - if (buf.readBoolean()) { - uiName = buf.readUtf(); - } - return new Content(inner, chance, maxChance, tierChanceBoost, slotName, uiName); + return new Content(inner, chance, maxChance, tierChanceBoost); } Codec codec(); @@ -90,10 +74,6 @@ default JsonElement toJsonContent(Content content) { json.addProperty("chance", content.chance); json.addProperty("maxChance", content.maxChance); json.addProperty("tierChanceBoost", content.tierChanceBoost); - if (content.slotName != null) - json.addProperty("slotName", content.slotName); - if (content.uiName != null) - json.addProperty("uiName", content.uiName); return json; } @@ -104,9 +84,7 @@ default Content fromJsonContent(JsonElement json) { int maxChance = jsonObject.has("maxChance") ? jsonObject.get("maxChance").getAsInt() : ChanceLogic.getMaxChancedValue(); int tierChanceBoost = jsonObject.has("tierChanceBoost") ? jsonObject.get("tierChanceBoost").getAsInt() : 0; - String slotName = jsonObject.has("slotName") ? jsonObject.get("slotName").getAsString() : null; - String uiName = jsonObject.has("uiName") ? jsonObject.get("uiName").getAsString() : null; - return new Content(inner, chance, maxChance, tierChanceBoost, slotName, uiName); + return new Content(inner, chance, maxChance, tierChanceBoost); } default Tag toNbt(T content) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java index f6b953622d..1bf100bd40 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/RecipeModifierList.java @@ -46,10 +46,10 @@ public GTRecipe apply(MetaMachine machine, @NotNull GTRecipe recipe, @NotNull OC } if (result.getEut() > 0) { modifiedRecipe.tickInputs.put(EURecipeCapability.CAP, List.of(new Content(result.getEut(), - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0))); } else if (result.getEut() < 0) { modifiedRecipe.tickOutputs.put(EURecipeCapability.CAP, List.of(new Content(-result.getEut(), - ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null))); + ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0))); } if (result.getParallel() > 1) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java index 76a7643f36..1af44a9ebd 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/data/GTRecipeModifiers.java @@ -212,7 +212,7 @@ public static GTRecipe ebfOverclock(MetaMachine machine, @NotNull GTRecipe recip applyCoilEUtDiscount(RecipeHelper.getInputEUt(recipe), blastFurnaceTemperature, recipe.data.getInt("ebf_temp")), ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), - 0, null, null))); + 0))); return RecipeHelper.applyOverclock( new OverclockingLogic((p, r, maxVoltage) -> OverclockingLogic.heatingCoilOC( @@ -265,7 +265,7 @@ public static GTRecipe multiSmelterParallel(MetaMachine machine, @NotNull GTReci recipe.duration = (int) Math.max(1, FURNACE_DURATION * 2 * parallelValue / Math.max(1.0, maxParallel)); recipe.tickInputs.put(EURecipeCapability.CAP, List.of(new Content(eut, ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), - 0, null, null))); + 0))); RecipeHelper.applyOverclock(new OverclockingLogic((p, r, maxVoltage) -> { OverclockingLogic.NON_PERFECT_OVERCLOCK.getLogic() diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java index dd0be37943..ac6023a0c8 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java @@ -89,10 +89,6 @@ public class GTRecipeBuilder { @Setter public boolean perTick; @Setter - public String slotName; - @Setter - public String uiName; - @Setter public int chance = ChanceLogic.getMaxChancedValue(); @Setter public int maxChance = ChanceLogic.getMaxChancedValue(); @@ -160,8 +156,6 @@ public GTRecipeBuilder copy(ResourceLocation id) { copy.perTick = this.perTick; copy.isFuel = this.isFuel; copy.recipeCategory = this.recipeCategory; - copy.uiName = this.uiName; - copy.slotName = this.slotName; copy.onSave = this.onSave; return copy; } @@ -177,7 +171,7 @@ public GTRecipeBuilder input(RecipeCapability capability, T obj) { id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxInputs(capability)); } t.computeIfAbsent(capability, c -> new ArrayList<>()) - .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost, slotName, uiName)); + .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost)); return this; } @@ -189,7 +183,7 @@ public GTRecipeBuilder input(RecipeCapability capability, T... obj) { } (perTick ? tickInput : input).computeIfAbsent(capability, c -> new ArrayList<>()).addAll(Arrays.stream(obj) .map(capability::of) - .map(o -> new Content(o, chance, maxChance, tierChanceBoost, slotName, uiName)).toList()); + .map(o -> new Content(o, chance, maxChance, tierChanceBoost)).toList()); return this; } @@ -200,7 +194,7 @@ public GTRecipeBuilder output(RecipeCapability capability, T obj) { id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxOutputs(capability)); } (perTick ? tickOutput : output).computeIfAbsent(capability, c -> new ArrayList<>()) - .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost, slotName, uiName)); + .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost)); return this; } @@ -212,7 +206,7 @@ public GTRecipeBuilder output(RecipeCapability capability, T... obj) { } (perTick ? tickOutput : output).computeIfAbsent(capability, c -> new ArrayList<>()).addAll(Arrays.stream(obj) .map(capability::of) - .map(o -> new Content(o, chance, maxChance, tierChanceBoost, slotName, uiName)).toList()); + .map(o -> new Content(o, chance, maxChance, tierChanceBoost)).toList()); return this; } @@ -223,7 +217,7 @@ public GTRecipeBuilder inputs(RecipeCapability capability, Object obj) { id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxInputs(capability)); } (perTick ? tickInput : input).computeIfAbsent(capability, c -> new ArrayList<>()) - .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost, slotName, uiName)); + .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost)); return this; } @@ -235,7 +229,7 @@ public GTRecipeBuilder inputs(RecipeCapability capability, Object... obj) } (perTick ? tickInput : input).computeIfAbsent(capability, c -> new ArrayList<>()).addAll(Arrays.stream(obj) .map(capability::of) - .map(o -> new Content(o, chance, maxChance, tierChanceBoost, slotName, uiName)).toList()); + .map(o -> new Content(o, chance, maxChance, tierChanceBoost)).toList()); return this; } @@ -246,7 +240,7 @@ public GTRecipeBuilder outputs(RecipeCapability capability, Object obj) { id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxOutputs(capability)); } (perTick ? tickOutput : output).computeIfAbsent(capability, c -> new ArrayList<>()) - .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost, slotName, uiName)); + .add(new Content(capability.of(obj), chance, maxChance, tierChanceBoost)); return this; } @@ -258,7 +252,7 @@ public GTRecipeBuilder outputs(RecipeCapability capability, Object... obj } (perTick ? tickOutput : output).computeIfAbsent(capability, c -> new ArrayList<>()).addAll(Arrays.stream(obj) .map(capability::of) - .map(o -> new Content(o, chance, maxChance, tierChanceBoost, slotName, uiName)).toList()); + .map(o -> new Content(o, chance, maxChance, tierChanceBoost)).toList()); return this; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java index f92c72f707..242319dc08 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java @@ -116,7 +116,7 @@ public GTRecipeJS input(RecipeCapability capability, Object... obj) { "Trying to add more inputs than RecipeType can support, id: %s, Max %s%sInputs: %s", id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxInputs(capability))); } - map.add(capability, new Content(object, chance, maxChance, tierChanceBoost, null, null)); + map.add(capability, new Content(object, chance, maxChance, tierChanceBoost)); } } save(); @@ -141,7 +141,7 @@ public GTRecipeJS output(RecipeCapability capability, Object... obj) { "Trying to add more outputs than RecipeType can support, id: %s, Max %s%sOutputs: %s", id, (perTick ? "Tick " : ""), capability.name, recipeType.getMaxOutputs(capability))); } - map.add(capability, new Content(object, chance, maxChance, tierChanceBoost, null, null)); + map.add(capability, new Content(object, chance, maxChance, tierChanceBoost)); } } save(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java index 745c67fa61..3d9694d7b7 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java @@ -35,12 +35,6 @@ public JsonElement write(RecipeJS recipe, Content value) { object.addProperty("chance", value.chance); object.addProperty("maxChance", value.maxChance); object.addProperty("tierChanceBoost", value.tierChanceBoost); - if (value.slotName != null) { - object.addProperty("slotName", value.slotName); - } - if (value.uiName != null) { - object.addProperty("uiName", value.uiName); - } return object; } @@ -52,9 +46,7 @@ else if (from instanceof JsonObject json) { int chance = GsonHelper.getAsInt(json, "chance", ChanceLogic.getMaxChancedValue()); int maxChance = GsonHelper.getAsInt(json, "maxChance", ChanceLogic.getMaxChancedValue()); int tierChanceBoost = GsonHelper.getAsInt(json, "tierChanceBoost", 0); - String slotName = GsonHelper.getAsString(json, "slotName", null); - String uiName = GsonHelper.getAsString(json, "uiName", null); - return new Content(content, chance, maxChance, tierChanceBoost, slotName, uiName); + return new Content(content, chance, maxChance, tierChanceBoost); } return null; } @@ -73,14 +65,14 @@ public boolean isOutput(RecipeJS recipe, Content value, ReplacementMatch match) public Content replaceInput(RecipeJS recipe, Content original, ReplacementMatch match, InputReplacement with) { return isInput(recipe, original, match) ? new Content( baseComponent.replaceInput(recipe, baseComponent.read(recipe, original.content), match, with), - original.chance, original.maxChance, original.tierChanceBoost, original.slotName, original.uiName) : + original.chance, original.maxChance, original.tierChanceBoost) : original; } @Override public Content replaceOutput(RecipeJS recipe, Content original, ReplacementMatch match, OutputReplacement with) { return isOutput(recipe, original, match) ? new Content(with.replaceOutput(recipe, match, with), - original.chance, original.maxChance, original.tierChanceBoost, original.slotName, original.uiName) : + original.chance, original.maxChance, original.tierChanceBoost) : original; } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTOreByProduct.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTOreByProduct.java index 6801ba44dd..f3ab04d16a 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTOreByProduct.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTOreByProduct.java @@ -347,7 +347,7 @@ private void addToInputs(ItemStack stack) { private void addChance(int base, int tier) { // this is solely for the chance overlay and tooltip, neither of which care about the ItemStack chances.put(currentSlot - 1, - new Content(ItemStack.EMPTY, base, ChanceLogic.getMaxChancedValue(), tier, null, null)); + new Content(ItemStack.EMPTY, base, ChanceLogic.getMaxChancedValue(), tier)); } // make the code less :weary: From 48461344e62fb3ece546ac44de46afd3d94f4fac Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sat, 14 Dec 2024 21:54:02 -0700 Subject: [PATCH 12/29] fix miner capability map npeing --- .../gtceu/common/machine/trait/miner/MinerLogic.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 8d6395fcfb..4c0df05ba2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -160,8 +160,8 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, this.capabilitiesProxy.put(IO.IN, List.of(inHandlers)); this.capabilitiesProxy.put(IO.OUT, List.of(outHandlers)); - var inMap = this.capabilitiesFlat.put(IO.IN, new Object2ObjectOpenHashMap<>()); - var outMap = this.capabilitiesFlat.put(IO.OUT, new Object2ObjectOpenHashMap<>()); + var inMap = this.capabilitiesFlat.computeIfAbsent(IO.IN, k -> new Object2ObjectOpenHashMap<>()); + var outMap = this.capabilitiesFlat.computeIfAbsent(IO.OUT, k -> new Object2ObjectOpenHashMap<>()); inMap.put(ItemRecipeCapability.CAP, List.of(inputItemHandler)); inMap.put(EURecipeCapability.CAP, List.of(inputEnergyHandler)); outMap.put(ItemRecipeCapability.CAP, List.of(outputItemHandler)); From d0b83f7d29ef2b6bdbb9aebefadb49c9db9b3c24 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:09:58 -0700 Subject: [PATCH 13/29] minor change --- .../ae2/machine/trait/MEPatternBufferRecipeHandler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java index 242175942e..577842b495 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java @@ -58,8 +58,7 @@ public MEPatternBufferPartMachine getMachine() { return (MEPatternBufferPartMachine) super.getMachine(); } - public List handleItemInner( - GTRecipe recipe, List left, boolean simulate) { + public List handleItemInner(GTRecipe recipe, List left, boolean simulate) { var internalInv = getMachine().getInternalInventory(); if (recipe.id.equals(lockedRecipeId) && lockedSlot >= 0) { return internalInv[lockedSlot].handleItemInternal(left, simulate); @@ -72,7 +71,7 @@ public List handleItemInner( contents = internalInv[i].handleItemInternal(contents, simulate); if (contents == null) { this.lockedSlot = i; - return contents; + return null; } contents = copyIngredients(left); } From 7a64fa8b014193967f95f73396b8ab6e995f59c7 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:29:06 -0700 Subject: [PATCH 14/29] =?UTF-8?q?atleast=20no=20more=20merge=20conflicts?= =?UTF-8?q?=20=F0=9F=A5=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capability/recipe/EURecipeCapability.java | 2 +- .../machine/feature/IRecipeLogicMachine.java | 1 + .../gtceu/api/machine/trait/RecipeLogic.java | 1 + .../gtceu/api/recipe/GTRecipe.java | 7 ---- .../gtceu/api/recipe/RecipeHelper.java | 7 ++-- .../api/recipe/modifier/ParallelLogic.java | 4 ++- .../electric/DistillationTowerMachine.java | 35 ++++++++++--------- .../LargeCombustionEngineMachine.java | 2 +- .../trait/customlogic/BreweryLogic.java | 4 +-- .../gregtechceu/gtceu/test/GTGameTests.java | 1 + 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/EURecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/EURecipeCapability.java index bb75ca67ea..69ae5f1a92 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/EURecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/EURecipeCapability.java @@ -84,7 +84,7 @@ public int getMaxParallelRatio(IRecipeCapabilityHolder holder, GTRecipe recipe, */ public static List makeEUContent(Long eu) { return List.of( - new Content(eu, ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0, null, null)); + new Content(eu, ChanceLogic.getMaxChancedValue(), ChanceLogic.getMaxChancedValue(), 0)); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java index 3c9576c38e..714c43af09 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.config.ConfigHolder; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index cacc9147f1..40f7a10429 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.sound.AutoReleasedSound; import com.gregtechceu.gtceu.config.ConfigHolder; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 947de97c5d..34960c92d3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -1,33 +1,26 @@ package com.gregtechceu.gtceu.api.recipe; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; -import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.Container; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeSerializer; import net.minecraft.world.level.Level; -import it.unimi.dsi.fastutil.objects.Object2IntMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.Supplier; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 97a6727d10..885565d688 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -1,9 +1,8 @@ package com.gregtechceu.gtceu.api.recipe; -import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.data.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.utils.GTUtil; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ParallelLogic.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ParallelLogic.java index 6100920ad5..28061748aa 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ParallelLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ParallelLogic.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import net.minecraft.MethodsReturnNonnullByDefault; @@ -200,7 +201,8 @@ public static int getParallelAmountFast(MetaMachine machine, @NotNull GTRecipe r while (parallelLimit > 0) { var copied = recipe.copy(ContentModifier.multiplier(parallelLimit), false); - if (copied.matchRecipe(holder).isSuccess() && copied.matchTickRecipe(holder).isSuccess()) { + if (RecipeHelper.matchRecipe(holder, copied).isSuccess() && + RecipeHelper.matchTickRecipe(holder, copied).isSuccess()) { return parallelLimit; } parallelLimit /= 2; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index a7ea3c244c..93b3d82e5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; @@ -81,7 +82,7 @@ public void onStructureFormed() { .toList(); if (!parts.isEmpty()) { - // Loop from controller y + offset -> highest output hatch + // Loop from controller y + offset -> the highest output hatch int y = getPos().getY() + yOffset; int maxY = parts.get(parts.size() - 1).self().getPos().getY(); fluidOutputs = new ObjectArrayList<>(maxY - y); @@ -94,9 +95,7 @@ public void onStructureFormed() { var part = parts.get(outputIndex); if (part.self().getPos().getY() == y) { part.getRecipeHandlers().handlerMap.forEach((cap, handler) -> { - boolean found = false; if (handler instanceof IFluidHandler fluidHandler) { - found = true; fluidOutputs.add(fluidHandler); if (firstValid == null) { firstValid = fluidHandler; @@ -196,9 +195,11 @@ public Iterator searchRecipe() { // Do recipe searching ourselves so we can match the outputs how we want IRecipeCapabilityHolder holder = this.machine; - if (!holder.hasProxies()) return null; + if (!holder.hasCapabilityProxies()) return null; var iterator = recipeType.getLookup().getRecipeIterator(holder, recipe -> !recipe.isFuel && - this.matchDTRecipe(recipe, holder).isSuccess() && recipe.matchTickRecipe(holder).isSuccess()); + + this.matchDTRecipe(recipe, holder).isSuccess() && + RecipeHelper.matchTickRecipe(holder, recipe).isSuccess()); boolean any = false; while (iterator.hasNext()) { @@ -225,8 +226,9 @@ public void findAndHandleRecipe() { lastFailedMatches = null; if (!recipeDirty && lastRecipe != null && matchDTRecipe(lastRecipe, this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { + RecipeHelper.matchTickRecipe(this.machine, lastRecipe).isSuccess() && + RecipeHelper.checkConditions(lastRecipe, this).size() == 1 && + RecipeHelper.checkConditions(lastRecipe, this).get(0).isSuccess()) { var recipe = lastRecipe; lastRecipe = null; lastOriginRecipe = null; @@ -244,9 +246,10 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { var matchCopy = match.copy(); var modified = machine.fullModifyRecipe(matchCopy); if (modified != null) { - if (modified.checkConditions(this).isSuccess() && + var conditions = RecipeHelper.checkConditions(modified, this); + if (conditions.size() == 1 && conditions.get(0).isSuccess() && matchDTRecipe(modified, machine).isSuccess() && - modified.matchTickRecipe(machine).isSuccess()) { + RecipeHelper.matchTickRecipe(machine, modified).isSuccess()) { setupRecipe(modified); } if (lastRecipe != null && getStatus() == Status.WORKING) { @@ -262,7 +265,7 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { - lastRecipe.postWorking(machine); + RecipeHelper.postWorking(machine, lastRecipe); handleRecipeIO(lastRecipe, IO.OUT); if (machine.alwaysTryModifyRecipe()) { if (lastOriginRecipe != null) { @@ -273,11 +276,11 @@ public void onRecipeFinish() { markLastRecipeDirty(); } } - + var conditions = RecipeHelper.checkConditions(lastRecipe, this); if (!recipeDirty && !suspendAfterFinish && matchDTRecipe(lastRecipe, this.machine).isSuccess() && - lastRecipe.matchTickRecipe(this.machine).isSuccess() && - lastRecipe.checkConditions(this).isSuccess()) { + RecipeHelper.matchTickRecipe(this.machine, lastRecipe).isSuccess() && + conditions.size() == 1 && conditions.get(0).isSuccess()) { setupRecipe(lastRecipe); } else { if (suspendAfterFinish) { @@ -293,9 +296,9 @@ public void onRecipeFinish() { } } - private RecipeHelper.ActionResult checkRecipe(GTRecipe recipe) { - var result = RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), - false, true); + private RecipeHelper.ActionResult matchDTRecipe(GTRecipe recipe, IRecipeCapabilityHolder holder) { + var result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, + Collections.emptyMap(), false, false); if (!result.isSuccess()) return result; var items = recipe.getOutputContents(ItemRecipeCapability.CAP); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java index acb9a82ad5..19e7df5e51 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java @@ -140,7 +140,7 @@ public static ModifierFunction recipeModifier(@NotNull MetaMachine machine, @Not long EUt = RecipeHelper.getOutputEUt(recipe); // has lubricant if (EUt > 0 && !engineMachine.isIntakesObstructed() && - engineMachine.getLubricantRecipe().matchRecipe(engineMachine).isSuccess()) { + RecipeHelper.matchRecipe(engineMachine, engineMachine.getLubricantRecipe()).isSuccess()) { int maxParallel = (int) (engineMachine.getOverclockVoltage() / EUt); // get maximum parallel int actualParallel = ParallelLogic.getParallelAmount(engineMachine, recipe, maxParallel); double eutMultiplier = actualParallel * engineMachine.getProductionBoost(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java index 2a3ca77a78..38f6717c5d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java @@ -39,7 +39,7 @@ public class BreweryLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { var itemInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), + .requireNonNullElseGet(holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP), ArrayList::new) .stream() .filter(IItemHandlerModifiable.class::isInstance) @@ -47,7 +47,7 @@ public class BreweryLogic implements GTRecipeType.ICustomRecipeLogic { .toArray(IItemHandlerModifiable[]::new); var fluidInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, FluidRecipeCapability.CAP), + .requireNonNullElseGet(holder.getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP), ArrayList::new) .stream() .filter(IFluidHandler.class::isInstance).map(IFluidHandler.class::cast) diff --git a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java b/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java index e69de29bb2..8b13789179 100644 --- a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java +++ b/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java @@ -0,0 +1 @@ + From ef7addf0c8d1bbb29071843e3b4fb63c1fd4ff72 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 22 Dec 2024 03:51:59 -0700 Subject: [PATCH 15/29] thinking emoji --- .../ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java | 2 +- .../ae2/machine/trait/MEPatternBufferRecipeHandler.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java index a40c5f3e82..987742bf57 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java @@ -59,7 +59,7 @@ public int getSize() { @Override public double getTotalContentAmount() { - long amount = 0; + double amount = 0; for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { amount += handlerTrait.getTotalContentAmount(); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java index 577842b495..0d829b16b8 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java @@ -65,15 +65,15 @@ public List handleItemInner(GTRecipe recipe, List left, } this.lockedRecipeId = recipe.id; - List contents = left; for (int i = 0; i < internalInv.length; i++) { if (internalInv[i].isItemEmpty()) continue; + List contents = left; contents = internalInv[i].handleItemInternal(contents, simulate); if (contents == null) { this.lockedSlot = i; return null; } - contents = copyIngredients(left); + // contents = copyIngredients(left); } this.lockedSlot = -1; return left; From 3e5324226c72435d46e2d87353511a74be4e1b97 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Fri, 27 Dec 2024 20:45:34 -0700 Subject: [PATCH 16/29] recipe runner cleanup --- .../gtceu/api/recipe/RecipeRunner.java | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index a54606bfbb..b9d6d10623 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -23,26 +23,14 @@ class RecipeRunner { record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, RecipeHelper.ActionResult result) {} - // -------------------------------------------------------------------------------------------------------- - private final GTRecipe recipe; private final IO io; private final boolean isTick; - private final IRecipeCapabilityHolder holder; private final Map, Object2IntMap> chanceCaches; private final Map> capabilityProxies; private final boolean simulated; - - // These are only used to store mutable state during each invocation of handle() - private RecipeCapability capability; - private Set used; private Map, List> recipeContents; private Map, List> searchRecipeContents; - /* - * @Getter - * private Map contentMatchList; - * private @UnknownNullability List searchingMatchList; - */ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -50,7 +38,6 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.recipe = recipe; this.io = io; this.isTick = isTick; - this.holder = holder; this.chanceCaches = chanceCaches; this.capabilityProxies = holder.getCapabilitiesProxy(); this.recipeContents = new IdentityHashMap<>(); @@ -58,10 +45,9 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.simulated = simulated; } + @Nullable public RecipeHandlingResult handle(Map, List> entries) { - initState(); - fillContentMatchList(entries); if (searchRecipeContents.isEmpty()) @@ -70,12 +56,6 @@ public RecipeHandlingResult handle(Map, List> entri return this.handleContents(); } - private void initState() { - used = new HashSet<>(); - // contentMatchList = new ArrayList<>(); - // searchingMatchList = simulated ? contentMatchList : new ArrayList<>(); - } - /** * Populates the content match list to know if conditions are satisfied. */ @@ -88,7 +68,9 @@ private void fillContentMatchList(Map, List> entrie } ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick); List chancedContents = new ArrayList<>(); + // skip if empty if (entry.getValue().isEmpty()) continue; + // populate recipe content capability map this.recipeContents.putIfAbsent(cap, new ArrayList<>()); for (Content cont : entry.getValue()) { this.searchRecipeContents.computeIfAbsent(cap, c -> new ArrayList<>()).add(cont.content); @@ -103,6 +85,7 @@ private void fillContentMatchList(Map, List> entrie } } + // add chanced contents to the recipe content map if (!chancedContents.isEmpty()) { int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); int chanceTier = recipeTier + recipe.ocLevel; @@ -115,10 +98,7 @@ private void fillContentMatchList(Map, List> entrie } } - if (!recipeContents.get(cap).isEmpty()) {} - // recipeContents.put(cap, recipeContents.get(cap).stream().map(cap::copyContent).toList()); - else - recipeContents.remove(cap); + if (recipeContents.get(cap).isEmpty()) recipeContents.remove(cap); } } From a6288cd3834f24ac1bd872fb5b30f949ff2b61e6 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:15:01 -0500 Subject: [PATCH 17/29] Fix merge issues --- .../electric/DistillationTowerMachine.java | 25 ++----------------- .../trait/customlogic/ArcFurnaceLogic.java | 6 ++--- .../trait/customlogic/MaceratorLogic.java | 6 ++--- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 506199e814..4d8f683013 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -97,29 +97,8 @@ public void onStructureFormed() { var part = parts.get(outputIndex); if (part.self().getPos().getY() == y) { - part.getRecipeHandlers().handlerMap.forEach((cap, handler) -> { - if (handler instanceof IFluidHandler fluidHandler) { - fluidOutputs.add(fluidHandler); - if (firstValid == null) { - firstValid = fluidHandler; - } - } else { - fluidOutputs.add(VoidFluidHandler.INSTANCE); - } - }); - - /* - * part.getRecipeHandlers().stream() - * .filter(IFluidHandler.class::isInstance) - * .findFirst() - * .ifPresentOrElse(h -> { - * fluidOutputs.add((IFluidHandler) h); - * if (firstValid == null) firstValid = (IFluidHandler) h; - * }, - * () -> fluidOutputs.add(VoidFluidHandler.INSTANCE)); - */ - - var handler = part.getRecipeHandlers().stream() + var handler = part.getRecipeHandlers().getCapability(FluidRecipeCapability.CAP) + .stream() .filter(IFluidHandler.class::isInstance) .findFirst() .map(IFluidHandler.class::cast) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java index 5a129b8ca3..c3d8867c7b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java @@ -33,15 +33,13 @@ public class ArcFurnaceLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var itemInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - ArrayList::new) + var inputHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP) .stream() .filter(IItemHandlerModifiable.class::isInstance) .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new); - var inputs = new CombinedInvWrapper(itemInputs); + var inputs = new CombinedInvWrapper(inputHandlers); var stack = inputs.getStackInSlot(0); var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java index a599517b16..69d51a75c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java @@ -33,15 +33,13 @@ public class MaceratorLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var itemInputs = Objects - .requireNonNullElseGet(holder.getCapabilitiesProxy().get(IO.IN, ItemRecipeCapability.CAP), - ArrayList::new) + var inputHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP) .stream() .filter(IItemHandlerModifiable.class::isInstance) .map(IItemHandlerModifiable.class::cast) .toArray(IItemHandlerModifiable[]::new); - var inputs = new CombinedInvWrapper(itemInputs); + var inputs = new CombinedInvWrapper(inputHandlers); var stack = inputs.getStackInSlot(0); var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); From d9fe9ddd98326105d13dda0287e6f7012c00ea45 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:36:47 -0500 Subject: [PATCH 18/29] Remove extra 'fuel' recipe references --- .../gtceu/api/machine/trait/RecipeLogic.java | 39 +++++++------------ .../gtceu/api/recipe/GTRecipe.java | 9 +---- .../gtceu/api/recipe/GTRecipeSerializer.java | 10 ++--- .../api/recipe/modifier/ModifierFunction.java | 2 +- .../electric/DistillationTowerMachine.java | 2 +- .../research/ResearchStationMachine.java | 1 - .../data/recipe/builder/GTRecipeBuilder.java | 12 +----- .../integration/kjs/GregTechKubeJSPlugin.java | 3 -- .../kjs/builders/GTRecipeTypeBuilder.java | 7 ---- .../kjs/recipe/GTRecipeSchema.java | 6 +-- 10 files changed, 24 insertions(+), 67 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index f6134c195e..f1760e48c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -96,12 +96,6 @@ public enum Status { @Getter @Persisted protected int duration; - @Getter - @Persisted - protected int fuelTime; - @Getter - @Persisted - protected int fuelMaxTime; @Getter(onMethod_ = @VisibleForTesting) protected boolean recipeDirty; @Persisted @@ -148,7 +142,6 @@ public void resetRecipeLogic() { progress = 0; duration = 0; isActive = false; - fuelTime = 0; lastFailedMatches = null; if (status != Status.SUSPEND) status = Status.IDLE; @@ -162,7 +155,7 @@ public void onMachineLoad() { } public void updateTickSubscription() { - if ((isSuspend() && fuelTime == 0) || !machine.isRecipeLogicAvailable()) { + if (isSuspend() || !machine.isRecipeLogicAvailable()) { if (subscription != null) { subscription.unsubscribe(); subscription = null; @@ -203,24 +196,20 @@ public void serverTick() { } } } - if (fuelTime > 0) { - fuelTime--; - } else { - boolean unsubscribe = false; - if (isSuspend()) { - unsubscribe = true; - } else if (lastRecipe == null && isIdle() && !machine.keepSubscribing() && !recipeDirty && - lastFailedMatches == null) { - // machine isn't working enabled - // or - // there is no available recipes, so it will wait for notification. - unsubscribe = true; - } + boolean unsubscribe = false; + if (isSuspend()) { + unsubscribe = true; + } else if (lastRecipe == null && isIdle() && !machine.keepSubscribing() && !recipeDirty && + lastFailedMatches == null) { + // machine isn't working enabled + // or + // there is no available recipes, so it will wait for notification. + unsubscribe = true; + } - if (unsubscribe && subscription != null) { - subscription.unsubscribe(); - subscription = null; - } + if (unsubscribe && subscription != null) { + subscription.unsubscribe(); + subscription = null; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 34960c92d3..13c580c2ba 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -57,8 +57,6 @@ public class GTRecipe implements net.minecraft.world.item.crafting.Recipe, List> inputs, @@ -73,11 +71,10 @@ public GTRecipe(GTRecipeType recipeType, List ingredientActions, @NotNull CompoundTag data, int duration, - boolean isFuel, @NotNull GTRecipeCategory recipeCategory) { this(recipeType, null, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, ingredientActions, data, duration, isFuel, recipeCategory); + conditions, ingredientActions, data, duration, recipeCategory); } public GTRecipe(GTRecipeType recipeType, @@ -94,7 +91,6 @@ public GTRecipe(GTRecipeType recipeType, List ingredientActions, @NotNull CompoundTag data, int duration, - boolean isFuel, @NotNull GTRecipeCategory recipeCategory) { this.recipeType = recipeType; this.id = id; @@ -113,7 +109,6 @@ public GTRecipe(GTRecipeType recipeType, this.ingredientActions = ingredientActions; this.data = data; this.duration = duration; - this.isFuel = isFuel; this.recipeCategory = (recipeCategory != GTRecipeCategory.DEFAULT) ? recipeCategory : recipeType.getCategory(); } @@ -132,7 +127,7 @@ public GTRecipe copy(ContentModifier modifier, boolean modifyDuration) { new HashMap<>(inputChanceLogics), new HashMap<>(outputChanceLogics), new HashMap<>(tickInputChanceLogics), new HashMap<>(tickOutputChanceLogics), new ArrayList<>(conditions), - new ArrayList<>(ingredientActions), data, duration, isFuel, recipeCategory); + new ArrayList<>(ingredientActions), data, duration, recipeCategory); if (modifyDuration) { copied.duration = modifier.apply(this.duration); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java index 8848adc348..3007c78705 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java @@ -138,7 +138,6 @@ public GTRecipe fromNetwork(@NotNull ResourceLocation id, @NotNull FriendlyByteB if (data == null) { data = new CompoundTag(); } - boolean isFuel = buf.readBoolean(); ResourceLocation categoryLoc = buf.readResourceLocation(); GTRecipeType type = (GTRecipeType) BuiltInRegistries.RECIPE_TYPE.get(recipeType); @@ -147,7 +146,7 @@ public GTRecipe fromNetwork(@NotNull ResourceLocation id, @NotNull FriendlyByteB GTRecipe recipe = new GTRecipe(type, id, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, ingredientActions, data, duration, isFuel, category); + conditions, ingredientActions, data, duration, category); recipe.recipeCategory.addRecipe(recipe); @@ -190,7 +189,6 @@ public void toNetwork(FriendlyByteBuf buf, GTRecipe recipe) { KJSCallWrapper.writeIngredientActions(recipe.ingredientActions, buf); } buf.writeNbt(recipe.data); - buf.writeBoolean(recipe.isFuel); buf.writeResourceLocation(recipe.recipeCategory.registryKey); } @@ -214,15 +212,14 @@ private static Codec makeCodec(boolean isKubeLoaded) { RecipeCondition.CODEC.listOf().optionalFieldOf("recipeConditions", List.of()).forGetter(val -> val.conditions), CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration), - Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel), GTRegistries.RECIPE_CATEGORIES.codec().optionalFieldOf("category", GTRecipeCategory.DEFAULT).forGetter(val -> val.recipeCategory)) .apply(instance, (type, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, data, duration, isFuel, recipeCategory) -> + conditions, data, duration, recipeCategory) -> new GTRecipe(type, inputs, outputs, tickInputs, tickOutputs, inputChanceLogics, outputChanceLogics, tickInputChanceLogics, tickOutputChanceLogics, - conditions, List.of(), data, duration, isFuel, recipeCategory))); + conditions, List.of(), data, duration, recipeCategory))); } else { return RecordCodecBuilder.create(instance -> instance.group( GTRegistries.RECIPE_TYPES.codec().fieldOf("type").forGetter(val -> val.recipeType), @@ -242,7 +239,6 @@ private static Codec makeCodec(boolean isKubeLoaded) { KJSCallWrapper.INGREDIENT_ACTION_CODEC.optionalFieldOf("kubejs:actions", List.of()).forGetter(val -> (List) val.ingredientActions), CompoundTag.CODEC.optionalFieldOf("data", new CompoundTag()).forGetter(val -> val.data), ExtraCodecs.NON_NEGATIVE_INT.fieldOf("duration").forGetter(val -> val.duration), - Codec.BOOL.optionalFieldOf("isFuel", false).forGetter(val -> val.isFuel), GTRegistries.RECIPE_CATEGORIES.codec().optionalFieldOf("category", GTRecipeCategory.DEFAULT).forGetter(val -> val.recipeCategory)) .apply(instance, GTRecipe::new)); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java index 79faf4a813..53baccee4f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java @@ -156,7 +156,7 @@ public ModifierFunction build() { new HashMap<>(recipe.inputChanceLogics), new HashMap<>(recipe.outputChanceLogics), new HashMap<>(recipe.tickInputChanceLogics), new HashMap<>(recipe.tickOutputChanceLogics), newConditions, new ArrayList<>(recipe.ingredientActions), - recipe.data, recipe.duration, recipe.isFuel, recipe.recipeCategory); + recipe.data, recipe.duration, recipe.recipeCategory); copied.parallels = recipe.parallels * parallels; copied.ocLevel = recipe.ocLevel + addOCs; if (recipe.data.getBoolean("duration_is_total_cwu")) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 4d8f683013..cd88775b27 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -189,7 +189,7 @@ public Iterator searchRecipe() { // Do recipe searching ourselves, so we can match the outputs how we want IRecipeCapabilityHolder holder = this.machine; if (!holder.hasCapabilityProxies()) return null; - var iterator = recipeType.getLookup().getRecipeIterator(holder, recipe -> !recipe.isFuel && + var iterator = recipeType.getLookup().getRecipeIterator(holder, recipe -> this.matchDTRecipe(recipe, holder).isSuccess() && RecipeHelper.matchTickRecipe(holder, recipe).isSuccess()); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 1bb9653848..db8350e3e4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -139,7 +139,6 @@ public Iterator searchRecipe() { IRecipeCapabilityHolder holder = this.machine; if (!holder.hasCapabilityProxies()) return null; var iterator = machine.getRecipeType().getLookup().getRecipeIterator(holder, recipe -> { - if (recipe.isFuel) return false; if (!holder.hasCapabilityProxies()) return false; var result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, false); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java index 3d7f7434c6..88d58bea07 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/builder/GTRecipeBuilder.java @@ -94,8 +94,6 @@ public class GTRecipeBuilder { public int maxChance = ChanceLogic.getMaxChancedValue(); @Setter public int tierChanceBoost = 0; - @Setter - public boolean isFuel = false; public GTRecipeCategory recipeCategory; @Setter public BiConsumer> onSave; @@ -123,7 +121,6 @@ public GTRecipeBuilder(GTRecipe toCopy, GTRecipeType recipeType) { this.conditions.addAll(toCopy.conditions); this.data = toCopy.data.copy(); this.duration = toCopy.duration; - this.isFuel = toCopy.isFuel; this.recipeCategory = toCopy.recipeCategory; } @@ -154,7 +151,6 @@ public GTRecipeBuilder copy(ResourceLocation id) { copy.duration = this.duration; copy.chance = this.chance; copy.perTick = this.perTick; - copy.isFuel = this.isFuel; copy.recipeCategory = this.recipeCategory; copy.onSave = this.onSave; return copy; @@ -1162,9 +1158,6 @@ public void toJson(JsonObject json) { } json.add("recipeConditions", array); } - if (isFuel) { - json.addProperty("isFuel", true); - } } public JsonObject capabilitiesToJson(Map, List> contents) { @@ -1246,11 +1239,10 @@ public void save(Consumer consumer) { } public GTRecipe buildRawRecipe() { - var recipe = new GTRecipe(recipeType, id.withPrefix(recipeType.registryName.getPath() + "/"), + return new GTRecipe(recipeType, id.withPrefix(recipeType.registryName.getPath() + "/"), input, output, tickInput, tickOutput, inputChanceLogic, outputChanceLogic, tickInputChanceLogic, tickOutputChanceLogic, - conditions, List.of(), data, duration, isFuel, recipeCategory); - return recipe; + conditions, List.of(), data, duration, recipeCategory); } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java index 5dd0615793..64f0879adb 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GregTechKubeJSPlugin.java @@ -456,9 +456,6 @@ public void injectRuntimeRecipes(RecipesEventJS event, RecipeManager manager, if (gtRecipe.getValue(GTRecipeSchema.CONDITIONS) != null) { builder.conditions.addAll(Arrays.stream(gtRecipe.getValue(GTRecipeSchema.CONDITIONS)).toList()); } - if (gtRecipe.getValue(GTRecipeSchema.IS_FUEL) != null) { - builder.isFuel = gtRecipe.getValue(GTRecipeSchema.IS_FUEL); - } if (gtRecipe.getValue(GTRecipeSchema.CATEGORY) != null) { builder.recipeCategory = GTRegistries.RECIPE_CATEGORIES .get(gtRecipe.getValue(GTRecipeSchema.CATEGORY)); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java index 7fa66a2421..c000a2e58c 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/GTRecipeTypeBuilder.java @@ -43,7 +43,6 @@ public class GTRecipeTypeBuilder extends BuilderBase { protected SoundEntry sound; protected boolean hasResearchSlot; protected int maxTooltips; - protected boolean isFuelRecipeType; private GTRecipeType smallRecipeMap; private Supplier iconSupplier; @@ -62,7 +61,6 @@ public GTRecipeTypeBuilder(ResourceLocation i) { this.sound = null; this.hasResearchSlot = false; this.maxTooltips = 3; - this.isFuelRecipeType = false; this.smallRecipeMap = null; this.iconSupplier = null; this.uiBuilder = null; @@ -145,11 +143,6 @@ public GTRecipeTypeBuilder setMaxTooltips(int maxTooltips) { return this; } - public GTRecipeTypeBuilder setFuelRecipeType(boolean isFuelRecipeType) { - this.isFuelRecipeType = isFuelRecipeType; - return this; - } - public GTRecipeTypeBuilder setSmallRecipeMap(GTRecipeType smallRecipeMap) { this.smallRecipeMap = smallRecipeMap; return this; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java index 99181aae5f..99806f04d3 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java @@ -78,8 +78,6 @@ class GTRecipeJS extends RecipeJS { public int maxChance = ChanceLogic.getMaxChancedValue(); @Setter public int tierChanceBoost = 0; - @Setter - public boolean isFuel = false; @Getter private ResourceLocation idWithoutType; @Setter @@ -969,7 +967,6 @@ public InputFluid readInputFluid(Object from) { RecipeKey DATA = GTRecipeComponents.TAG.key("data").optional((CompoundTag) null); RecipeKey CONDITIONS = GTRecipeComponents.RECIPE_CONDITION.asArray().key("recipeConditions") .defaultOptional(); - RecipeKey IS_FUEL = BooleanComponent.BOOLEAN.key("isFuel").optional(false); RecipeKey CATEGORY = GTRecipeComponents.RESOURCE_LOCATION.key("category").defaultOptional(); RecipeKey ALL_INPUTS = GTRecipeComponents.IN.key("inputs").defaultOptional(); @@ -989,8 +986,7 @@ public InputFluid readInputFluid(Object from) { RecipeSchema SCHEMA = new RecipeSchema(GTRecipeJS.class, GTRecipeJS::new, DURATION, DATA, CONDITIONS, ALL_INPUTS, ALL_TICK_INPUTS, ALL_OUTPUTS, ALL_TICK_OUTPUTS, - INPUT_CHANCE_LOGICS, OUTPUT_CHANCE_LOGICS, TICK_INPUT_CHANCE_LOGICS, TICK_OUTPUT_CHANCE_LOGICS, - IS_FUEL, CATEGORY) + INPUT_CHANCE_LOGICS, OUTPUT_CHANCE_LOGICS, TICK_INPUT_CHANCE_LOGICS, TICK_OUTPUT_CHANCE_LOGICS, CATEGORY) .constructor((recipe, schemaType, keys, from) -> recipe.id(from.getValue(recipe, ID)), ID) .constructor(DURATION, CONDITIONS, ALL_INPUTS, ALL_OUTPUTS, ALL_TICK_INPUTS, ALL_TICK_OUTPUTS); } From 44bb42475d27c7175ac285e384e462eabdbcd953 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Thu, 23 Jan 2025 02:30:16 -0500 Subject: [PATCH 19/29] here you go --- .../recipe/IRecipeCapabilityHolder.java | 16 +- .../gtceu/api/item/tool/ToolHelper.java | 19 +-- .../api/machine/WorkableTieredMachine.java | 13 +- .../WorkableElectricMultiblockMachine.java | 14 +- .../multiblock/WorkableMultiblockMachine.java | 25 +-- .../part/MultiblockPartMachine.java | 7 +- .../api/machine/steam/SimpleSteamMachine.java | 5 +- .../machine/steam/SteamWorkableMachine.java | 12 +- .../api/machine/trait/RecipeHandlerList.java | 46 +++++- .../gtceu/api/machine/trait/RecipeLogic.java | 66 ++++---- .../gtceu/api/recipe/ActionResult.java | 31 ++++ .../gtceu/api/recipe/RecipeCondition.java | 7 +- .../gtceu/api/recipe/RecipeHelper.java | 66 +++----- .../gtceu/api/recipe/RecipeRunner.java | 38 ++--- .../api/recipe/lookup/GTRecipeLookup.java | 24 ++- .../electric/DistillationTowerMachine.java | 131 +++------------ .../research/ResearchStationMachine.java | 149 ++++++------------ .../steam/SteamParallelMultiblockMachine.java | 12 +- .../machine/trait/NotifiableStressTrait.java | 0 .../trait/customlogic/ArcFurnaceLogic.java | 3 - .../trait/customlogic/MaceratorLogic.java | 3 - .../machine/trait/miner/MinerLogic.java | 18 +-- .../condition/AdjacentBlockCondition.java | 2 +- .../recipe/condition/BiomeCondition.java | 2 +- .../recipe/condition/CleanroomCondition.java | 2 +- .../recipe/condition/DimensionCondition.java | 2 +- .../recipe/condition/EUToStartCondition.java | 2 +- .../EnvironmentalHazardCondition.java | 2 +- .../recipe/condition/PositionYCondition.java | 2 +- .../recipe/condition/RainingCondition.java | 2 +- .../recipe/condition/ResearchCondition.java | 2 +- .../condition/RockBreakerCondition.java | 2 +- .../recipe/condition/ThunderCondition.java | 2 +- .../recipe/condition/VentCondition.java | 2 +- .../kjs/recipe/GTRecipeSchema.java | 1 - .../gtceu/utils/DummyMachineBlockEntity.java | 1 + .../gtceu/utils/DummyRecipeLogicMachine.java | 10 ++ 37 files changed, 311 insertions(+), 430 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 09af339acb..0841e3ebec 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -2,8 +2,10 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; @@ -20,9 +22,17 @@ default boolean hasCapabilityProxies() { Map, List>>> getCapabilitiesFlat(); default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { - if (getCapabilitiesProxy().get(io) == null) { - return Collections.emptyList(); + return getCapabilitiesFlat() + .getOrDefault(io, Collections.emptyMap()) + .getOrDefault(cap, Collections.emptyList()); + } + + default void addHandlerList(RecipeHandlerList handler) { + IO io = handler.getHandlerIO(); + getCapabilitiesProxy().computeIfAbsent(io, i -> new ArrayList<>()).add(handler); + var inner = getCapabilitiesFlat().computeIfAbsent(io, i -> new Reference2ObjectOpenHashMap<>()); + for (var entry : handler.handlerMap.entrySet()) { + inner.computeIfAbsent(entry.getKey(), c -> new ArrayList<>()).addAll(entry.getValue()); } - return getCapabilitiesFlat().get(io).get(cap); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index a3201b3bb8..6953cf72bc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -415,15 +415,16 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It Map> caps = new IdentityHashMap<>(); DummyMachineBlockEntity be = new DummyMachineBlockEntity(GTValues.LV, GTRecipeTypes.FORGE_HAMMER_RECIPES, GTMachineUtils.defaultTankSizeFunction, caps); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()) - .add(RecipeHandlerList.of(IO.IN, new InfiniteEnergyContainer(be.getMetaMachine(), - GTValues.V[GTValues.LV], GTValues.V[GTValues.LV], 1, GTValues.V[GTValues.LV], 1))); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()) - .add(RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 1, - IO.IN, IO.IN, (slots) -> new CustomItemStackHandler(silktouchDrop)))); - caps.computeIfAbsent(IO.IN, i -> new ArrayList()).add( - RecipeHandlerList.of(IO.IN, new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT))); - be.getMetaMachine().reinitializeCapabilities(caps); + RecipeHandlerList dummyInputs = new RecipeHandlerList(IO.IN); + dummyInputs.addHandlers( + new InfiniteEnergyContainer(be.getMetaMachine(), GTValues.V[GTValues.LV], + GTValues.V[GTValues.LV], 1, GTValues.V[GTValues.LV], 1), + new NotifiableItemStackHandler(be.getMetaMachine(), 1, IO.IN, IO.IN, + (slots) -> new CustomItemStackHandler(silktouchDrop))); + + RecipeHandlerList dummyOutputs = RecipeHandlerList.of(IO.OUT, + new NotifiableItemStackHandler(be.getMetaMachine(), 2, IO.OUT)); + be.getMetaMachine().reinitializeHandlers(List.of(dummyInputs, dummyOutputs)); Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, r -> RecipeHelper.matchContents(be.metaMachine, r).isSuccess()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index cf7763bd7f..f07c4487fb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -14,7 +14,6 @@ import com.mojang.blaze3d.MethodsReturnNonnullByDefault; import it.unimi.dsi.fastutil.ints.Int2IntFunction; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -87,8 +86,8 @@ public WorkableTieredMachine(IMachineBlockEntity holder, int tier, Int2IntFuncti this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.tankScalingFunction = tankScalingFunction; - this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); - this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); + this.capabilitiesProxy = new EnumMap<>(IO.class); + this.capabilitiesFlat = new EnumMap<>(IO.class); this.traitSubscriptions = new ArrayList<>(); this.recipeLogic = createRecipeLogic(args); this.importItems = createImportItemHandler(args); @@ -165,20 +164,18 @@ protected RecipeLogic createRecipeLogic(Object... args) { public void onLoad() { super.onLoad(); // attach self traits - Map>> ioTraits = new Object2ObjectOpenHashMap<>(); + Map>> ioTraits = new EnumMap<>(IO.class); for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); - capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) - .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); - handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); - capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + handlerList.addHandlers(entry.getValue()); + this.addHandlerList(handlerList); traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java index 5be24b8273..9e58a3fb4a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java @@ -192,19 +192,17 @@ public long getOverclockVoltage() { public EnergyContainerList getEnergyContainer() { List containers = new ArrayList<>(); - var capabilities = capabilitiesProxy.get(IO.IN).stream() - .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); - if (!capabilities.isEmpty()) { - for (IRecipeHandler handler : capabilities) { + var handlers = getCapabilitiesFlat(IO.IN, EURecipeCapability.CAP); + if (!handlers.isEmpty()) { + for (IRecipeHandler handler : handlers) { if (handler instanceof IEnergyContainer container) { containers.add(container); } } } else { - capabilities = capabilitiesProxy.get(IO.OUT).stream() - .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); - if (!capabilities.isEmpty()) { - for (IRecipeHandler handler : capabilities) { + handlers = getCapabilitiesFlat(IO.OUT, EURecipeCapability.CAP); + if (!handlers.isEmpty()) { + for (IRecipeHandler handler : handlers) { if (handler instanceof IEnergyContainer container) { containers.add(container); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 8c9feb4b4c..752898d3b1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -27,7 +27,6 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.LongSet; import it.unimi.dsi.fastutil.longs.LongSets; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -83,8 +82,8 @@ public WorkableMultiblockMachine(IMachineBlockEntity holder, Object... args) { this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); - this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); - this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); + this.capabilitiesProxy = new EnumMap<>(IO.class); + this.capabilitiesFlat = new EnumMap<>(IO.class); this.traitSubscriptions = new ArrayList<>(); } @@ -129,34 +128,22 @@ public void onStructureFormed() { var handlerList = part.getRecipeHandlers(); if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - capabilitiesProxy.computeIfAbsent(handlerList.getHandlerIO(), i -> new ArrayList<>()).add(handlerList); - var inner = capabilitiesFlat.computeIfAbsent(handlerList.getHandlerIO(), - i -> new Object2ObjectOpenHashMap<>()); - for (var cap : handlerList.handlerMap.entrySet()) { - inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); - } + this.addHandlerList(handlerList); traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } // attach self traits - Map>> ioTraits = new Object2ObjectOpenHashMap<>(); - + Map>> ioTraits = new EnumMap<>(IO.class); for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); - capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) - .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); - handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); - capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); - var inner = capabilitiesFlat.computeIfAbsent(entry.getKey(), i -> new Object2ObjectOpenHashMap<>()); - for (var cap : handlerList.handlerMap.entrySet()) { - inner.computeIfAbsent(cap.getKey(), i -> new ArrayList<>()).addAll(cap.getValue()); - } + handlerList.addHandlers(entry.getValue()); + this.addHandlerList(handlerList); traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } // schedule recipe logic diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index 3751555ee7..f0bf2fe13c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.UnmodifiableView; import java.util.Collections; -import java.util.List; import java.util.Set; import java.util.SortedSet; @@ -95,14 +94,16 @@ public SortedSet getControllers() { public RecipeHandlerList getRecipeHandlers() { if (handlerList == null) { - var a = traits.stream().filter(IRecipeHandlerTrait.class::isInstance).map(IRecipeHandlerTrait.class::cast) + var a = traits.stream() + .filter(IRecipeHandlerTrait.class::isInstance) + .map(IRecipeHandlerTrait.class::cast) .toList(); if (a.isEmpty()) { handlerList = new RecipeHandlerList(IO.NONE); return handlerList; } handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); - handlerList.addHandler(a.toArray(new IRecipeHandler[0])); + handlerList.addHandlers(a.toArray(new IRecipeHandler[0])); } return handlerList; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java index fdeb7e862d..cf96d20898 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java @@ -86,9 +86,8 @@ protected NotifiableItemStackHandler createExportItemHandler(@SuppressWarnings(" @Override public void onLoad() { super.onLoad(); - // Fine, we use it to provide eu cap for recipe, simulating an EU machine. - capabilitiesProxy.computeIfAbsent(IO.IN, i -> new ArrayList<>()) - .add(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(steamTank, getConversionRate()))); + // Simulate an EU machine via a SteamEnergyHandler + this.addHandlerList(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(steamTank, getConversionRate()))); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index c8ee8e18dc..52f666c6b5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -89,8 +89,8 @@ public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, this.recipeTypes = getDefinition().getRecipeTypes(); this.activeRecipeType = 0; this.recipeLogic = createRecipeLogic(args); - this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); - this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); + this.capabilitiesProxy = new EnumMap<>(IO.class); + this.capabilitiesFlat = new EnumMap<>(IO.class); this.traitSubscriptions = new ArrayList<>(); this.outputFacing = hasFrontFacing() ? getFrontFacing().getOpposite() : Direction.UP; } @@ -107,20 +107,18 @@ public ManagedFieldHolder getFieldHolder() { public void onLoad() { super.onLoad(); // attach self traits - Map>> ioTraits = new Object2ObjectOpenHashMap<>(); + Map>> ioTraits = new Object2ObjectOpenHashMap<>(); for (MachineTrait trait : getTraits()) { if (trait instanceof IRecipeHandlerTrait handlerTrait) { ioTraits.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new ArrayList<>()).add(handlerTrait); - capabilitiesFlat.computeIfAbsent(handlerTrait.getHandlerIO(), i -> new IdentityHashMap<>()) - .computeIfAbsent(handlerTrait.getCapability(), i -> new ArrayList<>()).add(handlerTrait); } } for (var entry : ioTraits.entrySet()) { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); - handlerList.addHandler(entry.getValue().toArray(new IRecipeHandler[0])); - capabilitiesProxy.computeIfAbsent(entry.getKey(), i -> new ArrayList<>()).add(handlerList); + handlerList.addHandlers(entry.getValue()); + this.addHandlerList(handlerList); traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index 79bfa956b6..e1e4f5bbd0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -7,7 +7,8 @@ import com.lowdragmc.lowdraglib.syncdata.ISubscription; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; @@ -15,11 +16,21 @@ public class RecipeHandlerList { - public Map, List>> handlerMap = new Object2ObjectOpenHashMap<>(); - private IO io; + public static final Comparator COMPARATOR = (h1, h2) -> { + int cmp = Long.compare(h1.getPriority(), h2.getPriority()); + if (cmp != 0) return cmp; + boolean b1 = h1.getTotalContentAmount() > 0; + boolean b2 = h2.getTotalContentAmount() > 0; + return Boolean.compare(b1, b2); + }; + + public final Map, List>> handlerMap = new Reference2ObjectOpenHashMap<>(); + private final List> allHandlers = new ObjectArrayList<>(); + private final IO io; @Setter @Getter private boolean isDistinct = false; + private long priority = 0; public RecipeHandlerList(IO io) { this.io = io; @@ -27,7 +38,7 @@ public RecipeHandlerList(IO io) { public static RecipeHandlerList of(IO io, IRecipeHandler handler) { RecipeHandlerList rhl = new RecipeHandlerList(io); - rhl.addHandler(handler); + rhl.addHandlers(handler); return rhl; } @@ -35,9 +46,22 @@ public List> getCapability(RecipeCapability cap) { return handlerMap.getOrDefault(cap, Collections.emptyList()); } - public void addHandler(IRecipeHandler... handlers) { + public void addHandlers(IRecipeHandler... handlers) { + addHandlers(Arrays.asList(handlers)); + } + + public void addHandlers(Collection> handlers) { for (var handler : handlers) { handlerMap.computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); + priority += handler.getPriority(); + } + allHandlers.addAll(handlers); + sort(); + } + + public void sort() { + for (var list : handlerMap.values()) { + list.sort(IRecipeHandler.ENTRY_COMPARATOR); } } @@ -49,6 +73,18 @@ public IO getHandlerIO() { return io; } + public long getPriority() { + long priority = 0; + for (var handler : allHandlers) priority += handler.getPriority(); + return priority; + } + + public double getTotalContentAmount() { + double sum = 0; + for (var handler : allHandlers) sum += handler.getTotalContentAmount(); + return sum; + } + public List addChangeListeners(Runnable listener) { List ret = new ArrayList<>(); for (var handlerList : handlerMap.values()) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index f1760e48c3..297c413309 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; +import com.gregtechceu.gtceu.api.recipe.ActionResult; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -213,31 +214,31 @@ public void serverTick() { } } - protected RecipeHelper.ActionResult checkRecipe(GTRecipe recipe) { - var recipeConditions = RecipeHelper.checkConditions(recipe, this).stream().filter(v -> !v.isSuccess()) - .findFirst(); - if (recipeConditions.isPresent()) { - return recipeConditions.get(); - } + protected ActionResult matchRecipe(GTRecipe recipe) { var match = RecipeHelper.matchRecipe(this.machine, recipe); + if (!match.isSuccess()) return match; + var matchTick = RecipeHelper.matchTickRecipe(this.machine, recipe); - if (!match.isSuccess()) - return match; - if (!matchTick.isSuccess()) - return matchTick; - return RecipeHelper.ActionResult.SUCCESS; - // return recipeConditions.orElseGet(() -> RecipeHandler.matchContents(this.machine, recipe)); + if (!matchTick.isSuccess()) return matchTick; + + return ActionResult.SUCCESS; + } + + protected ActionResult checkRecipe(GTRecipe recipe) { + var conditionResult = RecipeHelper.checkConditions(recipe, this); + if (!conditionResult.isSuccess()) return conditionResult; + + return matchRecipe(recipe); } public boolean checkMatchedRecipeAvailable(GTRecipe match) { - var matchCopy = match.copy(); - var modified = machine.fullModifyRecipe(matchCopy); + var modified = machine.fullModifyRecipe(match); if (modified != null) { var recipeMatch = checkRecipe(modified); if (recipeMatch.isSuccess()) { setupRecipe(modified); } else { - setWaiting(recipeMatch.getReason()); + setWaiting(recipeMatch.reason()); } if (lastRecipe != null && getStatus() == Status.WORKING) { lastOriginRecipe = match; @@ -251,12 +252,10 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { public void handleRecipeWorking() { Status last = this.status; assert lastRecipe != null; - var conditionResults = RecipeHelper.checkConditions(lastRecipe, this).stream().filter(v -> !v.isSuccess()) - .findFirst(); - RecipeHelper.ActionResult result; - if (conditionResults.isEmpty()) { - result = handleTickRecipe(lastRecipe); - if (result.isSuccess()) { + var conditionResult = RecipeHelper.checkConditions(lastRecipe, this); + if (conditionResult.isSuccess()) { + var handleTick = handleTickRecipe(lastRecipe); + if (handleTick.isSuccess()) { setStatus(Status.WORKING); if (!machine.onWorking()) { this.interruptRecipe(); @@ -265,10 +264,10 @@ public void handleRecipeWorking() { progress++; totalContinuousRunningTime++; } else { - setWaiting(result.reason().get()); + setWaiting(handleTick.reason()); } } else { - setWaiting(conditionResults.get().getReason()); + setWaiting(conditionResult.reason()); } if (isWaiting()) { doDamping(); @@ -291,8 +290,7 @@ protected void doDamping() { } public Iterator searchRecipe() { - return machine.getRecipeType().searchRecipe(this.machine, - r -> RecipeHelper.matchContents(this.machine, r).isSuccess()); + return machine.getRecipeType().searchRecipe(machine, r -> matchRecipe(r).isSuccess()); } public void findAndHandleRecipe() { @@ -328,7 +326,7 @@ protected void handleSearchingRecipes(Iterator matches) { } } - public RecipeHelper.ActionResult handleTickRecipe(GTRecipe recipe) { + public ActionResult handleTickRecipe(GTRecipe recipe) { if (recipe.hasTick()) { var result = RecipeHelper.matchTickRecipe(this.machine, recipe); if (result.isSuccess()) { @@ -338,7 +336,7 @@ public RecipeHelper.ActionResult handleTickRecipe(GTRecipe recipe) { return result; } } - return RecipeHelper.ActionResult.SUCCESS; + return ActionResult.SUCCESS; } public void setupRecipe(GTRecipe recipe) { @@ -363,7 +361,7 @@ public void setupRecipe(GTRecipe recipe) { duration = recipe.duration; isActive = true; } else { - setWaiting(handledIO.getReason()); + setWaiting(handledIO.reason()); } } @@ -437,11 +435,6 @@ public boolean isActive() { return isWorking() || isWaiting() || (isSuspend() && isActive); } - @Deprecated - public boolean isHasNotEnoughEnergy() { - return isWaiting(); - } - public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { @@ -461,8 +454,7 @@ public void onRecipeFinish() { } } // try it again - var recipeMatch = checkRecipe(lastRecipe); - if (!recipeDirty && !suspendAfterFinish && recipeMatch.isSuccess()) { + if (!recipeDirty && !suspendAfterFinish && checkRecipe(lastRecipe).isSuccess()) { setupRecipe(lastRecipe); } else { if (suspendAfterFinish) { @@ -479,11 +471,11 @@ public void onRecipeFinish() { } } - protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { return RecipeHelper.handleRecipeIO(io, this.machine, recipe, this.chanceCaches); } - protected RecipeHelper.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + protected ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { return RecipeHelper.handleTickRecipeIO(io, this.machine, recipe, this.chanceCaches); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java new file mode 100644 index 0000000000..c7cfe25ff7 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java @@ -0,0 +1,31 @@ +package com.gregtechceu.gtceu.api.recipe; + +import net.minecraft.network.chat.Component; + +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +/** + * @param isSuccess is action success + * @param reasonSupplier if fail, fail reasonSupplier + */ +public record ActionResult(boolean isSuccess, Supplier<@Nullable Component> reasonSupplier) { + + public final static ActionResult SUCCESS = new ActionResult(true, () -> null); + public final static ActionResult FAIL_NO_REASON = new ActionResult(false, () -> null); + public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, + () -> Component.translatable("gtceu.recipe_logic.no_contents")); + public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, + () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + + public static ActionResult fail(Supplier<@Nullable Component> component) { + return new ActionResult(false, component); + } + + public Component reason() { + var comp = reasonSupplier.get(); + if (comp == null) return Component.empty(); + return comp; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeCondition.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeCondition.java index e8d6ecdeb4..2baeb80ad9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeCondition.java @@ -69,7 +69,12 @@ public boolean isOr() { public abstract Component getTooltips(); - public abstract boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic); + public boolean check(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + boolean test = testCondition(recipe, recipeLogic); + return test != isReverse; + } + + protected abstract boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic); public abstract RecipeCondition createTemplate(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 885565d688..1d9c0da413 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -12,11 +12,10 @@ import net.minecraftforge.fluids.FluidStack; import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.Supplier; import java.util.stream.Collectors; /** @@ -256,8 +255,8 @@ public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, G public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { var match = matchRecipe(holder, recipe); - if (!match.isSuccess()) - return match; + if (!match.isSuccess()) return match; + return matchTickRecipe(holder, recipe); } @@ -272,7 +271,7 @@ public static void postWorking(IRecipeCapabilityHolder holder, GTRecipe recipe) } public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { - (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + (io == IO.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { var capFlatMap = holder.getCapabilitiesFlat(io, capability); if (!capFlatMap.isEmpty()) { for (IRecipeHandler capabilityProxy : capFlatMap) { @@ -287,7 +286,7 @@ public static void handlePre(IRecipeCapabilityHolder holder, GTRecipe recipe, IO } public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io) { - (io == io.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { + (io == IO.IN ? recipe.inputs : recipe.outputs).forEach(((capability, tuples) -> { var capFlatMap = holder.getCapabilitiesFlat(io, capability); if (!capFlatMap.isEmpty()) { for (IRecipeHandler capabilityProxy : capFlatMap) { @@ -308,29 +307,31 @@ public static void handlePost(IRecipeCapabilityHolder holder, GTRecipe recipe, I * @param recipeLogic the logic to test against the conditions * @return the list of failed conditions, or success if all conditions are satisfied */ - public static List checkConditions(GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { - if (recipe.conditions.isEmpty()) return List.of(ActionResult.SUCCESS); - Map, List> or = new HashMap<>(); - List failures = new ArrayList<>(); + public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + if (recipe.conditions.isEmpty()) return ActionResult.SUCCESS; + Map, List> or = new Reference2ObjectArrayMap<>(); for (RecipeCondition condition : recipe.conditions) { if (condition.isOr()) { or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); - } else if (condition.test(recipe, recipeLogic) == condition.isReverse()) { - failures.add(ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails").append(": ") - .append(condition.getTooltips()))); + } else if (!condition.check(recipe, recipeLogic)) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails") + .append(": ") + .append(condition.getTooltips())); } } for (List conditions : or.values()) { - if (conditions.stream() - .allMatch(condition -> condition.test(recipe, recipeLogic) == condition.isReverse())) { - failures.add(ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails"))); + boolean passed = conditions.isEmpty(); + for (RecipeCondition condition : conditions) { + passed = condition.check(recipe, recipeLogic); + if (passed) break; + } + + if (!passed) { + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails")); } } - if (!failures.isEmpty()) - return failures; - return List.of(ActionResult.SUCCESS); + return ActionResult.SUCCESS; } /** @@ -479,29 +480,4 @@ private static ActionResult checkFluidValid(Map, List reason) { - - public final static ActionResult SUCCESS = new ActionResult(true, null); - public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); - public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, - () -> Component.translatable("gtceu.recipe_logic.no_contents")); - public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, - () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); - - public static ActionResult fail(@Nullable Supplier component) { - return new ActionResult(false, component); - } - - public Component getReason() { - if (reason() == null) { - return Component.empty(); - } - return reason().get(); - } - } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index b9d6d10623..e654d307c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.recipe.content.Content; import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; @@ -21,7 +22,7 @@ class RecipeRunner { record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, - RecipeHelper.ActionResult result) {} + ActionResult result) {} private final GTRecipe recipe; private final IO io; @@ -40,18 +41,17 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.isTick = isTick; this.chanceCaches = chanceCaches; this.capabilityProxies = holder.getCapabilitiesProxy(); - this.recipeContents = new IdentityHashMap<>(); - this.searchRecipeContents = simulated ? recipeContents : new IdentityHashMap<>(); + this.recipeContents = new Reference2ObjectOpenHashMap<>(); + this.searchRecipeContents = simulated ? recipeContents : new Reference2ObjectOpenHashMap<>(); this.simulated = simulated; } - @Nullable public RecipeHandlingResult handle(Map, List> entries) { fillContentMatchList(entries); if (searchRecipeContents.isEmpty()) - return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.PASS_NO_CONTENTS); + return new RecipeHandlingResult(null, null, ActionResult.PASS_NO_CONTENTS); return this.handleContents(); } @@ -102,10 +102,9 @@ private void fillContentMatchList(Map, List> entrie } } - @Nullable private RecipeHandlingResult handleContents() { if (recipeContents.isEmpty()) { - return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); } var result = handleContentsInternal(io); if (!result.result.isSuccess()) { @@ -116,20 +115,17 @@ private RecipeHandlingResult handleContents() { private RecipeHandlingResult handleContentsInternal(IO capIO) { if (!capabilityProxies.containsKey(capIO)) - return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); - // noinspection DataFlowIssue checked above. - var handlers = new ArrayList<>(capabilityProxies.get(capIO)); - List distinct = new ArrayList<>(), nondistinct = new ArrayList<>(); + var handlers = capabilityProxies.get(capIO); + handlers.sort(RecipeHandlerList.COMPARATOR.reversed()); + List distinct = new ArrayList<>(); + List indistinct = new ArrayList<>(); for (var handler : handlers) { - if (handler.isDistinct()) - distinct.add(handler); - else - nondistinct.add(handler); + if (handler.isDistinct()) distinct.add(handler); + else indistinct.add(handler); } - // handlers.sort(IRecipeHandler.ENTRY_COMPARATOR); - // handle distinct first boolean handled = false; for (var handler : distinct) { @@ -144,7 +140,7 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } if (!handled) { - for (var handler : nondistinct) { + for (var handler : indistinct) { if (!recipeContents.isEmpty()) { recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); } @@ -168,16 +164,16 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } if (handled) { - return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.SUCCESS); + return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); } for (var entry : recipeContents.entrySet()) { if (entry.getValue() != null && !entry.getValue().isEmpty()) { return new RecipeHandlingResult(entry.getKey(), entry.getValue(), - RecipeHelper.ActionResult.FAIL_NO_REASON); + ActionResult.FAIL_NO_REASON); } } - return new RecipeHandlingResult(null, null, RecipeHelper.ActionResult.FAIL_NO_REASON); + return new RecipeHandlingResult(null, null, ActionResult.FAIL_NO_REASON); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 89b1794968..2b73257df6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -58,10 +58,9 @@ public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { protected List> prepareRecipeFind(@NotNull IRecipeCapabilityHolder holder) { // First, check if items and fluids are valid. int totalSize = 0; - List recipeList = new ArrayList<>( - holder.getCapabilitiesProxy().getOrDefault(IO.IN, new ArrayList<>())); + List handlers = holder.getCapabilitiesProxy().getOrDefault(IO.IN, new ArrayList<>()); - for (var handler : recipeList) { + for (var handler : handlers) { for (var entries : handler.handlerMap.entrySet()) { int size = 0; if (!entries.getKey().isRecipeSearchFilter()) { @@ -431,28 +430,27 @@ protected List> fromRecipe(@NotNull GTRecipe r) { */ @NotNull protected List> fromHolder(@NotNull IRecipeCapabilityHolder r) { - var recipeList = r.getCapabilitiesProxy().get(IO.IN).stream().toList(); + var handlerLists = r.getCapabilitiesProxy().getOrDefault(IO.IN, Collections.emptyList()); int size = 0; - for (var handler : recipeList) { + for (var handler : handlerLists) { for (var entry : handler.handlerMap.entrySet()) { size += entry.getValue().size(); } } List> list = new ObjectArrayList<>(size); - r.getCapabilitiesProxy().get(IO.IN).forEach(v -> v.handlerMap.forEach((cap, handlers) -> { - if (cap.isRecipeSearchFilter() && !handlers.isEmpty()) { - for (IRecipeHandler handler : handlers) { - if (handler.isProxy()) { - continue; - } + for (var handlerList : handlerLists) { + handlerList.handlerMap.forEach((cap, handlers) -> { + if (!cap.isRecipeSearchFilter() || handlers.isEmpty()) return; + for (var handler : handlers) { + if (handler.isProxy()) continue; List compressed = cap.compressIngredients(handler.getContents()); for (Object content : compressed) { list.add(cap.convertToMapIngredient(content)); } } - } - })); + }); + } return list; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index cd88775b27..c530b5c9c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -9,8 +9,8 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.ActionResult; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; @@ -181,118 +181,21 @@ public DistillationTowerMachine getMachine() { } @Override - @Nullable - public Iterator searchRecipe() { - var recipeType = machine.getRecipeType(); - if (recipeType == GTRecipeTypes.DISTILLERY_RECIPES) return super.searchRecipe(); - - // Do recipe searching ourselves, so we can match the outputs how we want - IRecipeCapabilityHolder holder = this.machine; - if (!holder.hasCapabilityProxies()) return null; - var iterator = recipeType.getLookup().getRecipeIterator(holder, recipe -> - - this.matchDTRecipe(recipe, holder).isSuccess() && - RecipeHelper.matchTickRecipe(holder, recipe).isSuccess()); - - boolean any = false; - while (iterator.hasNext()) { - GTRecipe recipe = iterator.next(); - if (recipe == null) continue; - any = true; - break; - } - - if (any) { - iterator.reset(); - return iterator; - } - - for (GTRecipeType.ICustomRecipeLogic logic : recipeType.getCustomRecipeLogicRunners()) { - GTRecipe recipe = logic.createCustomRecipe(holder); - if (recipe != null) return Collections.singleton(recipe).iterator(); - } - return Collections.emptyIterator(); - } - - @Override - public void findAndHandleRecipe() { - lastFailedMatches = null; - if (!recipeDirty && lastRecipe != null && - matchDTRecipe(lastRecipe, this.machine).isSuccess() && - RecipeHelper.matchTickRecipe(this.machine, lastRecipe).isSuccess() && - RecipeHelper.checkConditions(lastRecipe, this).size() == 1 && - RecipeHelper.checkConditions(lastRecipe, this).get(0).isSuccess()) { - var recipe = lastRecipe; - lastRecipe = null; - lastOriginRecipe = null; - setupRecipe(recipe); - } else { - workingRecipe = null; - lastRecipe = null; - lastOriginRecipe = null; - handleSearchingRecipes(searchRecipe()); - } - } + protected ActionResult matchRecipe(GTRecipe recipe) { + var match = matchDTRecipe(recipe); + if (!match.isSuccess()) return match; - @Override - public boolean checkMatchedRecipeAvailable(GTRecipe match) { - var matchCopy = match.copy(); - var modified = machine.fullModifyRecipe(matchCopy); - if (modified != null) { - var conditions = RecipeHelper.checkConditions(modified, this); - if (conditions.size() == 1 && conditions.get(0).isSuccess() && - matchDTRecipe(modified, machine).isSuccess() && - RecipeHelper.matchTickRecipe(machine, modified).isSuccess()) { - setupRecipe(modified); - } - if (lastRecipe != null && getStatus() == Status.WORKING) { - lastOriginRecipe = match; - lastFailedMatches = null; - return true; - } - } - return false; + return RecipeHelper.matchTickRecipe(this.machine, recipe); } @Override - public void onRecipeFinish() { - machine.afterWorking(); - if (lastRecipe != null) { - RecipeHelper.postWorking(machine, lastRecipe); - handleRecipeIO(lastRecipe, IO.OUT); - if (machine.alwaysTryModifyRecipe()) { - if (lastOriginRecipe != null) { - var modified = machine.fullModifyRecipe(lastOriginRecipe.copy()); - if (modified == null) markLastRecipeDirty(); - else lastRecipe = modified; - } else { - markLastRecipeDirty(); - } - } - var conditions = RecipeHelper.checkConditions(lastRecipe, this); - if (!recipeDirty && !suspendAfterFinish && - matchDTRecipe(lastRecipe, this.machine).isSuccess() && - RecipeHelper.matchTickRecipe(this.machine, lastRecipe).isSuccess() && - conditions.size() == 1 && conditions.get(0).isSuccess()) { - setupRecipe(lastRecipe); - if (isActive) consecutiveRecipes++; - } else { - if (suspendAfterFinish) { - setStatus(Status.SUSPEND); - suspendAfterFinish = false; - } else { - setStatus(Status.IDLE); - } - consecutiveRecipes = 0; - progress = 0; - duration = 0; - isActive = false; - } - } + protected void handleSearchingRecipes(Iterator matches) { + workingRecipe = null; + super.handleSearchingRecipes(matches); } - private RecipeHelper.ActionResult matchDTRecipe(GTRecipe recipe, IRecipeCapabilityHolder holder) { - var result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, + private ActionResult matchDTRecipe(GTRecipe recipe) { + var result = RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), false, false); if (!result.isSuccess()) return result; @@ -304,13 +207,13 @@ private RecipeHelper.ActionResult matchDTRecipe(GTRecipe recipe, IRecipeCapabili } if (!applyFluidOutputs(recipe, FluidAction.SIMULATE)) { - return RecipeHelper.ActionResult + return ActionResult .fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } - return RecipeHelper.ActionResult.SUCCESS; + return ActionResult.SUCCESS; } private void updateWorkingRecipe(GTRecipe recipe) { @@ -330,7 +233,7 @@ private void updateWorkingRecipe(GTRecipe recipe) { } @Override - protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { var handleIO = super.handleRecipeIO(recipe, io); if (handleIO.isSuccess()) { @@ -340,15 +243,19 @@ protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { } return handleIO; } + var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); RecipeHelper.handleRecipe(io, this.machine, recipe, out, chanceCaches, false, false); } + if (applyFluidOutputs(recipe, FluidAction.EXECUTE)) { - return RecipeHelper.ActionResult.SUCCESS; + workingRecipe = null; + return ActionResult.SUCCESS; } - return RecipeHelper.ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + + return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index db8350e3e4..7de7ad0840 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -6,7 +6,6 @@ import com.gregtechceu.gtceu.api.capability.forge.GTCapability; import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; @@ -15,8 +14,8 @@ import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.ActionResult; import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import net.minecraft.MethodsReturnNonnullByDefault; @@ -25,10 +24,8 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.Collections; -import java.util.Iterator; import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @@ -61,15 +58,18 @@ public ResearchStationRecipeLogic getRecipeLogic() { public void onStructureFormed() { super.onStructureFormed(); for (IMultiPart part : getParts()) { - IOpticalComputationProvider provider = part.self().holder.self() - .getCapability(GTCapability.CAPABILITY_COMPUTATION_PROVIDER).resolve().orElse(null); - if (provider != null) { - this.computationProvider = provider; - } - if (part instanceof IObjectHolder objectHolder) { - this.getCapabilitiesProxy().put(IO.IN, - List.of(RecipeHandlerList.of(IO.IN, objectHolder.getAsHandler()))); + if (part instanceof IObjectHolder iObjectHolder) { + if (iObjectHolder.getFrontFacing() != getFrontFacing().getOpposite()) { + onStructureInvalid(); + return; + } + this.objectHolder = iObjectHolder; + addHandlerList(RecipeHandlerList.of(IO.IN, iObjectHolder.getAsHandler())); } + + part.self().holder.self() + .getCapability(GTCapability.CAPABILITY_COMPUTATION_PROVIDER) + .ifPresent(provider -> this.computationProvider = provider); } // should never happen, but would rather do this than have an obscure NPE @@ -120,7 +120,7 @@ public void addDisplayText(List textList) { .addProgressLineOnlyPercent(recipeLogic.getProgressPercent()); } - private static class ResearchStationRecipeLogic extends RecipeLogic { + public static class ResearchStationRecipeLogic extends RecipeLogic { public ResearchStationRecipeLogic(ResearchStationMachine metaTileEntity) { super(metaTileEntity); @@ -132,41 +132,13 @@ public ResearchStationMachine getMachine() { return (ResearchStationMachine) super.getMachine(); } - // Custom recipe matching logic to override output space test - @Nullable + // skip "can fit" checks, it can always fit @Override - public Iterator searchRecipe() { - IRecipeCapabilityHolder holder = this.machine; - if (!holder.hasCapabilityProxies()) return null; - var iterator = machine.getRecipeType().getLookup().getRecipeIterator(holder, recipe -> { - if (!holder.hasCapabilityProxies()) return false; - var result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), - false, false); - if (!result.isSuccess()) return false; - if (recipe.hasTick()) { - result = RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, - Collections.emptyMap(), false, false); - return result.isSuccess(); - } - return true; - }); - boolean any = false; - while (iterator.hasNext()) { - GTRecipe recipe = iterator.next(); - if (recipe == null) continue; - any = true; - break; - } - if (any) { - iterator.reset(); - return iterator; - } + protected ActionResult matchRecipe(GTRecipe recipe) { + var match = matchRecipeNoOutput(recipe); + if (!match.isSuccess()) return match; - for (GTRecipeType.ICustomRecipeLogic logic : machine.getRecipeType().getCustomRecipeLogicRunners()) { - GTRecipe recipe = logic.createCustomRecipe(holder); - if (recipe != null) return Collections.singleton(recipe).iterator(); - } - return Collections.emptyIterator(); + return matchTickRecipeNoOutput(recipe); } @Override @@ -177,13 +149,11 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { !modified.tickInputs.containsKey(CWURecipeCapability.CAP)) { return true; } - // skip "can fit" checks, it can always fit - var conditions = RecipeHelper.checkConditions(modified, this).stream().filter(v -> !v.isSuccess()) - .findFirst(); - if (conditions.isEmpty() && - this.matchRecipeNoOutput(modified, machine).isSuccess() && - this.matchTickRecipeNoOutput(modified, machine).isSuccess()) { + var recipeMatch = checkRecipe(modified); + if (recipeMatch.isSuccess()) { setupRecipe(modified); + } else { + setWaiting(recipeMatch.reason()); } if (lastRecipe != null && getStatus() == Status.WORKING) { lastOriginRecipe = match; @@ -194,73 +164,58 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { return false; } - public RecipeHelper.ActionResult matchRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { - if (!holder.hasCapabilityProxies()) return RecipeHelper.ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.inputs, Collections.emptyMap(), false, + protected ActionResult matchRecipeNoOutput(GTRecipe recipe) { + if (!machine.hasCapabilityProxies()) return ActionResult.FAIL_NO_CAPABILITIES; + return RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), false, true); } - public RecipeHelper.ActionResult matchTickRecipeNoOutput(GTRecipe recipe, IRecipeCapabilityHolder holder) { + protected ActionResult matchTickRecipeNoOutput(GTRecipe recipe) { if (recipe.hasTick()) { - if (!holder.hasCapabilityProxies()) - return RecipeHelper.ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHelper.handleRecipe(IO.IN, holder, recipe, recipe.tickInputs, Collections.emptyMap(), + if (!machine.hasCapabilityProxies()) return ActionResult.FAIL_NO_CAPABILITIES; + return RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.tickInputs, Collections.emptyMap(), false, true); } - return RecipeHelper.ActionResult.SUCCESS; + return ActionResult.SUCCESS; } + // Handle RecipeIO manually @Override - public void setupRecipe(GTRecipe recipe) { - // lock the object holder on recipe start - IObjectHolder holder = getMachine().getObjectHolder(); - holder.setLocked(true); - - // Do RecipeLogic#setupRecipe but without any i/o - if (!machine.beforeWorking(recipe)) { - return; + protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + if (io == IO.IN) { + // lock the object holder on recipe start + IObjectHolder holder = getMachine().getObjectHolder(); + holder.setLocked(true); + return ActionResult.SUCCESS; } - RecipeHelper.preWorking(this.machine, recipe); - - // do not consume inputs here, consume them on completion - recipeDirty = false; - lastRecipe = recipe; - setStatus(Status.WORKING); - progress = 0; - duration = recipe.duration; - } - // "replace" the items in the slots rather than outputting elsewhere - // unlock the object holder - @Override - public void onRecipeFinish() { - super.onRecipeFinish(); + // "replace" the items in the slots rather than outputting elsewhere + // unlock the object holder IObjectHolder holder = getMachine().getObjectHolder(); - holder.setHeldItem(ItemStack.EMPTY); + if (lastRecipe == null) { + holder.setLocked(false); + return ActionResult.SUCCESS; + } + holder.setHeldItem(ItemStack.EMPTY); ItemStack outputItem = ItemStack.EMPTY; - if (lastRecipe.getOutputContents(ItemRecipeCapability.CAP).size() >= 1) { - outputItem = ItemRecipeCapability.CAP - .of(getLastRecipe().getOutputContents(ItemRecipeCapability.CAP).get(0).content).getItems()[0]; + var contents = lastRecipe.getOutputContents(ItemRecipeCapability.CAP); + if (!contents.isEmpty()) { + outputItem = ItemRecipeCapability.CAP.of(contents.get(0).content).getItems()[0]; } - holder.setDataItem(outputItem); - holder.setLocked(false); - } - - @Override - protected RecipeHelper.ActionResult handleRecipeIO(GTRecipe recipe, IO io) { - if (io != IO.OUT) { - return super.handleRecipeIO(recipe, io); + if (!outputItem.isEmpty()) { + holder.setDataItem(outputItem); } - return RecipeHelper.ActionResult.SUCCESS; + holder.setLocked(false); + return ActionResult.SUCCESS; } @Override - protected RecipeHelper.ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + protected ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { if (io != IO.OUT) { return super.handleTickRecipeIO(recipe, io); } - return RecipeHelper.ActionResult.SUCCESS; + return ActionResult.SUCCESS; } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index b8e292b28b..4727831b71 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -36,9 +36,7 @@ import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import javax.annotation.ParametersAreNonnullByDefault; @@ -61,8 +59,7 @@ public SteamParallelMultiblockMachine(IMachineBlockEntity holder, Object... args @Override public void onStructureFormed() { super.onStructureFormed(); - var handlers = capabilitiesProxy.get(IO.IN).stream() - .flatMap(rhl -> rhl.getCapability(FluidRecipeCapability.CAP).stream()).collect(Collectors.toList()); + var handlers = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP); if (handlers.isEmpty()) return; var itr = handlers.iterator(); while (itr.hasNext()) { @@ -70,8 +67,8 @@ public void onStructureFormed() { if (handler instanceof NotifiableFluidTank tank) { if (tank.isFluidValid(0, GTMaterials.Steam.getFluid(1))) { itr.remove(); - capabilitiesProxy.computeIfAbsent(IO.IN, c -> new ArrayList<>()) - .add(RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, getConversionRate()))); + this.addHandlerList( + RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, getConversionRate()))); /* * if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { * capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, new ArrayList<>()); @@ -128,8 +125,7 @@ public static ModifierFunction recipeModifier(@NotNull MetaMachine machine, @Not public void addDisplayText(List textList) { IDisplayUIMachine.super.addDisplayText(textList); if (isFormed()) { - var handlers = capabilitiesProxy.get(IO.IN).stream() - .flatMap(rhl -> rhl.getCapability(EURecipeCapability.CAP).stream()).toList(); + var handlers = getCapabilitiesFlat(IO.IN, EURecipeCapability.CAP); if (!handlers.isEmpty() && handlers.get(0) instanceof SteamEnergyRecipeHandler steamHandler) { if (steamHandler.getCapacity() > 0) { long steamStored = steamHandler.getStored(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/NotifiableStressTrait.java deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java index c3d8867c7b..96fb740b7c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java @@ -23,9 +23,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Objects; - import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.ARC_FURNACE_RECIPES; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java index 69d51a75c3..3081f012b2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java @@ -23,9 +23,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Objects; - import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.MACERATOR_RECIPES; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 8d6846b178..34dcaf6b59 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -42,7 +42,6 @@ import net.minecraftforge.items.IItemHandlerModifiable; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; @@ -144,8 +143,8 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, this.isDone = false; this.pickaxeTool = GTMaterialItems.TOOL_ITEMS.get(GTMaterials.Neutronium, GTToolType.PICKAXE).get().get(); this.pickaxeTool.enchant(Enchantments.BLOCK_FORTUNE, fortune); - this.capabilitiesProxy = new Object2ObjectOpenHashMap<>(); - this.capabilitiesFlat = new Object2ObjectOpenHashMap<>(); + this.capabilitiesProxy = new EnumMap<>(IO.class); + this.capabilitiesFlat = new EnumMap<>(IO.class); this.inputItemHandler = new ItemRecipeHandler(IO.IN, machine.getRecipeType().getMaxInputs(ItemRecipeCapability.CAP)); this.outputItemHandler = new ItemRecipeHandler(IO.OUT, @@ -155,16 +154,11 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, RecipeHandlerList inHandlers = new RecipeHandlerList(IO.IN); RecipeHandlerList outHandlers = new RecipeHandlerList(IO.OUT); - inHandlers.addHandler(inputItemHandler, inputEnergyHandler); - outHandlers.addHandler(outputItemHandler); + inHandlers.addHandlers(inputItemHandler, inputEnergyHandler); + outHandlers.addHandlers(outputItemHandler); - this.capabilitiesProxy.put(IO.IN, List.of(inHandlers)); - this.capabilitiesProxy.put(IO.OUT, List.of(outHandlers)); - var inMap = this.capabilitiesFlat.computeIfAbsent(IO.IN, k -> new Object2ObjectOpenHashMap<>()); - var outMap = this.capabilitiesFlat.computeIfAbsent(IO.OUT, k -> new Object2ObjectOpenHashMap<>()); - inMap.put(ItemRecipeCapability.CAP, List.of(inputItemHandler)); - inMap.put(EURecipeCapability.CAP, List.of(inputEnergyHandler)); - outMap.put(ItemRecipeCapability.CAP, List.of(outputItemHandler)); + addHandlerList(inHandlers); + addHandlerList(outHandlers); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java index 5774deb674..631f4e53be 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java @@ -40,7 +40,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { var blockA = BuiltInRegistries.BLOCK.get(new ResourceLocation(recipe.data.getString("blockA"))); var blockB = BuiltInRegistries.BLOCK.get(new ResourceLocation(recipe.data.getString("blockB"))); boolean hasBlockA = false, hasBlockB = false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java index 2f2755d17c..2bcafb0f13 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java @@ -68,7 +68,7 @@ public ResourceLocation getBiome() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { Level level = recipeLogic.machine.self().getLevel(); if (level == null) return false; Holder biome = level.getBiome(recipeLogic.machine.self().getPos()); diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java index 9105335357..ba3ea1e14a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java @@ -54,7 +54,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { if (!ConfigHolder.INSTANCE.machines.enableCleanroom) return true; MetaMachine machine = recipeLogic.getMachine(); if (machine instanceof ICleanroomReceiver receiver && this.cleanroom != null) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java index 8cd8220d62..12423e23c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java @@ -89,7 +89,7 @@ public ResourceLocation getDimension() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { Level level = recipeLogic.machine.self().getLevel(); return level != null && dimension.equals(level.dimension().location()); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java index 54f3c4efc8..f522b5d1a6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java @@ -53,7 +53,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { return recipeLogic.getMachine().getTraits().stream().filter(IEnergyContainer.class::isInstance) .anyMatch(energyContainer -> ((IEnergyContainer) energyContainer).getEnergyCapacity() > euToStart); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java index 881b212113..9d4af95469 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java @@ -56,7 +56,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { if (!ConfigHolder.INSTANCE.gameplay.hazardsEnabled) return true; if (!(recipeLogic.getMachine().getLevel() instanceof ServerLevel serverLevel)) { return false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java index 433c7944c3..2acc8a40a9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java @@ -65,7 +65,7 @@ public int getMax() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { int y = recipeLogic.machine.self().getPos().getY(); return y >= this.min && y <= this.max; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java index 2df96806fb..2ba69f3bfa 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java @@ -57,7 +57,7 @@ public float getLevel() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { Level level = recipeLogic.machine.self().getLevel(); return level != null && level.getRainLevel(1) >= this.level; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java index d7327efff2..49caa274f4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java @@ -72,7 +72,7 @@ public RecipeCondition fromNetwork(FriendlyByteBuf buf) { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { return true; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RockBreakerCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RockBreakerCondition.java index a81e10a3f0..eae1e449dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RockBreakerCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RockBreakerCondition.java @@ -46,7 +46,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { var fluidA = BuiltInRegistries.FLUID.get(new ResourceLocation(recipe.data.getString("fluidA"))); var fluidB = BuiltInRegistries.FLUID.get(new ResourceLocation(recipe.data.getString("fluidB"))); boolean hasFluidA = false, hasFluidB = false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java index be8cec0e5c..9950ef5912 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java @@ -57,7 +57,7 @@ public float getLevel() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { Level level = recipeLogic.machine.self().getLevel(); return level != null && level.getThunderLevel(1) >= this.level; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/VentCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/VentCondition.java index 45792aa7a7..869a3a880c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/VentCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/VentCondition.java @@ -42,7 +42,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { if (recipeLogic.getProgress() % 10 == 0 && recipeLogic.machine instanceof IExhaustVentMachine ventMachine) { return !(ventMachine.isNeedsVenting() && ventMachine.isVentingBlocked()); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java index 99806f04d3..d784b8911f 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java @@ -46,7 +46,6 @@ import dev.latvian.mods.kubejs.recipe.RecipeExceptionJS; import dev.latvian.mods.kubejs.recipe.RecipeJS; import dev.latvian.mods.kubejs.recipe.RecipeKey; -import dev.latvian.mods.kubejs.recipe.component.BooleanComponent; import dev.latvian.mods.kubejs.recipe.component.TimeComponent; import dev.latvian.mods.kubejs.recipe.schema.RecipeSchema; import dev.latvian.mods.kubejs.util.ConsoleJS; diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java index 8d3f1c5ef0..ed9933ac4d 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java @@ -25,6 +25,7 @@ public class DummyMachineBlockEntity implements IMachineBlockEntity { @Getter private final MachineDefinition definition; + // TODO: Fix the proxy parameter public DummyMachineBlockEntity(int tier, GTRecipeType type, Int2IntFunction tankScalingFunction, Map> capabilitiesProxy, Object... args) { diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java index 9759c00e63..f1a4f98564 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java @@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -25,7 +26,16 @@ public DummyRecipeLogicMachine(IMachineBlockEntity be, int tier, Int2IntFunction public void reinitializeCapabilities(Map> caps) { this.capabilitiesProxy.clear(); + this.capabilitiesFlat.clear(); this.capabilitiesProxy.putAll(caps); } + + public void reinitializeHandlers(Collection handlers) { + this.capabilitiesProxy.clear(); + this.capabilitiesFlat.clear(); + for (RecipeHandlerList handlerList : handlers) { + this.addHandlerList(handlerList); + } + } } From be6560008a647acd21cb49f6caa2eb2c5dd0cf7a Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Fri, 24 Jan 2025 19:10:31 -0500 Subject: [PATCH 20/29] only sort for non-tick outputs --- .../gtceu/api/machine/trait/RecipeHandlerList.java | 11 ++++++++--- .../gregtechceu/gtceu/api/recipe/RecipeRunner.java | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index e1e4f5bbd0..0d51ed9ef9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -12,7 +12,12 @@ import lombok.Getter; import lombok.Setter; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; public class RecipeHandlerList { @@ -50,7 +55,7 @@ public void addHandlers(IRecipeHandler... handlers) { addHandlers(Arrays.asList(handlers)); } - public void addHandlers(Collection> handlers) { + public void addHandlers(List> handlers) { for (var handler : handlers) { handlerMap.computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); priority += handler.getPriority(); @@ -100,7 +105,7 @@ public List addChangeListeners(Runnable listener) { public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { if (handlerMap.isEmpty()) return contents; - var copy = new IdentityHashMap<>(contents); + var copy = new Reference2ObjectOpenHashMap<>(contents); var it = copy.entrySet().iterator(); while (it.hasNext()) { var entry = it.next(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index e654d307c3..ec9b09e89f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -118,7 +118,10 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); var handlers = capabilityProxies.get(capIO); - handlers.sort(RecipeHandlerList.COMPARATOR.reversed()); + // Only sort for non-tick outputs + if (!isTick && capIO == IO.OUT) { + handlers.sort(RecipeHandlerList.COMPARATOR.reversed()); + } List distinct = new ArrayList<>(); List indistinct = new ArrayList<>(); for (var handler : handlers) { From 401a253d6c0def2ac0e4dfed0f0d2aa2f015f434 Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Sun, 26 Jan 2025 13:24:32 -0700 Subject: [PATCH 21/29] doesn't include null RHL in the handler map --- .../gtceu/api/capability/recipe/IRecipeCapabilityHolder.java | 1 + .../gtceu/api/machine/feature/multiblock/IMultiPart.java | 1 + .../api/machine/multiblock/part/MultiblockPartMachine.java | 5 +++-- .../gtceu/api/machine/trait/RecipeHandlerList.java | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 0841e3ebec..0520b399f7 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -28,6 +28,7 @@ default List> getCapabilitiesFlat(IO io, RecipeCapability c } default void addHandlerList(RecipeHandlerList handler) { + if (handler == RecipeHandlerList.NO_DATA) return; IO io = handler.getHandlerIO(); getCapabilitiesProxy().computeIfAbsent(io, i -> new ArrayList<>()).add(handler); var inner = getCapabilitiesFlat().computeIfAbsent(io, i -> new Reference2ObjectOpenHashMap<>()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java index 73de82bb5d..8dfc00e96a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java @@ -64,6 +64,7 @@ default boolean canShared() { /** * Get all available traits for recipe logic. */ + @Nullable RecipeHandlerList getRecipeHandlers(); /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index f0bf2fe13c..a0e21eb7c9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -1,6 +1,5 @@ package com.gregtechceu.gtceu.api.machine.multiblock.part; -import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; @@ -20,6 +19,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.Collections; @@ -92,6 +92,7 @@ public SortedSet getControllers() { return Collections.unmodifiableSortedSet(controllers); } + @Nullable public RecipeHandlerList getRecipeHandlers() { if (handlerList == null) { var a = traits.stream() @@ -99,7 +100,7 @@ public RecipeHandlerList getRecipeHandlers() { .map(IRecipeHandlerTrait.class::cast) .toList(); if (a.isEmpty()) { - handlerList = new RecipeHandlerList(IO.NONE); + handlerList = RecipeHandlerList.NO_DATA; return handlerList; } handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index 0d51ed9ef9..b0855d5169 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -21,6 +21,8 @@ public class RecipeHandlerList { + public static RecipeHandlerList NO_DATA = new RecipeHandlerList(IO.NONE); + public static final Comparator COMPARATOR = (h1, h2) -> { int cmp = Long.compare(h1.getPriority(), h2.getPriority()); if (cmp != 0) return cmp; From c0d8345c0f5f502a7d723be165728529e58a2f11 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Sat, 25 Jan 2025 21:09:18 -0500 Subject: [PATCH 22/29] Downgrade journeymap-api (#2790) --- settings.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/settings.gradle b/settings.gradle index 70cbca9c82..fa25ac0113 100644 --- a/settings.gradle +++ b/settings.gradle @@ -38,7 +38,7 @@ dependencyResolutionManagement { def xaerosWorldMapVersion = "5658224" def xaerosMinimapVersion = "5773012" def journeyMapVersion = "5789363" - def journeyMapApiVersion = "2.0.0" + def journeyMapApiVersion = "1.20-1.9" def ftbteamsForgeFile = "5267190" def ftblibraryForgeFile = "5567591" def ftbchunksForgeFile = "5956390" @@ -121,8 +121,8 @@ dependencyResolutionManagement { def xaerosMiniMap = version("xaerosMinimap", xaerosMinimapVersion) library("xaerosminimap", "curse.maven", "xaeros-minimap-263420").versionRef(xaerosMiniMap) - def journeyMapApi = version("journeyMapApi", journeyMapApiVersion + "-" + minecraftVersion + "-SNAPSHOT") - library("journeymap-api", "info.journeymap", "journeymap-api-forge").versionRef(journeyMapApi) + def journeyMapApi = version("journeyMapApi", journeyMapApiVersion + "-SNAPSHOT") + library("journeymap-api", "info.journeymap", "journeymap-api").versionRef(journeyMapApi) def journeyMap = version("journeyMap", journeyMapVersion) library("journeymap-forge", "curse.maven", "journeymap-32274").versionRef(journeyMap) From 627a974b913eb8d3767e5706092919f137826ebf Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Fri, 31 Jan 2025 01:51:35 -0500 Subject: [PATCH 23/29] =?UTF-8?q?pattern=20buffer=20=F0=9F=98=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/assets/gtceu/lang/en_ud.json | 1 + .../resources/assets/gtceu/lang/en_us.json | 1 + .../recipe/IRecipeCapabilityHolder.java | 2 +- .../feature/multiblock/IMultiPart.java | 3 +- .../multiblock/WorkableMultiblockMachine.java | 11 +- .../part/MultiblockPartMachine.java | 13 +- .../api/machine/trait/RecipeHandlerList.java | 37 +- .../api/recipe/lookup/GTRecipeLookup.java | 6 +- .../electric/ActiveTransformerMachine.java | 31 +- .../multiblock/electric/CleanroomMachine.java | 15 +- .../electric/DistillationTowerMachine.java | 2 +- .../electric/FusionReactorMachine.java | 23 +- .../electric/LargeMinerMachine.java | 19 +- .../electric/PowerSubstationMachine.java | 31 +- .../electric/research/DataBankMachine.java | 15 +- .../electric/research/HPCAMachine.java | 21 +- .../multiblock/part/DualHatchPartMachine.java | 2 +- .../multiblock/part/ItemBusPartMachine.java | 4 +- .../primitive/PrimitivePumpMachine.java | 28 +- .../machine/trait/miner/MinerLogic.java | 2 +- .../gtceu/data/lang/IntegrationLang.java | 1 + .../machine/MEPatternBufferPartMachine.java | 387 ++++++++++-------- .../MEPatternBufferProxyPartMachine.java | 99 ++--- .../trait/InternalSlotRecipeHandler.java | 128 ++++++ .../MEPatternBufferProxyRecipeHandler.java | 102 ----- .../trait/MEPatternBufferRecipeHandler.java | 284 ------------- .../machine/trait/ProxySlotRecipeHandler.java | 185 +++++++++ .../gtceu/integration/jade/GTJadePlugin.java | 4 +- .../jade/provider/GTFluidStorageProvider.java | 16 +- .../jade/provider/GTItemStorageProvider.java | 17 +- .../provider/MEPatternBufferProvider.java | 135 +++--- .../MEPatternBufferProxyProvider.java | 102 ++--- .../gregtechceu/gtceu/utils/GTHashMaps.java | 2 +- .../com/gregtechceu/gtceu/utils/GTMath.java | 15 + 34 files changed, 840 insertions(+), 904 deletions(-) create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/InternalSlotRecipeHandler.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java create mode 100644 src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index b8a3c37607..c4154a938b 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -3515,6 +3515,7 @@ "gtceu.top.allow_output_input": "ʇnduI ʍoןןⱯ", "gtceu.top.auto_output": "ʇndʇnO oʇnⱯ", "gtceu.top.buffer_bound_pos": "%s :Z '%s :ʎ '%s :X - o⟘ punoᗺ", + "gtceu.top.buffer_not_bound": "punoᗺ ʎןʇuǝɹɹnƆ ʇoN ɹǝɟɟnᗺ", "gtceu.top.cable_amperage": " :ǝbɐɹǝdɯⱯ", "gtceu.top.cable_voltage": " :ǝbɐʇןoΛ", "gtceu.top.convert_eu": "ɹ§ƎℲɔ§ >- ɹ§∩Ǝǝ§ buıʇɹǝʌuoƆ", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 2bfbc8b809..8e804721ba 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -3515,6 +3515,7 @@ "gtceu.top.allow_output_input": "Allow Input", "gtceu.top.auto_output": "Auto Output", "gtceu.top.buffer_bound_pos": "Bound To - X: %s, Y: %s, Z: %s", + "gtceu.top.buffer_not_bound": "Buffer Not Currently Bound", "gtceu.top.cable_amperage": "Amperage: ", "gtceu.top.cable_voltage": "Voltage: ", "gtceu.top.convert_eu": "Converting §eEU§r -> §cFE§r", diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 0520b399f7..7725988740 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -32,7 +32,7 @@ default void addHandlerList(RecipeHandlerList handler) { IO io = handler.getHandlerIO(); getCapabilitiesProxy().computeIfAbsent(io, i -> new ArrayList<>()).add(handler); var inner = getCapabilitiesFlat().computeIfAbsent(io, i -> new Reference2ObjectOpenHashMap<>()); - for (var entry : handler.handlerMap.entrySet()) { + for (var entry : handler.getHandlerMap().entrySet()) { inner.computeIfAbsent(entry.getKey(), c -> new ArrayList<>()).addAll(entry.getValue()); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java index 8dfc00e96a..afe2f75568 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiPart.java @@ -64,8 +64,7 @@ default boolean canShared() { /** * Get all available traits for recipe logic. */ - @Nullable - RecipeHandlerList getRecipeHandlers(); + List getRecipeHandlers(); /** * whether its base model can be replaced by controller when it is formed. diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 752898d3b1..f8bc9c721a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -125,11 +125,14 @@ public void onStructureFormed() { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; - this.addHandlerList(handlerList); - traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + this.addHandlerList(handlerList); + traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + } } // attach self traits diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index a0e21eb7c9..0f65eabfb6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -19,10 +19,10 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; -import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.Collections; +import java.util.List; import java.util.Set; import java.util.SortedSet; @@ -92,8 +92,7 @@ public SortedSet getControllers() { return Collections.unmodifiableSortedSet(controllers); } - @Nullable - public RecipeHandlerList getRecipeHandlers() { + public List getRecipeHandlers() { if (handlerList == null) { var a = traits.stream() .filter(IRecipeHandlerTrait.class::isInstance) @@ -101,12 +100,12 @@ public RecipeHandlerList getRecipeHandlers() { .toList(); if (a.isEmpty()) { handlerList = RecipeHandlerList.NO_DATA; - return handlerList; + } else { + handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); + handlerList.addHandlers(a.toArray(new IRecipeHandler[0])); } - handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); - handlerList.addHandlers(a.toArray(new IRecipeHandler[0])); } - return handlerList; + return List.of(handlerList); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index b0855d5169..d20ce5f68c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -31,13 +31,13 @@ public class RecipeHandlerList { return Boolean.compare(b1, b2); }; - public final Map, List>> handlerMap = new Reference2ObjectOpenHashMap<>(); + @Getter + private final Map, List>> handlerMap = new Reference2ObjectOpenHashMap<>(); private final List> allHandlers = new ObjectArrayList<>(); private final IO io; @Setter @Getter private boolean isDistinct = false; - private long priority = 0; public RecipeHandlerList(IO io) { this.io = io; @@ -45,12 +45,16 @@ public RecipeHandlerList(IO io) { public static RecipeHandlerList of(IO io, IRecipeHandler handler) { RecipeHandlerList rhl = new RecipeHandlerList(io); - rhl.addHandlers(handler); + rhl.addHandler(handler); return rhl; } public List> getCapability(RecipeCapability cap) { - return handlerMap.getOrDefault(cap, Collections.emptyList()); + return getHandlerMap().getOrDefault(cap, Collections.emptyList()); + } + + public void addHandler(IRecipeHandler handler) { + addHandlers(List.of(handler)); } public void addHandlers(IRecipeHandler... handlers) { @@ -59,21 +63,20 @@ public void addHandlers(IRecipeHandler... handlers) { public void addHandlers(List> handlers) { for (var handler : handlers) { - handlerMap.computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); - priority += handler.getPriority(); + getHandlerMap().computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); + allHandlers.add(handler); } - allHandlers.addAll(handlers); - sort(); + if (io == IO.OUT) sort(); } - public void sort() { - for (var list : handlerMap.values()) { + private void sort() { + for (var list : getHandlerMap().values()) { list.sort(IRecipeHandler.ENTRY_COMPARATOR); } } public boolean hasCapability(RecipeCapability cap) { - return handlerMap.containsKey(cap); + return getHandlerMap().containsKey(cap); } public IO getHandlerIO() { @@ -94,11 +97,9 @@ public double getTotalContentAmount() { public List addChangeListeners(Runnable listener) { List ret = new ArrayList<>(); - for (var handlerList : handlerMap.values()) { - for (var handler : handlerList) { - if (handler instanceof IRecipeHandlerTrait handlerTrait) { - ret.add(handlerTrait.addChangedListener(listener)); - } + for (var handler : allHandlers) { + if (handler instanceof IRecipeHandlerTrait trait) { + ret.add(trait.addChangedListener(listener)); } } return ret; @@ -106,12 +107,12 @@ public List addChangeListeners(Runnable listener) { public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { - if (handlerMap.isEmpty()) return contents; + if (getHandlerMap().isEmpty()) return contents; var copy = new Reference2ObjectOpenHashMap<>(contents); var it = copy.entrySet().iterator(); while (it.hasNext()) { var entry = it.next(); - var handlerList = handlerMap.get(entry.getKey()); + var handlerList = getHandlerMap().get(entry.getKey()); if (handlerList == null) continue; for (var handler : handlerList) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 2b73257df6..ccd2b6a5db 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -61,7 +61,7 @@ protected List> prepareRecipeFind(@NotNull IRecipeCa List handlers = holder.getCapabilitiesProxy().getOrDefault(IO.IN, new ArrayList<>()); for (var handler : handlers) { - for (var entries : handler.handlerMap.entrySet()) { + for (var entries : handler.getHandlerMap().entrySet()) { int size = 0; if (!entries.getKey().isRecipeSearchFilter()) { continue; @@ -433,14 +433,14 @@ protected List> fromHolder(@NotNull IRecipeCapabilit var handlerLists = r.getCapabilitiesProxy().getOrDefault(IO.IN, Collections.emptyList()); int size = 0; for (var handler : handlerLists) { - for (var entry : handler.handlerMap.entrySet()) { + for (var entry : handler.getHandlerMap().entrySet()) { size += entry.getValue().size(); } } List> list = new ObjectArrayList<>(size); for (var handlerList : handlerLists) { - handlerList.handlerMap.forEach((cap, handlers) -> { + handlerList.getHandlerMap().forEach((cap, handlers) -> { if (!cap.isRecipeSearchFilter() || handlers.isEmpty()) return; for (var handler : handlers) { if (handler.isProxy()) continue; 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 384b5d7033..56e26b0af2 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 @@ -89,21 +89,24 @@ public void onStructureFormed() { for (IMultiPart part : getPrioritySortedParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer) v) - .toList(); - - if (handlerList.getHandlerIO() == IO.IN) { - powerInput.addAll(containers); - } else if (handlerList.getHandlerIO() == IO.OUT) { - powerOutput.addAll(containers); - } + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .map(v -> (IEnergyContainer) v) + .toList(); + + if (handlerList.getHandlerIO() == IO.IN) { + powerInput.addAll(containers); + } else if (handlerList.getHandlerIO() == IO.OUT) { + powerOutput.addAll(containers); + } - traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription)); + traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription)); + } } // Invalidate the structure if there is not at least one output and one input 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 d7881affb6..bfaf4c37a8 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 @@ -186,12 +186,15 @@ protected void initializeAbilities() { if (isPartIgnored(part)) continue; IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE || io == IO.OUT) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer) v)); + } if (part instanceof IMaintenanceMachine maintenanceMachine) { getRecipeLogic().setMaintenanceMachine(maintenanceMachine); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index c530b5c9c3..deb4b03ab5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -97,7 +97,7 @@ public void onStructureFormed() { var part = parts.get(outputIndex); if (part.self().getPos().getY() == y) { - var handler = part.getRecipeHandlers().getCapability(FluidRecipeCapability.CAP) + var handler = part.getRecipeHandlers().get(0).getCapability(FluidRecipeCapability.CAP) .stream() .filter(IFluidHandler.class::isInstance) .findFirst() diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java index fa81d02cd1..7dbc3fa4fd 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java @@ -111,13 +111,16 @@ public void onStructureFormed() { for (IMultiPart part : getParts()) { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE || io == IO.OUT) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); - traitSubscriptions.addAll(handlerList.addChangeListeners(this::updatePreHeatSubscription)); + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer) v)); + traitSubscriptions.addAll(handlerList.addChangeListeners(this::updatePreHeatSubscription)); + } } this.inputEnergyContainers = new EnergyContainerList(energyContainers); energyContainer.resetBasicInfo(calculateEnergyStorageFactor(getTier(), energyContainers.size()), 0, 0, 0, 0); @@ -203,14 +206,10 @@ public static void registerFusionTier(int tier, @NotNull String name) { registeredFusionTiers.put(maxEU, Pair.of(tier, name)); } - @Override - public boolean alwaysTryModifyRecipe() { - return true; - } - @Override public boolean onWorking() { GTRecipe recipe = recipeLogic.getLastRecipe(); + assert recipe != null; if (recipe.data.contains("eu_to_start")) { long heatDiff = recipe.data.getLong("eu_to_start") - this.heat; // if the remaining energy needed is more than stored, do not run diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java index 390497cc26..c7d7a8700c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java @@ -140,15 +140,18 @@ private void initializeAbilities() { IO io = ioMap.getOrDefault(part.self().getPos().asLong(), IO.BOTH); if (io == IO.NONE) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; - handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); - handlerList.getCapability(FluidRecipeCapability.CAP).stream() - .filter(v -> v instanceof IFluidHandler) - .forEach(v -> fluidTanks.add((IFluidHandler) v)); + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer) v)); + handlerList.getCapability(FluidRecipeCapability.CAP).stream() + .filter(v -> v instanceof IFluidHandler) + .forEach(v -> fluidTanks.add((IFluidHandler) v)); + } } this.energyContainer = new EnergyContainerList(energyContainers); this.inputFluidInventory = new FluidHandlerList(fluidTanks); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java index e3fe94af1e..58c29bdc17 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java @@ -101,21 +101,24 @@ public void onStructureFormed() { if (part instanceof IMaintenanceMachine maintenanceMachine) { this.maintenance = maintenanceMachine; } - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer) v) - .toList(); - - if (handlerList.getHandlerIO() == IO.IN) { - inputs.addAll(containers); - } else if (handlerList.getHandlerIO() == IO.OUT) { - outputs.addAll(containers); - } + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .map(v -> (IEnergyContainer) v) + .toList(); + + if (handlerList.getHandlerIO() == IO.IN) { + inputs.addAll(containers); + } else if (handlerList.getHandlerIO() == IO.OUT) { + outputs.addAll(containers); + } - traitSubscriptions.addAll(handlerList.addChangeListeners(tickSubscription::updateSubscription)); + traitSubscriptions.addAll(handlerList.addChangeListeners(tickSubscription::updateSubscription)); + } } this.inputHatches = new EnergyContainerList(inputs); this.outputHatches = new EnergyContainerList(outputs); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java index e2b297129c..ab3c3212e2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java @@ -67,12 +67,15 @@ public void onStructureFormed() { this.maintenance = maintenanceMachine; } if (io == IO.NONE || io == IO.OUT) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer) v)); + } } this.energyContainer = new EnergyContainerList(energyContainers); this.energyUsage = calculateEnergyUsage(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index f9c986eb4e..214b3d3613 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -111,15 +111,18 @@ public void onStructureFormed() { this.maintenance = maintenanceMachine; } if (io == IO.NONE || io == IO.OUT) continue; - var handlerList = part.getRecipeHandlers(); - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) continue; - - handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); - handlerList.getCapability(FluidRecipeCapability.CAP).stream() - .filter(v -> v instanceof IFluidHandler) - .forEach(v -> coolantContainers.add((IFluidHandler) v)); + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) + continue; + + handlerList.getCapability(EURecipeCapability.CAP).stream() + .filter(v -> v instanceof IEnergyContainer) + .forEach(v -> energyContainers.add((IEnergyContainer) v)); + handlerList.getCapability(FluidRecipeCapability.CAP).stream() + .filter(v -> v instanceof IFluidHandler) + .forEach(v -> coolantContainers.add((IFluidHandler) v)); + } } this.energyContainer = new EnergyContainerList(energyContainers); this.coolantHandler = new FluidHandlerList(coolantContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java index caa37522c2..737d7fe45f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java @@ -166,7 +166,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { super.setDistinct(isDistinct); tank.setDistinct(isDistinct); - getRecipeHandlers().setDistinct(isDistinct); + getRecipeHandlers().get(0).setDistinct(isDistinct); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java index 12aed38bfb..49730570dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java @@ -116,7 +116,7 @@ public void onLoad() { serverLevel.getServer().tell(new TickTask(0, this::updateInventorySubscription)); } inventorySubs = getInventory().addChangedListener(this::updateInventorySubscription); - getRecipeHandlers().setDistinct(getInventory().isDistinct()); + getRecipeHandlers().get(0).setDistinct(getInventory().isDistinct()); } @Override @@ -137,7 +137,7 @@ public boolean isDistinct() { public void setDistinct(boolean isDistinct) { getInventory().setDistinct(isDistinct); circuitInventory.setDistinct(isDistinct); - getRecipeHandlers().setDistinct(isDistinct); + getRecipeHandlers().get(0).setDistinct(isDistinct); } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java index 748fa6aeb1..037a65f09e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitivePumpMachine.java @@ -51,20 +51,22 @@ public void onStructureFormed() { private void initializeTank() { for (IMultiPart part : getParts()) { - var handlerList = part.getRecipeHandlers(); - - var recipeCap = handlerList.getCapability(FluidRecipeCapability.CAP); - if (handlerList.getHandlerIO() == IO.OUT && !recipeCap.isEmpty()) { - fluidTank = (NotifiableFluidTank) recipeCap.get(0); - long tankCapacity = fluidTank.getTankCapacity(0); - if (tankCapacity == FluidType.BUCKET_VOLUME) { - hatchModifier = 1; - } else if (tankCapacity == FluidType.BUCKET_VOLUME * 8) { - hatchModifier = 2; - } else { - hatchModifier = 4; + var handlerLists = part.getRecipeHandlers(); + + for (var handlerList : handlerLists) { + var recipeCap = handlerList.getCapability(FluidRecipeCapability.CAP); + if (handlerList.getHandlerIO() == IO.OUT && !recipeCap.isEmpty()) { + fluidTank = (NotifiableFluidTank) recipeCap.get(0); + long tankCapacity = fluidTank.getTankCapacity(0); + if (tankCapacity == FluidType.BUCKET_VOLUME) { + hatchModifier = 1; + } else if (tankCapacity == FluidType.BUCKET_VOLUME * 8) { + hatchModifier = 2; + } else { + hatchModifier = 4; + } + return; } - return; } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 34dcaf6b59..eff5bbe4ab 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -155,7 +155,7 @@ public MinerLogic(@NotNull IRecipeLogicMachine machine, int fortune, int speed, RecipeHandlerList outHandlers = new RecipeHandlerList(IO.OUT); inHandlers.addHandlers(inputItemHandler, inputEnergyHandler); - outHandlers.addHandlers(outputItemHandler); + outHandlers.addHandler(outputItemHandler); addHandlerList(inHandlers); addHandlerList(outHandlers); diff --git a/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java b/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java index 4752f5be1c..8c293cd57e 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/lang/IntegrationLang.java @@ -87,6 +87,7 @@ private static void initWailaLikeLang(RegistrateLangProvider provider) { provider.add("gtceu.top.exhaust_vent_blocked", "Blocked"); provider.add("gtceu.top.machine_mode", "Machine Mode: "); provider.add("gtceu.top.stained", "Colored: %s"); + provider.add("gtceu.top.buffer_not_bound", "Buffer Not Currently Bound"); provider.add("gtceu.top.buffer_bound_pos", "Bound To - X: %s, Y: %s, Z: %s"); provider.add("gtceu.top.proxies_bound", "Buffer Proxies Bound: %s"); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index 38329926f4..2d6074449b 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -1,9 +1,6 @@ package com.gregtechceu.gtceu.integration.ae2.machine; -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; @@ -17,19 +14,19 @@ import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; import com.gregtechceu.gtceu.api.machine.feature.IHasCircuitSlot; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; -import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.SizedIngredient; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.common.data.machines.GTAEMachines; import com.gregtechceu.gtceu.common.item.IntCircuitBehaviour; import com.gregtechceu.gtceu.integration.ae2.gui.widget.AETextInputButtonWidget; import com.gregtechceu.gtceu.integration.ae2.gui.widget.slot.AEPatternViewSlotWidget; -import com.gregtechceu.gtceu.integration.ae2.machine.trait.MEPatternBufferRecipeHandler; -import com.gregtechceu.gtceu.integration.ae2.utils.AEUtil; +import com.gregtechceu.gtceu.integration.ae2.machine.trait.InternalSlotRecipeHandler; import com.gregtechceu.gtceu.utils.GTMath; -import com.gregtechceu.gtceu.utils.GTUtil; +import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.util.ClickData; @@ -72,9 +69,11 @@ import appeng.helpers.patternprovider.PatternContainer; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import it.unimi.dsi.fastutil.objects.*; import lombok.Getter; import lombok.Setter; -import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -143,9 +142,12 @@ public void setItemDirect(int slotIndex, ItemStack stack) { private boolean needPatternSync; @Persisted - private HashSet proxies = new HashSet<>(); + private final Set proxies = new ObjectOpenHashSet<>(); + private final Set proxyMachines = new ReferenceOpenHashSet<>(); - protected final MEPatternBufferRecipeHandler recipeHandler = new MEPatternBufferRecipeHandler(this); + // protected final MEPatternBufferRecipeHandler recipeHandler = new MEPatternBufferRecipeHandler(this); + @Getter + protected final InternalSlotRecipeHandler ISRHL; @Nullable protected TickableSubscription updateSubs; @@ -174,6 +176,7 @@ public MEPatternBufferPartMachine(IMachineBlockEntity holder, Object... args) { .setFilter(IntCircuitBehaviour::isIntegratedCircuit); this.shareInventory = new NotifiableItemStackHandler(this, 9, IO.IN, IO.NONE); this.shareTank = new NotifiableFluidTank(this, 9, 8 * FluidType.BUCKET_VOLUME, IO.IN, IO.NONE); + this.ISRHL = new InternalSlotRecipeHandler(this, internalInventory); } @Override @@ -189,16 +192,13 @@ public void onLoad() { } } })); + for (var rhl : getRecipeHandlers()) rhl.setDistinct(true); } - getRecipeHandlers().handlerMap.forEach((cap, handler) -> handler.stream() - .filter(v -> v instanceof IRecipeHandlerTrait) - .forEach(u -> ((IRecipeHandlerTrait) u).addChangedListener(() -> getProxies().forEach(proxy -> { - if (cap == ItemRecipeCapability.CAP) { - proxy.itemProxyHandler.notifyListeners(); - } else if (cap == FluidRecipeCapability.CAP) { - proxy.fluidProxyHandler.notifyListeners(); - } - })))); + } + + @Override + public List getRecipeHandlers() { + return ISRHL.getSlotHandlers(); } @Override @@ -225,20 +225,24 @@ protected void update() { public void addProxy(MEPatternBufferProxyPartMachine proxy) { proxies.add(proxy.getPos()); + proxyMachines.remove(proxy); } public void removeProxy(MEPatternBufferProxyPartMachine proxy) { proxies.remove(proxy.getPos()); + proxyMachines.remove(proxy); } public Set getProxies() { - Set proxies1 = new HashSet<>(); - for (var pos : proxies) { - if (MetaMachine.getMachine(getLevel(), pos) instanceof MEPatternBufferProxyPartMachine p) { - proxies1.add(p); + if (proxyMachines.size() != proxies.size()) { + proxyMachines.clear(); + for (var pos : proxies) { + if (MetaMachine.getMachine(getLevel(), pos) instanceof MEPatternBufferProxyPartMachine proxy) { + proxyMachines.add(proxy); + } } } - return proxies1; + return Collections.unmodifiableSet(proxyMachines); } private void refundAll(ClickData clickData) { @@ -339,7 +343,6 @@ public boolean pushPattern(IPatternDetails patternDetails, KeyCounter[] inputHol var slot = detailsSlotMap.get(patternDetails); if (slot != null) { slot.pushPattern(patternDetails, inputHolder); - recipeHandler.onChanged(); return true; } return false; @@ -428,21 +431,30 @@ public InteractionResult onDataStickShiftUse(Player player, ItemStack dataStick) return InteractionResult.SUCCESS; } + public Pair, Object2LongMap> mergeInternalSlots() { + Object2LongMap items = new Object2LongOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); + Object2LongMap fluids = new Object2LongOpenHashMap<>(); + for (InternalSlot slot : internalInventory) { + slot.itemInventory.forEach((stack, count) -> items.mergeLong(stack, count, Long::sum)); + slot.fluidInventory.forEach((stack, amount) -> fluids.mergeLong(stack, amount, Long::sum)); + } + return new ImmutablePair<>(items, fluids); + } + public class InternalSlot implements ITagSerializable, IContentChangeAware { @Getter @Setter - protected Runnable onContentsChanged = () -> { - /**/ - }; + private Runnable onContentsChanged = () -> {}; - private final Set itemInventory; - private final Set fluidInventory; + private final Object2LongMap itemInventory = new Object2LongOpenCustomHashMap<>( + ItemStackHashStrategy.comparingAllButCount()); + private final Object2LongMap fluidInventory = new Object2LongOpenHashMap<>(); + private List itemStacks = null; + private List fluidStacks = null; - public InternalSlot() { - this.itemInventory = new HashSet<>(); - this.fluidInventory = new HashSet<>(); - } + public InternalSlot() {} public boolean isItemEmpty() { return itemInventory.isEmpty(); @@ -452,48 +464,39 @@ public boolean isFluidEmpty() { return fluidInventory.isEmpty(); } - private void addItem(AEItemKey key, long amount) { - if (amount <= 0L) return; - for (ItemStack item : itemInventory) { - if (key.matches(item)) { - long sum = item.getCount() + amount; - if (sum <= Integer.MAX_VALUE) { - item.grow((int) amount); - } else { - itemInventory.remove(item); - itemInventory.addAll(List.of(AEUtil.toItemStacks(key, sum))); - } - return; - } - } - itemInventory.addAll(List.of(AEUtil.toItemStacks(key, amount))); - recipeHandler.getItemInputHandler().notifyListeners(); + public void onContentsChanged() { + itemStacks = null; + fluidStacks = null; + onContentsChanged.run(); } - private void addFluid(AEFluidKey key, int amount) { + private void add(AEKey what, long amount) { if (amount <= 0L) return; - for (FluidStack fluid : fluidInventory) { - if (key.matches(fluid)) { - int free = Integer.MAX_VALUE - fluid.getAmount(); - if (amount <= free) { - fluid.grow(amount); - } else { - fluid.setAmount(Integer.MAX_VALUE); - fluidInventory.add(AEUtil.toFluidStack(key, amount - free)); - } - return; - } + if (what instanceof AEItemKey itemKey) { + var stack = itemKey.toStack(); + itemInventory.mergeLong(stack, amount, Long::sum); + } else if (what instanceof AEFluidKey fluidKey) { + var stack = fluidKey.toStack(1); + fluidInventory.mergeLong(stack, amount, Long::sum); } - fluidInventory.add(AEUtil.toFluidStack(key, amount)); - recipeHandler.getFluidInputHandler().notifyListeners(); } - public ItemStack[] getItemInputs() { - return ArrayUtils.addAll(itemInventory.toArray(new ItemStack[0])); + public List getItems() { + if (itemStacks == null) { + itemStacks = itemInventory.object2LongEntrySet().stream() + .flatMap(e -> GTMath.splitStacks(e.getKey(), e.getLongValue()).stream()) + .toList(); + } + return itemStacks; } - public FluidStack[] getFluidInputs() { - return ArrayUtils.addAll(fluidInventory.toArray(new FluidStack[0])); + public List getFluids() { + if (fluidStacks == null) { + fluidStacks = fluidInventory.object2LongEntrySet().stream() + .map(e -> new FluidStack(e.getKey(), GTMath.saturatedCast(e.getLongValue()))) + .toList(); + } + return fluidStacks; } public void refund() { @@ -501,118 +504,153 @@ public void refund() { if (network != null) { MEStorage networkInv = network.getStorageService().getInventory(); var energy = network.getEnergyService(); - for (ItemStack stack : itemInventory) { - if (stack == null) continue; + + for (var it = itemInventory.object2LongEntrySet().iterator(); it.hasNext();) { + var entry = it.next(); + var stack = entry.getKey(); + var count = entry.getLongValue(); + if (stack.isEmpty() || count == 0) { + it.remove(); + continue; + } var key = AEItemKey.of(stack); if (key == null) continue; - long inserted = StorageHelper.poweredInsert(energy, networkInv, key, stack.getCount(), - actionSource); + long inserted = StorageHelper.poweredInsert(energy, networkInv, key, count, actionSource); if (inserted > 0) { - stack.shrink((int) inserted); - if (stack.isEmpty()) { - itemInventory.remove(stack); - } + count -= inserted; + if (count == 0) it.remove(); + else entry.setValue(count); } } - for (FluidStack stack : fluidInventory) { - if (stack == null || stack.isEmpty()) continue; + for (var it = fluidInventory.object2LongEntrySet().iterator(); it.hasNext();) { + var entry = it.next(); + var stack = entry.getKey(); + var amount = entry.getLongValue(); + if (stack.isEmpty() || amount == 0) { + it.remove(); + continue; + } - int inserted = GTMath.saturatedCast(StorageHelper.poweredInsert( - energy, - networkInv, - AEFluidKey.of(stack.getFluid(), stack.getTag()), - stack.getAmount(), - actionSource)); + var key = AEFluidKey.of(stack); + if (key == null) continue; + + long inserted = StorageHelper.poweredInsert(energy, networkInv, key, amount, actionSource); if (inserted > 0) { - stack.shrink(inserted); - if (stack.isEmpty()) { - fluidInventory.remove(stack); - } + amount -= inserted; + if (amount == 0) it.remove(); + else entry.setValue(amount); } } - onContentsChanged.run(); + onContentsChanged(); } } public void pushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder) { - patternDetails.pushInputsToExternalInventory(inputHolder, (what, amount) -> { - if (what instanceof AEFluidKey key) { - addFluid(key, GTMath.saturatedCast(amount)); + patternDetails.pushInputsToExternalInventory(inputHolder, this::add); + onContentsChanged(); + } + + public @Nullable List handleItemInternal(List left, boolean simulate) { + boolean changed = false; + for (var it = left.listIterator(); it.hasNext();) { + var ingredient = it.next(); + if (ingredient.isEmpty()) { + it.remove(); + continue; } - if (what instanceof AEItemKey key) { - addItem(key, amount); + var items = ingredient.getItems(); + if (items.length == 0 || items[0].isEmpty()) { + it.remove(); + continue; } - }); - onContentsChanged.run(); - } - public @Nullable List handleItemInternal(List left, boolean simulate) { - Iterator iterator = left.iterator(); - while (iterator.hasNext()) { - Ingredient ingredient = iterator.next(); - SLOT_LOOKUP: - for (ItemStack stack : itemInventory) { - if (ingredient.test(stack)) { - ItemStack[] ingredientStacks = ingredient.getItems(); - for (ItemStack ingredientStack : ingredientStacks) { - if (ingredientStack.is(stack.getItem())) { - int extracted = Math.min(ingredientStack.getCount(), stack.getCount()); - if (!simulate) { - stack.shrink(extracted); - if (stack.isEmpty()) { - itemInventory.remove(stack); - } - onContentsChanged.run(); - } - ingredientStack.shrink(extracted); - if (ingredientStack.isEmpty()) { - iterator.remove(); - break SLOT_LOOKUP; - } - } - } + int amount = items[0].getCount(); + for (var it2 = itemInventory.object2LongEntrySet().iterator(); it2.hasNext();) { + var entry = it2.next(); + var stack = entry.getKey(); + var count = entry.getLongValue(); + if (stack.isEmpty() || count == 0) { + it2.remove(); + continue; + } + if (!ingredient.test(stack)) continue; + int extracted = Math.min(GTMath.saturatedCast(count), amount); + if (!simulate && extracted > 0) { + changed = true; + count -= extracted; + if (count == 0) it2.remove(); + else entry.setValue(count); + } + amount -= extracted; + + if (amount <= 0) { + it.remove(); + break; + } + } + + if (amount > 0) { + if (ingredient instanceof SizedIngredient si) { + si.setAmount(amount); + } else { + items[0].setCount(amount); } } } + if (changed) onContentsChanged(); return left.isEmpty() ? null : left; } public @Nullable List handleFluidInternal(List left, boolean simulate) { - Iterator iterator = left.iterator(); - while (iterator.hasNext()) { - FluidIngredient fluidStack = iterator.next(); - if (fluidStack.isEmpty()) { - iterator.remove(); + boolean changed = false; + for (var it = left.listIterator(); it.hasNext();) { + var ingredient = it.next(); + if (ingredient.isEmpty()) { + it.remove(); continue; } - boolean found = false; - FluidStack foundStack = null; - for (FluidStack stack : fluidInventory) { - if (!fluidStack.test(stack)) { + + var fluids = ingredient.getStacks(); + if (fluids.length == 0 || fluids[0].isEmpty()) { + it.remove(); + continue; + } + + int amount = fluids[0].getAmount(); + for (var it2 = fluidInventory.object2LongEntrySet().iterator(); it2.hasNext();) { + var entry = it2.next(); + var stack = entry.getKey(); + var count = entry.getLongValue(); + if (stack.isEmpty() || count == 0) { + it2.remove(); continue; } - found = true; - foundStack = stack; - } - if (!found) continue; - int drained = Math.min(foundStack.getAmount(), fluidStack.getAmount()); - if (!simulate) { - foundStack.shrink(drained); - if (foundStack.isEmpty()) { - fluidInventory.remove(foundStack); + if (!ingredient.test(stack)) continue; + int extracted = Math.min(GTMath.saturatedCast(count), amount); + if (!simulate && extracted > 0) { + changed = true; + count -= extracted; + if (count == 0) it2.remove(); + else entry.setValue(count); + } + amount -= extracted; + + if (amount <= 0) { + it.remove(); + break; } - onContentsChanged.run(); } - fluidStack.setAmount(fluidStack.getAmount() - drained); - if (fluidStack.getAmount() <= 0) { - iterator.remove(); + if (amount > 0) { + ingredient.setAmount(amount); } } + + if (changed) onContentsChanged(); return left.isEmpty() ? null : left; } @@ -620,51 +658,44 @@ public void pushPattern(IPatternDetails patternDetails, KeyCounter[] inputHolder public CompoundTag serializeNBT() { CompoundTag tag = new CompoundTag(); - ListTag itemInventoryTag = new ListTag(); - for (ItemStack itemStack : this.itemInventory) { - itemInventoryTag.add(GTUtil.saveItemStack(itemStack, new CompoundTag())); + ListTag itemsTag = new ListTag(); + for (var entry : itemInventory.object2LongEntrySet()) { + var ct = entry.getKey().serializeNBT(); + ct.putLong("real", entry.getLongValue()); + itemsTag.add(ct); } - tag.put("inventory", itemInventoryTag); + if (!itemsTag.isEmpty()) tag.put("inventory", itemsTag); - ListTag fluidInventoryTag = new ListTag(); - for (FluidStack fluidStack : fluidInventory) { - fluidInventoryTag.add(fluidStack.writeToNBT(new CompoundTag())); + ListTag fluidsTag = new ListTag(); + for (var entry : fluidInventory.object2LongEntrySet()) { + var ct = entry.getKey().writeToNBT(new CompoundTag()); + ct.putLong("real", entry.getLongValue()); + fluidsTag.add(ct); } - tag.put("fluidInventory", fluidInventoryTag); + if (!fluidsTag.isEmpty()) tag.put("fluidInventory", fluidsTag); return tag; } @Override public void deserializeNBT(CompoundTag tag) { - ListTag inv = tag.getList("inventory", Tag.TAG_COMPOUND); - for (int i = 0; i < inv.size(); i++) { - CompoundTag tagItemStack = inv.getCompound(i); - var item = GTUtil.loadItemStack(tagItemStack); - if (item != null) { - if (!item.isEmpty()) { - itemInventory.add(item); - } - } else { - GTCEu.LOGGER - .warn( - "An error occurred while loading contents of ME Crafting Input Bus. This item has been voided: " + - tagItemStack); + ListTag items = tag.getList("inventory", Tag.TAG_COMPOUND); + for (Tag t : items) { + if (!(t instanceof CompoundTag ct)) continue; + var stack = ItemStack.of(ct); + var count = ct.getLong("real"); + if (!stack.isEmpty() && count > 0) { + itemInventory.put(stack, count); } } - ListTag fluidInv = tag.getList("fluidInventory", Tag.TAG_COMPOUND); - for (int i = 0; i < fluidInv.size(); i++) { - CompoundTag tagFluidStack = fluidInv.getCompound(i); - var fluid = FluidStack.loadFluidStackFromNBT(tagFluidStack); - if (fluid != null) { - if (!fluid.isEmpty()) { - fluidInventory.add(fluid); - } - } else { - GTCEu.LOGGER - .warn( - "An error occurred while loading contents of ME Crafting Input Bus. This fluid has been voided: " + - tagFluidStack); + + ListTag fluids = tag.getList("fluidInventory", Tag.TAG_COMPOUND); + for (Tag t : fluids) { + if (!(t instanceof CompoundTag ct)) continue; + var stack = FluidStack.loadFluidStackFromNBT(ct); + var amount = ct.getLong("real"); + if (!stack.isEmpty() && amount > 0) { + fluidInventory.put(stack, amount); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java index fdcab31c40..215536f527 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java @@ -1,18 +1,14 @@ package com.gregtechceu.gtceu.integration.ae2.machine; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredIOPartMachine; import com.gregtechceu.gtceu.api.machine.trait.*; -import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; -import com.gregtechceu.gtceu.integration.ae2.machine.trait.MEPatternBufferProxyRecipeHandler; +import com.gregtechceu.gtceu.integration.ae2.machine.trait.ProxySlotRecipeHandler; import com.lowdragmc.lowdraglib.gui.modular.ModularUI; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; @@ -28,13 +24,11 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.phys.BlockHitResult; import lombok.Getter; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @@ -48,20 +42,19 @@ public class MEPatternBufferProxyPartMachine extends TieredIOPartMachine MEPatternBufferProxyPartMachine.class, TieredIOPartMachine.MANAGED_FIELD_HOLDER); @Getter - protected MEPatternBufferProxyRecipeHandler itemProxyHandler; - - @Getter - protected MEPatternBufferProxyRecipeHandler fluidProxyHandler; + private final ProxySlotRecipeHandler proxySlotRecipeHandler; @Persisted @Getter @DescSynced - private BlockPos bufferPos; + private @Nullable BlockPos bufferPos; + + private @Nullable MEPatternBufferPartMachine buffer = null; + private boolean bufferResolved = false; public MEPatternBufferProxyPartMachine(IMachineBlockEntity holder) { super(holder, GTValues.LuV, IO.IN); - this.itemProxyHandler = new MEPatternBufferProxyRecipeHandler<>(this, IO.IN, ItemRecipeCapability.CAP); - this.fluidProxyHandler = new MEPatternBufferProxyRecipeHandler<>(this, IO.IN, FluidRecipeCapability.CAP); + proxySlotRecipeHandler = new ProxySlotRecipeHandler(this, MEPatternBufferPartMachine.MAX_PATTERN_COUNT); } @Override @@ -70,67 +63,44 @@ public void onLoad() { if (getLevel() instanceof ServerLevel level) { level.getServer().tell(new TickTask(0, () -> this.setBuffer(bufferPos))); } + for (var rhl : getRecipeHandlers()) rhl.setDistinct(true); } - public boolean setBuffer(@Nullable BlockPos pos) { - var level = getLevel(); - if (pos == null || level == null) return false; - if (MetaMachine.getMachine(getLevel(), pos) instanceof MEPatternBufferPartMachine machine) { - this.bufferPos = pos; - - List> itemHandlers = new ArrayList<>(); - List> fluidHandlers = new ArrayList<>(); - var handlerList = machine.getRecipeHandlers(); - handlerList.handlerMap.forEach((cap, handlers) -> { - for (var handler : handlers) { - if (handler.isProxy()) continue; - - if (handler.getCapability() == ItemRecipeCapability.CAP) { - itemHandlers.add((NotifiableRecipeHandlerTrait) handler); - } else { - fluidHandlers.add((NotifiableRecipeHandlerTrait) handler); - } - } - }); - itemProxyHandler.setHandlers(itemHandlers); - fluidProxyHandler.setHandlers(fluidHandlers); - - machine.addProxy(this); - - return true; - } else { - return false; - } + @Override + public List getRecipeHandlers() { + return proxySlotRecipeHandler.getProxySlotHandlers(); } - @Nullable - private MEPatternBufferPartMachine getBuffer() { + public void setBuffer(@Nullable BlockPos pos) { + bufferResolved = true; var level = getLevel(); - if (level == null || bufferPos == null) return null; - if (MetaMachine.getMachine(level, bufferPos) instanceof MEPatternBufferPartMachine buffer) { - return buffer; + if (level == null || pos == null) { + buffer = null; + } else if (MetaMachine.getMachine(level, pos) instanceof MEPatternBufferPartMachine machine) { + bufferPos = pos; + buffer = machine; + machine.addProxy(this); + if (!isRemote()) proxySlotRecipeHandler.updateProxy(machine); } else { - this.bufferPos = null; - return null; + buffer = null; } } - @Override - public MetaMachine self() { - var buffer = getBuffer(); - return buffer != null ? buffer.self() : super.self(); + @Nullable + public MEPatternBufferPartMachine getBuffer() { + if (!bufferResolved) setBuffer(bufferPos); + return buffer; } @Override public boolean shouldOpenUI(Player player, InteractionHand hand, BlockHitResult hit) { - var buffer = getBuffer(); - return buffer != null; + return getBuffer() != null; } @Override - public @Nullable ModularUI createUI(Player entityPlayer) { - GTCEu.LOGGER.warn("'createUI' of the Crafting Buffer Proxy was incorrectly called!"); - return null; + public ModularUI createUI(Player entityPlayer) { + assert getBuffer() != null; // UI should never be able to be opened when buffer is null + return getBuffer().createUI(entityPlayer); } @Override @@ -140,17 +110,18 @@ public ManagedFieldHolder getFieldHolder() { @Override public void onMachineRemoved() { - var level = getLevel(); - if (level == null || bufferPos == null) return; - if (MetaMachine.getMachine(getLevel(), this.bufferPos) instanceof MEPatternBufferPartMachine machine) { - machine.removeProxy(this); + var buf = getBuffer(); + if (buf != null) { + buf.removeProxy(this); + proxySlotRecipeHandler.clearProxy(); } } @Override public InteractionResult onDataStickUse(Player player, ItemStack dataStick) { if (dataStick.hasTag()) { - if (dataStick.getOrCreateTag().contains("pos", Tag.TAG_INT_ARRAY)) { + assert dataStick.getTag() != null; + if (dataStick.getTag().contains("pos", Tag.TAG_INT_ARRAY)) { var posArray = dataStick.getOrCreateTag().getIntArray("pos"); var bufferPos = new BlockPos(posArray[0], posArray[1], posArray[2]); setBuffer(bufferPos); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/InternalSlotRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/InternalSlotRecipeHandler.java new file mode 100644 index 0000000000..7fa927c7e2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/InternalSlotRecipeHandler.java @@ -0,0 +1,128 @@ +package com.gregtechceu.gtceu.integration.ae2.machine.trait; + +import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; +import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine.InternalSlot; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraftforge.fluids.FluidStack; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +public class InternalSlotRecipeHandler { + + @Getter + private final List slotHandlers; + + public InternalSlotRecipeHandler(MEPatternBufferPartMachine buffer, InternalSlot[] slots) { + this.slotHandlers = new ObjectArrayList<>(slots.length); + for (int i = 0; i < slots.length; i++) { + InternalSlot slot = slots[i]; + var rhl = new SlotRHL(buffer, slot, i); + rhl.setDistinct(true); + slotHandlers.add(rhl); + } + } + + @Getter + protected static class SlotRHL extends RecipeHandlerList { + + private final SlotItemRecipeHandler itemRecipeHandler; + private final SlotFluidRecipeHandler fluidRecipeHandler; + + public SlotRHL(MEPatternBufferPartMachine buffer, InternalSlot slot, int idx) { + super(IO.IN); + itemRecipeHandler = new SlotItemRecipeHandler(buffer, slot, idx); + fluidRecipeHandler = new SlotFluidRecipeHandler(buffer, slot, idx); + + itemRecipeHandler.setDistinct(true); + fluidRecipeHandler.setDistinct(true); + + addHandlers(List.of( + buffer.getCircuitInventory(), + buffer.getShareInventory(), + buffer.getShareTank(), + itemRecipeHandler, + fluidRecipeHandler)); + setDistinct(true); + } + } + + @Getter + private static class SlotItemRecipeHandler extends NotifiableRecipeHandlerTrait { + + private final InternalSlot slot; + private final int priority; + + private final int size = 81; + private final RecipeCapability capability = ItemRecipeCapability.CAP; + private final IO handlerIO = IO.IN; + + private SlotItemRecipeHandler(MEPatternBufferPartMachine buffer, InternalSlot slot, int index) { + super(buffer); + this.slot = slot; + this.priority = IFilteredHandler.HIGH + index + 1; + slot.setOnContentsChanged(this::notifyListeners); + } + + @Override + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { + if (io != IO.IN || slot.isItemEmpty()) return left; + return slot.handleItemInternal(left, simulate); + } + + @Override + public List getContents() { + return new ArrayList<>(slot.getItems()); + } + + @Override + public double getTotalContentAmount() { + return slot.getItems().stream().mapToLong(ItemStack::getCount).sum(); + } + } + + @Getter + private static class SlotFluidRecipeHandler extends NotifiableRecipeHandlerTrait { + + private final InternalSlot slot; + private final int priority; + + private final int size = 81; + private final RecipeCapability capability = FluidRecipeCapability.CAP; + private final IO handlerIO = IO.IN; + + private SlotFluidRecipeHandler(MEPatternBufferPartMachine buffer, InternalSlot slot, int index) { + super(buffer); + this.slot = slot; + this.priority = IFilteredHandler.HIGH + index + 1; + slot.setOnContentsChanged(this::notifyListeners); + } + + @Override + public List handleRecipeInner(IO io, GTRecipe recipe, List left, + boolean simulate) { + if (io != IO.IN || slot.isFluidEmpty()) return left; + return slot.handleFluidInternal(left, simulate); + } + + @Override + public List getContents() { + return new ArrayList<>(slot.getFluids()); + } + + @Override + public double getTotalContentAmount() { + return slot.getFluids().stream().mapToLong(FluidStack::getAmount).sum(); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java deleted file mode 100644 index 987742bf57..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferProxyRecipeHandler.java +++ /dev/null @@ -1,102 +0,0 @@ -package com.gregtechceu.gtceu.integration.ae2.machine.trait; - -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.machine.trait.NotifiableRecipeHandlerTrait; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import lombok.Setter; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -public class MEPatternBufferProxyRecipeHandler extends NotifiableRecipeHandlerTrait { - - private final IO handlerIO; - private final RecipeCapability capability; - - @Setter - private Collection> handlers = Collections.emptyList(); - - public MEPatternBufferProxyRecipeHandler(MetaMachine machine, IO handlerIO, RecipeCapability capability) { - super(machine); - this.handlerIO = handlerIO; - this.capability = capability; - } - - @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, - boolean simulate) { - for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, simulate); - if (left.isEmpty()) return null; - } - return left; - } - - @Override - public List getContents() { - List contents = new ObjectArrayList<>(2); - for (NotifiableRecipeHandlerTrait handler : handlers) { - contents.addAll(handler.getContents()); - } - return contents; - } - - @Override - public int getSize() { - int size = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - size += handlerTrait.getSize(); - } - return size; - } - - @Override - public double getTotalContentAmount() { - double amount = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - amount += handlerTrait.getTotalContentAmount(); - } - return amount; - } - - @Override - public boolean isDistinct() { - for (NotifiableRecipeHandlerTrait handler : handlers) { - if (!handler.isDistinct()) - return false; - } - return true; - } - - @Override - public void setDistinct(boolean distinct) { - handlers.forEach(handler -> handler.setDistinct(distinct)); - } - - @Override - public void preWorking(IRecipeCapabilityHolder holder, IO io, GTRecipe recipe) { - handlers.forEach(handler -> handler.preWorking(holder, io, recipe)); - } - - @Override - public void postWorking(IRecipeCapabilityHolder holder, IO io, GTRecipe recipe) { - handlers.forEach(handler -> handler.postWorking(holder, io, recipe)); - } - - @Override - public RecipeCapability getCapability() { - return capability; - } - - @Override - public IO getHandlerIO() { - return handlerIO; - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java deleted file mode 100644 index 0d829b16b8..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/MEPatternBufferRecipeHandler.java +++ /dev/null @@ -1,284 +0,0 @@ -package com.gregtechceu.gtceu.integration.ae2.machine.trait; - -import com.gregtechceu.gtceu.api.capability.recipe.*; -import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; -import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; -import com.gregtechceu.gtceu.api.machine.trait.NotifiableRecipeHandlerTrait; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; -import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; - -import com.lowdragmc.lowdraglib.syncdata.ISubscription; -import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; - -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.minecraft.world.level.material.Fluid; -import net.minecraftforge.fluids.FluidStack; - -import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import lombok.Getter; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class MEPatternBufferRecipeHandler extends MachineTrait { - - protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder( - MEPatternBufferPartMachine.class); - private ResourceLocation lockedRecipeId; - private int lockedSlot; - protected List listeners = new ArrayList<>(); - - @Getter - protected final NotifiableRecipeHandlerTrait itemInputHandler; - - @Getter - protected final NotifiableRecipeHandlerTrait fluidInputHandler; - - public MEPatternBufferRecipeHandler(MEPatternBufferPartMachine ioBuffer) { - super(ioBuffer); - this.itemInputHandler = new ItemInputHandler(ioBuffer); - this.fluidInputHandler = new FluidInputHandler(ioBuffer); - } - - public void onChanged() { - listeners.forEach(Runnable::run); - } - - @Override - public MEPatternBufferPartMachine getMachine() { - return (MEPatternBufferPartMachine) super.getMachine(); - } - - public List handleItemInner(GTRecipe recipe, List left, boolean simulate) { - var internalInv = getMachine().getInternalInventory(); - if (recipe.id.equals(lockedRecipeId) && lockedSlot >= 0) { - return internalInv[lockedSlot].handleItemInternal(left, simulate); - } - - this.lockedRecipeId = recipe.id; - for (int i = 0; i < internalInv.length; i++) { - if (internalInv[i].isItemEmpty()) continue; - List contents = left; - contents = internalInv[i].handleItemInternal(contents, simulate); - if (contents == null) { - this.lockedSlot = i; - return null; - } - // contents = copyIngredients(left); - } - this.lockedSlot = -1; - return left; - } - - public List handleFluidInner( - GTRecipe recipe, List left, boolean simulate) { - var internalInv = getMachine().getInternalInventory(); - if (recipe.id.equals(lockedRecipeId) && lockedSlot >= 0) { - return internalInv[lockedSlot].handleFluidInternal(left, simulate); - } - - this.lockedRecipeId = recipe.id; - List contents = left; - for (int i = 0; i < internalInv.length; i++) { - if (internalInv[i].isFluidEmpty()) continue; - contents = internalInv[i].handleFluidInternal(contents, simulate); - - if (contents == null) { - this.lockedSlot = i; - return contents; - } - contents = copyFluidIngredients(left); - } - this.lockedSlot = -1; - return left; - } - - @SuppressWarnings("rawtypes") - public List getRecipeHandlers() { - return List.of(fluidInputHandler, itemInputHandler); - } - - @Override - public ManagedFieldHolder getFieldHolder() { - return MANAGED_FIELD_HOLDER; - } - - public class ItemInputHandler extends NotifiableRecipeHandlerTrait { - - public ItemInputHandler(MEPatternBufferPartMachine machine) { - super(machine); - } - - public MEPatternBufferPartMachine getMachine() { - return (MEPatternBufferPartMachine) this.machine; - } - - @Override - public IO getHandlerIO() { - return IO.IN; - } - - @Override - public ISubscription addChangedListener(Runnable listener) { - listeners.add(listener); - return () -> listeners.remove(listener); - } - - @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, - boolean simulate) { - if (io != IO.IN) return left; - var machine = getMachine(); - machine.getCircuitInventorySimulated().handleRecipeInner(io, recipe, left, simulate); - machine.getShareInventory().handleRecipeInner(io, recipe, left, simulate); - return handleItemInner(recipe, left, simulate); - } - - @Override - public List getContents() { - return Arrays.stream(getMachine().getInternalInventory()) - .map(MEPatternBufferPartMachine.InternalSlot::getItemInputs) - .flatMap(Arrays::stream) - .collect(Collectors.toList()); - } - - @Override - public double getTotalContentAmount() { - return Arrays.stream(getMachine().getInternalInventory()) - .map(MEPatternBufferPartMachine.InternalSlot::getItemInputs) - .flatMap(Arrays::stream) - .mapToLong(ItemStack::getCount) - .sum(); - } - - @Override - public int getPriority() { - return Integer.MAX_VALUE; - } - - @Override - public boolean isDistinct() { - super.setDistinct(true); - return true; - } - - @Override - public RecipeCapability getCapability() { - return ItemRecipeCapability.CAP; - } - - @Override - public void preWorking(IRecipeCapabilityHolder holder, IO io, GTRecipe recipe) { - super.preWorking(holder, io, recipe); - lockedRecipeId = null; - } - } - - public class FluidInputHandler extends NotifiableRecipeHandlerTrait { - - public FluidInputHandler(MEPatternBufferPartMachine machine) { - super(machine); - } - - public MEPatternBufferPartMachine getMachine() { - return (MEPatternBufferPartMachine) this.machine; - } - - @Override - public IO getHandlerIO() { - return IO.IN; - } - - @Override - public ISubscription addChangedListener(Runnable listener) { - listeners.add(listener); - return () -> listeners.remove(listener); - } - - @Override - public List handleRecipeInner(IO io, GTRecipe recipe, - List left, boolean simulate) { - if (io != IO.IN) return left; - getMachine().getShareTank().handleRecipeInner(io, recipe, left, simulate); - return handleFluidInner(recipe, left, simulate); - } - - @Override - public List getContents() { - return Arrays.stream(getMachine().getInternalInventory()) - .map(MEPatternBufferPartMachine.InternalSlot::getFluidInputs) - .flatMap(Arrays::stream) - .collect(Collectors.toList()); - } - - @Override - public double getTotalContentAmount() { - return Arrays.stream(getMachine().getInternalInventory()) - .map(MEPatternBufferPartMachine.InternalSlot::getFluidInputs) - .flatMap(Arrays::stream) - .mapToLong(FluidStack::getAmount) - .sum(); - } - - @Override - public int getPriority() { - return Integer.MAX_VALUE; - } - - @Override - public boolean isDistinct() { - return true; - } - - @Override - public RecipeCapability getCapability() { - return FluidRecipeCapability.CAP; - } - - @Override - public void preWorking(IRecipeCapabilityHolder holder, IO io, GTRecipe recipe) { - super.preWorking(holder, io, recipe); - lockedRecipeId = null; - } - } - - private static List copyIngredients(List ingredients) { - List result = new ObjectArrayList<>(ingredients.size()); - for (Ingredient ingredient : ingredients) { - result.add(ItemRecipeCapability.CAP.copyInner(ingredient)); - } - return result; - } - - private static List copyFluidIngredients(List ingredients) { - List result = new ObjectArrayList<>(ingredients.size()); - for (FluidIngredient ingredient : ingredients) { - result.add(FluidRecipeCapability.CAP.copyInner(ingredient)); - } - return result; - } - - public static Pair, Object2LongOpenHashMap> mergeInternalSlot( - MEPatternBufferPartMachine.InternalSlot[] internalSlots) { - Object2LongOpenHashMap items = new Object2LongOpenHashMap<>(); - Object2LongOpenHashMap fluids = new Object2LongOpenHashMap<>(); - for (MEPatternBufferPartMachine.InternalSlot internalSlot : internalSlots) { - for (ItemStack stack : internalSlot.getItemInputs()) { - items.addTo(stack.getItem(), stack.getCount()); - } - for (FluidStack stack : internalSlot.getFluidInputs()) { - fluids.addTo(stack.getFluid(), stack.getAmount()); - } - } - return new ImmutablePair<>(items, fluids); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java new file mode 100644 index 0000000000..a839fb00fd --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java @@ -0,0 +1,185 @@ +package com.gregtechceu.gtceu.integration.ae2.machine.trait; + +import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; +import com.gregtechceu.gtceu.api.recipe.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferProxyPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.trait.InternalSlotRecipeHandler.SlotRHL; + +import com.lowdragmc.lowdraglib.syncdata.ISubscription; + +import net.minecraft.world.item.crafting.Ingredient; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import lombok.Getter; + +import java.util.Collections; +import java.util.List; + +public class ProxySlotRecipeHandler { + + @Getter + private final List proxySlotHandlers; + + public ProxySlotRecipeHandler(MEPatternBufferProxyPartMachine machine, int slots) { + proxySlotHandlers = new ObjectArrayList<>(slots); + for (int i = 0; i < slots; ++i) { + var rhl = new ProxyRHL(machine); + rhl.setDistinct(true); + proxySlotHandlers.add(rhl); + } + } + + public void updateProxy(MEPatternBufferPartMachine patternBuffer) { + var slotHandlers = patternBuffer.getISRHL().getSlotHandlers(); + for (int i = 0; i < proxySlotHandlers.size(); ++i) { + ProxyRHL proxyRHL = (ProxyRHL) proxySlotHandlers.get(i); + SlotRHL slotRHL = (SlotRHL) slotHandlers.get(i); + proxyRHL.setBuffer(patternBuffer, slotRHL); + } + } + + public void clearProxy() { + for (var slotHandler : proxySlotHandlers) { + ((ProxyRHL) slotHandler).clearBuffer(); + } + } + + private static class ProxyRHL extends RecipeHandlerList { + + private final ProxyItemRecipeHandler circuit; + private final ProxyItemRecipeHandler sharedItem; + private final ProxyItemRecipeHandler slotItem; + private final ProxyFluidRecipeHandler sharedFluid; + private final ProxyFluidRecipeHandler slotFluid; + + public ProxyRHL(MEPatternBufferProxyPartMachine machine) { + super(IO.IN); + circuit = new ProxyItemRecipeHandler(machine); + sharedItem = new ProxyItemRecipeHandler(machine); + slotItem = new ProxyItemRecipeHandler(machine); + sharedFluid = new ProxyFluidRecipeHandler(machine); + slotFluid = new ProxyFluidRecipeHandler(machine); + addHandlers(circuit, sharedItem, slotItem, sharedFluid, slotFluid); + } + + public void setBuffer(MEPatternBufferPartMachine buffer, SlotRHL slotRHL) { + circuit.setProxy(buffer.getCircuitInventory()); + sharedItem.setProxy(buffer.getShareInventory()); + sharedFluid.setProxy(buffer.getShareTank()); + slotItem.setProxy(slotRHL.getItemRecipeHandler()); + slotFluid.setProxy(slotRHL.getFluidRecipeHandler()); + } + + public void clearBuffer() { + circuit.setProxy(null); + sharedItem.setProxy(null); + sharedFluid.setProxy(null); + slotItem.setProxy(null); + slotFluid.setProxy(null); + } + } + + @Getter + private static class ProxyItemRecipeHandler extends NotifiableRecipeHandlerTrait { + + private IRecipeHandlerTrait proxy = null; + private ISubscription proxySub = null; + + private final int size = 81; + private final IO handlerIO = IO.IN; + private final RecipeCapability capability = ItemRecipeCapability.CAP; + + public ProxyItemRecipeHandler(MEPatternBufferProxyPartMachine machine) { + super(machine); + } + + public void setProxy(IRecipeHandlerTrait proxy) { + this.proxy = proxy; + if (proxySub != null) { + proxySub.unsubscribe(); + proxySub = null; + } + if (proxy != null) { + proxySub = proxy.addChangedListener(this::notifyListeners); + } + } + + @Override + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { + if (proxy == null) return left; + return proxy.handleRecipeInner(io, recipe, left, simulate); + } + + @Override + public List getContents() { + if (proxy == null) return Collections.emptyList(); + return proxy.getContents(); + } + + @Override + public double getTotalContentAmount() { + if (proxy == null) return 0; + return proxy.getTotalContentAmount(); + } + + public int getPriority() { + if (proxy == null) return IFilteredHandler.LOW; + return proxy.getPriority(); + } + } + + @Getter + private static class ProxyFluidRecipeHandler extends NotifiableRecipeHandlerTrait { + + private IRecipeHandlerTrait proxy = null; + private ISubscription proxySub = null; + + private final int size = 81; + private final IO handlerIO = IO.IN; + private final RecipeCapability capability = FluidRecipeCapability.CAP; + + public ProxyFluidRecipeHandler(MEPatternBufferProxyPartMachine machine) { + super(machine); + } + + public void setProxy(IRecipeHandlerTrait proxy) { + this.proxy = proxy; + if (proxySub != null) { + proxySub.unsubscribe(); + proxySub = null; + } + if (proxy != null) { + proxySub = proxy.addChangedListener(this::notifyListeners); + } + } + + @Override + public List handleRecipeInner(IO io, GTRecipe recipe, List left, + boolean simulate) { + if (proxy == null) return left; + return proxy.handleRecipeInner(io, recipe, left, simulate); + } + + @Override + public List getContents() { + if (proxy == null) return Collections.emptyList(); + return proxy.getContents(); + } + + @Override + public double getTotalContentAmount() { + if (proxy == null) return 0; + return proxy.getTotalContentAmount(); + } + + public int getPriority() { + if (proxy == null) return IFilteredHandler.LOW; + return proxy.getPriority(); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java index 269313b31d..c5449c4fd1 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java @@ -43,8 +43,8 @@ public void register(IWailaCommonRegistration registration) { registration.registerBlockDataProvider(new TransformerBlockProvider(), BlockEntity.class); registration.registerBlockDataProvider(new PrimitivePumpBlockProvider(), BlockEntity.class); if (GTCEu.Mods.isAE2Loaded()) { - registration.registerBlockDataProvider(new MEPatternBufferProxyProvider(), BlockEntity.class); registration.registerBlockDataProvider(new MEPatternBufferProvider(), BlockEntity.class); + registration.registerBlockDataProvider(new MEPatternBufferProxyProvider(), BlockEntity.class); } registration.registerItemStorage(GTItemStorageProvider.INSTANCE, MetaMachineBlockEntity.class); @@ -72,8 +72,8 @@ public void registerClient(IWailaClientRegistration registration) { registration.registerBlockComponent(new TransformerBlockProvider(), Block.class); registration.registerBlockComponent(new PrimitivePumpBlockProvider(), Block.class); if (GTCEu.Mods.isAE2Loaded()) { - registration.registerBlockComponent(new MEPatternBufferProxyProvider(), Block.class); registration.registerBlockComponent(new MEPatternBufferProvider(), Block.class); + registration.registerBlockComponent(new MEPatternBufferProxyProvider(), Block.class); } registration.registerItemStorageClient(GTItemStorageProvider.INSTANCE); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTFluidStorageProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTFluidStorageProvider.java index 165e23e654..c2c60d83df 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTFluidStorageProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTFluidStorageProvider.java @@ -2,8 +2,11 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.common.machine.storage.CreativeTankMachine; import com.gregtechceu.gtceu.common.machine.storage.QuantumTankMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferProxyPartMachine; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; @@ -25,11 +28,12 @@ import snownee.jade.api.view.ViewGroup; import snownee.jade.util.FluidTextHelper; +import java.util.Collections; import java.util.List; /** * Custom FluidView info provider for any machines that require it - * Currently: Quantum Tanks + * Currently: Quantum Tanks, Pattern Buffer Proxies * Defaults to Jade's normal FluidView provider */ public enum GTFluidStorageProvider implements IServerExtensionProvider, @@ -50,10 +54,12 @@ public List> getClientGroups(Accessor accessor, Li @Override public @Nullable List> getGroups(ServerPlayer serverPlayer, ServerLevel serverLevel, MetaMachineBlockEntity mmbe, boolean b) { - if (mmbe.getMetaMachine() instanceof QuantumTankMachine qtm) { + MetaMachine machine = mmbe.getMetaMachine(); + if (machine instanceof QuantumTankMachine qtm) { CompoundTag tag = new CompoundTag(); tag.putBoolean("special", true); FluidStack stored = qtm.getStored(); + if (stored.isEmpty() && qtm instanceof CreativeTankMachine) return Collections.emptyList(); tag.putString("fluid", BuiltInRegistries.FLUID.getKey(stored.getFluid()).toString()); long amount = qtm.getStoredAmount(); if (qtm instanceof CreativeTankMachine ctm) { @@ -63,6 +69,12 @@ public List> getClientGroups(Accessor accessor, Li tag.putLong("capacity", qtm.getMaxAmount()); if (stored.hasTag()) tag.put("tag", stored.getTag()); return List.of(new ViewGroup<>(List.of(tag))); + } else if (machine instanceof MEPatternBufferPartMachine buffer && !buffer.isFormed()) { + return Collections.emptyList(); + } else if (machine instanceof MEPatternBufferProxyPartMachine proxy) { + var buffer = proxy.getBuffer(); + if (buffer == null) return Collections.emptyList(); + return FluidStorageProvider.INSTANCE.getGroups(serverPlayer, serverLevel, buffer.holder, b); } return FluidStorageProvider.INSTANCE.getGroups(serverPlayer, serverLevel, mmbe, b); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTItemStorageProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTItemStorageProvider.java index 1683db36ef..a3b6fb7310 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTItemStorageProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/GTItemStorageProvider.java @@ -2,8 +2,11 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.common.machine.storage.CreativeChestMachine; import com.gregtechceu.gtceu.common.machine.storage.QuantumChestMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferProxyPartMachine; import com.gregtechceu.gtceu.utils.GTMath; import net.minecraft.resources.ResourceLocation; @@ -21,11 +24,12 @@ import snownee.jade.api.view.ViewGroup; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** * Custom ItemStack provider for any machines that require it - * Currently: Quantum Chests + * Currently: Quantum Chests, Pattern Buffer Proxies * Defaults to Jade's normal ItemStack provider */ public enum GTItemStorageProvider implements IServerExtensionProvider, @@ -46,7 +50,8 @@ public List> getClientGroups(Accessor accessor, Lis @Override public @Nullable List> getGroups(ServerPlayer serverPlayer, ServerLevel serverLevel, MetaMachineBlockEntity mmbe, boolean b) { - if (mmbe.getMetaMachine() instanceof QuantumChestMachine qcm) { + MetaMachine machine = mmbe.getMetaMachine(); + if (machine instanceof QuantumChestMachine qcm) { ItemStack stored = qcm.getStored(); long amount = qcm.getStoredAmount(); if (qcm instanceof CreativeChestMachine ccm) { @@ -58,6 +63,14 @@ public List> getClientGroups(Accessor accessor, Lis } return list.isEmpty() ? List.of() : List.of(new ViewGroup<>(list)); } + + if (machine instanceof MEPatternBufferPartMachine buffer && !buffer.isFormed()) return Collections.emptyList(); + if (machine instanceof MEPatternBufferProxyPartMachine proxy) { + var buffer = proxy.getBuffer(); + if (buffer == null) return Collections.emptyList(); + return ItemStorageProvider.INSTANCE.getGroups(serverPlayer, serverLevel, buffer.holder, b); + } + return ItemStorageProvider.INSTANCE.getGroups(serverPlayer, serverLevel, mmbe, b); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java index 81a30c1f3d..fdc2ab8f4b 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java @@ -3,7 +3,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; -import com.gregtechceu.gtceu.integration.ae2.machine.trait.MEPatternBufferRecipeHandler; +import com.gregtechceu.gtceu.utils.FormattingUtil; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; @@ -11,61 +11,28 @@ import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.material.Fluid; -import net.minecraftforge.fluids.FluidType; -import net.minecraftforge.registries.ForgeRegistries; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; -import org.jetbrains.annotations.Nullable; import snownee.jade.api.BlockAccessor; import snownee.jade.api.IBlockComponentProvider; import snownee.jade.api.IServerDataProvider; import snownee.jade.api.ITooltip; import snownee.jade.api.config.IPluginConfig; +import snownee.jade.api.ui.IElementHelper; public class MEPatternBufferProvider implements IBlockComponentProvider, IServerDataProvider { @Override public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { - if (blockEntity.getMetaMachine() instanceof MEPatternBufferPartMachine buffer) { - + if (blockEntity.getMetaMachine() instanceof MEPatternBufferPartMachine) { CompoundTag serverData = blockAccessor.getServerData(); + if (!serverData.getBoolean("formed")) return; iTooltip.add(Component.translatable("gtceu.top.proxies_bound", serverData.getInt("proxies")) .withStyle(ChatFormatting.LIGHT_PURPLE)); - - ListTag itemTags = serverData.getList("items", Tag.TAG_COMPOUND); - ListTag fluidTags = serverData.getList("fluids", Tag.TAG_COMPOUND); - for (int i = 0; i < itemTags.size(); ++i) { - CompoundTag itemTag = itemTags.getCompound(i); - Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemTag.getString("item"))); - long count = itemTag.getLong("count"); - if (item != null && !item.equals(Items.AIR)) { - iTooltip.add(item.getDescription() - .copy() - .withStyle(ChatFormatting.GOLD) - .append(Component.literal(" * ").withStyle(ChatFormatting.WHITE)) - .append(Component.literal("" + count).withStyle(ChatFormatting.LIGHT_PURPLE))); - } - } - for (int i = 0; i < fluidTags.size(); ++i) { - CompoundTag fluidTag = fluidTags.getCompound(i); - @Nullable - FluidType fluid = ForgeRegistries.FLUID_TYPES - .get() - .getValue(new ResourceLocation(fluidTag.getString("fluid"))); - long count = fluidTag.getLong("count"); - if (fluid != null) { - iTooltip.add(fluid - .getDescription() - .copy() - .withStyle(ChatFormatting.AQUA) - .append(Component.literal(" * ").withStyle(ChatFormatting.WHITE)) - .append(Component.literal("" + count).withStyle(ChatFormatting.LIGHT_PURPLE))); - } - } + readBufferTag(iTooltip, serverData); } } } @@ -74,35 +41,13 @@ public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPlugi public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) { if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { if (blockEntity.getMetaMachine() instanceof MEPatternBufferPartMachine buffer) { - compoundTag.putInt("proxies", buffer.getProxies().size()); - - var merged = MEPatternBufferRecipeHandler.mergeInternalSlot(buffer.getInternalInventory()); - var items = merged.getLeft(); - var fluids = merged.getRight(); - - ListTag itemTags = new ListTag(); - for (Item item : items.keySet()) { - ResourceLocation key = ForgeRegistries.ITEMS.getKey(item); - if (key != null) { - CompoundTag itemTag = new CompoundTag(); - itemTag.putString("item", key.toString()); - itemTag.putLong("count", items.getLong(item)); - itemTags.add(itemTag); - } - } - compoundTag.put("items", itemTags); - - ListTag fluidTags = new ListTag(); - for (Fluid fluid : fluids.keySet()) { - ResourceLocation key = ForgeRegistries.FLUID_TYPES.get().getKey(fluid.getFluidType()); - if (key != null) { - CompoundTag fluidTag = new CompoundTag(); - fluidTag.putString("fluid", key.toString()); - fluidTag.putLong("count", fluids.getLong(fluid)); - fluidTags.add(fluidTag); - } + if (!buffer.isFormed()) { + compoundTag.putBoolean("formed", false); + return; } - compoundTag.put("fluids", fluidTags); + compoundTag.putBoolean("formed", true); + compoundTag.putInt("proxies", buffer.getProxies().size()); + writeBufferTag(compoundTag, buffer); } } } @@ -111,4 +56,58 @@ public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccesso public ResourceLocation getUid() { return GTCEu.id("me_pattern_buffer"); } + + public static void writeBufferTag(CompoundTag compoundTag, MEPatternBufferPartMachine buffer) { + var merged = buffer.mergeInternalSlots(); + var items = merged.getLeft(); + var fluids = merged.getRight(); + + ListTag itemsTag = new ListTag(); + for (var entry : items.object2LongEntrySet()) { + var ct = entry.getKey().serializeNBT(); + ct.putLong("real", entry.getLongValue()); + itemsTag.add(ct); + } + if (!itemsTag.isEmpty()) compoundTag.put("items", itemsTag); + + ListTag fluidsTag = new ListTag(); + for (var entry : fluids.object2LongEntrySet()) { + var ct = entry.getKey().writeToNBT(new CompoundTag()); + ct.putLong("real", entry.getLongValue()); + fluidsTag.add(ct); + } + if (!fluidsTag.isEmpty()) compoundTag.put("fluids", fluidsTag); + } + + public static void readBufferTag(ITooltip iTooltip, CompoundTag serverData) { + IElementHelper helper = iTooltip.getElementHelper(); + + ListTag itemsTag = serverData.getList("items", Tag.TAG_COMPOUND); + for (Tag t : itemsTag) { + if (!(t instanceof CompoundTag ct)) continue; + var stack = ItemStack.of(ct); + var count = ct.getLong("real"); + if (!stack.isEmpty() && count > 0) { + iTooltip.add(helper.smallItem(stack)); + Component text = Component.literal(" ") + .append(Component.literal(String.valueOf(count)).withStyle(ChatFormatting.LIGHT_PURPLE)) + .append(Component.literal("× ").withStyle(ChatFormatting.WHITE)) + .append(stack.getHoverName().copy().withStyle(ChatFormatting.GOLD)); + iTooltip.append(text); + } + } + ListTag fluidsTag = serverData.getList("fluids", Tag.TAG_COMPOUND); + for (Tag t : fluidsTag) { + if (!(t instanceof CompoundTag ct)) continue; + var stack = FluidStack.loadFluidStackFromNBT(ct); + var amount = ct.getLong("real"); + if (!stack.isEmpty() && amount > 0) { + Component text = Component.literal(FormattingUtil.formatBuckets(amount)) + .withStyle(ChatFormatting.LIGHT_PURPLE) + .append(Component.literal(" ").withStyle(ChatFormatting.WHITE)) + .append(stack.getDisplayName().copy().withStyle(ChatFormatting.GOLD)); + iTooltip.add(text); + } + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProxyProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProxyProvider.java index 959a8741e7..69134ef135 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProxyProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProxyProvider.java @@ -2,23 +2,13 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; -import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferPartMachine; import com.gregtechceu.gtceu.integration.ae2.machine.MEPatternBufferProxyPartMachine; -import com.gregtechceu.gtceu.integration.ae2.machine.trait.MEPatternBufferRecipeHandler; import net.minecraft.ChatFormatting; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.ListTag; -import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.material.Fluid; -import net.minecraftforge.fluids.FluidType; -import net.minecraftforge.registries.ForgeRegistries; -import org.jetbrains.annotations.Nullable; import snownee.jade.api.BlockAccessor; import snownee.jade.api.IBlockComponentProvider; import snownee.jade.api.IServerDataProvider; @@ -30,46 +20,19 @@ public class MEPatternBufferProxyProvider implements IBlockComponentProvider, IS @Override public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { - if (blockEntity.getMetaMachine() instanceof MEPatternBufferProxyPartMachine proxy) { + if (blockEntity.getMetaMachine() instanceof MEPatternBufferProxyPartMachine) { CompoundTag serverData = blockAccessor.getServerData(); - - if (serverData.contains("posX")) { - int posX = serverData.getInt("posX"), posY = serverData.getInt("posY"), - posZ = serverData.getInt("posZ"); - iTooltip.add(Component.translatable("gtceu.top.buffer_bound_pos", posX, posY, posZ) - .withStyle(ChatFormatting.YELLOW)); + if (!serverData.getBoolean("formed")) return; + if (!serverData.getBoolean("bound")) { + iTooltip.add(Component.translatable("gtceu.top.buffer_not_bound").withStyle(ChatFormatting.RED)); + return; } - ListTag itemTags = serverData.getList("items", Tag.TAG_COMPOUND); - ListTag fluidTags = serverData.getList("fluids", Tag.TAG_COMPOUND); - for (int i = 0; i < itemTags.size(); ++i) { - CompoundTag itemTag = itemTags.getCompound(i); - Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemTag.getString("item"))); - long count = itemTag.getLong("count"); - if (item != null && !item.equals(Items.AIR)) { - iTooltip.add(item.getDescription() - .copy() - .withStyle(ChatFormatting.GOLD) - .append(Component.literal(" * ").withStyle(ChatFormatting.WHITE)) - .append(Component.literal("" + count).withStyle(ChatFormatting.LIGHT_PURPLE))); - } - } - for (int i = 0; i < fluidTags.size(); ++i) { - CompoundTag fluidTag = fluidTags.getCompound(i); - @Nullable - FluidType fluid = ForgeRegistries.FLUID_TYPES - .get() - .getValue(new ResourceLocation(fluidTag.getString("fluid"))); - long count = fluidTag.getLong("count"); - if (fluid != null) { - iTooltip.add(fluid - .getDescription() - .copy() - .withStyle(ChatFormatting.AQUA) - .append(Component.literal(" * ").withStyle(ChatFormatting.WHITE)) - .append(Component.literal("" + count).withStyle(ChatFormatting.LIGHT_PURPLE))); - } - } + int[] pos = serverData.getIntArray("pos"); + iTooltip.add(Component.translatable("gtceu.top.buffer_bound_pos", pos[0], pos[1], pos[2]) + .withStyle(ChatFormatting.YELLOW)); + + MEPatternBufferProvider.readBufferTag(iTooltip, serverData); } } } @@ -77,41 +40,22 @@ public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPlugi @Override public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) { if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { - if (blockEntity.getMetaMachine() instanceof MEPatternBufferProxyPartMachine proxy && - proxy.self() instanceof MEPatternBufferPartMachine pattern) { - if (proxy.getBufferPos() != null) { - compoundTag.putInt("posX", proxy.getBufferPos().getX()); - compoundTag.putInt("posY", proxy.getBufferPos().getY()); - compoundTag.putInt("posZ", proxy.getBufferPos().getZ()); + if (blockEntity.getMetaMachine() instanceof MEPatternBufferProxyPartMachine proxy) { + if (!proxy.isFormed()) { + compoundTag.putBoolean("formed", false); + return; } - - var merged = MEPatternBufferRecipeHandler.mergeInternalSlot(pattern.getInternalInventory()); - var items = merged.getLeft(); - var fluids = merged.getRight(); - - ListTag itemTags = new ListTag(); - for (Item item : items.keySet()) { - ResourceLocation key = ForgeRegistries.ITEMS.getKey(item); - if (key != null) { - CompoundTag itemTag = new CompoundTag(); - itemTag.putString("item", key.toString()); - itemTag.putLong("count", items.getLong(item)); - itemTags.add(itemTag); - } + compoundTag.putBoolean("formed", true); + var buffer = proxy.getBuffer(); + if (buffer == null) { + compoundTag.putBoolean("bound", false); + return; } - compoundTag.put("items", itemTags); + compoundTag.putBoolean("bound", true); - ListTag fluidTags = new ListTag(); - for (Fluid fluid : fluids.keySet()) { - ResourceLocation key = ForgeRegistries.FLUID_TYPES.get().getKey(fluid.getFluidType()); - if (key != null) { - CompoundTag fluidTag = new CompoundTag(); - fluidTag.putString("fluid", key.toString()); - fluidTag.putLong("count", fluids.getLong(fluid)); - fluidTags.add(fluidTag); - } - } - compoundTag.put("fluids", fluidTags); + var pos = buffer.getPos(); + compoundTag.putIntArray("pos", new int[] { pos.getX(), pos.getY(), pos.getZ() }); + MEPatternBufferProvider.writeBufferTag(compoundTag, buffer); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTHashMaps.java b/src/main/java/com/gregtechceu/gtceu/utils/GTHashMaps.java index 9fe48d62d3..57e909fccf 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTHashMaps.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTHashMaps.java @@ -87,7 +87,7 @@ public static Object2IntMap fromItemStackCollection(@NotNull Iterable } @NotNull - private static Object2IntMap createItemStackMap(boolean linked) { + public static Object2IntMap createItemStackMap(boolean linked) { ItemStackHashStrategy strategy = ItemStackHashStrategy.comparingAllButCount(); return linked ? new Object2IntLinkedOpenCustomHashMap<>(strategy) : new Object2IntOpenCustomHashMap<>(strategy); } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java index 5d5fbf9500..be87a3a2e9 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java @@ -1,8 +1,13 @@ package com.gregtechceu.gtceu.utils; import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.world.item.ItemStack; import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.util.Collections; +import java.util.List; import javax.annotation.ParametersAreNonnullByDefault; @@ -18,6 +23,16 @@ public static int clamp(int value, int min, int max) { return Math.max(min, Math.min(max, value)); } + public static List splitStacks(ItemStack stack, long amount) { + int count = saturatedCast(amount); + int fullStacks = count / 64; + int rem = count % 64; + List stacks = new ObjectArrayList<>(fullStacks + 1); + if (fullStacks > 0) stacks.addAll(Collections.nCopies(fullStacks, stack.copyWithCount(64))); + if (rem > 0) stacks.add(stack.copyWithCount(rem)); + return stacks; + } + public static int[] split(long value) { IntArrayList result = new IntArrayList(); while (value > 0) { From 888838f672bc5db2fd8c1a38c756c6dc744d6d23 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Fri, 31 Jan 2025 23:04:57 -0500 Subject: [PATCH 24/29] Fix custom recipe logics --- .../resources/assets/gtceu/lang/en_ud.json | 1 + .../resources/assets/gtceu/lang/en_us.json | 1 + .../recipe/IRecipeCapabilityHolder.java | 4 + .../part/MultiblockPartMachine.java | 3 +- .../trait/customlogic/ArcFurnaceLogic.java | 42 ++++---- .../trait/customlogic/BreweryLogic.java | 1 + .../trait/customlogic/CannerLogic.java | 92 ++++++++---------- .../trait/customlogic/FormingPressLogic.java | 97 +++++++++++++------ .../trait/customlogic/MaceratorLogic.java | 38 ++++---- 9 files changed, 158 insertions(+), 121 deletions(-) diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index d9db0631c7..c58133fc6d 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -1797,6 +1797,7 @@ "config.gtceu.option.machines": "sǝuıɥɔɐɯ", "config.gtceu.option.machinesEmissiveTextures": "sǝɹnʇxǝ⟘ǝʌıssıɯƎsǝuıɥɔɐɯ", "config.gtceu.option.meHatchEnergyUsage": "ǝbɐs∩ʎbɹǝuƎɥɔʇɐHǝɯ", + "config.gtceu.option.minerSpeed": "pǝǝdSɹǝuıɯ", "config.gtceu.option.minimap": "dɐɯıuıɯ", "config.gtceu.option.nanoSaber": "ɹǝqɐSouɐu", "config.gtceu.option.nanoSaberBaseDamage": "ǝbɐɯɐᗡǝsɐᗺɹǝqɐSouɐu", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 6421ca7315..b5b555241c 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -1797,6 +1797,7 @@ "config.gtceu.option.machines": "machines", "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", "config.gtceu.option.meHatchEnergyUsage": "meHatchEnergyUsage", + "config.gtceu.option.minerSpeed": "minerSpeed", "config.gtceu.option.minimap": "minimap", "config.gtceu.option.nanoSaber": "nanoSaber", "config.gtceu.option.nanoSaberBaseDamage": "nanoSaberBaseDamage", diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 7725988740..23f2ccd7b5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -21,6 +21,10 @@ default boolean hasCapabilityProxies() { Map, List>>> getCapabilitiesFlat(); + default List getCapabilitiesForIO(IO io) { + return getCapabilitiesProxy().getOrDefault(io, Collections.emptyList()); + } + default List> getCapabilitiesFlat(IO io, RecipeCapability cap) { return getCapabilitiesFlat() .getOrDefault(io, Collections.emptyMap()) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index 0f65eabfb6..ac94bb282e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -19,6 +19,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; import java.util.Collections; @@ -46,7 +47,7 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { protected final Set controllerPositions = new ObjectOpenHashSet<>(8); protected final SortedSet controllers = new ReferenceLinkedOpenHashSet<>(8); - protected RecipeHandlerList handlerList; + protected @Nullable RecipeHandlerList handlerList; public MultiblockPartMachine(IMachineBlockEntity holder) { super(holder); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java index 96fb740b7c..6fca64c035 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/ArcFurnaceLogic.java @@ -17,31 +17,36 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.wrapper.CombinedInvWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.ingot; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.nugget; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.turbineBlade; +import static com.gregtechceu.gtceu.common.data.GTRecipeCategories.ARC_FURNACE_RECYCLING; import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.ARC_FURNACE_RECIPES; public class ArcFurnaceLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var inputHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP) - .stream() - .filter(IItemHandlerModifiable.class::isInstance) - .map(IItemHandlerModifiable.class::cast) - .toArray(IItemHandlerModifiable[]::new); - - var inputs = new CombinedInvWrapper(inputHandlers); - var stack = inputs.getStackInSlot(0); + var recipeHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP); + for (var handler : recipeHandlers) { + for (var content : handler.getContents()) { + if (!(content instanceof ItemStack stack)) continue; + if (stack.isEmpty()) continue; + var recipe = search(stack); + if (recipe != null) return recipe; + } + } + return null; + } + private @Nullable GTRecipe search(ItemStack stack) { var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); if (turbineBehaviour != null) { - float durability = 1.f - (float) turbineBehaviour.getPartDamage(stack) / + float durability = 1f - (float) turbineBehaviour.getPartDamage(stack) / (float) turbineBehaviour.getPartMaxDurability(stack); return applyDurabilityRecipe("rotor_decomp", stack, turbineBehaviour.getPartMaterial(stack), (float) (turbineBlade.materialAmount() * 8) / GTValues.M, durability, GTValues.VH[GTValues.EV], 1); @@ -61,8 +66,7 @@ public class ArcFurnaceLogic implements GTRecipeType.ICustomRecipeLogic { public @Nullable GTRecipe applyDurabilityRecipe(String id, ItemStack inputStack, @NotNull Material mat, float fullAmount, float durability, long voltage, int durationFactor) { - if (!mat.hasProperty(PropertyKey.INGOT)) - return null; + if (!mat.hasProperty(PropertyKey.INGOT)) return null; var material = mat.getProperty(PropertyKey.INGOT); var materialArc = material.getArcSmeltingInto(); @@ -71,8 +75,7 @@ public class ArcFurnaceLogic implements GTRecipeType.ICustomRecipeLogic { int dustAmount = (int) outputAmount; int leftover = (int) ((outputAmount - (float) dustAmount) * 9.f); - if (dustAmount == 0 && leftover == 0) - return null; + if (dustAmount == 0 && leftover == 0) return null; var builder = ARC_FURNACE_RECIPES.recipeBuilder(id + "/" + mat.getName()) .inputItems(inputStack) @@ -90,6 +93,7 @@ public class ArcFurnaceLogic implements GTRecipeType.ICustomRecipeLogic { return builder.buildRawRecipe(); } + @SuppressWarnings("ConstantConditions") @Override public void buildRepresentativeRecipes() { ItemStack stack = GTItems.TURBINE_ROTOR.asStack(); @@ -97,7 +101,6 @@ public void buildRepresentativeRecipes() { GTRecipe rotorRecipe; GTRecipe pickaxeRecipe; float durability = 0.69f; - // noinspection ConstantConditions TurbineRotorBehaviour.getBehaviour(stack).setPartMaterial(stack, GTMaterials.Iron); TurbineRotorBehaviour.getBehaviour(stack).setPartDamage(stack, 8928); var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); @@ -114,8 +117,7 @@ public void buildRepresentativeRecipes() { GTValues.VH[GTValues.LV], 2); pickaxeRecipe.setId(pickaxeRecipe.getId().withPrefix("/")); - ARC_FURNACE_RECIPES.addToMainCategory(pickaxeRecipe); - ARC_FURNACE_RECIPES.addToMainCategory(rotorRecipe); - GTRecipeType.ICustomRecipeLogic.super.buildRepresentativeRecipes(); + ARC_FURNACE_RECYCLING.addRecipe(pickaxeRecipe); + ARC_FURNACE_RECYCLING.addRecipe(rotorRecipe); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java index 38f6717c5d..cd289fa778 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/BreweryLogic.java @@ -38,6 +38,7 @@ public class BreweryLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { + // TODO: Make this use generic IRecipeHandlers and not Item/FluidHandlers - i.e. pattern buffer var itemInputs = Objects .requireNonNullElseGet(holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP), ArrayList::new) diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java index e07a13d926..1768468f95 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/CannerLogic.java @@ -10,69 +10,57 @@ import com.gregtechceu.gtceu.utils.GTStringUtils; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandlerItem; -import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.wrapper.CombinedInvWrapper; +import net.minecraftforge.fluids.FluidUtil; import org.jetbrains.annotations.Nullable; +import static net.minecraftforge.fluids.capability.IFluidHandler.*; + public class CannerLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var itemInputs = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() - .filter(IItemHandlerModifiable.class::isInstance) - .map(IItemHandlerModifiable.class::cast) - .toArray(IItemHandlerModifiable[]::new); - - var fluidInputs = holder.getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() - .filter(IFluidHandler.class::isInstance).map(IFluidHandler.class::cast) - .toArray(IFluidHandler[]::new); - - var inputs = new CombinedInvWrapper(itemInputs); - for (int i = 0; i < inputs.getSlots(); i++) { - ItemStack item = inputs.getStackInSlot(i); - if (!item.isEmpty()) { - ItemStack inputStack = item.copy(); - inputStack.setCount(1); - - ItemStack fluidHandlerStack = inputStack.copy(); - IFluidHandlerItem fluidHandlerItem = fluidHandlerStack - .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).resolve().orElse(null); - if (fluidHandlerItem == null) - continue; - - FluidStack fluid = fluidHandlerItem.drain(Integer.MAX_VALUE, IFluidHandler.FluidAction.EXECUTE); + // TODO: Make this respect distinctness while searching + var itemInputs = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP); + var fluidInputs = holder.getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP); + for (var itemInput : itemInputs) { + for (var obj : itemInput.getContents()) { + if (!(obj instanceof ItemStack stack)) continue; + if (stack.isEmpty()) continue; + var singleStack = stack.copyWithCount(1); + var copy = stack.copyWithCount(1); + var fluidHandler = FluidUtil.getFluidHandler(copy).resolve().orElse(null); + if (fluidHandler == null) continue; + // Try to drain first + var fluid = fluidHandler.drain(Integer.MAX_VALUE, FluidAction.EXECUTE); if (!fluid.isEmpty()) { - return GTRecipeTypes.CANNER_RECIPES.recipeBuilder(GTStringUtils.itemStackToString(item)) - .inputItems(inputStack) - .outputItems(fluidHandlerItem.getContainer()) - .outputFluids(new FluidStack(fluid.getFluid(), - fluid.getAmount(), fluid.getTag())) - .duration(Math.max(16, fluid.getAmount() / 64)).EUt(4) + return GTRecipeTypes.CANNER_RECIPES + .recipeBuilder("drain_" + GTStringUtils.itemStackToString(singleStack)) + .inputItems(singleStack) + .outputItems(fluidHandler.getContainer()) + .outputFluids(fluid) + .duration(Math.max(16, fluid.getAmount() / 64)) + .EUt(4) .buildRawRecipe(); } - - // nothing drained so try filling - for (IFluidHandler fluidInput : fluidInputs) { - var fluidStack1 = fluidInput.getFluidInTank(0); - if (fluidStack1.isEmpty()) { - continue; - } - fluidStack1 = fluidStack1.copy(); - fluidStack1.setAmount( - fluidHandlerItem.fill(new FluidStack(fluidStack1.getFluid(), fluidStack1.getAmount()), - IFluidHandler.FluidAction.EXECUTE)); - if (fluidStack1.getAmount() > 0) { - return GTRecipeTypes.CANNER_RECIPES.recipeBuilder(GTStringUtils.itemStackToString(item)) - .inputItems(inputStack) - .inputFluids(fluidStack1) - .outputItems(fluidHandlerItem.getContainer()) - .duration(Math.max(16, fluid.getAmount() / 64)).EUt(4) - .buildRawRecipe(); + // Nothing to drain, so try to fill + for (var fluidInput : fluidInputs) { + for (var obj2 : fluidInput.getContents()) { + if (!(obj2 instanceof FluidStack fluidStack)) continue; + if (fluidStack.isEmpty()) continue; + var filled = fluidHandler.fill(fluidStack, FluidAction.EXECUTE); + if (filled > 0) { + var copyFluid = new FluidStack(fluidStack, filled); + return GTRecipeTypes.CANNER_RECIPES + .recipeBuilder("fill_" + GTStringUtils.itemStackToString(singleStack)) + .inputItems(singleStack) + .inputFluids(copyFluid) + .outputItems(fluidHandler.getContainer()) + .duration(Math.max(16, filled / 64)) + .EUt(4) + .buildRawRecipe(); + } } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java index daa584364d..aa4b15c207 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/FormingPressLogic.java @@ -2,16 +2,15 @@ import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; +import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; -import com.gregtechceu.gtceu.api.machine.trait.NotifiableRecipeHandlerTrait; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.GTRecipe; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.common.data.GTItems; import com.gregtechceu.gtceu.common.data.GTRecipeTypes; import com.gregtechceu.gtceu.utils.GTStringUtils; -import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -19,62 +18,98 @@ import org.jetbrains.annotations.Nullable; import java.util.Collections; +import java.util.List; import java.util.stream.Collectors; public class FormingPressLogic implements GTRecipeType.ICustomRecipeLogic { + // Data class so that item data can be kept between searches + private static class RecipeData { + + public ItemStack mold = ItemStack.EMPTY; + public ItemStack item = ItemStack.EMPTY; + + public boolean found() { + return !mold.isEmpty() && !item.isEmpty(); + } + + public void clear() { + mold = ItemStack.EMPTY; + item = ItemStack.EMPTY; + } + + public boolean isEmpty() { + return mold.isEmpty() && item.isEmpty(); + } + } + @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var handlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() - .filter(NotifiableItemStackHandler.class::isInstance) - .map(NotifiableItemStackHandler.class::cast) - .filter(i -> i.getSlots() > 1) - .collect(Collectors.groupingBy(NotifiableRecipeHandlerTrait::isDistinct)); + var handlerLists = holder.getCapabilitiesForIO(IO.IN).stream() + .filter(rhl -> rhl.hasCapability(ItemRecipeCapability.CAP)) + .collect(Collectors.groupingBy(RecipeHandlerList::isDistinct)); + + if (handlerLists.isEmpty()) return null; - if (handlers.isEmpty()) return null; + RecipeData data = new RecipeData(); // Distinct first, reset our stacks for every inventory - for (var handler : handlers.getOrDefault(true, Collections.emptyList())) { - ItemStack mold = ItemStack.EMPTY; - ItemStack item = ItemStack.EMPTY; - GTRecipe recipe = findRecipe(mold, item, handler); + for (var handlerList : handlerLists.getOrDefault(true, Collections.emptyList())) { + data.clear(); + GTRecipe recipe = search(data, handlerList.getCapability(ItemRecipeCapability.CAP)); if (recipe != null) return recipe; } + data.clear(); // Non-distinct, return as soon as we find valid items - ItemStack mold = ItemStack.EMPTY; - ItemStack item = ItemStack.EMPTY; - for (var handler : handlers.getOrDefault(false, Collections.emptyList())) { - GTRecipe recipe = findRecipe(mold, item, handler); + for (var handlerList : handlerLists.getOrDefault(false, Collections.emptyList())) { + GTRecipe recipe = search(data, handlerList.getCapability(ItemRecipeCapability.CAP)); + if (recipe != null) return recipe; + } + + if (data.isEmpty()) return null; + + // If we found one of the two, search for the other in the distinct handlers. + ItemStack existingMold = data.mold; + ItemStack existingItem = data.item; + for (var handlerList : handlerLists.getOrDefault(true, Collections.emptyList())) { + data.mold = existingMold; + data.item = existingItem; + GTRecipe recipe = search(data, handlerList.getCapability(ItemRecipeCapability.CAP)); if (recipe != null) return recipe; } return null; } - private @Nullable GTRecipe findRecipe(ItemStack mold, ItemStack item, NotifiableItemStackHandler handler) { - for (int i = 0; i < handler.getSlots(); ++i) { - if (!mold.isEmpty() && !item.isEmpty()) break; - var input = handler.getStackInSlot(i); - if (mold.isEmpty() && input.is(GTItems.SHAPE_MOLD_NAME.asItem())) { - if (input.hasTag() && input.getTag().contains(ItemStack.TAG_DISPLAY, Tag.TAG_COMPOUND)) { - mold = input; + private @Nullable GTRecipe search(final RecipeData data, List> recipeHandlers) { + for (var rh : recipeHandlers) { + for (var obj : rh.getContents()) { + if (!(obj instanceof ItemStack stack)) continue; + if (stack.isEmpty()) continue; + // Skip programmed circuits to avoid using circuit inventory - TODO: Think of better way to skip it + if (GTItems.PROGRAMMED_CIRCUIT.isIn(stack)) continue; + if (data.mold.isEmpty() && GTItems.SHAPE_MOLD_NAME.isIn(stack) && stack.hasCustomHoverName()) { + data.mold = stack; + } else if (data.item.isEmpty()) { + data.item = stack; } - } else if (item.isEmpty()) { - item = input; + if (data.found()) break; } + if (data.found()) break; } - if (!mold.isEmpty() && !item.isEmpty()) { - ItemStack output = item.copyWithCount(1); - output.setHoverName(mold.getHoverName()); + if (data.found()) { + ItemStack output = data.item.copyWithCount(1); + output.setHoverName(data.mold.getHoverName()); return GTRecipeTypes.FORMING_PRESS_RECIPES.recipeBuilder(GTStringUtils.itemStackToString(output)) - .notConsumable(mold) - .inputItems(item.copyWithCount(1)) + .notConsumable(data.mold) + .inputItems(data.item.copyWithCount(1)) .outputItems(output) .duration(40).EUt(4) .buildRawRecipe(); } + return null; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java index 3081f012b2..7ca5ced52f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java @@ -17,28 +17,34 @@ import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.wrapper.CombinedInvWrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.*; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.dust; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.dustSmall; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.dustTiny; +import static com.gregtechceu.gtceu.api.data.tag.TagPrefix.turbineBlade; +import static com.gregtechceu.gtceu.common.data.GTRecipeCategories.MACERATOR_RECYCLING; import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.MACERATOR_RECIPES; public class MaceratorLogic implements GTRecipeType.ICustomRecipeLogic { @Override public @Nullable GTRecipe createCustomRecipe(IRecipeCapabilityHolder holder) { - var inputHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP) - .stream() - .filter(IItemHandlerModifiable.class::isInstance) - .map(IItemHandlerModifiable.class::cast) - .toArray(IItemHandlerModifiable[]::new); - - var inputs = new CombinedInvWrapper(inputHandlers); - var stack = inputs.getStackInSlot(0); + var recipeHandlers = holder.getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP); + for (var handler : recipeHandlers) { + for (var content : handler.getContents()) { + if (!(content instanceof ItemStack stack)) continue; + if (stack.isEmpty()) continue; + var recipe = search(stack); + if (recipe != null) return recipe; + } + } + return null; + } + private @Nullable GTRecipe search(ItemStack stack) { var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); if (turbineBehaviour != null) { float durability = 1.f - (float) turbineBehaviour.getPartDamage(stack) / @@ -67,8 +73,7 @@ public class MaceratorLogic implements GTRecipeType.ICustomRecipeLogic { TagPrefix tag = leftover % 4 >= leftover % 9 ? dustSmall : dustTiny; int leftAmount = leftover % 4 >= leftover % 9 ? leftover / 9 : leftover / 4; - if (dustAmount == 0 && leftAmount == 0) - return null; + if (dustAmount == 0 && leftAmount == 0) return null; var builder = MACERATOR_RECIPES.recipeBuilder(id + "/" + mat.getName()) .inputItems(inputStack) @@ -85,6 +90,7 @@ public class MaceratorLogic implements GTRecipeType.ICustomRecipeLogic { return builder.buildRawRecipe(); } + @SuppressWarnings("ConstantConditions") @Override public void buildRepresentativeRecipes() { ItemStack stack = GTItems.TURBINE_ROTOR.asStack(); @@ -92,7 +98,6 @@ public void buildRepresentativeRecipes() { GTRecipe rotorRecipe; GTRecipe pickaxeRecipe; float durability = 0.75f; - // noinspection ConstantConditions TurbineRotorBehaviour.getBehaviour(stack).setPartMaterial(stack, GTMaterials.Iron); TurbineRotorBehaviour.getBehaviour(stack).setPartDamage(stack, 8928); var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); @@ -109,8 +114,7 @@ public void buildRepresentativeRecipes() { GTValues.VH[GTValues.LV], 2); pickaxeRecipe.setId(pickaxeRecipe.getId().withPrefix("/")); - MACERATOR_RECIPES.addToMainCategory(pickaxeRecipe); - MACERATOR_RECIPES.addToMainCategory(rotorRecipe); - GTRecipeType.ICustomRecipeLogic.super.buildRepresentativeRecipes(); + MACERATOR_RECYCLING.addRecipe(pickaxeRecipe); + MACERATOR_RECYCLING.addRecipe(rotorRecipe); } } From 2bf2ee1406a6cdf32defbfa00fcb77ff2790572b Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Sat, 1 Feb 2025 19:37:21 -0500 Subject: [PATCH 25/29] More work --- gradle/scripts/moddevgradle.gradle | 2 + .../gtceu/api/item/tool/ToolHelper.java | 2 +- .../api/machine/trait/RecipeHandlerList.java | 11 ++-- .../gtceu/api/machine/trait/RecipeLogic.java | 4 +- .../gtceu/api/recipe/RecipeHelper.java | 40 +++++------- .../gtceu/api/recipe/RecipeRunner.java | 63 ++++++++----------- .../gtceu/common/commands/GTCommands.java | 15 ++--- .../electric/DistillationTowerMachine.java | 6 +- .../research/ResearchStationMachine.java | 4 +- .../LargeCombustionEngineMachine.java | 4 +- .../machine/trait/BedrockOreMinerLogic.java | 2 +- .../common/machine/trait/FluidDrillLogic.java | 2 +- .../machine/trait/miner/MinerLogic.java | 2 +- 13 files changed, 68 insertions(+), 89 deletions(-) diff --git a/gradle/scripts/moddevgradle.gradle b/gradle/scripts/moddevgradle.gradle index e2de760e7d..3fc42d61f2 100644 --- a/gradle/scripts/moddevgradle.gradle +++ b/gradle/scripts/moddevgradle.gradle @@ -98,6 +98,8 @@ legacyForge { // "REGISTRIES": For firing of registry events. // "REGISTRYDUMP": For getting the contents of all registries. systemProperty 'forge.logging.markers', 'REGISTRIES' + // Enable assertions for our classes in dev environment + jvmArgument('-ea:com.gregtechceu.gtceu') // Recommended logging level for the console // You can set various levels here. diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index 6953cf72bc..eb7333b9b1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -429,7 +429,7 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It Iterator hammerRecipes = GTRecipeTypes.FORGE_HAMMER_RECIPES.searchRecipe(be.metaMachine, r -> RecipeHelper.matchContents(be.metaMachine, r).isSuccess()); GTRecipe hammerRecipe = hammerRecipes == null || !hammerRecipes.hasNext() ? null : hammerRecipes.next(); - if (hammerRecipe != null && RecipeHelper.handleRecipeIO(IO.IN, be.metaMachine, hammerRecipe, + if (hammerRecipe != null && RecipeHelper.handleRecipeIO(be.metaMachine, hammerRecipe, IO.IN, be.getMetaMachine().recipeLogic.getChanceCaches()).isSuccess()) { drops.clear(); TagPrefix prefix = ChemicalHelper.getPrefix(silktouchDrop.getItem()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index d20ce5f68c..61326c82d4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -49,10 +49,6 @@ public static RecipeHandlerList of(IO io, IRecipeHandler handler) { return rhl; } - public List> getCapability(RecipeCapability cap) { - return getHandlerMap().getOrDefault(cap, Collections.emptyList()); - } - public void addHandler(IRecipeHandler handler) { addHandlers(List.of(handler)); } @@ -79,6 +75,10 @@ public boolean hasCapability(RecipeCapability cap) { return getHandlerMap().containsKey(cap); } + public List> getCapability(RecipeCapability cap) { + return getHandlerMap().getOrDefault(cap, Collections.emptyList()); + } + public IO getHandlerIO() { return io; } @@ -113,8 +113,7 @@ public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, Object2IntMap> chanceCaches) { if (!holder.hasCapabilityProxies() || io == IO.BOTH) return ActionResult.FAIL_NO_CAPABILITIES; - return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, + return handleRecipe(holder, recipe, io, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, false); } - public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + public static ActionResult handleTickRecipeIO(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io, Map, Object2IntMap> chanceCaches) { if (!holder.hasCapabilityProxies() || io == IO.BOTH) return ActionResult.FAIL_NO_CAPABILITIES; - return handleRecipe(io, holder, recipe, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, + return handleRecipe(holder, recipe, io, io == IO.IN ? recipe.tickInputs : recipe.tickOutputs, chanceCaches, true, false); } @@ -223,13 +223,14 @@ public static ActionResult handleTickRecipeIO(IO io, IRecipeCapabilityHolder hol * @param simulated checks that the recipe ingredients are in the holder if true, * process the recipe contents if false */ - public static ActionResult handleRecipe(IO io, IRecipeCapabilityHolder holder, GTRecipe recipe, + public static ActionResult handleRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, IO io, Map, List> contents, Map, Object2IntMap> chanceCaches, boolean isTick, boolean simulated) { RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); var handle = runner.handle(contents); + // TODO: make this actually log error on failed non-simulate if (handle == null || handle.content() != null) { String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); return ActionResult.fail(() -> Component.translatable(key) @@ -432,27 +433,18 @@ else if (nonChanced.isEmpty()) { return outputs; } - public static List checkRecipeValidity(GTRecipe recipe) { - List results = new ArrayList<>(); + public static ActionResult checkRecipeValidity(GTRecipe recipe) { var result = checkItemValid(recipe.inputs, "input"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } + if (!result.isSuccess()) return result; + result = checkItemValid(recipe.outputs, "output"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } + if (!result.isSuccess()) return result; + result = checkItemValid(recipe.tickInputs, "tickInput"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } + if (!result.isSuccess()) return result; + result = checkItemValid(recipe.outputs, "tickOutput"); - if (result != ActionResult.SUCCESS) { - results.add(result); - } - if (!results.isEmpty()) - return results; - return List.of(ActionResult.SUCCESS); + return result; } private static ActionResult checkItemValid(Map, List> contents, String name) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index ec9b09e89f..9cca49535b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -22,7 +22,10 @@ class RecipeRunner { record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, - ActionResult result) {} + ActionResult result) { + + public static RecipeHandlingResult SUCCESS = new RecipeHandlingResult(null, null, ActionResult.SUCCESS); + } private final GTRecipe recipe; private final IO io; @@ -31,7 +34,7 @@ record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNu private final Map> capabilityProxies; private final boolean simulated; private Map, List> recipeContents; - private Map, List> searchRecipeContents; + private final Map, List> searchRecipeContents; public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -61,6 +64,8 @@ public RecipeHandlingResult handle(Map, List> entri */ private void fillContentMatchList(Map, List> entries) { ChanceBoostFunction function = recipe.getType().getChanceFunction(); + int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); + int chanceTier = recipeTier + recipe.ocLevel; for (var entry : entries.entrySet()) { RecipeCapability cap = entry.getKey(); if (!cap.doMatchInRecipe()) { @@ -71,15 +76,16 @@ private void fillContentMatchList(Map, List> entrie // skip if empty if (entry.getValue().isEmpty()) continue; // populate recipe content capability map - this.recipeContents.putIfAbsent(cap, new ArrayList<>()); + var contentList = this.recipeContents.computeIfAbsent(cap, c -> new ArrayList<>()); + var searchContentList = this.searchRecipeContents.computeIfAbsent(cap, c -> new ArrayList<>()); for (Content cont : entry.getValue()) { - this.searchRecipeContents.computeIfAbsent(cap, c -> new ArrayList<>()).add(cont.content); + searchContentList.add(cont.content); // When simulating the recipe handling (used for recipe matching), chanced contents are ignored. if (simulated) continue; if (cont.chance >= cont.maxChance) { - this.recipeContents.get(cap).add(cont.content); + contentList.add(cont.content); } else { chancedContents.add(cont); } @@ -87,24 +93,22 @@ private void fillContentMatchList(Map, List> entrie // add chanced contents to the recipe content map if (!chancedContents.isEmpty()) { - int recipeTier = RecipeHelper.getPreOCRecipeEuTier(recipe); - int chanceTier = recipeTier + recipe.ocLevel; var cache = this.chanceCaches.get(cap); chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, recipe.parallels); for (Content cont : chancedContents) { - this.recipeContents.get(cap).add(cont.content); + contentList.add(cont.content); } } - if (recipeContents.get(cap).isEmpty()) recipeContents.remove(cap); + if (contentList.isEmpty()) recipeContents.remove(cap); } } private RecipeHandlingResult handleContents() { if (recipeContents.isEmpty()) { - return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); + return RecipeHandlingResult.SUCCESS; } var result = handleContentsInternal(io); if (!result.result.isSuccess()) { @@ -114,8 +118,9 @@ private RecipeHandlingResult handleContents() { } private RecipeHandlingResult handleContentsInternal(IO capIO) { - if (!capabilityProxies.containsKey(capIO)) - return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); + if (!capabilityProxies.containsKey(capIO)) { + return new RecipeHandlingResult(null, null, ActionResult.FAIL_NO_REASON); + } var handlers = capabilityProxies.get(capIO); // Only sort for non-tick outputs @@ -130,46 +135,30 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { } // handle distinct first - boolean handled = false; for (var handler : distinct) { var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); if (res.isEmpty()) { if (!simulated) { handler.handleRecipe(io, recipe, recipeContents, false); } - handled = true; - break; + return RecipeHandlingResult.SUCCESS; } } - if (!handled) { - for (var handler : indistinct) { - if (!recipeContents.isEmpty()) { - recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); - } - if (recipeContents.isEmpty()) { - handled = true; - break; - } + for (var handler : indistinct) { + recipeContents = handler.handleRecipe(io, recipe, recipeContents, simulated); + if (recipeContents.isEmpty()) { + return RecipeHandlingResult.SUCCESS; } } - if (!handled) { - for (var handler : distinct) { - if (!recipeContents.isEmpty()) { - var res = handler.handleRecipe(io, recipe, recipeContents, simulated); - if (res.isEmpty()) { - handled = true; - break; - } - } + for (var handler : distinct) { + var res = handler.handleRecipe(io, recipe, recipeContents, simulated); + if (res.isEmpty()) { + return RecipeHandlingResult.SUCCESS; } } - if (handled) { - return new RecipeHandlingResult(null, null, ActionResult.SUCCESS); - } - for (var entry : recipeContents.entrySet()) { if (entry.getValue() != null && !entry.getValue().isEmpty()) { return new RecipeHandlingResult(entry.getKey(), entry.getValue(), diff --git a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java index b4b656f0de..f095aa4e24 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java +++ b/src/main/java/com/gregtechceu/gtceu/common/commands/GTCommands.java @@ -64,15 +64,12 @@ public static void register(CommandDispatcher dispatcher, Co .executes(context -> { for (Recipe recipe : context.getSource().getServer().getRecipeManager() .getRecipes()) { - if (recipe instanceof GTRecipe gtRecipe) { - var recipeValid = RecipeHelper.checkRecipeValidity(gtRecipe).stream() - .filter(v -> !v.isSuccess()).findAny(); - if (recipeValid.isPresent()) { - context.getSource().sendSuccess( - () -> Component - .literal("Recipe %s is invalid".formatted(gtRecipe.id)), - false); - } + if (recipe instanceof GTRecipe gtRecipe && + !RecipeHelper.checkRecipeValidity(gtRecipe).isSuccess()) { + context.getSource().sendSuccess( + () -> Component + .literal("Recipe %s is invalid".formatted(gtRecipe.id)), + false); } } return 1; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index deb4b03ab5..1ac9885b3b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -195,14 +195,14 @@ protected void handleSearchingRecipes(Iterator matches) { } private ActionResult matchDTRecipe(GTRecipe recipe) { - var result = RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, + var result = RecipeHelper.handleRecipe(machine, recipe, IO.IN, recipe.inputs, Collections.emptyMap(), false, false); if (!result.isSuccess()) return result; var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - result = RecipeHelper.handleRecipe(IO.OUT, machine, recipe, out, Collections.emptyMap(), false, true); + result = RecipeHelper.handleRecipe(machine, recipe, IO.OUT, out, Collections.emptyMap(), false, true); if (!result.isSuccess()) return result; } @@ -247,7 +247,7 @@ protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { var items = recipe.getOutputContents(ItemRecipeCapability.CAP); if (!items.isEmpty()) { Map, List> out = Map.of(ItemRecipeCapability.CAP, items); - RecipeHelper.handleRecipe(io, this.machine, recipe, out, chanceCaches, false, false); + RecipeHelper.handleRecipe(this.machine, recipe, io, out, chanceCaches, false, false); } if (applyFluidOutputs(recipe, FluidAction.EXECUTE)) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 7de7ad0840..77b982c322 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -166,14 +166,14 @@ public boolean checkMatchedRecipeAvailable(GTRecipe match) { protected ActionResult matchRecipeNoOutput(GTRecipe recipe) { if (!machine.hasCapabilityProxies()) return ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.inputs, Collections.emptyMap(), false, + return RecipeHelper.handleRecipe(machine, recipe, IO.IN, recipe.inputs, Collections.emptyMap(), false, true); } protected ActionResult matchTickRecipeNoOutput(GTRecipe recipe) { if (recipe.hasTick()) { if (!machine.hasCapabilityProxies()) return ActionResult.FAIL_NO_CAPABILITIES; - return RecipeHelper.handleRecipe(IO.IN, machine, recipe, recipe.tickInputs, Collections.emptyMap(), + return RecipeHelper.handleRecipe(machine, recipe, IO.IN, recipe.tickInputs, Collections.emptyMap(), false, true); } return ActionResult.SUCCESS; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java index 19e7df5e51..4b36a030b2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/generator/LargeCombustionEngineMachine.java @@ -162,7 +162,7 @@ public boolean onWorking() { if (runningTimer % 72 == 0) { // insufficient lubricant - if (RecipeHelper.handleRecipeIO(IO.IN, this, getLubricantRecipe(), this.recipeLogic.getChanceCaches()) + if (RecipeHelper.handleRecipeIO(this, getLubricantRecipe(), IO.IN, this.recipeLogic.getChanceCaches()) .isSuccess()) { recipeLogic.interruptRecipe(); return false; @@ -172,7 +172,7 @@ public boolean onWorking() { if (isBoostAllowed()) { var boosterRecipe = getBoostRecipe(); this.isOxygenBoosted = RecipeHelper.matchRecipe(this, boosterRecipe).isSuccess() && - RecipeHelper.handleRecipeIO(IO.IN, this, boosterRecipe, this.recipeLogic.getChanceCaches()) + RecipeHelper.handleRecipeIO(this, boosterRecipe, IO.IN, this.recipeLogic.getChanceCaches()) .isSuccess(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java index 3979349702..bf4c4e9098 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/BedrockOreMinerLogic.java @@ -146,7 +146,7 @@ public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { RecipeHelper.postWorking(this.machine, lastRecipe); - RecipeHelper.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); + RecipeHelper.handleRecipeIO(this.machine, lastRecipe, IO.OUT, this.chanceCaches); } depleteVein(); // try it again diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java index a04f6135e8..bb3a7fd07a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/FluidDrillLogic.java @@ -114,7 +114,7 @@ public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { RecipeHelper.postWorking(this.machine, lastRecipe); - RecipeHelper.handleRecipeIO(IO.OUT, this.machine, lastRecipe, this.chanceCaches); + RecipeHelper.handleRecipeIO(this.machine, lastRecipe, IO.OUT, this.chanceCaches); } depleteVein(); // try it again diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index eff5bbe4ab..1842e69ec6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -363,7 +363,7 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState var eut = RecipeHelper.getInputEUt(match); if (GTUtil.getTierByVoltage(eut) <= getVoltageTier()) { - if (RecipeHelper.handleRecipeIO(IO.OUT, this, match, this.chanceCaches).isSuccess()) { + if (RecipeHelper.handleRecipeIO(this, match, IO.OUT, this.chanceCaches).isSuccess()) { blockDrops.clear(); var result = new ArrayList(); for (int i = 0; i < outputItemHandler.storage.getSlots(); ++i) { From fbf24e3a6dd9e325f1f17a124935176bb0763f05 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Sun, 2 Feb 2025 03:06:31 -0500 Subject: [PATCH 26/29] Further work --- .../capability/recipe/RecipeCapability.java | 9 ++++ .../gtceu/api/item/tool/ToolHelper.java | 4 +- .../multiblock/WorkableMultiblockMachine.java | 4 +- .../api/machine/trait/RecipeHandlerList.java | 15 +++++++ .../gtceu/api/machine/trait/RecipeLogic.java | 31 ++++++------- .../gtceu/api/recipe/RecipeRunner.java | 4 +- .../api/recipe/lookup/GTRecipeLookup.java | 32 +++++-------- .../electric/ActiveTransformerMachine.java | 10 ++--- .../electric/AssemblyLineMachine.java | 20 +++++---- .../multiblock/electric/CleanroomMachine.java | 9 ++-- .../electric/FusionReactorMachine.java | 11 ++--- .../electric/LargeMinerMachine.java | 14 +++--- .../electric/PowerSubstationMachine.java | 10 ++--- .../electric/research/DataBankMachine.java | 9 ++-- .../electric/research/HPCAMachine.java | 13 +++--- .../research/NetworkSwitchMachine.java | 45 ++++++++----------- .../research/ResearchStationMachine.java | 1 + .../steam/SteamParallelMultiblockMachine.java | 7 --- .../machine/MEPatternBufferPartMachine.java | 6 ++- .../MEPatternBufferProxyPartMachine.java | 2 +- .../gregtechceu/gtceu/test/GTGameTests.java | 1 - .../gtceu/utils/DummyMachineBlockEntity.java | 8 ++-- .../gtceu/utils/DummyRecipeLogicMachine.java | 14 +----- 23 files changed, 136 insertions(+), 143 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java index 7fddd937bf..9ab639d031 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java @@ -21,6 +21,7 @@ import io.netty.buffer.Unpooled; import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import org.apache.commons.lang3.mutable.MutableInt; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -120,6 +121,14 @@ public List compressIngredients(Collection ingredients) { return new ArrayList<>(ingredients); } + public List> convertCompressedIngredients(List ingredients) { + List> ret = new ObjectArrayList<>(ingredients.size()); + for (var ingredient : ingredients) { + ret.add(convertToMapIngredient(ingredient)); + } + return ret; + } + /** * Does the recipe test if this capability is workable? if not, you should test validity somewhere else. */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index eb7333b9b1..b3032c2ff5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -412,9 +412,9 @@ public static void applyHammerDropConversion(ServerLevel world, BlockPos pos, It // Stack lists can be immutable going into Recipe#matches barring no rewrites // Search for forge hammer recipes from all drops individually (only LV or under) - Map> caps = new IdentityHashMap<>(); DummyMachineBlockEntity be = new DummyMachineBlockEntity(GTValues.LV, - GTRecipeTypes.FORGE_HAMMER_RECIPES, GTMachineUtils.defaultTankSizeFunction, caps); + GTRecipeTypes.FORGE_HAMMER_RECIPES, GTMachineUtils.defaultTankSizeFunction, + Collections.emptyList()); RecipeHandlerList dummyInputs = new RecipeHandlerList(IO.IN); dummyInputs.addHandlers( new InfiniteEnergyContainer(be.getMetaMachine(), GTValues.V[GTValues.LV], diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index f8bc9c721a..a1faf3d72a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -127,9 +127,7 @@ public void onStructureFormed() { var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; - + if (!handlerList.isValid(io)) continue; this.addHandlerList(handlerList); traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index 61326c82d4..c392517d89 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -79,6 +79,11 @@ public List> getCapability(RecipeCapability cap) { return getHandlerMap().getOrDefault(cap, Collections.emptyList()); } + public boolean isValid(IO extIO) { + if (this == NO_DATA) return false; + return (extIO == IO.BOTH || io == IO.BOTH || extIO == io); + } + public IO getHandlerIO() { return io; } @@ -105,6 +110,16 @@ public List addChangeListeners(Runnable listener) { return ret; } + public List addChangeListeners(Runnable listener, RecipeCapability cap) { + List ret = new ArrayList<>(); + for (var handler : getCapability(cap)) { + if (handler instanceof IRecipeHandlerTrait trait) { + ret.add(trait.addChangedListener(listener)); + } + } + return ret; + } + public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { if (getHandlerMap().isEmpty()) return contents; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index e5c7febb3d..ceabcac1ef 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -215,10 +215,10 @@ public void serverTick() { } protected ActionResult matchRecipe(GTRecipe recipe) { - var match = RecipeHelper.matchRecipe(this.machine, recipe); + var match = RecipeHelper.matchRecipe(machine, recipe); if (!match.isSuccess()) return match; - var matchTick = RecipeHelper.matchTickRecipe(this.machine, recipe); + var matchTick = RecipeHelper.matchTickRecipe(machine, recipe); if (!matchTick.isSuccess()) return matchTick; return ActionResult.SUCCESS; @@ -327,16 +327,13 @@ protected void handleSearchingRecipes(Iterator matches) { } public ActionResult handleTickRecipe(GTRecipe recipe) { - if (recipe.hasTick()) { - var result = RecipeHelper.matchTickRecipe(this.machine, recipe); - if (result.isSuccess()) { - handleTickRecipeIO(recipe, IO.IN); - handleTickRecipeIO(recipe, IO.OUT); - } else { - return result; - } + if (!recipe.hasTick()) return ActionResult.SUCCESS; + var result = RecipeHelper.matchTickRecipe(machine, recipe); + if (result.isSuccess()) { + handleTickRecipeIO(recipe, IO.IN); + handleTickRecipeIO(recipe, IO.OUT); } - return ActionResult.SUCCESS; + return result; } public void setupRecipe(GTRecipe recipe) { @@ -348,7 +345,7 @@ public void setupRecipe(GTRecipe recipe) { isActive = false; return; } - RecipeHelper.preWorking(this.machine, recipe); + RecipeHelper.preWorking(machine, recipe); var handledIO = handleRecipeIO(recipe, IO.IN); if (handledIO.isSuccess()) { if (lastRecipe != null && !recipe.equals(lastRecipe)) { @@ -439,7 +436,7 @@ public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { consecutiveRecipes++; - RecipeHelper.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(machine, lastRecipe); handleRecipeIO(lastRecipe, IO.OUT); if (machine.alwaysTryModifyRecipe()) { if (lastOriginRecipe != null) { @@ -472,11 +469,11 @@ public void onRecipeFinish() { } protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { - return RecipeHelper.handleRecipeIO(this.machine, recipe, io, this.chanceCaches); + return RecipeHelper.handleRecipeIO(machine, recipe, io, this.chanceCaches); } protected ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { - return RecipeHelper.handleTickRecipeIO(this.machine, recipe, io, this.chanceCaches); + return RecipeHelper.handleTickRecipeIO(machine, recipe, io, this.chanceCaches); } /** @@ -485,7 +482,7 @@ protected ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { public void interruptRecipe() { machine.afterWorking(); if (lastRecipe != null) { - RecipeHelper.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(machine, lastRecipe); setStatus(Status.IDLE); progress = 0; duration = 0; @@ -494,7 +491,7 @@ public void interruptRecipe() { public void inValid() { if (lastRecipe != null && isWorking()) { - RecipeHelper.postWorking(this.machine, lastRecipe); + RecipeHelper.postWorking(machine, lastRecipe); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 9cca49535b..670ebbfed1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -13,7 +13,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnknownNullability; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * Used to handle recipes, only valid for a single RecipeCapability's entries diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index ccd2b6a5db..5339caa986 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -58,7 +58,7 @@ public GTRecipe findRecipe(final IRecipeCapabilityHolder holder) { protected List> prepareRecipeFind(@NotNull IRecipeCapabilityHolder holder) { // First, check if items and fluids are valid. int totalSize = 0; - List handlers = holder.getCapabilitiesProxy().getOrDefault(IO.IN, new ArrayList<>()); + List handlers = holder.getCapabilitiesForIO(IO.IN); for (var handler : handlers) { for (var entries : handler.getHandlerMap().entrySet()) { @@ -430,26 +430,18 @@ protected List> fromRecipe(@NotNull GTRecipe r) { */ @NotNull protected List> fromHolder(@NotNull IRecipeCapabilityHolder r) { - var handlerLists = r.getCapabilitiesProxy().getOrDefault(IO.IN, Collections.emptyList()); - int size = 0; - for (var handler : handlerLists) { - for (var entry : handler.getHandlerMap().entrySet()) { - size += entry.getValue().size(); - } - } - + var handlerMap = r.getCapabilitiesFlat().getOrDefault(IO.IN, Collections.emptyMap()); + int size = handlerMap.values().size(); List> list = new ObjectArrayList<>(size); - for (var handlerList : handlerLists) { - handlerList.getHandlerMap().forEach((cap, handlers) -> { - if (!cap.isRecipeSearchFilter() || handlers.isEmpty()) return; - for (var handler : handlers) { - if (handler.isProxy()) continue; - List compressed = cap.compressIngredients(handler.getContents()); - for (Object content : compressed) { - list.add(cap.convertToMapIngredient(content)); - } - } - }); + for (var entry : handlerMap.entrySet()) { + var cap = entry.getKey(); + var handlers = entry.getValue(); + if (!cap.isRecipeSearchFilter()) continue; + for (var handler : handlers) { + if (handler.isProxy()) continue; + var compressed = cap.compressIngredients(handler.getContents()); + list.addAll(cap.convertCompressedIngredients(compressed)); + } } return list; } 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 56e26b0af2..3d43527c29 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 @@ -91,12 +91,11 @@ public void onStructureFormed() { if (io == IO.NONE) continue; var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; + if (!handlerList.isValid(io)) continue; var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer) v) + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) .toList(); if (handlerList.getHandlerIO() == IO.IN) { @@ -105,7 +104,8 @@ public void onStructureFormed() { powerOutput.addAll(containers); } - traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription)); + traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription, + EURecipeCapability.CAP)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java index 1e8db776fa..ff327a1693 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java @@ -28,14 +28,16 @@ public AssemblyLineMachine(IMachineBlockEntity holder) { @Override public boolean beforeWorking(@Nullable GTRecipe recipe) { + if (recipe == null) return false; if (ConfigHolder.INSTANCE.machines.orderedAssemblyLineItems) { - - var recipeInputs = recipe.inputs.get(ItemRecipeCapability.CAP); + var recipeInputs = recipe.inputs.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList()); var itemInputInventory = getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).stream() .filter(handler -> !handler.isProxy()) - .map(container -> container.getContents().stream().filter(ItemStack.class::isInstance) - .map(ItemStack.class::cast).toList()) - .filter(container -> !container.isEmpty()) + .map(container -> container.getContents().stream() + .filter(ItemStack.class::isInstance) + .map(ItemStack.class::cast) + .toList()) + .filter(list -> !list.isEmpty()) .toList(); if (itemInputInventory.size() < recipeInputs.size()) return false; @@ -51,9 +53,11 @@ public boolean beforeWorking(@Nullable GTRecipe recipe) { if (ConfigHolder.INSTANCE.machines.orderedAssemblyLineFluids) { recipeInputs = recipe.inputs.get(FluidRecipeCapability.CAP); var itemFluidInventory = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP).stream() - .map(container -> container.getContents().stream().filter(FluidStack.class::isInstance) - .map(FluidStack.class::cast).toList()) - .filter(container -> !container.isEmpty()) + .map(container -> container.getContents().stream() + .filter(FluidStack.class::isInstance) + .map(FluidStack.class::cast) + .toList()) + .filter(list -> !list.isEmpty()) .toList(); if (itemFluidInventory.size() < recipeInputs.size()) return false; 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 bfaf4c37a8..106f7c7482 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 @@ -188,12 +188,11 @@ protected void initializeAbilities() { if (io == IO.NONE || io == IO.OUT) continue; var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; - + if (!handlerList.isValid(io)) continue; handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); } if (part instanceof IMaintenanceMachine maintenanceMachine) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java index 7dbc3fa4fd..3eaf2a1f0f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java @@ -113,13 +113,14 @@ public void onStructureFormed() { if (io == IO.NONE || io == IO.OUT) continue; var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; + if (!handlerList.isValid(io)) continue; handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); - traitSubscriptions.addAll(handlerList.addChangeListeners(this::updatePreHeatSubscription)); + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); + traitSubscriptions.addAll( + handlerList.addChangeListeners(this::updatePreHeatSubscription, EURecipeCapability.CAP)); } } this.inputEnergyContainers = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java index c7d7a8700c..fe5f7f2f1a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/LargeMinerMachine.java @@ -142,15 +142,15 @@ private void initializeAbilities() { var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; - + if (!handlerList.isValid(io)) continue; handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); handlerList.getCapability(FluidRecipeCapability.CAP).stream() - .filter(v -> v instanceof IFluidHandler) - .forEach(v -> fluidTanks.add((IFluidHandler) v)); + .filter(IFluidHandler.class::isInstance) + .map(IFluidHandler.class::cast) + .forEach(fluidTanks::add); } } this.energyContainer = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java index 58c29bdc17..5e887794cb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java @@ -103,12 +103,11 @@ public void onStructureFormed() { } var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; + if (!handlerList.isValid(io)) continue; var containers = handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .map(v -> (IEnergyContainer) v) + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) .toList(); if (handlerList.getHandlerIO() == IO.IN) { @@ -117,7 +116,8 @@ public void onStructureFormed() { outputs.addAll(containers); } - traitSubscriptions.addAll(handlerList.addChangeListeners(tickSubscription::updateSubscription)); + traitSubscriptions.addAll( + handlerList.addChangeListeners(tickSubscription::updateSubscription, EURecipeCapability.CAP)); } } this.inputHatches = new EnergyContainerList(inputs); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java index ab3c3212e2..e98d992d4c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java @@ -69,12 +69,11 @@ public void onStructureFormed() { if (io == IO.NONE || io == IO.OUT) continue; var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; - + if (!handlerList.isValid(io)) continue; handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); } } this.energyContainer = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index 214b3d3613..9d5d9a1c60 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -113,15 +113,16 @@ public void onStructureFormed() { if (io == IO.NONE || io == IO.OUT) continue; var handlerLists = part.getRecipeHandlers(); for (var handlerList : handlerLists) { - if (io != IO.BOTH && handlerList.getHandlerIO() != IO.BOTH && io != handlerList.getHandlerIO()) - continue; + if (!handlerList.isValid(io)) continue; handlerList.getCapability(EURecipeCapability.CAP).stream() - .filter(v -> v instanceof IEnergyContainer) - .forEach(v -> energyContainers.add((IEnergyContainer) v)); + .filter(IEnergyContainer.class::isInstance) + .map(IEnergyContainer.class::cast) + .forEach(energyContainers::add); handlerList.getCapability(FluidRecipeCapability.CAP).stream() - .filter(v -> v instanceof IFluidHandler) - .forEach(v -> coolantContainers.add((IFluidHandler) v)); + .filter(IFluidHandler.class::isInstance) + .map(IFluidHandler.class::cast) + .forEach(coolantContainers::add); } } this.energyContainer = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java index 948a86ed7d..ab4a4877a9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.IOpticalComputationHatch; import com.gregtechceu.gtceu.api.capability.IOpticalComputationProvider; +import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; @@ -60,34 +61,26 @@ public void onStructureFormed() { List receivers = new ArrayList<>(); List transmitters = new ArrayList<>(); for (var part : this.getParts()) { - var handlerList = part.getRecipeHandlers(); + Block block = part.self().getBlockState().getBlock(); + List list; + if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { + list = receivers; + } else if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { + list = transmitters; + } else { + continue; + } if (part instanceof IOpticalComputationHatch hatch) { - Block block = part.self().getBlockState().getBlock(); - if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { - receivers.add(hatch); - } - if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { - transmitters.add(hatch); + list.add(hatch); + } else { + var handlerLists = part.getRecipeHandlers(); + for (var handlerList : handlerLists) { + for (var cwu : handlerList.getCapability(CWURecipeCapability.CAP)) { + if (cwu instanceof IOpticalComputationHatch hatch) { + list.add(hatch); + } + } } - } else if (false/* - * || part.getRecipeHandlers().getCapability(CWURecipeCapability.CAP).stream().anyMatch( - * IOpticalComputationHatch.class::isInstance) - */) { - /* - * var hatch = part.getRecipeHandlers().stream().filter(IOpticalComputationHatch.class::isInstance) - * .map(IOpticalComputationHatch.class::cast).findFirst().orElse(null); - */ - /* - * if (hatch != null) { - * Block block = part.self().getBlockState().getBlock(); - * if (PartAbility.COMPUTATION_DATA_RECEPTION.isApplicable(block)) { - * receivers.add(hatch); - * } - * if (PartAbility.COMPUTATION_DATA_TRANSMISSION.isApplicable(block)) { - * transmitters.add(hatch); - * } - * } - */ } } computationHandler.onStructureForm(receivers, transmitters); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java index 77b982c322..692b7129b2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/ResearchStationMachine.java @@ -145,6 +145,7 @@ protected ActionResult matchRecipe(GTRecipe recipe) { public boolean checkMatchedRecipeAvailable(GTRecipe match) { var modified = machine.fullModifyRecipe(match); if (modified != null) { + // What is the point of this if (!modified.inputs.containsKey(CWURecipeCapability.CAP) && !modified.tickInputs.containsKey(CWURecipeCapability.CAP)) { return true; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index 4727831b71..2326d7d4d5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -69,13 +69,6 @@ public void onStructureFormed() { itr.remove(); this.addHandlerList( RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, getConversionRate()))); - /* - * if (!capabilitiesProxy.contains(IO.IN, EURecipeCapability.CAP)) { - * capabilitiesProxy.put(IO.IN, EURecipeCapability.CAP, new ArrayList<>()); - * } - * capabilitiesProxy.get(IO.IN, EURecipeCapability.CAP) - * .add(new SteamEnergyRecipeHandler(tank, CONVERSION_RATE)); - */ return; } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index 2d6074449b..2dfd04d0c9 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -76,7 +76,10 @@ import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; import javax.annotation.ParametersAreNonnullByDefault; @@ -145,7 +148,6 @@ public void setItemDirect(int slotIndex, ItemStack stack) { private final Set proxies = new ObjectOpenHashSet<>(); private final Set proxyMachines = new ReferenceOpenHashSet<>(); - // protected final MEPatternBufferRecipeHandler recipeHandler = new MEPatternBufferRecipeHandler(this); @Getter protected final InternalSlotRecipeHandler ISRHL; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java index 215536f527..26b9d4e599 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferProxyPartMachine.java @@ -7,7 +7,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredIOPartMachine; -import com.gregtechceu.gtceu.api.machine.trait.*; +import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.integration.ae2.machine.trait.ProxySlotRecipeHandler; import com.lowdragmc.lowdraglib.gui.modular.ModularUI; diff --git a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java b/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java deleted file mode 100644 index 8b13789179..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/test/GTGameTests.java +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java index ed9933ac4d..515325a67b 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyMachineBlockEntity.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.utils; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; @@ -12,8 +11,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction; import lombok.Getter; -import java.util.List; -import java.util.Map; +import java.util.Collection; /** * Dummy machine BE used for wrapping {@link DummyRecipeLogicMachine}s @@ -27,13 +25,13 @@ public class DummyMachineBlockEntity implements IMachineBlockEntity { // TODO: Fix the proxy parameter public DummyMachineBlockEntity(int tier, GTRecipeType type, Int2IntFunction tankScalingFunction, - Map> capabilitiesProxy, + Collection handlers, Object... args) { this.definition = MachineDefinition.createDefinition(GTCEu.id("dummy")); this.definition.setRecipeTypes(new GTRecipeType[] { type }); this.definition.setTier(tier); - this.metaMachine = new DummyRecipeLogicMachine(this, tier, tankScalingFunction, capabilitiesProxy, args); + this.metaMachine = new DummyRecipeLogicMachine(this, tier, tankScalingFunction, handlers, args); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java index f1a4f98564..93e1c6fce4 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/DummyRecipeLogicMachine.java @@ -1,6 +1,5 @@ package com.gregtechceu.gtceu.utils; -import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.WorkableTieredMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; @@ -9,8 +8,6 @@ import it.unimi.dsi.fastutil.ints.Int2IntFunction; import java.util.Collection; -import java.util.List; -import java.util.Map; /** * Dummy machine used for searching recipes outside of a machine. @@ -18,17 +15,10 @@ public class DummyRecipeLogicMachine extends WorkableTieredMachine implements IRecipeLogicMachine { public DummyRecipeLogicMachine(IMachineBlockEntity be, int tier, Int2IntFunction tankScalingFunction, - Map> capabilitiesProxy, + Collection handlers, Object... args) { super(be, tier, tankScalingFunction, args); - reinitializeCapabilities(capabilitiesProxy); - } - - public void reinitializeCapabilities(Map> caps) { - this.capabilitiesProxy.clear(); - this.capabilitiesFlat.clear(); - - this.capabilitiesProxy.putAll(caps); + reinitializeHandlers(handlers); } public void reinitializeHandlers(Collection handlers) { From 96fd6589285410159965d6d73f3a2955bcee89be Mon Sep 17 00:00:00 2001 From: YoungOnion <39562198+YoungOnionMC@users.noreply.github.com> Date: Wed, 5 Mar 2025 00:33:36 -0700 Subject: [PATCH 27/29] some changes --- .../api/machine/WorkableTieredMachine.java | 2 +- .../multiblock/WorkableMultiblockMachine.java | 2 +- .../machine/steam/SteamWorkableMachine.java | 2 +- .../gtceu/api/recipe/ActionResult.java | 19 ++++++++----------- .../gtceu/api/recipe/RecipeHelper.java | 14 +++++++------- .../electric/DistillationTowerMachine.java | 4 ++-- .../machine/trait/miner/MinerLogic.java | 2 +- 7 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index f07c4487fb..242d19abb1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -67,7 +67,7 @@ public abstract class WorkableTieredMachine extends TieredEnergyMachine implemen @Getter protected final Map> capabilitiesProxy; @Getter - protected Map, List>>> capabilitiesFlat; + protected final Map, List>>> capabilitiesFlat; @Persisted @Getter protected int overclockTier; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index a1faf3d72a..3ee6af5f35 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -65,7 +65,7 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach @Getter protected final Map> capabilitiesProxy; @Getter - protected Map, List>>> capabilitiesFlat; + protected final Map, List>>> capabilitiesFlat; protected final List traitSubscriptions; @Getter @Setter diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index 52f666c6b5..aac64aa3a5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -81,7 +81,7 @@ public abstract class SteamWorkableMachine extends SteamMachine @Getter protected final Map> capabilitiesProxy; @Getter - protected Map, List>>> capabilitiesFlat; + protected final Map, List>>> capabilitiesFlat; protected final List traitSubscriptions; public SteamWorkableMachine(IMachineBlockEntity holder, boolean isHighPressure, Object... args) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java index c7cfe25ff7..3ad987d674 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java @@ -4,28 +4,25 @@ import org.jetbrains.annotations.Nullable; -import java.util.function.Supplier; - /** * @param isSuccess is action success * @param reasonSupplier if fail, fail reasonSupplier */ -public record ActionResult(boolean isSuccess, Supplier<@Nullable Component> reasonSupplier) { +public record ActionResult(boolean isSuccess, @Nullable Component reasonSupplier) { - public final static ActionResult SUCCESS = new ActionResult(true, () -> null); - public final static ActionResult FAIL_NO_REASON = new ActionResult(false, () -> null); + public final static ActionResult SUCCESS = new ActionResult(true, null); + public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, - () -> Component.translatable("gtceu.recipe_logic.no_contents")); + Component.translatable("gtceu.recipe_logic.no_contents")); public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, - () -> Component.translatable("gtceu.recipe_logic.no_capabilities")); + Component.translatable("gtceu.recipe_logic.no_capabilities")); - public static ActionResult fail(Supplier<@Nullable Component> component) { + public static ActionResult fail(@Nullable Component component) { return new ActionResult(false, component); } public Component reason() { - var comp = reasonSupplier.get(); - if (comp == null) return Component.empty(); - return comp; + if (reasonSupplier == null) return Component.empty(); + return reasonSupplier; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 09473744dd..1ebdd58435 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -233,7 +233,7 @@ public static ActionResult handleRecipe(IRecipeCapabilityHolder holder, GTRecipe // TODO: make this actually log error on failed non-simulate if (handle == null || handle.content() != null) { String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); - return ActionResult.fail(() -> Component.translatable(key) + return ActionResult.fail(Component.translatable(key) .append(": ").append(handle.capability().getName())); } return handle.result(); @@ -315,7 +315,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic if (condition.isOr()) { or.computeIfAbsent(condition.getType(), type -> new ArrayList<>()).add(condition); } else if (!condition.check(recipe, recipeLogic)) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails") + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.condition_fails") .append(": ") .append(condition.getTooltips())); } @@ -329,7 +329,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic } if (!passed) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.condition_fails")); + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.condition_fails")); } } return ActionResult.SUCCESS; @@ -452,9 +452,9 @@ private static ActionResult checkItemValid(Map, List Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + .fail(Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); } else if (Arrays.stream(items).anyMatch(ItemStack::isEmpty)) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.invalid_stack")); } } return ActionResult.SUCCESS; @@ -465,9 +465,9 @@ private static ActionResult checkFluidValid(Map, List Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); + .fail(Component.translatable("gtceu.recipe_logic.no_" + name + "_ingredients")); } else if (Arrays.stream(fluids).anyMatch(FluidStack::isEmpty)) { - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.invalid_stack")); + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.invalid_stack")); } } return ActionResult.SUCCESS; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 1ac9885b3b..830005d6b3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -208,7 +208,7 @@ private ActionResult matchDTRecipe(GTRecipe recipe) { if (!applyFluidOutputs(recipe, FluidAction.SIMULATE)) { return ActionResult - .fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + .fail(Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } @@ -255,7 +255,7 @@ protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { return ActionResult.SUCCESS; } - return ActionResult.fail(() -> Component.translatable("gtceu.recipe_logic.insufficient_out") + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") .append(FluidRecipeCapability.CAP.getName())); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index 1842e69ec6..2e17292800 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -118,7 +118,7 @@ public class MinerLogic extends RecipeLogic implements IRecipeCapabilityHolder { @Getter private final Map> capabilitiesProxy; @Getter - protected Map, List>>> capabilitiesFlat; + protected final Map, List>>> capabilitiesFlat; private final ItemRecipeHandler inputItemHandler, outputItemHandler; private final IgnoreEnergyRecipeHandler inputEnergyHandler; @Setter From f998edeea31aab74ac3df32e25bbdd6aecc9f2dd Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Wed, 5 Mar 2025 22:40:44 -0500 Subject: [PATCH 28/29] Merge conflicts --- gradle/scripts/moddevgradle.gradle | 2 +- .../common/machine/multiblock/steam/LargeBoilerMachine.java | 4 ++-- .../gtceu/common/recipe/condition/DaytimeCondition.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle/scripts/moddevgradle.gradle b/gradle/scripts/moddevgradle.gradle index 3fc42d61f2..91f5a0d942 100644 --- a/gradle/scripts/moddevgradle.gradle +++ b/gradle/scripts/moddevgradle.gradle @@ -99,7 +99,7 @@ legacyForge { // "REGISTRYDUMP": For getting the contents of all registries. systemProperty 'forge.logging.markers', 'REGISTRIES' // Enable assertions for our classes in dev environment - jvmArgument('-ea:com.gregtechceu.gtceu') + jvmArgument('-ea:com.gregtechceu.gtceu...') // Recommended logging level for the console // You can set various levels here. diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java index a19f187cee..c14bd64fb8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java @@ -124,7 +124,7 @@ protected void updateCurrentTemperature() { if (currentTemperature < 100) { steamGenerated = 0; for (IRecipeHandler tank : inputTanks) { - drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, null, true); + drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, true); this.hasNoWater = !(drainWater == null || drainWater.isEmpty() || drainWater.get(0).getAmount() > 0); if (!this.hasNoWater) { @@ -133,7 +133,7 @@ protected void updateCurrentTemperature() { } } else { for (IRecipeHandler tank : inputTanks) { - drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, null, false); + drainWater = (List) tank.handleRecipe(IO.IN, null, drainWater, false); if (drainWater == null || drainWater.isEmpty()) { break; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DaytimeCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DaytimeCondition.java index 08779bb8b7..c6c1a0457d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DaytimeCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DaytimeCondition.java @@ -42,7 +42,7 @@ public Component getTooltips() { } @Override - public boolean test(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { Level level = recipeLogic.machine.self().getLevel(); return level != null && !level.isNight(); } From 64ef7bc488df7eea8e9cf0cdbf6b16d150b59698 Mon Sep 17 00:00:00 2001 From: kross <135918757+krossgg@users.noreply.github.com> Date: Fri, 7 Mar 2025 04:19:31 -0500 Subject: [PATCH 29/29] =?UTF-8?q?=F0=9F=99=84=20onion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/machine/WorkableTieredMachine.java | 2 +- .../gtceu/api/machine/feature/IVoidable.java | 6 +- .../multiblock/WorkableMultiblockMachine.java | 6 +- .../part/MultiblockPartMachine.java | 16 ++- .../machine/steam/SteamWorkableMachine.java | 2 +- .../trait/FluidHandlerProxyRecipeTrait.java | 110 --------------- .../trait/ItemHandlerProxyRecipeTrait.java | 109 --------------- .../machine/trait/NotifiableFluidTank.java | 58 ++++---- .../trait/NotifiableItemStackHandler.java | 5 +- .../api/machine/trait/RecipeHandlerList.java | 81 +++++++----- .../gtceu/api/recipe/GTRecipe.java | 5 + .../gtceu/api/recipe/RecipeHelper.java | 125 ++++++------------ .../gtceu/api/recipe/RecipeRunner.java | 23 ++-- .../gtceu/api/recipe/content/Content.java | 12 +- .../api/transfer/fluid/CustomFluidTank.java | 30 +---- .../electric/ActiveTransformerMachine.java | 4 +- .../electric/FusionReactorMachine.java | 3 +- .../electric/PowerSubstationMachine.java | 4 +- .../multiblock/part/DualHatchPartMachine.java | 12 -- .../multiblock/part/ItemBusPartMachine.java | 28 +--- .../part/ReservoirHatchPartMachine.java | 7 - .../steam/SteamParallelMultiblockMachine.java | 53 +++++--- .../ae2/machine/MEOutputHatchPartMachine.java | 12 -- .../machine/MEPatternBufferPartMachine.java | 39 +++--- .../machine/trait/ProxySlotRecipeHandler.java | 2 +- .../provider/MEPatternBufferProvider.java | 4 +- 26 files changed, 227 insertions(+), 531 deletions(-) delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java delete mode 100644 src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 242d19abb1..40312a33c5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -176,7 +176,7 @@ public void onLoad() { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandlers(entry.getValue()); this.addHandlerList(handlerList); - traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + traitSubscriptions.add(handlerList.subscribe(recipeLogic::updateTickSubscription)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java index 89e626b2a2..4c968d6c91 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java @@ -4,18 +4,16 @@ import net.minecraft.util.StringRepresentable; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; -import java.util.Map; - public interface IVoidable extends IMachineFeature { default boolean canVoidRecipeOutputs(RecipeCapability capability) { return self().getDefinition().getRecipeOutputLimits().containsKey(capability); } - // -1 or empty is taken into account as a skip case. - default Map, Integer> getOutputLimits() { + default Object2IntMap> getOutputLimits() { return self().getDefinition().getRecipeOutputLimits(); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 3ee6af5f35..f62d39bd8c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -129,7 +129,7 @@ public void onStructureFormed() { for (var handlerList : handlerLists) { if (!handlerList.isValid(io)) continue; this.addHandlerList(handlerList); - traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + traitSubscriptions.add(handlerList.subscribe(recipeLogic::updateTickSubscription)); } } @@ -145,7 +145,7 @@ public void onStructureFormed() { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandlers(entry.getValue()); this.addHandlerList(handlerList); - traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + traitSubscriptions.add(handlerList.subscribe(recipeLogic::updateTickSubscription)); } // schedule recipe logic recipeLogic.updateTickSubscription(); @@ -211,7 +211,7 @@ protected GTRecipe getRealRecipe(GTRecipe recipe) { public void updateActiveBlocks(boolean active) { if (activeBlocks != null) { - for (Long pos : activeBlocks) { + for (long pos : activeBlocks) { var blockPos = BlockPos.of(pos); var blockState = getLevel().getBlockState(blockPos); if (blockState.getBlock() instanceof ActiveBlock block) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index ac94bb282e..c6deaad20a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -47,7 +47,7 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { protected final Set controllerPositions = new ObjectOpenHashSet<>(8); protected final SortedSet controllers = new ReferenceLinkedOpenHashSet<>(8); - protected @Nullable RecipeHandlerList handlerList; + private @Nullable RecipeHandlerList handlerList; public MultiblockPartMachine(IMachineBlockEntity holder) { super(holder); @@ -94,19 +94,23 @@ public SortedSet getControllers() { } public List getRecipeHandlers() { + return List.of(getHandlerList()); + } + + protected RecipeHandlerList getHandlerList() { if (handlerList == null) { - var a = traits.stream() + var handlerTraits = traits.stream() .filter(IRecipeHandlerTrait.class::isInstance) .map(IRecipeHandlerTrait.class::cast) .toList(); - if (a.isEmpty()) { + if (handlerTraits.isEmpty()) { handlerList = RecipeHandlerList.NO_DATA; } else { - handlerList = new RecipeHandlerList(a.get(0).getHandlerIO()); - handlerList.addHandlers(a.toArray(new IRecipeHandler[0])); + handlerList = new RecipeHandlerList(handlerTraits.get(0).getHandlerIO()); + handlerList.addHandlers(handlerTraits.toArray(new IRecipeHandler[0])); } } - return List.of(handlerList); + return handlerList; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java index aac64aa3a5..080b5a9cd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamWorkableMachine.java @@ -119,7 +119,7 @@ public void onLoad() { RecipeHandlerList handlerList = new RecipeHandlerList(entry.getKey()); handlerList.addHandlers(entry.getValue()); this.addHandlerList(handlerList); - traitSubscriptions.addAll(handlerList.addChangeListeners(recipeLogic::updateTickSubscription)); + traitSubscriptions.add(handlerList.subscribe(recipeLogic::updateTickSubscription)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java deleted file mode 100644 index a0e2f523e1..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/FluidHandlerProxyRecipeTrait.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.gregtechceu.gtceu.api.machine.trait; - -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; -import com.gregtechceu.gtceu.api.recipe.ingredient.FluidIngredient; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import lombok.Getter; -import lombok.Setter; - -import java.util.Collection; -import java.util.List; - -public class FluidHandlerProxyRecipeTrait extends NotifiableRecipeHandlerTrait - implements ICapabilityTrait { - - @Getter - public final IO handlerIO; - @Getter - public final IO capabilityIO; - @Getter - @Setter - private long timeStamp; - private boolean enabled; - - @Getter - private final Collection> handlers; - - public FluidHandlerProxyRecipeTrait(MetaMachine machine, - Collection> handlers, - IO handlerIO, - IO capabilityIO) { - super(machine); - this.timeStamp = Long.MIN_VALUE; - this.handlerIO = handlerIO; - this.capabilityIO = capabilityIO; - this.handlers = handlers; - } - - @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, - boolean simulate) { - if (!enabled) return left; - for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, simulate); - if (left.isEmpty()) return null; - } - return left; - } - - @Override - public List getContents() { - List contents = new ObjectArrayList<>(2); - for (NotifiableRecipeHandlerTrait handler : handlers) { - contents.addAll(handler.getContents()); - } - return contents; - } - - @Override - public int getSize() { - int size = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - size += handlerTrait.getSize(); - } - return size; - } - - @Override - public double getTotalContentAmount() { - long amount = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - amount += handlerTrait.getTotalContentAmount(); - } - return amount; - } - - @Override - public RecipeCapability getCapability() { - return FluidRecipeCapability.CAP; - } - - @Override - public boolean isDistinct() { - for (NotifiableRecipeHandlerTrait handler : handlers) { - if (!handler.isDistinct) - return false; - } - return true; - } - - @Override - public void setDistinct(boolean distinct) { - handlers.forEach(handler -> handler.setDistinct(distinct)); - recomputeEnabledState(); - } - - @Override - public boolean isProxy() { - return true; - } - - public void recomputeEnabledState() { - this.enabled = isDistinct(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java deleted file mode 100644 index 8dd407a975..0000000000 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/ItemHandlerProxyRecipeTrait.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.gregtechceu.gtceu.api.machine.trait; - -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; -import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; -import com.gregtechceu.gtceu.api.machine.MetaMachine; -import com.gregtechceu.gtceu.api.recipe.GTRecipe; - -import net.minecraft.world.item.crafting.Ingredient; - -import it.unimi.dsi.fastutil.objects.ObjectArrayList; -import lombok.Getter; -import lombok.Setter; - -import java.util.Collection; -import java.util.List; - -public class ItemHandlerProxyRecipeTrait extends NotifiableRecipeHandlerTrait implements ICapabilityTrait { - - @Getter - public final IO handlerIO; - @Getter - public final IO capabilityIO; - @Getter - @Setter - private long timeStamp; - private boolean enabled; - - @Getter - private final Collection> handlers; - - public ItemHandlerProxyRecipeTrait(MetaMachine machine, - Collection> handlers, IO handlerIO, - IO capabilityIO) { - super(machine); - this.timeStamp = Long.MIN_VALUE; - this.handlerIO = handlerIO; - this.capabilityIO = capabilityIO; - this.handlers = handlers; - } - - @Override - public List handleRecipeInner(IO io, GTRecipe recipe, List left, - boolean simulate) { - if (!enabled) return left; - for (IRecipeHandler handler : handlers) { - handler.handleRecipeInner(io, recipe, left, simulate); - if (left.isEmpty()) return null; - } - return left; - } - - @Override - public List getContents() { - List contents = new ObjectArrayList<>(2); - for (NotifiableRecipeHandlerTrait handler : handlers) { - contents.addAll(handler.getContents()); - } - return contents; - } - - @Override - public int getSize() { - int size = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - size += handlerTrait.getSize(); - } - return size; - } - - @Override - public double getTotalContentAmount() { - long amount = 0; - for (NotifiableRecipeHandlerTrait handlerTrait : handlers) { - amount += handlerTrait.getTotalContentAmount(); - } - return amount; - } - - @Override - public RecipeCapability getCapability() { - return ItemRecipeCapability.CAP; - } - - @Override - public boolean isDistinct() { - for (NotifiableRecipeHandlerTrait handler : handlers) { - if (!handler.isDistinct) - return false; - } - return true; - } - - @Override - public void setDistinct(boolean distinct) { - handlers.forEach(handler -> handler.setDistinct(distinct)); - recomputeEnabledState(); - } - - @Override - public boolean isProxy() { - return true; - } - - public void recomputeEnabledState() { - this.enabled = isDistinct(); - } -} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java index 4be0502b02..892b88e379 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java @@ -60,7 +60,7 @@ public NotifiableFluidTank(MetaMachine machine, int slots, int capacity, IO io, this.capabilityIO = capabilityIO; for (int i = 0; i < this.storages.length; i++) { this.storages[i] = new CustomFluidTank(capacity); - this.storages[i].setOnContentsChanged(this::onContentsChanged); + // this.storages[i].setOnContentsChanged(this::onContentsChanged); } } @@ -69,9 +69,9 @@ public NotifiableFluidTank(MetaMachine machine, List storages, this.handlerIO = io; this.storages = storages.toArray(CustomFluidTank[]::new); this.capabilityIO = capabilityIO; - for (CustomFluidTank storage : this.storages) { - storage.setOnContentsChanged(this::onContentsChanged); - } + // for (CustomFluidTank storage : this.storages) { + // storage.setOnContentsChanged(this::onContentsChanged); + // } if (io == IO.IN) { this.allowSameFluids = true; } @@ -102,6 +102,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List handleRecipeInner(IO io, GTRecipe recipe, List 0) { + changed = action.execute(); visited[tank] = drained.copy(); visited[tank].setAmount(amount - drained.getAmount()); ingredient.shrink(drained.getAmount()); @@ -158,6 +160,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List 0) { + changed = action.execute(); visited[tank] = output.copy(); visited[tank].setAmount(filled); ingredient.shrink(filled); @@ -175,6 +178,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List stack.isFluidEqual(this.lockedFluid.getFluid())); - } else { - this.lockedFluid.setFluid(FluidStack.EMPTY); - setFilter(stack -> true); - onContentsChanged(); - } + setLocked(locked, storages[0].getFluid()); } public void setLocked(boolean locked, FluidStack fluidStack) { @@ -212,13 +205,12 @@ public void setLocked(boolean locked, FluidStack fluidStack) { if (locked && !fluidStack.isEmpty()) { this.lockedFluid.setFluid(fluidStack.copy()); this.lockedFluid.getFluid().setAmount(1); - onContentsChanged(); setFilter(stack -> stack.isFluidEqual(this.lockedFluid.getFluid())); } else { this.lockedFluid.setFluid(FluidStack.EMPTY); setFilter(stack -> true); - onContentsChanged(); } + onContentsChanged(); } public NotifiableFluidTank setFilter(Predicate filter) { @@ -312,6 +304,7 @@ public FluidStack getFluidInTank(int tank) { public void setFluidInTank(int tank, @NotNull FluidStack fluidStack) { storages[tank].setFluid(fluidStack); + onContentsChanged(); } @Override @@ -356,7 +349,9 @@ public int fillInternal(FluidStack resource, FluidAction action) { } else { copied.shrink(existingStorage.fill(copied.copy(), action)); } - return resource.getAmount() - copied.getAmount(); + int filled = resource.getAmount() - copied.getAmount(); + if (filled > 0 && action.execute()) onContentsChanged(); + return filled; } @NotNull @@ -369,17 +364,17 @@ public FluidStack drain(FluidStack resource, FluidAction action) { } public FluidStack drainInternal(FluidStack resource, FluidAction action) { - if (!resource.isEmpty()) { - var copied = resource.copy(); - for (var storage : storages) { - var candidate = copied.copy(); - copied.shrink(storage.drain(candidate, action).getAmount()); - if (copied.isEmpty()) break; - } - copied.setAmount(resource.getAmount() - copied.getAmount()); - return copied; + if (resource.isEmpty()) return FluidStack.EMPTY; + + var copied = resource.copy(); + for (var storage : storages) { + var candidate = copied.copy(); + copied.shrink(storage.drain(candidate, action).getAmount()); + if (copied.isEmpty()) break; } - return FluidStack.EMPTY; + copied.setAmount(resource.getAmount() - copied.getAmount()); + if (!copied.isEmpty() && action.execute()) onContentsChanged(); + return copied; } @NotNull @@ -392,9 +387,7 @@ public FluidStack drain(int maxDrain, FluidAction action) { } public FluidStack drainInternal(int maxDrain, FluidAction action) { - if (maxDrain == 0) { - return FluidStack.EMPTY; - } + if (maxDrain == 0) return FluidStack.EMPTY; FluidStack totalDrained = null; for (var storage : storages) { if (totalDrained == null || totalDrained.isEmpty()) { @@ -413,6 +406,7 @@ public FluidStack drainInternal(int maxDrain, FluidAction action) { } if (maxDrain <= 0) break; } + if (totalDrained != null && !totalDrained.isEmpty() && action.execute()) onContentsChanged(); return totalDrained == null ? FluidStack.EMPTY : totalDrained; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java index f1246e24f1..cdce7e53c1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java @@ -30,6 +30,7 @@ import java.util.Arrays; import java.util.List; import java.util.function.Function; +import java.util.function.Predicate; /** * @author KilaBash @@ -67,8 +68,8 @@ public NotifiableItemStackHandler(MetaMachine machine, int slots, @NotNull IO ha this(machine, slots, handlerIO, handlerIO); } - public NotifiableItemStackHandler setFilter(Function filter) { - this.storage.setFilter(filter::apply); + public NotifiableItemStackHandler setFilter(Predicate filter) { + this.storage.setFilter(filter); return this; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java index c392517d89..0f8d9e665f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeHandlerList.java @@ -7,10 +7,8 @@ import com.lowdragmc.lowdraglib.syncdata.ISubscription; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import lombok.Getter; -import lombok.Setter; import java.util.ArrayList; import java.util.Arrays; @@ -21,7 +19,7 @@ public class RecipeHandlerList { - public static RecipeHandlerList NO_DATA = new RecipeHandlerList(IO.NONE); + public static final RecipeHandlerList NO_DATA = new RecipeHandlerList(IO.NONE); public static final Comparator COMPARATOR = (h1, h2) -> { int cmp = Long.compare(h1.getPriority(), h2.getPriority()); @@ -33,14 +31,16 @@ public class RecipeHandlerList { @Getter private final Map, List>> handlerMap = new Reference2ObjectOpenHashMap<>(); - private final List> allHandlers = new ObjectArrayList<>(); - private final IO io; - @Setter + private final List> allHandlers = new ArrayList<>(); + private final List> allHandlerTraits = new ArrayList<>(); + + @Getter + private final IO handlerIO; @Getter private boolean isDistinct = false; - public RecipeHandlerList(IO io) { - this.io = io; + public RecipeHandlerList(IO handlerIO) { + this.handlerIO = handlerIO; } public static RecipeHandlerList of(IO io, IRecipeHandler handler) { @@ -61,8 +61,9 @@ public void addHandlers(List> handlers) { for (var handler : handlers) { getHandlerMap().computeIfAbsent(handler.getCapability(), c -> new ArrayList<>()).add(handler); allHandlers.add(handler); + if (handler instanceof IRecipeHandlerTrait rht) allHandlerTraits.add(rht); } - if (io == IO.OUT) sort(); + if (handlerIO == IO.OUT) sort(); } private void sort() { @@ -71,6 +72,17 @@ private void sort() { } } + public void setDistinct(boolean distinct) { + if (isDistinct != distinct) { + isDistinct = distinct; + for (var rht : allHandlerTraits) { + if (rht instanceof NotifiableRecipeHandlerTrait nrht) { + nrht.setDistinct(distinct); + } + } + } + } + public boolean hasCapability(RecipeCapability cap) { return getHandlerMap().containsKey(cap); } @@ -81,11 +93,7 @@ public List> getCapability(RecipeCapability cap) { public boolean isValid(IO extIO) { if (this == NO_DATA) return false; - return (extIO == IO.BOTH || io == IO.BOTH || extIO == io); - } - - public IO getHandlerIO() { - return io; + return (extIO == IO.BOTH || handlerIO == IO.BOTH || extIO == handlerIO); } public long getPriority() { @@ -100,26 +108,6 @@ public double getTotalContentAmount() { return sum; } - public List addChangeListeners(Runnable listener) { - List ret = new ArrayList<>(); - for (var handler : allHandlers) { - if (handler instanceof IRecipeHandlerTrait trait) { - ret.add(trait.addChangedListener(listener)); - } - } - return ret; - } - - public List addChangeListeners(Runnable listener, RecipeCapability cap) { - List ret = new ArrayList<>(); - for (var handler : getCapability(cap)) { - if (handler instanceof IRecipeHandlerTrait trait) { - ret.add(trait.addChangedListener(listener)); - } - } - return ret; - } - public Map, List> handleRecipe(IO io, GTRecipe recipe, Map, List> contents, boolean simulate) { if (getHandlerMap().isEmpty()) return contents; @@ -141,4 +129,29 @@ public Map, List> handleRecipe(IO io, GTRecipe recipe, Map subs) implements ISubscription { + + @Override + public void unsubscribe() { + subs.forEach(ISubscription::unsubscribe); + } + } + + public ISubscription subscribe(Runnable listener) { + List subs = new ArrayList<>(allHandlerTraits.size()); + allHandlerTraits.forEach(rht -> subs.add(rht.addChangedListener(listener))); + return new Subscription(subs); + } + + public ISubscription subscribe(Runnable listener, RecipeCapability cap) { + var capList = getCapability(cap); + List subs = new ArrayList<>(capList.size()); + for (var handler : capList) { + if (handler instanceof IRecipeHandlerTrait trait) { + subs.add(trait.addChangedListener(listener)); + } + } + return new Subscription(subs); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java index 13c580c2ba..cbb0fbbc34 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipe.java @@ -222,4 +222,9 @@ public boolean equals(Object obj) { public int hashCode() { return id.hashCode(); } + + @Override + public String toString() { + return id.toString(); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 1ebdd58435..2b163feda5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.recipe; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; @@ -13,6 +14,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -45,14 +47,6 @@ public static long getRealEUt(@NotNull GTRecipe recipe) { return -getOutputEUt(recipe); } - public static void setInputEUt(GTRecipe recipe, long eut) { - recipe.getTickInputContents(EURecipeCapability.CAP).forEach(c -> c.content = eut); - } - - public static void setOutputEUt(GTRecipe recipe, long eut) { - recipe.getTickOutputContents(EURecipeCapability.CAP).forEach(c -> c.content = eut); - } - public static int getRecipeEUtTier(GTRecipe recipe) { long EUt = getInputEUt(recipe); if (EUt == 0) { @@ -228,30 +222,18 @@ public static ActionResult handleRecipe(IRecipeCapabilityHolder holder, GTRecipe Map, Object2IntMap> chanceCaches, boolean isTick, boolean simulated) { RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); - var handle = runner.handle(contents); + var result = runner.handle(contents); - // TODO: make this actually log error on failed non-simulate - if (handle == null || handle.content() != null) { + if (!result.isSuccess()) { + assert result.capability() != null; + if (!simulated) { + GTCEu.LOGGER.warn("IO Error while handling recipe {} outputs for {}", recipe, holder); + } String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); return ActionResult.fail(Component.translatable(key) - .append(": ").append(handle.capability().getName())); + .append(": ").append(result.capability().getName())); } - return handle.result(); - - /* - * RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, false); - * for (Map.Entry, List> entry : contents.entrySet()) { - * var handled = runner.handle(entry); - * if (handled == null) - * continue; - * - * if (handled.content() != null) { - * GTCEu.LOGGER.warn("io error while handling a recipe {} outputs. holder: {}", recipe.id, holder); - * return false; - * } - * } - * return true; - */ + return result.result(); } public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { @@ -338,13 +320,13 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic /** * Trims the recipe outputs and tick outputs based on the performing Machine's trim limit. */ - public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Map, Integer> trimLimits) { + public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Object2IntMap> trimLimits) { // Fast return early if no trimming desired - if (trimLimits.isEmpty() || trimLimits.values().stream().allMatch(integer -> integer == -1)) { + if (trimLimits.isEmpty() || trimLimits.values().intStream().allMatch(integer -> integer == -1)) { return recipe; } - GTRecipe current = recipe.copy(); + GTRecipe current = recipe;// .copy(); GTRecipeBuilder builder = new GTRecipeBuilder(current, recipe.recipeType); @@ -365,69 +347,42 @@ public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Map, List> doTrim(Map, List> current, - Map, Integer> trimLimits) { - Map, List> outputs = new HashMap<>(); + Object2IntMap> trimLimits) { + Map, List> outputs = new Reference2ObjectOpenHashMap<>(current.size()); + + for (var entry : current.entrySet()) { + var cap = entry.getKey(); + var contents = entry.getValue(); + if (contents.isEmpty()) continue; + if (!trimLimits.containsKey(cap)) { + outputs.computeIfAbsent(cap, c -> new ArrayList<>()).addAll(contents); + continue; + } - Set> trimmed = new HashSet<>(); - for (Map.Entry, Integer> entry : trimLimits.entrySet()) { - RecipeCapability key = entry.getKey(); + int N = trimLimits.getInt(cap); + if (N == 0) continue; - if (!current.containsKey(key)) continue; - List nonChanced = new ArrayList<>(); + int added = 0; + List list = outputs.computeIfAbsent(cap, c -> new ArrayList<>()); List chanced = new ArrayList<>(); - for (Content content : current.getOrDefault(key, List.of())) { - if (content.chance <= 0 || content.chance >= content.maxChance) nonChanced.add(content); - else chanced.add(content); - } - - int outputLimit = entry.getValue(); - if (outputLimit == -1) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()).addAll(nonChanced); - } - // If just the regular outputs would satisfy the outputLimit - else if (nonChanced.size() >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream() - .map(cont -> cont.copy(key, null)) - .toList() - .subList(0, outputLimit)); - - chanced.clear(); + for (var content : contents) { + if (added == N) break; + if (!content.isChanced()) { + added++; + list.add(content); + } else { + chanced.add(content); + } } - // If the regular outputs and chanced outputs are required to satisfy the outputLimit - else if (!nonChanced.isEmpty() && (nonChanced.size() + chanced.size()) >= outputLimit) { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - // Calculate the number of chanced outputs after adding all the regular outputs - int numChanced = outputLimit - nonChanced.size(); - - chanced = chanced.subList(0, Math.min(numChanced, chanced.size())); - } - // There are only chanced outputs to satisfy the outputLimit - else if (nonChanced.isEmpty()) { - chanced = chanced.subList(0, Math.min(outputLimit, chanced.size())); + if (added < N) { + int rem = Math.min(chanced.size(), N - added); + list.addAll(chanced.subList(0, rem)); } - // The number of outputs + chanced outputs is lower than the trim number, so just add everything - else { - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(nonChanced.stream().map(cont -> cont.copy(key, null)).toList()); - // Chanced outputs are taken care of in the original copy - } - - if (!chanced.isEmpty()) - outputs.computeIfAbsent(key, $ -> new ArrayList<>()) - .addAll(chanced.stream().map(cont -> cont.copy(key, null)).toList()); - - trimmed.add(key); - } - for (Map.Entry, List> entry : current.entrySet()) { - if (trimmed.contains(entry.getKey())) continue; - outputs.computeIfAbsent(entry.getKey(), $ -> new ArrayList<>()).addAll(entry.getValue()); } return outputs; diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 670ebbfed1..0878f3f441 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -10,8 +10,8 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; import java.util.ArrayList; import java.util.List; @@ -23,10 +23,14 @@ @SuppressWarnings({ "rawtypes", "unchecked" }) class RecipeRunner { - record RecipeHandlingResult(@Nullable RecipeCapability capability, @UnknownNullability List content, - ActionResult result) { + record RecipeHandlingResult(ActionResult result, + @Nullable("Null when isSuccess()") RecipeCapability capability) { - public static RecipeHandlingResult SUCCESS = new RecipeHandlingResult(null, null, ActionResult.SUCCESS); + public static RecipeHandlingResult SUCCESS = new RecipeHandlingResult(ActionResult.SUCCESS, null); + + public boolean isSuccess() { + return result.isSuccess(); + } } private final GTRecipe recipe; @@ -51,12 +55,12 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.simulated = simulated; } - @Nullable + @NotNull public RecipeHandlingResult handle(Map, List> entries) { fillContentMatchList(entries); if (searchRecipeContents.isEmpty()) - return new RecipeHandlingResult(null, null, ActionResult.PASS_NO_CONTENTS); + return new RecipeHandlingResult(ActionResult.PASS_NO_CONTENTS, null); return this.handleContents(); } @@ -121,7 +125,7 @@ private RecipeHandlingResult handleContents() { private RecipeHandlingResult handleContentsInternal(IO capIO) { if (!capabilityProxies.containsKey(capIO)) { - return new RecipeHandlingResult(null, null, ActionResult.FAIL_NO_REASON); + return new RecipeHandlingResult(ActionResult.FAIL_NO_REASON, null); } var handlers = capabilityProxies.get(capIO); @@ -163,11 +167,10 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { for (var entry : recipeContents.entrySet()) { if (entry.getValue() != null && !entry.getValue().isEmpty()) { - return new RecipeHandlingResult(entry.getKey(), entry.getValue(), - ActionResult.FAIL_NO_REASON); + return new RecipeHandlingResult(ActionResult.FAIL_NO_REASON, entry.getKey()); } } - return new RecipeHandlingResult(null, null, ActionResult.FAIL_NO_REASON); + return new RecipeHandlingResult(ActionResult.FAIL_NO_REASON, null); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java index 191226485f..74f4fe1752 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java @@ -29,10 +29,10 @@ public class Content { @Getter - public Object content; - public int chance; - public int maxChance; - public int tierChanceBoost; + public final Object content; + public final int chance; + public final int maxChance; + public final int tierChanceBoost; public Content(Object content, int chance, int maxChance, int tierChanceBoost) { this.content = content; @@ -65,6 +65,10 @@ public Content copy(RecipeCapability capability, @NotNull ContentModifier mod } } + public boolean isChanced() { + return chance > 0 && chance < maxChance; + } + /** * Attempts to fix and round the given chance boost due to potential differences * between the max chance and {@link ChanceLogic#getMaxChancedValue()}. diff --git a/src/main/java/com/gregtechceu/gtceu/api/transfer/fluid/CustomFluidTank.java b/src/main/java/com/gregtechceu/gtceu/api/transfer/fluid/CustomFluidTank.java index d97166a272..68ef0df826 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/transfer/fluid/CustomFluidTank.java +++ b/src/main/java/com/gregtechceu/gtceu/api/transfer/fluid/CustomFluidTank.java @@ -1,26 +1,18 @@ package com.gregtechceu.gtceu.api.transfer.fluid; -import com.lowdragmc.lowdraglib.syncdata.IContentChangeAware; import com.lowdragmc.lowdraglib.syncdata.ITagSerializable; import net.minecraft.nbt.CompoundTag; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.templates.FluidTank; -import lombok.Getter; -import lombok.Setter; - import java.util.function.Predicate; public class CustomFluidTank extends FluidTank - implements IFluidHandlerModifiable, ITagSerializable, IContentChangeAware { - - @Getter - @Setter - protected Runnable onContentsChanged = () -> {}; + implements IFluidHandlerModifiable, ITagSerializable { public CustomFluidTank(int capacity) { - this(capacity, e -> true); + super(capacity); } public CustomFluidTank(int capacity, Predicate validator) { @@ -32,29 +24,11 @@ public CustomFluidTank(FluidStack stack) { setFluid(stack); } - @Override - protected void onContentsChanged() { - onContentsChanged.run(); - } - - public CustomFluidTank copy() { - FluidStack copiedStack = this.fluid.copy(); - CustomFluidTank copied = new CustomFluidTank(this.capacity, this.validator); - copied.setFluid(copiedStack); - return copied; - } - @Override public void setFluidInTank(int tank, FluidStack stack) { setFluid(stack); } - @Override - public void setFluid(FluidStack stack) { - super.setFluid(stack); - this.onContentsChanged(); - } - @Override public CompoundTag serializeNBT() { return writeToNBT(new CompoundTag()); 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 3d43527c29..483fbdf6c2 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 @@ -104,8 +104,8 @@ public void onStructureFormed() { powerOutput.addAll(containers); } - traitSubscriptions.addAll(handlerList.addChangeListeners(converterSubscription::updateSubscription, - EURecipeCapability.CAP)); + traitSubscriptions + .add(handlerList.subscribe(converterSubscription::updateSubscription, EURecipeCapability.CAP)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java index c3d1e0393e..180105ca28 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/FusionReactorMachine.java @@ -134,8 +134,7 @@ public void onStructureFormed() { .filter(IEnergyContainer.class::isInstance) .map(IEnergyContainer.class::cast) .forEach(energyContainers::add); - traitSubscriptions.addAll( - handlerList.addChangeListeners(this::updatePreHeatSubscription, EURecipeCapability.CAP)); + traitSubscriptions.add(handlerList.subscribe(this::updatePreHeatSubscription, EURecipeCapability.CAP)); } } this.inputEnergyContainers = new EnergyContainerList(energyContainers); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java index 74397891aa..b822e98495 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/PowerSubstationMachine.java @@ -116,8 +116,8 @@ public void onStructureFormed() { outputs.addAll(containers); } - traitSubscriptions.addAll( - handlerList.addChangeListeners(tickSubscription::updateSubscription, EURecipeCapability.CAP)); + traitSubscriptions + .add(handlerList.subscribe(tickSubscription::updateSubscription, EURecipeCapability.CAP)); } } this.inputHatches = new EnergyContainerList(inputs); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java index 737d7fe45f..16d6ad29ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java @@ -157,18 +157,6 @@ public Widget createUIWidget() { return group; } - @Override - public boolean isDistinct() { - return io != IO.OUT && super.isDistinct() && tank.isDistinct(); - } - - @Override - public void setDistinct(boolean isDistinct) { - super.setDistinct(isDistinct); - tank.setDistinct(isDistinct); - getRecipeHandlers().get(0).setDistinct(isDistinct); - } - @Override public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java index 49730570dd..6658ececcc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java @@ -11,7 +11,6 @@ import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDistinctPart; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredIOPartMachine; -import com.gregtechceu.gtceu.api.machine.trait.ItemHandlerProxyRecipeTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.common.item.IntCircuitBehaviour; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -34,8 +33,6 @@ import lombok.Getter; import org.jetbrains.annotations.Nullable; -import java.util.Set; - import javax.annotation.ParametersAreNonnullByDefault; /** @@ -59,6 +56,9 @@ public class ItemBusPartMachine extends TieredIOPartMachine implements IDistinct @Getter @Persisted protected final NotifiableItemStackHandler circuitInventory; + @Getter + @Persisted + private boolean isDistinct = false; public ItemBusPartMachine(IMachineBlockEntity holder, int tier, IO io, Object... args) { super(holder, tier, io); @@ -92,14 +92,6 @@ protected NotifiableItemStackHandler createCircuitItemHandler(Object... args) { } } - protected ItemHandlerProxyRecipeTrait createCombinedItemHandler(Object... args) { - if (args.length > 0 && args[0] instanceof IO io && io == IO.IN) { - return new ItemHandlerProxyRecipeTrait(this, Set.of(getInventory(), circuitInventory), IO.IN, IO.NONE); - } else { - return new ItemHandlerProxyRecipeTrait(this, Set.of(getInventory(), circuitInventory), IO.NONE, IO.NONE); - } - } - @Override public void onMachineRemoved() { clearInventory(getInventory().storage); @@ -116,7 +108,7 @@ public void onLoad() { serverLevel.getServer().tell(new TickTask(0, this::updateInventorySubscription)); } inventorySubs = getInventory().addChangedListener(this::updateInventorySubscription); - getRecipeHandlers().get(0).setDistinct(getInventory().isDistinct()); + getHandlerList().setDistinct(isDistinct); } @Override @@ -129,15 +121,9 @@ public void onUnload() { } @Override - public boolean isDistinct() { - return io != IO.OUT && getInventory().isDistinct() && circuitInventory.isDistinct(); - } - - @Override - public void setDistinct(boolean isDistinct) { - getInventory().setDistinct(isDistinct); - circuitInventory.setDistinct(isDistinct); - getRecipeHandlers().get(0).setDistinct(isDistinct); + public void setDistinct(boolean distinct) { + isDistinct = (io == IO.OUT && distinct); + getHandlerList().setDistinct(isDistinct); } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ReservoirHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ReservoirHatchPartMachine.java index 4c1fcd1227..ba62aa0676 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ReservoirHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ReservoirHatchPartMachine.java @@ -101,12 +101,5 @@ public CompoundTag serializeNBT() { @Override public void deserializeNBT(CompoundTag nbt) {} - - @Override - public CustomFluidTank copy() { - var storage = new InfiniteWaterTank(capacity); - storage.setFluid(fluid.copy()); - return storage; - } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java index 2326d7d4d5..80571bf373 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/SteamParallelMultiblockMachine.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.common.machine.multiblock.steam; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -9,6 +8,7 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamEnergyRecipeHandler; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; @@ -34,7 +34,10 @@ import net.minecraft.network.chat.Style; import net.minecraft.world.entity.player.Player; +import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -44,7 +47,12 @@ @MethodsReturnNonnullByDefault public class SteamParallelMultiblockMachine extends WorkableMultiblockMachine implements IDisplayUIMachine { - public int maxParallels = ConfigHolder.INSTANCE.machines.steamMultiParallelAmount; + @Getter + @Setter + private int maxParallels = ConfigHolder.INSTANCE.machines.steamMultiParallelAmount; + + @Nullable + private SteamEnergyRecipeHandler steamEnergy = null; // if in millibuckets, this is 2.0, Meaning 2mb of steam -> 1 EU public static final double CONVERSION_RATE = 2.0; @@ -59,20 +67,24 @@ public SteamParallelMultiblockMachine(IMachineBlockEntity holder, Object... args @Override public void onStructureFormed() { super.onStructureFormed(); - var handlers = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP); - if (handlers.isEmpty()) return; - var itr = handlers.iterator(); - while (itr.hasNext()) { - var handler = itr.next(); - if (handler instanceof NotifiableFluidTank tank) { - if (tank.isFluidValid(0, GTMaterials.Steam.getFluid(1))) { - itr.remove(); - this.addHandlerList( - RecipeHandlerList.of(IO.IN, new SteamEnergyRecipeHandler(tank, getConversionRate()))); - return; + for (var part : getParts()) { + if (!PartAbility.STEAM.isApplicable(part.self().getDefinition().getBlock())) continue; + var handlers = part.getRecipeHandlers(); + for (var hl : handlers) { + if (!hl.isValid(IO.IN)) continue; + for (var fluidHandler : hl.getCapability(FluidRecipeCapability.CAP)) { + if (!(fluidHandler instanceof NotifiableFluidTank nft)) continue; + if (nft.isFluidValid(0, GTMaterials.Steam.getFluid(1))) { + steamEnergy = new SteamEnergyRecipeHandler(nft, getConversionRate()); + addHandlerList(RecipeHandlerList.of(IO.IN, steamEnergy)); + return; + } } } } + if (steamEnergy == null) { // No steam hatch found + onStructureInvalid(); + } } public double getConversionRate() { @@ -118,13 +130,11 @@ public static ModifierFunction recipeModifier(@NotNull MetaMachine machine, @Not public void addDisplayText(List textList) { IDisplayUIMachine.super.addDisplayText(textList); if (isFormed()) { - var handlers = getCapabilitiesFlat(IO.IN, EURecipeCapability.CAP); - if (!handlers.isEmpty() && handlers.get(0) instanceof SteamEnergyRecipeHandler steamHandler) { - if (steamHandler.getCapacity() > 0) { - long steamStored = steamHandler.getStored(); - textList.add(Component.translatable("gtceu.multiblock.steam.steam_stored", steamStored, - steamHandler.getCapacity())); - } + assert steamEnergy != null : "Formed without Steam Hatch"; + if (steamEnergy.getCapacity() > 0) { + long steamStored = steamEnergy.getStored(); + textList.add(Component.translatable("gtceu.multiblock.steam.steam_stored", steamStored, + steamEnergy.getCapacity())); } if (!isWorkingEnabled()) { @@ -132,8 +142,7 @@ public void addDisplayText(List textList) { } else if (isActive()) { textList.add(Component.translatable("gtceu.multiblock.running")); - if (maxParallels > 1) - textList.add(Component.translatable("gtceu.multiblock.parallel", maxParallels)); + if (maxParallels > 1) textList.add(Component.translatable("gtceu.multiblock.parallel", maxParallels)); int currentProgress = (int) (recipeLogic.getProgressPercent() * 100); double maxInSec = (float) recipeLogic.getDuration() / 20.0f; double currentInSec = (float) recipeLogic.getProgress() / 20.0f; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java index 0434d9bb49..f5581cae9d 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEOutputHatchPartMachine.java @@ -230,17 +230,5 @@ public boolean supportsFill(int tank) { public boolean supportsDrain(int tank) { return false; } - - @Override - public CustomFluidTank copy() { - // because recipe testing uses copy transfer instead of simulated operations - return new FluidStorageDelegate() { - - @Override - public int fill(FluidStack resource, FluidAction action) { - return super.fill(resource, action); - } - }; - } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index 2dfd04d0c9..b77e6e9493 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -72,10 +72,9 @@ import it.unimi.dsi.fastutil.objects.*; import lombok.Getter; import lombok.Setter; -import org.apache.commons.lang3.tuple.ImmutablePair; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; @@ -149,7 +148,7 @@ public void setItemDirect(int slotIndex, ItemStack stack) { private final Set proxyMachines = new ReferenceOpenHashSet<>(); @Getter - protected final InternalSlotRecipeHandler ISRHL; + protected final InternalSlotRecipeHandler internalRecipeHandler; @Nullable protected TickableSubscription updateSubs; @@ -178,7 +177,7 @@ public MEPatternBufferPartMachine(IMachineBlockEntity holder, Object... args) { .setFilter(IntCircuitBehaviour::isIntegratedCircuit); this.shareInventory = new NotifiableItemStackHandler(this, 9, IO.IN, IO.NONE); this.shareTank = new NotifiableFluidTank(this, 9, 8 * FluidType.BUCKET_VOLUME, IO.IN, IO.NONE); - this.ISRHL = new InternalSlotRecipeHandler(this, internalInventory); + this.internalRecipeHandler = new InternalSlotRecipeHandler(this, internalInventory); } @Override @@ -200,7 +199,7 @@ public void onLoad() { @Override public List getRecipeHandlers() { - return ISRHL.getSlotHandlers(); + return internalRecipeHandler.getSlotHandlers(); } @Override @@ -433,15 +432,16 @@ public InteractionResult onDataStickShiftUse(Player player, ItemStack dataStick) return InteractionResult.SUCCESS; } - public Pair, Object2LongMap> mergeInternalSlots() { - Object2LongMap items = new Object2LongOpenCustomHashMap<>( - ItemStackHashStrategy.comparingAllButCount()); - Object2LongMap fluids = new Object2LongOpenHashMap<>(); + public record BufferData(Object2LongMap items, Object2LongMap fluids) {} + + public BufferData mergeInternalSlots() { + var items = new Object2LongOpenCustomHashMap<>(ItemStackHashStrategy.comparingAllButCount()); + var fluids = new Object2LongOpenHashMap(); for (InternalSlot slot : internalInventory) { - slot.itemInventory.forEach((stack, count) -> items.mergeLong(stack, count, Long::sum)); - slot.fluidInventory.forEach((stack, amount) -> fluids.mergeLong(stack, amount, Long::sum)); + slot.itemInventory.object2LongEntrySet().fastForEach(e -> items.addTo(e.getKey(), e.getLongValue())); + slot.fluidInventory.object2LongEntrySet().fastForEach(e -> fluids.addTo(e.getKey(), e.getLongValue())); } - return new ImmutablePair<>(items, fluids); + return new BufferData(items, fluids); } public class InternalSlot implements ITagSerializable, IContentChangeAware { @@ -450,9 +450,9 @@ public class InternalSlot implements ITagSerializable, IContentChan @Setter private Runnable onContentsChanged = () -> {}; - private final Object2LongMap itemInventory = new Object2LongOpenCustomHashMap<>( + private final Object2LongOpenCustomHashMap itemInventory = new Object2LongOpenCustomHashMap<>( ItemStackHashStrategy.comparingAllButCount()); - private final Object2LongMap fluidInventory = new Object2LongOpenHashMap<>(); + private final Object2LongOpenHashMap fluidInventory = new Object2LongOpenHashMap<>(); private List itemStacks = null; private List fluidStacks = null; @@ -476,18 +476,19 @@ private void add(AEKey what, long amount) { if (amount <= 0L) return; if (what instanceof AEItemKey itemKey) { var stack = itemKey.toStack(); - itemInventory.mergeLong(stack, amount, Long::sum); + itemInventory.addTo(stack, amount); } else if (what instanceof AEFluidKey fluidKey) { var stack = fluidKey.toStack(1); - fluidInventory.mergeLong(stack, amount, Long::sum); + fluidInventory.addTo(stack, amount); } } public List getItems() { if (itemStacks == null) { - itemStacks = itemInventory.object2LongEntrySet().stream() - .flatMap(e -> GTMath.splitStacks(e.getKey(), e.getLongValue()).stream()) - .toList(); + itemStacks = new ArrayList<>(); + itemInventory.object2LongEntrySet().stream() + .map(e -> GTMath.splitStacks(e.getKey(), e.getLongValue())) + .forEach(itemStacks::addAll); } return itemStacks; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java index a839fb00fd..468ce2ee00 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/trait/ProxySlotRecipeHandler.java @@ -35,7 +35,7 @@ public ProxySlotRecipeHandler(MEPatternBufferProxyPartMachine machine, int slots } public void updateProxy(MEPatternBufferPartMachine patternBuffer) { - var slotHandlers = patternBuffer.getISRHL().getSlotHandlers(); + var slotHandlers = patternBuffer.getInternalRecipeHandler().getSlotHandlers(); for (int i = 0; i < proxySlotHandlers.size(); ++i) { ProxyRHL proxyRHL = (ProxyRHL) proxySlotHandlers.get(i); SlotRHL slotRHL = (SlotRHL) slotHandlers.get(i); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java index fdc2ab8f4b..80c233664e 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java @@ -59,8 +59,8 @@ public ResourceLocation getUid() { public static void writeBufferTag(CompoundTag compoundTag, MEPatternBufferPartMachine buffer) { var merged = buffer.mergeInternalSlots(); - var items = merged.getLeft(); - var fluids = merged.getRight(); + var items = merged.items(); + var fluids = merged.fluids(); ListTag itemsTag = new ListTag(); for (var entry : items.object2LongEntrySet()) {