Skip to content

Commit

Permalink
Merge pull request #21 from Tfarcenim/master
Browse files Browse the repository at this point in the history
fix shiftclicking craft bug
  • Loading branch information
MariaTheDinkus authored Jul 24, 2020
2 parents c0f86f4 + 98b3ef1 commit c39e9d2
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 25 deletions.
21 changes: 21 additions & 0 deletions src/main/java/io/github/alloffabric/artis/Artis.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,21 @@
import io.github.alloffabric.artis.util.ArtisRegistry;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
import net.fabricmc.fabric.impl.screenhandler.ExtendedScreenHandlerType;
import net.minecraft.block.Block;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.client.MinecraftClient;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.recipe.Recipe;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerContext;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
Expand All @@ -36,6 +42,10 @@
public class Artis implements ModInitializer {
public static final String MODID = "artis";

public static final Identifier recipe_sync = new Identifier(MODID,"sync_recipe");
public static final Identifier request_sync = new Identifier(MODID,"request_sync");
public static final Identifier dummy = new Identifier("null","null");

public static final Logger logger = LogManager.getLogger();

public static final ArrayList<ArtisTableBlock> ARTIS_TABLE_BLOCKS = new ArrayList<>();
Expand Down Expand Up @@ -80,6 +90,17 @@ public void onInitialize() {
ArtisEvents.init();
isLoaded = true;
ARTIS_BLOCK_ENTITY = registerBlockEntity("artis_table", ArtisTableBlockEntity::new, Arrays.copyOf(ARTIS_TABLE_BLOCKS.toArray(), ARTIS_TABLE_BLOCKS.size(), ArtisTableBlock[].class));

//seems to be required to not have the recipe vanish when initially opened
ServerSidePacketRegistry.INSTANCE.register(Artis.request_sync,
(packetContext, attachedData) -> {
packetContext.getTaskQueue().execute(() -> {
ScreenHandler container = packetContext.getPlayer().currentScreenHandler;
if (container instanceof ArtisCraftingController) {
container.onContentChanged(null);
}
});
});
}
}
}
35 changes: 35 additions & 0 deletions src/main/java/io/github/alloffabric/artis/ArtisClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,16 @@
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry;
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.recipe.Recipe;
import net.minecraft.screen.CraftingScreenHandler;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
Expand Down Expand Up @@ -75,6 +84,32 @@ public void onInitializeClient() {
assets.addItemModel(id, ITEM_MODELS.get(id));
}
});

ClientSidePacketRegistry.INSTANCE.register(Artis.recipe_sync,
(packetContext, attachedData) -> {
Identifier location = attachedData.readIdentifier();
packetContext.getTaskQueue().execute(() -> {
ScreenHandler container = packetContext.getPlayer().currentScreenHandler;
if (container instanceof ArtisCraftingController) {
Recipe<?> r = MinecraftClient.getInstance().world.getRecipeManager().get(location).orElse(null);
updateLastRecipe((ArtisCraftingController) packetContext.getPlayer().currentScreenHandler, (Recipe<CraftingInventory>) r);
}
});
});
}

public static void updateLastRecipe(ArtisCraftingController container, Recipe<CraftingInventory> rec) {

CraftingInventory craftInput = container.getCraftInv();
CraftingResultInventory craftResult = container.getResultInv();

if (craftInput == null) {
System.out.println("why are these null?");
} else {
craftResult.setLastRecipe(rec);
if (rec != null) craftResult.setStack(0, rec.craft(craftInput));
else craftResult.setStack(0, ItemStack.EMPTY);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
import io.github.cottonmc.cotton.gui.client.ScreenDrawing;
import io.github.cottonmc.cotton.gui.widget.*;
import io.github.cottonmc.cotton.gui.widget.data.HorizontalAlignment;
import io.netty.buffer.Unpooled;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.network.ClientSidePacketRegistry;
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.recipe.CraftingRecipe;
import net.minecraft.recipe.Recipe;
Expand All @@ -34,6 +38,7 @@
import net.minecraft.util.Identifier;
import net.minecraft.world.World;

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

public class ArtisCraftingController extends SyncedGuiDescription implements RecipeProvider {
Expand Down Expand Up @@ -65,7 +70,6 @@ public ArtisCraftingController(ScreenHandlerType type, ArtisTableType tableType,
craftInv.setStack(i, blockInventory.getStack(i));
}
}

ContainerLayout layout = new ContainerLayout(tableType.getWidth(), tableType.getHeight());

panel = new WPlainPanel();
Expand Down Expand Up @@ -95,6 +99,11 @@ public ArtisCraftingController(ScreenHandlerType type, ArtisTableType tableType,
panel.add(arrow, layout.getArrowX(), layout.getArrowY() + 4, 22, 15);

panel.validate(this);
craftInv.setCheckMatrixChanges(true);
if (player.world.isClient) {
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
ClientSidePacketRegistry.INSTANCE.sendToServer(Artis.request_sync, buf);
}
}

private static BackgroundPainter slotColor(int color) {
Expand Down Expand Up @@ -124,6 +133,10 @@ public ArtisCraftingInventory getCraftInv() {
return craftInv;
}

public CraftingResultInventory getResultInv() {
return resultInv;
}

public PlayerEntity getPlayer() {
return player;
}
Expand Down Expand Up @@ -188,6 +201,17 @@ public int getCraftingSlotCount() {
return getTableType().getWidth() * getTableType().getHeight();
}

// update crafting
//clientside only
@Override
public void updateSlotStacks(List<ItemStack> stacks) {
craftInv.setCheckMatrixChanges(false);
super.updateSlotStacks(stacks);
craftInv.setCheckMatrixChanges(true);
onContentChanged(null);
}

//leaving here in case it's needed
public void updateResult(int syncId, World world, PlayerEntity player, CraftingInventory craftInv, CraftingResultInventory resultInv) {
if (!world.isClient) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
Expand Down Expand Up @@ -224,11 +248,40 @@ public void updateResult(int syncId, World world, PlayerEntity player, CraftingI
}
}

//like vanilla, but not a pile of lag
public static void updateResult(World world, PlayerEntity player, CraftingInventory inv, CraftingResultInventory result, ArtisTableType artisTableType) {
if (!world.isClient) {

ItemStack itemstack = ItemStack.EMPTY;

boolean isArtis = false;

Recipe<CraftingInventory> recipe = (Recipe<CraftingInventory>) result.getLastRecipe();
//find artis recipe first
if (recipe == null || !recipe.matches(inv, world)) {
recipe = findArtisRecipe(artisTableType,inv, world);
if (recipe != null) isArtis = true;
}
//else fall back to vanilla
if (recipe == null && artisTableType.shouldIncludeNormalRecipes()) {
recipe = findVanillaRecipe(inv,world);
}
//there is no matching recipe
if (recipe != null) {
itemstack = recipe.craft(inv);
}

result.setStack(0, itemstack);
PacketByteBuf buf = new PacketByteBuf(Unpooled.buffer());
buf.writeIdentifier(recipe != null ? recipe.getId(): Artis.dummy);
ServerSidePacketRegistry.INSTANCE.sendToPlayer(player, Artis.recipe_sync, buf);
result.setLastRecipe(recipe);
}
}

@Override
public void onContentChanged(Inventory inv) {
this.context.run((world, pos) -> {
updateResult(this.syncId, world, this.player, this.craftInv, this.resultInv);
});
updateResult(world,player,craftInv,resultInv,tableType);
}

@Override
Expand All @@ -241,18 +294,12 @@ public ItemStack transferSlot(PlayerEntity player, int slotIndex) {
ItemStack stack = ItemStack.EMPTY;
Slot slot = this.slots.get(slotIndex);
if (slot != null && slot.hasStack()) {
ItemStack toTake = slot.getStack();
stack = toTake.copy();
if (slotIndex == getCraftingResultSlotIndex()) {
this.context.run((world, pos) -> {
toTake.getItem().onCraft(toTake, world, player);
});
if (!this.insertItem(toTake, 0, 35, true)) {
return ItemStack.EMPTY;
}

slot.onStackChanged(toTake, stack);
int slotcount = getCraftingSlotCount() + (tableType.hasCatalystSlot() ? 1 : 0);
return handleShiftCraft(player,this,slot,craftInv,resultInv,slotcount,slotcount + 36);
}
ItemStack toTake = slot.getStack();
stack = toTake.copy();

if (toTake.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
Expand Down Expand Up @@ -297,4 +344,50 @@ public void clearCraftingSlots() {
public boolean canInsertIntoSlot(ItemStack stack, Slot slot) {
return slot.inventory != this.resultInv && super.canInsertIntoSlot(stack, slot);
}

public static ItemStack handleShiftCraft(PlayerEntity player, ArtisCraftingController container, Slot resultSlot, ArtisCraftingInventory input, CraftingResultInventory craftResult, int outStart, int outEnd) {
ItemStack outputCopy = ItemStack.EMPTY;
input.setCheckMatrixChanges(false);
if (resultSlot != null && resultSlot.hasStack()) {

Recipe<CraftingInventory> recipe = (Recipe<CraftingInventory>) craftResult.getLastRecipe();
if (recipe == null && container.tableType.shouldIncludeNormalRecipes()) {
recipe = findVanillaRecipe(input,player.world);
}
while (recipe != null && recipe.matches(input, player.world)) {
ItemStack recipeOutput = resultSlot.getStack().copy();
outputCopy = recipeOutput.copy();

recipeOutput.getItem().onCraft(recipeOutput, player.world, player);

if (!player.world.isClient && !container.insertItem(recipeOutput, outStart, outEnd,true)) {
input.setCheckMatrixChanges(true);
return ItemStack.EMPTY;
}

resultSlot.onStackChanged(recipeOutput, outputCopy);
resultSlot.markDirty();

if (!player.world.isClient && recipeOutput.getCount() == outputCopy.getCount()) {
input.setCheckMatrixChanges(true);
return ItemStack.EMPTY;
}

ItemStack itemstack2 = resultSlot.onTakeItem(player, recipeOutput);
player.dropItem(itemstack2, false);
}
input.setCheckMatrixChanges(true);
updateResult(player.world, player, input, craftResult, container.tableType);
}
input.setCheckMatrixChanges(true);
return craftResult.getLastRecipe() == null ? ItemStack.EMPTY : outputCopy;
}

public static Recipe<CraftingInventory> findArtisRecipe(ArtisTableType tableType, CraftingInventory inv, World world) {
return (Recipe<CraftingInventory>) world.getRecipeManager().getFirstMatch(tableType, inv, world).orElse(null);
}

public static Recipe<CraftingInventory> findVanillaRecipe(CraftingInventory inv, World world) {
return world.getRecipeManager().getFirstMatch(RecipeType.CRAFTING, inv, world).orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
public class ArtisCraftingInventory extends CraftingInventory {
private final DefaultedList<ItemStack> stacks;
private final ArtisCraftingController container;
private boolean checkMatrixChanges = false;

public ArtisCraftingInventory(ArtisCraftingController container, int width, int height) {
super(container, width, height);
Expand Down Expand Up @@ -48,16 +49,15 @@ public ItemStack removeStack(int slot) {
public ItemStack removeStack(int slot, int amount) {
ItemStack stack = Inventories.splitStack(this.stacks, slot, amount);
if (!stack.isEmpty()) {
this.container.onContentChanged(this);
if (checkMatrixChanges)this.container.onContentChanged(this);
}

return stack;
}

@Override
public void setStack(int slot, ItemStack stack) {
this.stacks.set(slot, stack);
this.container.onContentChanged(this);
if (checkMatrixChanges)this.container.onContentChanged(this);
}

@Override
Expand Down Expand Up @@ -94,4 +94,12 @@ public boolean shouldCompareCatalyst() {
public PlayerEntity getPlayer() {
return container.getPlayer();
}

public void setCheckMatrixChanges(boolean b) {
this.checkMatrixChanges = b;
}

public DefaultedList<ItemStack> getStacks() {
return stacks;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import io.github.cottonmc.cotton.gui.ValidatedSlot;
import net.fabricmc.fabric.api.network.ServerSidePacketRegistry;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.inventory.CraftingInventory;
import net.minecraft.inventory.CraftingResultInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
Expand All @@ -27,6 +29,11 @@ public ValidatedArtisResultSlot(PlayerEntity player, ArtisCraftingInventory inve
this.syncId = syncId;
}

@Override
public void setStack(ItemStack stack) {
//super.setStack(stack);
}

@Override
public boolean canInsert(ItemStack stack) {
return false;
Expand All @@ -37,7 +44,6 @@ public ItemStack takeStack(int amount) {
if (this.hasStack()) {
this.amount += Math.min(amount, this.getStack().getCount());
}

return super.takeStack(amount);
}

Expand All @@ -57,19 +63,13 @@ protected void onCrafted(ItemStack stack) {
if (this.amount > 0) {
stack.onCraft(this.player.world, this.player, this.amount);
}

if (this.inventory instanceof RecipeUnlocker) {
((RecipeUnlocker) this.inventory).unlockLastRecipe(this.player);
}

this.amount = 0;
}

@Override
public ItemStack onTakeItem(PlayerEntity player, ItemStack stack) {
this.onCrafted(stack);
DefaultedList<ItemStack> remainders = player.world.getRecipeManager().getRemainingStacks(craftingInv.getType(), this.craftingInv, player.world);

DefaultedList<ItemStack> remainders = getRemainders(); //= player.world.getRecipeManager().getRemainingStacks(craftingInv.getType(), this.craftingInv, player.world);
for (int i = 0; i < remainders.size() - 1; ++i) {
ItemStack input = this.craftingInv.getStack(i);
ItemStack remainder = remainders.get(i);
Expand Down Expand Up @@ -116,4 +116,13 @@ public ItemStack onTakeItem(PlayerEntity player, ItemStack stack) {

return stack;
}

//note: inventory is actually CraftingResultInventory so it's a safe cast
public DefaultedList<ItemStack> getRemainders() {
Recipe<CraftingInventory> lastRecipe = (Recipe<CraftingInventory>) ((CraftingResultInventory)this.inventory).getLastRecipe();
if (lastRecipe != null &&
lastRecipe.matches(craftingInv, player.world))
return lastRecipe.getRemainingStacks(craftingInv);
else return craftingInv.getStacks();
}
}

0 comments on commit c39e9d2

Please sign in to comment.