diff --git a/gradle.properties b/gradle.properties index f0471953f..f89c719e3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ rei.version=16.0.754 jei.version=19.21.0.247 emi.version=1.1.22+1.21.1 dynamicdimensions.version=0.9.1+34 -machinelib.version=0.7.0+144 +machinelib.version=0.7.0+faee93e3 badpackets.version=0.8.2 wthit.version=12.5.4 obj.version=0.4.0 diff --git a/src/main/java/dev/galacticraft/mod/client/sounds/GCSoundManager.java b/src/main/java/dev/galacticraft/mod/client/sounds/GCSoundManager.java index 72e3209dd..d64fa8fa8 100644 --- a/src/main/java/dev/galacticraft/mod/client/sounds/GCSoundManager.java +++ b/src/main/java/dev/galacticraft/mod/client/sounds/GCSoundManager.java @@ -84,6 +84,8 @@ public Optional getSoundFromEntity(BlockEntity entity, MachineStat public static void onStatusChanged(Minecraft minecraft, LocalPlayer player, BlockPos pos, MachineStatus status, MachineStatus oldStatus) { MachineBlockEntity machine = (MachineBlockEntity) minecraft.level.getBlockEntity(pos); + if (machine == null) return; + GCSoundManager manager = GCSoundManager.getInstance(); boolean isActive = status.getType().isActive(); float maxVolume = isActive ? 1.0F : 0.2F; @@ -92,7 +94,7 @@ public static void onStatusChanged(Minecraft minecraft, LocalPlayer player, Bloc // Play new sound (if there is one) SoundEvent newSound = GCSoundMap.get(status, machine); if (newSound != null) { - manager.play(new MachineSound(machine, newSound, manager, maxVolume)); + manager.play(new MachineSound(machine, newSound, manager, maxVolume)); } } } diff --git a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/AbstractCompressorBlockEntity.java b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/AbstractCompressorBlockEntity.java new file mode 100644 index 000000000..f09abc493 --- /dev/null +++ b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/AbstractCompressorBlockEntity.java @@ -0,0 +1,334 @@ +/* + * Copyright (c) 2019-2026 Team Galacticraft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package dev.galacticraft.mod.content.block.entity.machine; + +import dev.galacticraft.machinelib.api.block.entity.BasicRecipeMachineBlockEntity; +import dev.galacticraft.machinelib.api.compat.transfer.MachineInsertHandler; +import dev.galacticraft.machinelib.api.compat.vanilla.RecipeHelper; +import dev.galacticraft.machinelib.api.machine.MachineStatus; +import dev.galacticraft.machinelib.api.storage.ResourceStorage; +import dev.galacticraft.machinelib.api.storage.StorageSpec; +import dev.galacticraft.machinelib.api.storage.slot.ItemResourceSlot; +import dev.galacticraft.mod.Constant; +import dev.galacticraft.mod.machine.GCMachineStatuses; +import dev.galacticraft.mod.recipe.CompressingRecipe; +import dev.galacticraft.mod.recipe.GCRecipes; +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.TransferVariant; +import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction; +import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext; +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.CraftingInput; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public abstract class AbstractCompressorBlockEntity extends BasicRecipeMachineBlockEntity implements MachineInsertHandler { + protected AbstractCompressorBlockEntity(BlockEntityType type, + BlockPos pos, BlockState state, StorageSpec spec, + int inputSlots, int inputSlotsLen, int outputSlots, int outputSlotsLen) { + super(type, pos, state, GCRecipes.COMPRESSING_TYPE, spec, inputSlots, inputSlotsLen, outputSlots, outputSlotsLen); + } + + @Override + protected @NotNull MachineStatus workingStatus(RecipeHolder recipe) { + return GCMachineStatuses.COMPRESSING; + } + + @Override + public int getProcessingTime(@NotNull RecipeHolder recipe) { + return recipe.value().getTime(); + } + + @Override + protected @NotNull CraftingInput craftingInv() { + return RecipeHelper.craftingInput(3, 3, this.inputSlots.getSlots()); + } + + @SuppressWarnings("UnstableApiUsage") + @Override + public long insert(ResourceStorage storage, TransferVariant variant, long maxAmount, TransactionContext transaction) { + if (!(variant instanceof ItemVariant incomingItemVariant)) { + return 0; + } + + // Stage 1: Find a valid recipe + ItemStack incomingItemStack = incomingItemVariant.toStack((int) maxAmount); + Int2ObjectMap initialItemStacks = collectItemStacks(storage, incomingItemStack); + + CompressingRecipe recipe = findRecipe(initialItemStacks.values()); + if (recipe == null) { + return 0; + } + + // Stage 2: Create a matching between the available item stacks and the recipe's ingredients + NonNullList ingredients = recipe.getIngredients(); + List sharedIngredients = new ArrayList<>(); + + for (int i = 0; i < this.inputSlotsLen; i++) { + Ingredient ingredient = i < ingredients.size() ? ingredients.get(i) : Ingredient.EMPTY; + + handled: { + for (SharedIngredient shared : sharedIngredients) { + if (ingredient.equals(shared.ingredient())) { + shared.slots().add(this.inputSlotsStart + i); + break handled; + } + } + + // Only reach this point if it has not been handled + sharedIngredients.add(new SharedIngredient(ingredient, IntArrayList.of(this.inputSlotsStart + i))); + } + } + + Int2ObjectMap toInsert = new Int2ObjectArrayMap<>(9); + + for (SharedIngredient shared : sharedIngredients) { + if (shared.ingredient().isEmpty()) { + continue; + } + + List stacks = initialItemStacks.values().stream() + .filter(stack -> shared.ingredient().test(stack)) + .collect(Collectors.toList()); + + int n = shared.slots().size(); + int k = stacks.size(); + if (n < k) { + return 0; + } + + stacks.sort((stack1, stack2) -> Integer.compare(stack2.getCount(), stack1.getCount())); + + int[] counts = stacks.stream().mapToInt(ItemStack::getCount).toArray(); + int[] solution = Solver.solve(counts, n); + + int index = 0; + for (int j = 0; j < k; j++) { + ItemStack stack = stacks.get(j); + int y = solution[j]; + + for (int i = 0; i < y; i++) { + toInsert.put(shared.slots().getInt(index), stack.copyWithCount((counts[j] + y - 1 - i) / y)); + ++index; + } + } + } + + try (Transaction tx = transaction.openNested()) { + // Stage 3: Rearrange items into the correct slots + // TODO: Try to leave ItemStacks where they are if we don't need to move them + for (int index = this.inputSlotsStart; index < this.inputSlotsStart + this.inputSlotsLen; index++) { + ItemResourceSlot slot = storage.slot(index); + + ItemStack stack = toInsert.getOrDefault(index, ItemStack.EMPTY); + Item item = stack.getItem(); + DataComponentPatch components = stack.getComponentsPatch(); + + if (slot.getResource() != null && !slot.contains(item, components)) { + slot.extract(slot.getResource(), slot.getComponents(), slot.getAmount(), tx); + } + + long difference = stack.getCount() - slot.getAmount(); + if (difference > 0) { + slot.insert(item, components, difference, tx); + } else if (difference < 0) { + slot.extract(item, components, -difference, tx); + } + } + + // Stage 4: Check that items haven't been created or destroyed and only commit everything matches up + Int2ObjectMap pendingItemStacks = collectItemStacks(storage, ItemStack.EMPTY); + + if (!initialItemStacks.keySet().equals(pendingItemStacks.keySet())) { + return 0; + } + + int incomingKey = ItemStack.hashItemAndComponents(incomingItemStack); + + for (var entry : initialItemStacks.int2ObjectEntrySet()) { + int key = entry.getIntKey(); + if (key == incomingKey) { + continue; + } + + ItemStack itemStack1 = entry.getValue(); + ItemStack itemStack2 = pendingItemStacks.get(key); + + if (itemStack1.getCount() != itemStack2.getCount()) { + return 0; + } + } + + ItemStack itemStack1 = initialItemStacks.get(incomingKey); + ItemStack itemStack2 = pendingItemStacks.get(incomingKey); + + long inserted = maxAmount - itemStack1.getCount() + itemStack2.getCount(); + if (inserted < 0 || inserted > maxAmount) { + return 0; + } + + tx.commit(); + return inserted; + } + } + + private Int2ObjectMap collectItemStacks(ResourceStorage storage, ItemStack incomingItemStack) { + Int2ObjectMap itemStacks = new Int2ObjectArrayMap<>(); + + if (!incomingItemStack.isEmpty()) { + itemStacks.put(ItemStack.hashItemAndComponents(incomingItemStack), incomingItemStack.copy()); + } + + for (int i = this.inputSlotsStart; i < this.inputSlotsStart + this.inputSlotsLen; i++) { + ItemResourceSlot slot = storage.slot(i); + Item item = slot.getResource(); + if (item != null) { + ItemStack stack = new ItemStack(item, (int) slot.getAmount()); + stack.applyComponents(slot.getComponents()); + + int key = ItemStack.hashItemAndComponents(stack); + if (itemStacks.containsKey(key)) { + itemStacks.get(key).grow(stack.getCount()); + } else { + itemStacks.put(key, stack); + } + } + } + + return itemStacks; + } + + private @Nullable CompressingRecipe findRecipe(Collection items) { + Predicate predicate = recipe -> items.stream().allMatch( + stack -> recipe.getIngredients().stream().anyMatch(ingredient -> ingredient.test(stack)) + ); + + RecipeHolder holder = this.getActiveRecipe(); + if (holder != null && holder.value() instanceof CompressingRecipe recipe && predicate.test(recipe)) { + return recipe; + } + + if (this.getLevel() == null) { + return null; + } + + RecipeManager recipeManager = this.getLevel().getRecipeManager(); + List recipes = recipeManager.getAllRecipesFor(GCRecipes.COMPRESSING_TYPE) + .stream().map(RecipeHolder::value).filter(predicate).toList(); + + if (recipes.size() > 1) { + Constant.LOGGER.info("Multiple compressing recipes found for the current set of items, arbitrarily choosing the first one."); + // TODO: Prioritise recipes with fewer missing ingredients, I'm not sure how else to make a more informed decision between these recipes + } + + return recipes.isEmpty() ? null : recipes.getFirst(); + } + + private record SharedIngredient(Ingredient ingredient, IntList slots) { + } + + private static class Solver { + private final int[] counts; + private final int k; + private final int n; + private float average = 0.0F; + private float minError = Float.POSITIVE_INFINITY; + private int[] bestSolution; + + public static int[] solve(int[] counts, int n) { + if (counts.length == 1) { + return new int[] {n}; + } + + Solver solver = new Solver(counts, n); + return solver.bestSolution; + } + + private Solver(int[] counts, int n) { + this.counts = counts; + this.k = this.counts.length; + this.n = n; + + for (int i = 0; i < this.k; i++) { + this.average += this.counts[i]; + } + this.average /= this.n; + + this.bestSolution = new int[this.k]; + Arrays.fill(this.bestSolution, 1); + if (this.k > 0) { + this.bestSolution[0] = this.n - this.k + 1; + } + + // Call a recursive function to find the solution + this.check(this.bestSolution); + } + + private void check(int[] x) { + float error = this.objectiveFunction(x); + if (error < this.minError) { + this.minError = error; + this.bestSolution = x; + } + + for (int i = 0; i < this.k - 1; i++) { + if (x[i] - 1 >= x[i + 1] + 1) { + int[] y = Arrays.copyOf(x, this.k); + y[i] -= 1; + y[i + 1] += 1; + this.check(y); + } else if (x[i] <= 2) { + break; + } + } + } + + private float objectiveFunction(int[] x) { + float output = 0.0F; + for (int i = 0; i < this.k; i++) { + output += Math.abs(this.counts[i] - this.average * x[i]); + } + return output; + } + } +} diff --git a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CircuitFabricatorBlockEntity.java b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CircuitFabricatorBlockEntity.java index b54ebe386..331d7f6fa 100644 --- a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CircuitFabricatorBlockEntity.java +++ b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CircuitFabricatorBlockEntity.java @@ -25,6 +25,7 @@ import com.mojang.datafixers.util.Pair; import dev.galacticraft.machinelib.api.block.entity.MachineBlockEntity; import dev.galacticraft.machinelib.api.block.entity.RecipeMachineBlockEntity; +import dev.galacticraft.machinelib.api.compat.transfer.MachineInsertHandler; import dev.galacticraft.machinelib.api.compat.vanilla.RecipeHelper; import dev.galacticraft.machinelib.api.filter.ResourceFilters; import dev.galacticraft.machinelib.api.machine.MachineStatus; @@ -32,6 +33,7 @@ import dev.galacticraft.machinelib.api.menu.MachineMenu; import dev.galacticraft.machinelib.api.storage.MachineEnergyStorage; import dev.galacticraft.machinelib.api.storage.MachineItemStorage; +import dev.galacticraft.machinelib.api.storage.ResourceStorage; import dev.galacticraft.machinelib.api.storage.StorageSpec; import dev.galacticraft.machinelib.api.storage.slot.ItemResourceSlot; import dev.galacticraft.machinelib.api.transfer.TransferType; @@ -43,14 +45,20 @@ import dev.galacticraft.mod.recipe.FabricationRecipe; import dev.galacticraft.mod.recipe.GCRecipes; import dev.galacticraft.mod.screen.CircuitFabricatorMenu; +import net.fabricmc.fabric.api.transfer.v1.item.ItemVariant; +import net.fabricmc.fabric.api.transfer.v1.storage.TransferVariant; +import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext; import net.minecraft.core.BlockPos; import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponentPatch; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.item.crafting.RecipeInput; @@ -63,7 +71,7 @@ import static dev.galacticraft.mod.Constant.CircuitFabricator.*; -public class CircuitFabricatorBlockEntity extends RecipeMachineBlockEntity { +public class CircuitFabricatorBlockEntity extends RecipeMachineBlockEntity implements MachineInsertHandler { public static final int CHARGE_SLOT = 0; public static final int DIAMOND_SLOT = 1; public static final int SILICON_SLOT_1 = 2; @@ -217,4 +225,46 @@ public int getProcessingTime(@NotNull RecipeHolder recipe) { public @Nullable MachineMenu createMenu(int syncId, Inventory inv, Player player) { return new CircuitFabricatorMenu(syncId, player, this); } + + @Override + public long insert(ResourceStorage storage, TransferVariant variant, long maxAmount, TransactionContext transaction) { + if (variant instanceof ItemVariant itemVariant) { + Item item = itemVariant.getItem(); + DataComponentPatch components = itemVariant.getComponents(); + return insertSilicon(storage, item, components, maxAmount, transaction); + } + return 0; + } + + public static long insertSilicon(ResourceStorage storage, Item item, DataComponentPatch components, long available, TransactionContext transaction) { + ItemResourceSlot slot1 = storage.slot(SILICON_SLOT_1); + ItemResourceSlot slot2 = storage.slot(SILICON_SLOT_2); + + long slot1Count = slot1.getAmount(); + long slot2Count = slot2.getAmount(); + long originalCount = slot1Count + slot2Count; + + if (slot1Count > 0 && !slot1.contains(item, components)) { + return 0; + } else if (slot2Count > 0 && !slot2.contains(item, components)) { + return 0; + } + + long slot1Capacity = slot1.getFilter().test(item, components) ? slot1.getCapacityFor(item, components) : 0; + long slot2Capacity = slot2.getFilter().test(item, components) ? slot2.getCapacityFor(item, components) : 0; + + long toInsert = Mth.clamp(slot1Capacity + slot2Capacity - originalCount, 0, available); + long inserted = 0; + + if (toInsert > 0) { + long totalCount = originalCount + toInsert; + long toInsert2 = Mth.clamp((totalCount / 2) - slot2Count, 0, toInsert); + long toInsert1 = toInsert - toInsert2; + + inserted += storage.slot(SILICON_SLOT_1).insert(item, components, toInsert1, transaction); + inserted += storage.slot(SILICON_SLOT_2).insert(item, components, toInsert2, transaction); + } + + return inserted; + } } diff --git a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CompressorBlockEntity.java b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CompressorBlockEntity.java index 5f9789586..8b4b2c799 100644 --- a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CompressorBlockEntity.java +++ b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/CompressorBlockEntity.java @@ -22,9 +22,7 @@ package dev.galacticraft.mod.content.block.entity.machine; -import dev.galacticraft.machinelib.api.block.entity.BasicRecipeMachineBlockEntity; import dev.galacticraft.machinelib.api.block.entity.MachineBlockEntity; -import dev.galacticraft.machinelib.api.compat.vanilla.RecipeHelper; import dev.galacticraft.machinelib.api.machine.MachineStatus; import dev.galacticraft.machinelib.api.menu.MachineMenu; import dev.galacticraft.machinelib.api.storage.MachineItemStorage; @@ -36,7 +34,6 @@ import dev.galacticraft.mod.content.block.machine.CompressorBlock; import dev.galacticraft.mod.machine.GCMachineStatuses; import dev.galacticraft.mod.recipe.CompressingRecipe; -import dev.galacticraft.mod.recipe.GCRecipes; import dev.galacticraft.mod.screen.CompressorMenu; import net.fabricmc.fabric.api.registry.FuelRegistry; import net.minecraft.core.BlockPos; @@ -49,7 +46,6 @@ import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; @@ -59,7 +55,7 @@ import static dev.galacticraft.mod.Constant.Compressor.*; -public class CompressorBlockEntity extends BasicRecipeMachineBlockEntity implements CoalPoweredMachine { +public class CompressorBlockEntity extends AbstractCompressorBlockEntity implements CoalPoweredMachine { public static final int FUEL_SLOT = 0; public static final int INPUT_SLOTS = 1; public static final int INPUT_LENGTH = 9; @@ -79,19 +75,16 @@ public class CompressorBlockEntity extends BasicRecipeMachineBlockEntity { Integer integer = FuelRegistry.INSTANCE.get(item); return integer != null && integer > 0; - })) + }) + ) .add3x3Grid(TransferType.INPUT, GRID_X, GRID_Y) .add(ItemResourceSlot.builder(TransferType.OUTPUT) - .pos(OUTPUT_X, OUTPUT_Y)) + .pos(OUTPUT_X, OUTPUT_Y) + ) ); public CompressorBlockEntity(BlockPos pos, BlockState state) { - super(GCBlockEntityTypes.COMPRESSOR, pos, state, GCRecipes.COMPRESSING_TYPE, SPEC, INPUT_SLOTS, INPUT_LENGTH, OUTPUT_SLOT); - } - - @Override - protected @NotNull MachineStatus workingStatus(RecipeHolder recipe) { - return GCMachineStatuses.COMPRESSING; + super(GCBlockEntityTypes.COMPRESSOR, pos, state, SPEC, INPUT_SLOTS, INPUT_LENGTH, OUTPUT_SLOT, 1); } @Override @@ -186,11 +179,6 @@ private boolean shouldExtinguish(Level level, BlockPos pos, BlockState state) { && !level.isBreathable(pos); } - @Override - public int getProcessingTime(@NotNull RecipeHolder recipe) { - return recipe.value().getTime(); - } - public int getFuelTime() { return fuelTime; } @@ -219,9 +207,4 @@ public void loadAdditional(CompoundTag tag, HolderLookup.Provider lookup) { public @Nullable MachineMenu createMenu(int syncId, Inventory inv, Player player) { return new CompressorMenu(syncId, player, this); } - - @Override - protected CraftingInput craftingInv() { - return RecipeHelper.craftingInput(3, 3, this.inputSlots.getSlots()); - } } diff --git a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/ElectricCompressorBlockEntity.java b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/ElectricCompressorBlockEntity.java index 5b30dff63..485fb52d3 100644 --- a/src/main/java/dev/galacticraft/mod/content/block/entity/machine/ElectricCompressorBlockEntity.java +++ b/src/main/java/dev/galacticraft/mod/content/block/entity/machine/ElectricCompressorBlockEntity.java @@ -23,9 +23,7 @@ package dev.galacticraft.mod.content.block.entity.machine; import com.mojang.datafixers.util.Pair; -import dev.galacticraft.machinelib.api.block.entity.BasicRecipeMachineBlockEntity; import dev.galacticraft.machinelib.api.block.entity.MachineBlockEntity; -import dev.galacticraft.machinelib.api.compat.vanilla.RecipeHelper; import dev.galacticraft.machinelib.api.filter.ResourceFilters; import dev.galacticraft.machinelib.api.machine.MachineStatus; import dev.galacticraft.machinelib.api.machine.MachineStatuses; @@ -39,9 +37,7 @@ import dev.galacticraft.mod.Constant; import dev.galacticraft.mod.Galacticraft; import dev.galacticraft.mod.content.GCBlockEntityTypes; -import dev.galacticraft.mod.machine.GCMachineStatuses; import dev.galacticraft.mod.recipe.CompressingRecipe; -import dev.galacticraft.mod.recipe.GCRecipes; import dev.galacticraft.mod.screen.GCMenuTypes; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -51,7 +47,6 @@ import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.item.crafting.CraftingInput; import net.minecraft.world.item.crafting.RecipeHolder; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; @@ -59,7 +54,7 @@ import static dev.galacticraft.mod.Constant.ElectricCompressor.*; -public class ElectricCompressorBlockEntity extends BasicRecipeMachineBlockEntity { +public class ElectricCompressorBlockEntity extends AbstractCompressorBlockEntity { public static final int CHARGE_SLOT = 0; public static final int INPUT_SLOTS = 1; public static final int INPUT_LENGTH = 9; @@ -89,7 +84,7 @@ public class ElectricCompressorBlockEntity extends BasicRecipeMachineBlockEntity ); public ElectricCompressorBlockEntity(BlockPos pos, BlockState state) { - super(GCBlockEntityTypes.ELECTRIC_COMPRESSOR, pos, state, GCRecipes.COMPRESSING_TYPE, SPEC, INPUT_SLOTS, INPUT_LENGTH, OUTPUT_SLOTS, OUTPUT_LENGTH); + super(GCBlockEntityTypes.ELECTRIC_COMPRESSOR, pos, state, SPEC, INPUT_SLOTS, INPUT_LENGTH, OUTPUT_SLOTS, OUTPUT_LENGTH); } @Override @@ -110,11 +105,6 @@ protected void tickConstant(@NotNull ServerLevel world, @NotNull BlockPos pos, @ return super.tick(level, pos, state, profiler); } - @Override - protected @NotNull MachineStatus workingStatus(RecipeHolder recipe) { - return GCMachineStatuses.COMPRESSING; - } - @Override protected @Nullable MachineStatus hasResourcesToWork() { return this.energyStorage().canExtract(Galacticraft.CONFIG.electricCompressorEnergyConsumptionRate()) ? null : MachineStatuses.NOT_ENOUGH_ENERGY; @@ -127,7 +117,7 @@ protected void extractResourcesToWork() { @Override public int getProcessingTime(@NotNull RecipeHolder recipe) { - return (int) (recipe.value().getTime() / 1.5F); + return (int) (super.getProcessingTime(recipe) / 1.5F); } @Override @@ -147,9 +137,4 @@ protected void craft(@NotNull ProfilerFiller profiler, @NotNull RecipeHolder= this.internalSlots && stackFrom.is(GCItemTags.SILICONS)) { + if (index >= this.internalSlots) { Item item = stackFrom.getItem(); - DataComponentPatch dataComponentPatch = stackFrom.getComponentsPatch(); + DataComponentPatch components = stackFrom.getComponentsPatch(); long available = stackFrom.getCount(); - ItemResourceSlot slot1 = this.itemStorage.slot(CircuitFabricatorBlockEntity.SILICON_SLOT_1); - ItemResourceSlot slot2 = this.itemStorage.slot(CircuitFabricatorBlockEntity.SILICON_SLOT_2); + try (Transaction transaction = Transaction.openOuter()) { + long inserted = CircuitFabricatorBlockEntity.insertSilicon(this.itemStorage, item, components, available, transaction); - long slot1Count = slot1.getAmount(); - long slot2Count = slot2.getAmount(); - long originalCount = slot1Count + slot2Count; + if (inserted > 0) { + transaction.commit(); + available -= inserted; - long slot1Capacity = slot1.getCapacityFor(item, dataComponentPatch); - long slot2Capacity = slot2.getCapacityFor(item, dataComponentPatch); + if (available == 0) { + slotFrom.setByPlayer(ItemStack.EMPTY); + } else { + stackFrom.setCount((int) available); + slotFrom.setChanged(); + } - long toInsert = Mth.clamp(slot1Capacity + slot2Capacity - originalCount, 0, available); - - if (toInsert > 0) { - long totalCount = originalCount + toInsert; - long toInsert2 = Mth.clamp((totalCount / 2) - slot2Count, 0, toInsert); - long toInsert1 = toInsert - toInsert2; - - available -= slot1.insert(item, dataComponentPatch, toInsert1); - available -= slot2.insert(item, dataComponentPatch, toInsert2); - - if (available == 0) { - slotFrom.setByPlayer(ItemStack.EMPTY); - } else { - stackFrom.setCount((int) available); - slotFrom.setChanged(); + return ItemStack.EMPTY; } - - return ItemStack.EMPTY; } }