Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: make crafting grid code reusable #723

Merged
merged 1 commit into from
Nov 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ subprojects {
group = "com.refinedmods.refinedstorage"
}

/* publish all subprojects to mavenLocal */
subprojects {
apply(plugin = "maven-publish")

publishing {
repositories {
mavenLocal()
}
}
}

project.extensions.getByType<SonarExtension>().apply {
properties {
property(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage.common.autocrafting.patterngrid;

import com.refinedmods.refinedstorage.api.network.storage.StorageNetworkComponent;
import com.refinedmods.refinedstorage.api.resource.ResourceAmount;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.common.Platform;
Expand Down Expand Up @@ -496,7 +497,9 @@ private boolean isPatternAvailable() {

void transferCraftingRecipe(final Player player, final List<List<ItemResource>> recipe) {
final Comparator<ResourceKey> sorter = ResourceSorters.create(
mainNetworkNode.getNetwork(),
mainNetworkNode.getNetwork() != null
? mainNetworkNode.getNetwork().getComponent(StorageNetworkComponent.class)
: null,
player.getInventory()
);
getCraftingMatrix().clearContent();
Expand All @@ -517,7 +520,9 @@ void transferProcessingRecipe(final Player player,
final List<List<ResourceAmount>> inputs,
final List<List<ResourceAmount>> outputs) {
final Comparator<ResourceAmount> sorter = ResourceSorters.create(
mainNetworkNode.getNetwork(),
mainNetworkNode.getNetwork() != null
? mainNetworkNode.getNetwork().getComponent(StorageNetworkComponent.class)
: null,
player.getInventory(),
ResourceAmount::resource
);
Expand Down Expand Up @@ -556,7 +561,9 @@ void transferSmithingTableRecipe(final Player player,
return;
}
final Comparator<ItemResource> sorter = ResourceSorters.create(
mainNetworkNode.getNetwork(),
mainNetworkNode.getNetwork() != null
? mainNetworkNode.getNetwork().getComponent(StorageNetworkComponent.class)
: null,
player.getInventory(),
r -> r
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
package com.refinedmods.refinedstorage.common.grid;

import com.refinedmods.refinedstorage.api.grid.view.GridResource;
import com.refinedmods.refinedstorage.api.grid.view.GridView;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.api.resource.list.MutableResourceList;
import com.refinedmods.refinedstorage.common.grid.view.ItemGridResource;
import com.refinedmods.refinedstorage.common.support.resource.ItemResource;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import javax.annotation.Nullable;

import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.MenuType;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.apiguardian.api.API;

public abstract class AbstractCraftingGridContainerMenu extends AbstractGridContainerMenu {
private static final int Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT = 69;

private final Player gridPlayer;
private final CraftingGrid craftingGrid;
private final List<Slot> craftingMatrixSlots = new ArrayList<>();

@Nullable
private Consumer<Boolean> activenessListener;
@Nullable
private BiPredicate<GridView, GridResource> filterBeforeFilteringBasedOnCraftingMatrixItems;

protected AbstractCraftingGridContainerMenu(final MenuType<? extends AbstractGridContainerMenu> menuType,
final int syncId,
final Inventory playerInventory,
final GridData gridData) {
super(menuType, syncId, playerInventory, gridData);
this.craftingGrid = new ClientCraftingGrid();
this.gridPlayer = playerInventory.player;
}

protected AbstractCraftingGridContainerMenu(final MenuType<? extends AbstractGridContainerMenu> menuType,
final int syncId,
final Inventory playerInventory,
final CraftingGrid craftingGrid) {
super(menuType, syncId, playerInventory, craftingGrid);
this.craftingGrid = craftingGrid;
this.gridPlayer = playerInventory.player;
}

public void setActivenessListener(@Nullable final Consumer<Boolean> activenessListener) {
this.activenessListener = activenessListener;
}

@Override
public void onActiveChanged(final boolean newActive) {
super.onActiveChanged(newActive);
if (activenessListener != null) {
activenessListener.accept(newActive);
}
}

@Override
public boolean canTakeItemForPickAll(final ItemStack stack, final Slot slot) {
if (slot instanceof CraftingGridResultSlot) {
return false;
}
return super.canTakeItemForPickAll(stack, slot);
}

@Override
@SuppressWarnings("resource")
public ItemStack quickMoveStack(final Player actor, final int slotIndex) {
final Slot slot = getSlot(slotIndex);
if (!actor.level().isClientSide()
&& slot instanceof CraftingGridResultSlot resultSlot
&& resultSlot.hasItem()) {
final ItemStack craftedStack = resultSlot.onQuickCraft(actor);
craftingGrid.acceptQuickCraft(actor, craftedStack);
return ItemStack.EMPTY;
}
return super.quickMoveStack(actor, slotIndex);
}

@Override
public void resized(final int playerInventoryY, final int topYStart, final int topYEnd) {
super.resized(playerInventoryY, topYStart, topYEnd);
craftingMatrixSlots.clear();
for (int y = 0; y < 3; ++y) {
for (int x = 0; x < 3; ++x) {
final int slotX = 26 + ((x % 3) * 18);
final int slotY = playerInventoryY
- Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT
+ ((y % 3) * 18);
craftingMatrixSlots.add(addSlot(new Slot(craftingGrid.getCraftingMatrix(), x + y * 3, slotX, slotY)));
}
}
addSlot(new CraftingGridResultSlot(
gridPlayer,
craftingGrid,
130 + 4,
playerInventoryY - Y_OFFSET_BETWEEN_PLAYER_INVENTORY_AND_FIRST_CRAFTING_MATRIX_SLOT + 18
));
}

public List<Slot> getCraftingMatrixSlots() {
return craftingMatrixSlots;
}

public void clear(final boolean toPlayerInventory) {
craftingGrid.clearMatrix(gridPlayer, toPlayerInventory);
}

@API(status = API.Status.INTERNAL)
public MutableResourceList getAvailableListForRecipeTransfer() {
final MutableResourceList available = getView().copyBackingList();
addContainerToList(craftingGrid.getCraftingMatrix(), available);
addContainerToList(gridPlayer.getInventory(), available);
return available;
}

private void addContainerToList(final Container container, final MutableResourceList available) {
for (int i = 0; i < container.getContainerSize(); ++i) {
final ItemStack stack = container.getItem(i);
if (stack.isEmpty()) {
continue;
}
available.add(ItemResource.ofItemStack(stack), stack.getCount());
}
}

public void transferRecipe(final List<List<ItemResource>> recipe) {
craftingGrid.transferRecipe(gridPlayer, recipe);
}

public void filterBasedOnCraftingMatrixItems() {
final Set<ItemResource> craftingMatrixItems = getCraftingMatrixItems();
filterBeforeFilteringBasedOnCraftingMatrixItems = getView().setFilterAndSort(
(view, resource) -> resource instanceof ItemGridResource itemResource
&& craftingMatrixItems.contains(itemResource.getItemResource())
);
}

private Set<ItemResource> getCraftingMatrixItems() {
final Set<ItemResource> craftingMatrixItems = new HashSet<>();
for (int i = 0; i < craftingGrid.getCraftingMatrix().getContainerSize(); ++i) {
final ItemStack craftingMatrixStack = craftingGrid.getCraftingMatrix().getItem(i);
if (craftingMatrixStack.isEmpty()) {
continue;
}
craftingMatrixItems.add(ItemResource.ofItemStack(craftingMatrixStack));
}
return craftingMatrixItems;
}

public void stopFilteringBasedOnCraftingMatrixItems() {
if (filterBeforeFilteringBasedOnCraftingMatrixItems == null) {
return;
}
getView().setFilterAndSort(filterBeforeFilteringBasedOnCraftingMatrixItems);
filterBeforeFilteringBasedOnCraftingMatrixItems = null;
}

@Nullable
@Override
protected ResourceKey getResourceForAutocraftableHint(final Slot slot) {
if (slot.container == craftingGrid.getCraftingMatrix() || slot.container == craftingGrid.getCraftingResult()) {
return ItemResource.ofItemStack(slot.getItem());
}
return super.getResourceForAutocraftableHint(slot);
}

@Override
public boolean isLargeSlot(final Slot slot) {
return slot.container == craftingGrid.getCraftingResult() || super.isLargeSlot(slot);
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
package com.refinedmods.refinedstorage.common.grid;

import com.refinedmods.refinedstorage.api.autocrafting.preview.Preview;
import com.refinedmods.refinedstorage.api.grid.operations.GridOperations;
import com.refinedmods.refinedstorage.api.grid.watcher.GridWatcher;
import com.refinedmods.refinedstorage.api.resource.ResourceKey;
import com.refinedmods.refinedstorage.api.storage.Actor;
import com.refinedmods.refinedstorage.api.storage.Storage;
import com.refinedmods.refinedstorage.api.storage.TrackedResourceAmount;
import com.refinedmods.refinedstorage.common.api.support.resource.PlatformResourceKey;
import com.refinedmods.refinedstorage.common.api.support.resource.ResourceType;
import com.refinedmods.refinedstorage.common.support.RecipeMatrixContainer;
import com.refinedmods.refinedstorage.common.support.packet.c2s.C2SPackets;
import com.refinedmods.refinedstorage.common.support.resource.ItemResource;

import java.util.List;
import java.util.Optional;
import java.util.Set;

import net.minecraft.core.NonNullList;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ResultContainer;
import net.minecraft.world.item.ItemStack;
Expand Down Expand Up @@ -37,13 +49,8 @@ public NonNullList<ItemStack> getRemainingItems(final Player player, final Craft
}

@Override
public CraftingGridRefillContext openRefillContext() {
throw new UnsupportedOperationException();
}

@Override
public CraftingGridRefillContext openSnapshotRefillContext(final Player player) {
throw new UnsupportedOperationException();
public ExtractTransaction startExtractTransaction(final Player player, final boolean directCommit) {
return ExtractTransaction.NOOP;
}

@Override
Expand All @@ -61,4 +68,49 @@ public void transferRecipe(final Player player, final List<List<ItemResource>> r
public void acceptQuickCraft(final Player player, final ItemStack craftedStack) {
throw new UnsupportedOperationException();
}

@Override
public void addWatcher(final GridWatcher watcher, final Class<? extends Actor> actorType) {
throw new UnsupportedOperationException();
}

@Override
public void removeWatcher(final GridWatcher watcher) {
throw new UnsupportedOperationException();
}

@Override
public Storage getItemStorage() {
throw new UnsupportedOperationException();
}

@Override
public boolean isGridActive() {
throw new UnsupportedOperationException();
}

@Override
public List<TrackedResourceAmount> getResources(final Class<? extends Actor> actorType) {
throw new UnsupportedOperationException();
}

@Override
public Set<PlatformResourceKey> getAutocraftableResources() {
throw new UnsupportedOperationException();
}

@Override
public GridOperations createOperations(final ResourceType resourceType, final ServerPlayer player) {
throw new UnsupportedOperationException();
}

@Override
public Optional<Preview> getPreview(final ResourceKey resource, final long amount) {
throw new UnsupportedOperationException();
}

@Override
public boolean startTask(final ResourceKey resource, final long amount) {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.refinedmods.refinedstorage.common.grid;

import com.refinedmods.refinedstorage.common.api.grid.Grid;
import com.refinedmods.refinedstorage.common.support.RecipeMatrixContainer;
import com.refinedmods.refinedstorage.common.support.resource.ItemResource;

Expand All @@ -11,16 +12,14 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingInput;

interface CraftingGrid {
public interface CraftingGrid extends Grid {
RecipeMatrixContainer getCraftingMatrix();

ResultContainer getCraftingResult();

NonNullList<ItemStack> getRemainingItems(Player player, CraftingInput input);

CraftingGridRefillContext openRefillContext();

CraftingGridRefillContext openSnapshotRefillContext(Player player);
ExtractTransaction startExtractTransaction(Player player, boolean directCommit);

boolean clearMatrix(Player player, boolean toPlayerInventory);

Expand Down
Loading
Loading