Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
On-the-fly smithing transform recipes
Dieser Commit ist enthalten in:
Ursprung
05f153c941
Commit
52679f9f81
@ -182,6 +182,13 @@ public class GeyserItemStack {
|
|||||||
return session.getItemMappings().getMapping(this.javaId);
|
return session.getItemMappings().getMapping(this.javaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SlotDisplay asSlotDisplay() {
|
||||||
|
if (isEmpty()) {
|
||||||
|
return new EmptySlotDisplay();
|
||||||
|
}
|
||||||
|
return new ItemStackSlotDisplay(this.getItemStack());
|
||||||
|
}
|
||||||
|
|
||||||
public Item asItem() {
|
public Item asItem() {
|
||||||
if (isEmpty()) {
|
if (isEmpty()) {
|
||||||
return Items.AIR;
|
return Items.AIR;
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.inventory.recipe;
|
||||||
|
|
||||||
|
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.SmithingRecipeDisplay;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;
|
||||||
|
|
||||||
|
public record GeyserSmithingRecipe(SlotDisplay template,
|
||||||
|
SlotDisplay base,
|
||||||
|
SlotDisplay addition,
|
||||||
|
SlotDisplay result) implements GeyserRecipe {
|
||||||
|
public GeyserSmithingRecipe(SmithingRecipeDisplay display) {
|
||||||
|
this(display.template(), display.base(), display.addition(), display.result());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isShaped() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -29,6 +29,7 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import io.netty.channel.EventLoop;
|
import io.netty.channel.EventLoop;
|
||||||
|
import it.unimi.dsi.fastutil.Pair;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
@ -77,6 +78,7 @@ import org.cloudburstmc.protocol.bedrock.data.command.SoftEnumUpdateType;
|
|||||||
import org.cloudburstmc.protocol.bedrock.data.definitions.DimensionDefinition;
|
import org.cloudburstmc.protocol.bedrock.data.definitions.DimensionDefinition;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.CraftingRecipeData;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.AvailableEntityIdentifiersPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.AvailableEntityIdentifiersPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.BedrockPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.BiomeDefinitionListPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.BiomeDefinitionListPacket;
|
||||||
@ -141,6 +143,7 @@ import org.geysermc.geyser.impl.camera.GeyserCameraData;
|
|||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
import org.geysermc.geyser.inventory.PlayerInventory;
|
import org.geysermc.geyser.inventory.PlayerInventory;
|
||||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||||
|
import org.geysermc.geyser.inventory.recipe.GeyserSmithingRecipe;
|
||||||
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
|
import org.geysermc.geyser.inventory.recipe.GeyserStonecutterData;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.item.type.BlockItem;
|
import org.geysermc.geyser.item.type.BlockItem;
|
||||||
@ -311,7 +314,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
private final AtomicInteger itemNetId = new AtomicInteger(2);
|
private final AtomicInteger itemNetId = new AtomicInteger(2);
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private ScheduledFuture<?> craftingGridFuture;
|
private ScheduledFuture<?> containerOutputFuture;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores session collision
|
* Stores session collision
|
||||||
@ -447,6 +450,8 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
private final Int2ObjectMap<List<String>> javaToBedrockRecipeIds;
|
private final Int2ObjectMap<List<String>> javaToBedrockRecipeIds;
|
||||||
|
|
||||||
private final Int2ObjectMap<GeyserRecipe> craftingRecipes;
|
private final Int2ObjectMap<GeyserRecipe> craftingRecipes;
|
||||||
|
@Setter
|
||||||
|
private Pair<CraftingRecipeData, GeyserRecipe> lastCreatedRecipe = null; // TODO try to prevent sending duplicate recipes
|
||||||
private final AtomicInteger lastRecipeNetId;
|
private final AtomicInteger lastRecipeNetId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -455,6 +460,7 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
*/
|
*/
|
||||||
@Setter
|
@Setter
|
||||||
private Int2ObjectMap<GeyserStonecutterData> stonecutterRecipes;
|
private Int2ObjectMap<GeyserStonecutterData> stonecutterRecipes;
|
||||||
|
private final List<GeyserSmithingRecipe> smithingRecipes = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to work around 1.13's different behavior in villager trading menus.
|
* Whether to work around 1.13's different behavior in villager trading menus.
|
||||||
|
@ -33,6 +33,11 @@ import org.geysermc.geyser.inventory.updater.UIInventoryUpdater;
|
|||||||
import org.geysermc.geyser.level.block.Blocks;
|
import org.geysermc.geyser.level.block.Blocks;
|
||||||
|
|
||||||
public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslator {
|
||||||
|
public static final int TEMPLATE = 0;
|
||||||
|
public static final int INPUT = 1;
|
||||||
|
public static final int MATERIAL = 2;
|
||||||
|
public static final int OUTPUT = 3;
|
||||||
|
|
||||||
public SmithingInventoryTranslator() {
|
public SmithingInventoryTranslator() {
|
||||||
super(4, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
super(4, Blocks.SMITHING_TABLE, ContainerType.SMITHING_TABLE, UIInventoryUpdater.INSTANCE);
|
||||||
}
|
}
|
||||||
@ -40,10 +45,10 @@ public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslato
|
|||||||
@Override
|
@Override
|
||||||
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
public int bedrockSlotToJava(ItemStackRequestSlotData slotInfoData) {
|
||||||
return switch (slotInfoData.getContainer()) {
|
return switch (slotInfoData.getContainer()) {
|
||||||
case SMITHING_TABLE_TEMPLATE -> 0;
|
case SMITHING_TABLE_TEMPLATE -> TEMPLATE;
|
||||||
case SMITHING_TABLE_INPUT -> 1;
|
case SMITHING_TABLE_INPUT -> INPUT;
|
||||||
case SMITHING_TABLE_MATERIAL -> 2;
|
case SMITHING_TABLE_MATERIAL -> MATERIAL;
|
||||||
case SMITHING_TABLE_RESULT, CREATED_OUTPUT -> 3;
|
case SMITHING_TABLE_RESULT, CREATED_OUTPUT -> OUTPUT;
|
||||||
default -> super.bedrockSlotToJava(slotInfoData);
|
default -> super.bedrockSlotToJava(slotInfoData);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -51,10 +56,10 @@ public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslato
|
|||||||
@Override
|
@Override
|
||||||
public BedrockContainerSlot javaSlotToBedrockContainer(int slot) {
|
public BedrockContainerSlot javaSlotToBedrockContainer(int slot) {
|
||||||
return switch (slot) {
|
return switch (slot) {
|
||||||
case 0 -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_TEMPLATE, 53);
|
case TEMPLATE -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_TEMPLATE, 53);
|
||||||
case 1 -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_INPUT, 51);
|
case INPUT -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_INPUT, 51);
|
||||||
case 2 -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_MATERIAL, 52);
|
case MATERIAL -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_MATERIAL, 52);
|
||||||
case 3 -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_RESULT, 50);
|
case OUTPUT -> new BedrockContainerSlot(ContainerSlotType.SMITHING_TABLE_RESULT, 50);
|
||||||
default -> super.javaSlotToBedrockContainer(slot);
|
default -> super.javaSlotToBedrockContainer(slot);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -62,10 +67,10 @@ public class SmithingInventoryTranslator extends AbstractBlockInventoryTranslato
|
|||||||
@Override
|
@Override
|
||||||
public int javaSlotToBedrock(int slot) {
|
public int javaSlotToBedrock(int slot) {
|
||||||
return switch (slot) {
|
return switch (slot) {
|
||||||
case 0 -> 53;
|
case TEMPLATE -> 53;
|
||||||
case 1 -> 51;
|
case INPUT -> 51;
|
||||||
case 2 -> 52;
|
case MATERIAL -> 52;
|
||||||
case 3 -> 50;
|
case OUTPUT -> 50;
|
||||||
default -> super.javaSlotToBedrock(slot);
|
default -> super.javaSlotToBedrock(slot);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import org.cloudburstmc.protocol.bedrock.packet.UnlockedRecipesPacket;
|
|||||||
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
|
||||||
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
|
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
|
||||||
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
|
import org.geysermc.geyser.inventory.recipe.GeyserShapelessRecipe;
|
||||||
|
import org.geysermc.geyser.inventory.recipe.GeyserSmithingRecipe;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.item.type.BedrockRequiresTagItem;
|
import org.geysermc.geyser.item.type.BedrockRequiresTagItem;
|
||||||
import org.geysermc.geyser.item.type.Item;
|
import org.geysermc.geyser.item.type.Item;
|
||||||
@ -176,6 +177,8 @@ public class JavaRecipeBookAddTranslator extends PacketTranslator<ClientboundRec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
javaToBedrockRecipeIds.put(contents.id(), bedrockRecipeIds);
|
javaToBedrockRecipeIds.put(contents.id(), bedrockRecipeIds);
|
||||||
|
session.getSmithingRecipes().add(new GeyserSmithingRecipe(smithingRecipe));
|
||||||
|
System.out.println(new GeyserSmithingRecipe(smithingRecipe));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
|||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.RecipeUnlockingRequirement;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.ShapedRecipeData;
|
||||||
|
import org.cloudburstmc.protocol.bedrock.data.inventory.crafting.recipe.SmithingTransformRecipeData;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
import org.cloudburstmc.protocol.bedrock.data.inventory.descriptor.ItemDescriptorWithCount;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.CraftingDataPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.InventorySlotPacket;
|
||||||
@ -36,15 +37,17 @@ import org.geysermc.geyser.GeyserLogger;
|
|||||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||||
import org.geysermc.geyser.inventory.Inventory;
|
import org.geysermc.geyser.inventory.Inventory;
|
||||||
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
|
import org.geysermc.geyser.inventory.recipe.GeyserShapedRecipe;
|
||||||
|
import org.geysermc.geyser.inventory.recipe.GeyserSmithingRecipe;
|
||||||
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
import org.geysermc.geyser.translator.inventory.InventoryTranslator;
|
||||||
import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
|
import org.geysermc.geyser.translator.inventory.PlayerInventoryTranslator;
|
||||||
|
import org.geysermc.geyser.translator.inventory.SmithingInventoryTranslator;
|
||||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
import org.geysermc.geyser.util.InventoryUtils;
|
import org.geysermc.geyser.util.InventoryUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.EmptySlotDisplay;
|
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.ItemStackSlotDisplay;
|
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.ItemStackSlotDisplay;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;
|
import org.geysermc.mcprotocollib.protocol.data.game.recipe.display.slot.SlotDisplay;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.clientbound.inventory.ClientboundContainerSetSlotPacket;
|
||||||
@ -83,7 +86,11 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCraftingGrid(session, slot, packet.getItem(), inventory, translator);
|
if (translator instanceof SmithingInventoryTranslator) {
|
||||||
|
updateSmithingTableOutput(session, slot, packet.getItem(), inventory);
|
||||||
|
} else {
|
||||||
|
updateCraftingGrid(session, slot, packet.getItem(), inventory, translator);
|
||||||
|
}
|
||||||
|
|
||||||
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
|
GeyserItemStack newItem = GeyserItemStack.from(packet.getItem());
|
||||||
if (packet.getContainerId() == 0 && !(translator instanceof PlayerInventoryTranslator)) {
|
if (packet.getContainerId() == 0 && !(translator instanceof PlayerInventoryTranslator)) {
|
||||||
@ -119,15 +126,15 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Only process the most recent crafting grid result, and cancel the previous one.
|
// Only process the most recent crafting grid result, and cancel the previous one.
|
||||||
if (session.getCraftingGridFuture() != null) {
|
if (session.getContainerOutputFuture() != null) {
|
||||||
session.getCraftingGridFuture().cancel(false);
|
session.getContainerOutputFuture().cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InventoryUtils.isEmpty(item)) {
|
if (InventoryUtils.isEmpty(item)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
session.setCraftingGridFuture(session.scheduleInEventLoop(() -> {
|
session.setContainerOutputFuture(session.scheduleInEventLoop(() -> {
|
||||||
int offset = gridSize == 4 ? 28 : 32;
|
int offset = gridSize == 4 ? 28 : 32;
|
||||||
int gridDimensions = gridSize == 4 ? 2 : 3;
|
int gridDimensions = gridSize == 4 ? 2 : 3;
|
||||||
int firstRow = -1, height = -1;
|
int firstRow = -1, height = -1;
|
||||||
@ -172,7 +179,7 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
|||||||
for (int col = firstCol; col < width + firstCol; col++) {
|
for (int col = firstCol; col < width + firstCol; col++) {
|
||||||
GeyserItemStack geyserItemStack = inventory.getItem(col + (row * gridDimensions) + 1);
|
GeyserItemStack geyserItemStack = inventory.getItem(col + (row * gridDimensions) + 1);
|
||||||
ingredients[index] = geyserItemStack.getItemData(session);
|
ingredients[index] = geyserItemStack.getItemData(session);
|
||||||
javaIngredients.add(geyserItemStack.isEmpty() ? new EmptySlotDisplay() : new ItemStackSlotDisplay(geyserItemStack.getItemStack()));
|
javaIngredients.add(geyserItemStack.asSlotDisplay());
|
||||||
|
|
||||||
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||||
slotPacket.setContainerId(ContainerId.UI);
|
slotPacket.setContainerId(ContainerId.UI);
|
||||||
@ -216,4 +223,74 @@ public class JavaContainerSetSlotTranslator extends PacketTranslator<Clientbound
|
|||||||
}
|
}
|
||||||
}, 150, TimeUnit.MILLISECONDS));
|
}, 150, TimeUnit.MILLISECONDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void updateSmithingTableOutput(GeyserSession session, int slot, ItemStack output, Inventory inventory) {
|
||||||
|
if (slot != SmithingInventoryTranslator.OUTPUT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only process the most recent output result, and cancel the previous one.
|
||||||
|
if (session.getContainerOutputFuture() != null) {
|
||||||
|
session.getContainerOutputFuture().cancel(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (InventoryUtils.isEmpty(output)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
session.setContainerOutputFuture(session.scheduleInEventLoop(() -> {
|
||||||
|
GeyserItemStack template = inventory.getItem(SmithingInventoryTranslator.TEMPLATE);
|
||||||
|
if (template.asItem() != Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE) {
|
||||||
|
// Technically we should probably also do this for custom items, but last I checked Bedrock doesn't even support that.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeyserItemStack input = inventory.getItem(SmithingInventoryTranslator.INPUT);
|
||||||
|
GeyserItemStack material = inventory.getItem(SmithingInventoryTranslator.MATERIAL);
|
||||||
|
GeyserItemStack geyserOutput = GeyserItemStack.from(output);
|
||||||
|
|
||||||
|
for (GeyserSmithingRecipe recipe : session.getSmithingRecipes()) {
|
||||||
|
if (InventoryUtils.acceptsAsInput(session, recipe.result(), geyserOutput)
|
||||||
|
&& InventoryUtils.acceptsAsInput(session, recipe.base(), input)
|
||||||
|
&& InventoryUtils.acceptsAsInput(session, recipe.addition(), material)
|
||||||
|
&& InventoryUtils.acceptsAsInput(session, recipe.template(), template)) {
|
||||||
|
// The client already recognizes this item.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
session.getSmithingRecipes().add(new GeyserSmithingRecipe(
|
||||||
|
template.asSlotDisplay(),
|
||||||
|
input.asSlotDisplay(),
|
||||||
|
material.asSlotDisplay(),
|
||||||
|
new ItemStackSlotDisplay(output)
|
||||||
|
));
|
||||||
|
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
ItemData bedrockAddition = ItemTranslator.translateToBedrock(session, material.getItemStack());
|
||||||
|
|
||||||
|
CraftingDataPacket craftPacket = new CraftingDataPacket();
|
||||||
|
craftPacket.getCraftingData().add(SmithingTransformRecipeData.of(
|
||||||
|
uuid.toString(),
|
||||||
|
ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, template.getItemStack())),
|
||||||
|
ItemDescriptorWithCount.fromItem(ItemTranslator.translateToBedrock(session, input.getItemStack())),
|
||||||
|
ItemDescriptorWithCount.fromItem(bedrockAddition),
|
||||||
|
ItemTranslator.translateToBedrock(session, output),
|
||||||
|
"smithing_table",
|
||||||
|
session.getLastRecipeNetId().incrementAndGet()
|
||||||
|
));
|
||||||
|
craftPacket.setCleanRecipes(false);
|
||||||
|
session.sendUpstreamPacket(craftPacket);
|
||||||
|
|
||||||
|
// Just set one of the slots to air, then right back to its proper item.
|
||||||
|
InventorySlotPacket slotPacket = new InventorySlotPacket();
|
||||||
|
slotPacket.setContainerId(ContainerId.UI);
|
||||||
|
slotPacket.setSlot(session.getInventoryTranslator().javaSlotToBedrock(SmithingInventoryTranslator.MATERIAL));
|
||||||
|
slotPacket.setItem(ItemData.AIR);
|
||||||
|
session.sendUpstreamPacket(slotPacket);
|
||||||
|
|
||||||
|
session.getInventoryTranslator().updateSlot(session, inventory, SmithingInventoryTranslator.MATERIAL);
|
||||||
|
}, 150, TimeUnit.MILLISECONDS));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren