forging now works

This commit is contained in:
Halbear
2026-08-03 20:29:31 +01:00
parent d606663b9d
commit 88ece5adf5
5 changed files with 118 additions and 31 deletions
@@ -4,10 +4,8 @@ import com.mojang.blaze3d.platform.InputConstants;
import net.halbear.aotg.custom.blocks.Forge.ForgeItemRecipe;
import net.halbear.aotg.custom.blocks.Forge.ForgeItemsScrollList;
import net.halbear.aotg.custom.blocks.Forge.ForgeWorkbenchGUI;
import net.halbear.aotg.registries.ModBlocks;
import net.halbear.aotg.registries.ModItems;
import net.halbear.aotg.registries.ModScreens;
import net.halbear.aotg.utility.Networking.AlloyFurnaceGuiButtonHandler;
import net.halbear.aotg.utility.Networking.ForgeWorkbenchGuiButtonHandler;
import net.minecraft.client.gui.GuiGraphicsExtractor;
import net.minecraft.client.gui.components.ImageButton;
@@ -15,15 +13,12 @@ import net.minecraft.client.gui.components.WidgetSprites;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.renderer.RenderPipelines;
import net.minecraft.core.BlockPos;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.neoforge.client.network.ClientPacketDistributor;
import java.util.ArrayList;
@@ -35,7 +30,7 @@ public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbe
private final int x, y, z;
private final Player entity;
private boolean menuStateUpdateActive = false;
private ImageButton Blower;
private ImageButton ForgeButton;
private static final Identifier BACKGROUND = Identifier.parse("ageofthegods:textures/screens/forge_gui.png");
private static final Identifier BELLOW_SPRITE_SHEET = Identifier.parse("ageofthegods:textures/screens/bellow-sheet.png");
private static final Identifier MOLTEN_FILL_SPRITE = Identifier.parse("ageofthegods:textures/screens/alloy_furnace_molten_element_gui.png");
@@ -139,19 +134,19 @@ public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbe
this.addRenderableWidget(this.scrollList);
this.addWidget(this.scrollList);
Blower = new ImageButton( this.leftPos + 100, this.topPos + 56, 47, 22,
ForgeButton = new ImageButton( this.leftPos + 100, this.topPos + 56, 47, 22,
new WidgetSprites(Identifier.parse("ageofthegods:textures/screens/forge_button_clear.png"), Identifier.parse("ageofthegods:textures/screens/forge_button_hover.png")), e -> {
int x = ForgeWorkbenchGUIScreen.this.x;
int y = ForgeWorkbenchGUIScreen.this.y;
int z = ForgeWorkbenchGUIScreen.this.z;
ClientPacketDistributor.sendToServer(new ForgeWorkbenchGuiButtonHandler(0, x, y, z));
ForgeWorkbenchGuiButtonHandler.handleButtonAction(entity, 0, x, y, z);
ClientPacketDistributor.sendToServer(new ForgeWorkbenchGuiButtonHandler(0,selectedStack.getItemName().getString(), x, y, z));
ForgeWorkbenchGuiButtonHandler.handleButtonAction(entity,0, x, y, z,selectedStack.getItem());
}) {
@Override
public void extractContents(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTicks) {
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, sprites.get(isActive(), isHoveredOrFocused()), getX(), getY(), 0, 0, width, height, width, height);
}
};
this.addRenderableWidget(Blower);
this.addRenderableWidget(ForgeButton);
}
}
@@ -12,8 +12,8 @@ import java.util.*;
import static net.halbear.aotg.custom.blocks.Forge.ForgedAlloyRecipe.GetRecipesContainingMetals;
public record ForgeItemRecipe(Item primaryOutcomeItem, Item[] RequiredItems, int[] RequiredItemCounts) {
public static final Map<Item, ForgeItemRecipe> FORGE_ITEM_RECIPE_MAP = new HashMap<>();
public static final Map<Item, List<Item>> ITEM_RECIPE_REVERSE_LOOKUP = new HashMap<>();
public static final Map<Item, ForgeItemRecipe> FORGE_ITEM_RECIPE_MAP = new LinkedHashMap<>();
public static final Map<Item, List<Item>> ITEM_RECIPE_REVERSE_LOOKUP = new LinkedHashMap<>();
static{
FORGE_ITEM_RECIPE_MAP.put(ModItems.XIPHOS_SWORD.asItem(),new ForgeItemRecipe(ModItems.XIPHOS_SWORD.asItem(),new Item[]{ModItems.BRONZE_INGOT.asItem(), Items.STICK},new int[]{2,1}));
CompileReverseLookupMap();
@@ -91,6 +91,10 @@ public class ForgeItemsScrollList extends ObjectSelectionList<ForgeItemsScrollLi
}
}
graphics.fakeItem(this.itemStack, left + 4, top);
if(alloy_recipe != null) {
int Count = (alloy_recipe.AlloyRatio() < 1 ? 1 / (int) alloy_recipe.AlloyRatio() + 1 : 1 + (int) alloy_recipe.AlloyRatio());
graphics.text(parent.getFont(), "" + Count, left + 4 + 17 - parent.getFont().width("" + Count), top + 9, -1, true);
}
graphics.pose().pushMatrix();
graphics.pose().translate(left + 28, top + 2);
graphics.pose().scale(0.75f, 0.75f);
@@ -9,14 +9,11 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.level.material.Fluids;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public record ForgedAlloyRecipe(Item OutcomeItem, Item RequiredMetal1, Item RequiredMetal2, float AlloyRatio) {
public static final Map<Item,ForgedAlloyRecipe> RecipeMap = new HashMap<>();
public static final Map<Item, List<Item>> ReverseLookupRecipeMap = new HashMap<>();
public static final Map<Item,ForgedAlloyRecipe> RecipeMap = new LinkedHashMap<>();
public static final Map<Item, List<Item>> ReverseLookupRecipeMap = new LinkedHashMap<>();
static {
RecipeMap.put(ModItems.BRONZE_INGOT.asItem(), new ForgedAlloyRecipe(ModItems.BRONZE_INGOT.asItem(), Items.COPPER_INGOT, ModItems.TIN_INGOT.asItem(),9f));
RecipeMap.put(ModItems.ELECTRUM_INGOT.asItem(), new ForgedAlloyRecipe(ModItems.ELECTRUM_INGOT.asItem(), Items.GOLD_INGOT, ModItems.SILVER_INGOT.asItem(), 3f));
@@ -60,14 +57,14 @@ public record ForgedAlloyRecipe(Item OutcomeItem, Item RequiredMetal1, Item Requ
if(Pot.getItem().equals(Items.DECORATED_POT)){
ItemContainerContents potContents = Pot.get(DataComponents.CONTAINER);
if (potContents != null) {
boolean hasMarker = potContents.getStackInSlot(0).getItem().equals(ModItems.FLUID_INDICATOR_ITEM.asItem());
boolean hasMarker = potContents.getSlots() == 3 && potContents.getStackInSlot(0).getItem().equals(ModItems.FLUID_INDICATOR_ITEM.asItem());
if (hasMarker) {
ItemStack AlloyMetal1 = potContents.getStackInSlot(1);
ItemStack AlloyMetal2 = potContents.getStackInSlot(2);
availableRecipes = GetRecipesContainingMetals(AlloyMetal1.getItem(),AlloyMetal2.getItem());
availableRecipes.forEach(forgedAlloyRecipe -> {
double Ratio = Math.floor((float) AlloyMetal1.getCount() /(float)AlloyMetal2.getCount());
if( Ratio == Math.floor(forgedAlloyRecipe.AlloyRatio)) {
double Ratio = ((float) AlloyMetal1.getCount() /(float)AlloyMetal2.getCount());
if( (Ratio > forgedAlloyRecipe.AlloyRatio * 0.75 && Ratio < forgedAlloyRecipe.AlloyRatio * 1.25)) {
ValidRecipes.add(forgedAlloyRecipe);
}
});
@@ -1,11 +1,14 @@
package net.halbear.aotg.utility.Networking;
import net.halbear.aotg.AgeoftheGods;
import net.halbear.aotg.custom.blocks.AlloyFurnace.AlloyFurnaceBlockEntity;
import net.halbear.aotg.custom.blocks.AlloyFurnace.AlloyFurnaceUpdateHandler;
import net.halbear.aotg.registries.ModBlocks;
import net.halbear.aotg.custom.GuiScreens.ForgeWorkbenchGUIScreen;
import net.halbear.aotg.custom.blocks.Forge.ForgeItemRecipe;
import net.halbear.aotg.custom.blocks.Forge.ForgeWorkbenchBlockEntity;
import net.halbear.aotg.custom.blocks.Forge.ForgedAlloyRecipe;
import net.halbear.aotg.registries.ModItems;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.network.codec.StreamCodec;
@@ -13,6 +16,10 @@ import net.minecraft.network.protocol.PacketFlow;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.resources.Identifier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.ItemContainerContents;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
@@ -23,41 +30,125 @@ import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
import static net.halbear.aotg.custom.blocks.AlloyFurnace.AlloyFurnaceMultiBlock.MODEL_PART;
import static net.halbear.aotg.custom.blocks.AlloyFurnace.AlloyFurnaceMultiBlock.PARENT_BLOCK;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
@EventBusSubscriber
public record ForgeWorkbenchGuiButtonHandler(int buttonID, int x, int y, int z) implements CustomPacketPayload {
public record ForgeWorkbenchGuiButtonHandler(int buttonID, String ResultItem, int x, int y, int z) implements CustomPacketPayload {
public static final Type<ForgeWorkbenchGuiButtonHandler> TYPE = new Type<>(Identifier.fromNamespaceAndPath(AgeoftheGods.MODID, "forge_workbench_buttons"));
public static final StreamCodec<RegistryFriendlyByteBuf, ForgeWorkbenchGuiButtonHandler> STREAM_CODEC = StreamCodec.of((RegistryFriendlyByteBuf buffer, ForgeWorkbenchGuiButtonHandler message) -> {
buffer.writeInt(message.buttonID);
buffer.writeByteArray(message.ResultItem.getBytes(Charset.defaultCharset()));
buffer.writeInt(message.x);
buffer.writeInt(message.y);
buffer.writeInt(message.z);
}, (RegistryFriendlyByteBuf buffer) -> new ForgeWorkbenchGuiButtonHandler(buffer.readInt(), buffer.readInt(), buffer.readInt(), buffer.readInt()));
}, (RegistryFriendlyByteBuf buffer) -> new ForgeWorkbenchGuiButtonHandler(buffer.readInt(),new String(buffer.readByteArray(),Charset.defaultCharset()), buffer.readInt(), buffer.readInt(), buffer.readInt()));
@Override
public Type<ForgeWorkbenchGuiButtonHandler> type() {
return TYPE;
}
public static Map<String, Item> ItemLookupMap = new HashMap<>();
public static void handleData(final ForgeWorkbenchGuiButtonHandler message, final IPayloadContext context) {
if (context.flow() == PacketFlow.SERVERBOUND) {
context.enqueueWork(() -> handleButtonAction(context.player(), message.buttonID, message.x, message.y, message.z)).exceptionally(e -> {
ItemLookupMap.clear();
ForgeItemRecipe.RecipeSet set = ForgeItemRecipe.GetAllValidRecipesFromContainer(ItemStack.EMPTY, ItemStack.EMPTY);
for(int i = 0; i < set.ItemRecipes().size(); i++){
ItemLookupMap.put(new ItemStack(set.ItemRecipes().get(i).primaryOutcomeItem()).getItemName().getString(), set.ItemRecipes().get(i).primaryOutcomeItem());
}
for(int i = 0; i < set.AlloyRecipes().size(); i++){
ItemLookupMap.put(new ItemStack(set.AlloyRecipes().get(i).OutcomeItem()).getItemName().getString(), set.AlloyRecipes().get(i).OutcomeItem());
}
context.enqueueWork(() -> handleButtonAction(context.player(), message.buttonID, message.x, message.y, message.z, ItemLookupMap.get(message.ResultItem))).exceptionally(e -> {
context.connection().disconnect(Component.literal(e.getMessage()));
return null;
});
}
}
public static void handleButtonAction(Player entity, int buttonID, int x, int y, int z) {
public static ItemStack[] CraftAlloy(ItemStack Pot, Item TargetItem,ItemContainerContents potContents, ForgedAlloyRecipe alloy_recipe){
ItemStack[] returnVal = new ItemStack[]{ItemStack.EMPTY,ItemStack.EMPTY,ItemStack.EMPTY};
ItemStack AlloyMetal1 = potContents.getStackInSlot(1);
ItemStack AlloyMetal2 = potContents.getStackInSlot(2);
if (alloy_recipe != null) {
float Ratio = alloy_recipe.AlloyRatio();
float InRatio = AlloyMetal1.getCount() / (float) AlloyMetal2.getCount();
int RequiredIngots1 = Ratio < 1 ? 1 : (int) Math.floor(Ratio);
int RequiredIngots2 = Ratio < 1 ? (int) Math.floor(1 / Ratio) : 1;
if ((InRatio > Ratio * 0.75 && InRatio < Ratio * 1.25)) {
int Overfow = AlloyMetal1.getCount() % RequiredIngots1;
float SetsProduced = (float) AlloyMetal1.getCount() / (float) RequiredIngots1;
int IngotsProduced = (int)Math.floor((RequiredIngots1 + RequiredIngots2) * SetsProduced) - Overfow;
int SlagProduced = AlloyMetal1.getCount() + AlloyMetal2.getCount() - IngotsProduced;
returnVal[0] = (new ItemStack(Items.DECORATED_POT, 1));
returnVal[1] = (new ItemStack(alloy_recipe.OutcomeItem(), IngotsProduced));
returnVal[2] = (new ItemStack(ModItems.HARDENED_SLAG.asItem(), SlagProduced));
} else{
int SlagProduced = AlloyMetal1.getCount() + AlloyMetal2.getCount();
returnVal[0] = (new ItemStack(Items.DECORATED_POT, 1));
returnVal[1] = (ItemStack.EMPTY);
returnVal[2] = (new ItemStack(ModItems.HARDENED_SLAG.asItem(), SlagProduced));
}
} else{
int SlagProduced = AlloyMetal1.getCount() + AlloyMetal2.getCount();
returnVal[0] = (new ItemStack(Items.DECORATED_POT, 1));
returnVal[1] = (ItemStack.EMPTY);
returnVal[2] = (new ItemStack(ModItems.HARDENED_SLAG.asItem(), SlagProduced));
}
return returnVal;
}
public static void handleButtonAction(Player entity, int buttonID, int x, int y, int z, Item TargetItem) {
Level world = entity.level();
if (!world.getChunkSource().hasChunk(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z)))
if (!world.getChunkSource().hasChunk(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z)) || TargetItem == null)
return;
if (buttonID == 0) {
AgeoftheGods.LOGGER.debug("ITEM RECIEVED: " + TargetItem.toString());
BlockPos TargetPos = new BlockPos(x,y,z);
BlockState blockstate = world.getBlockState(new BlockPos(x,y,z));
BlockEntity blockEntity = world.getBlockEntity(new BlockPos(TargetPos));
if(blockEntity instanceof ForgeWorkbenchBlockEntity forgeWorkbenchBlockEntity){
ItemStack Pot = forgeWorkbenchBlockEntity.getItem(0);
if(Pot.getItem().equals(Items.DECORATED_POT)) {
ItemContainerContents potContents = Pot.get(DataComponents.CONTAINER);
if (potContents != null) {
boolean hasMarker = potContents.getSlots() == 3 && potContents.getStackInSlot(0).getItem().equals(ModItems.FLUID_INDICATOR_ITEM.asItem());
if (hasMarker) {
ForgedAlloyRecipe alloy_recipe = ForgedAlloyRecipe.RecipeMap.get(TargetItem);
ForgeItemRecipe item_recipe = ForgeItemRecipe.FORGE_ITEM_RECIPE_MAP.get(TargetItem);
ItemStack Secondary = forgeWorkbenchBlockEntity.getItem(1);
if(alloy_recipe != null){
ItemStack[] CraftResult = CraftAlloy(Pot, TargetItem, potContents, alloy_recipe);
forgeWorkbenchBlockEntity.setItem(0,CraftResult[0]);
forgeWorkbenchBlockEntity.setItem(2,CraftResult[1]);
forgeWorkbenchBlockEntity.setItem(4,CraftResult[2]);
} else if(item_recipe != null){
ItemStack[] CraftResult = CraftAlloy(Pot, TargetItem, potContents, ForgedAlloyRecipe.RecipeMap.get(item_recipe.RequiredItems()[0].asItem()));
forgeWorkbenchBlockEntity.setItem(0,CraftResult[0]);
ItemStack Alloy = CraftResult[1];
ItemStack Slag = CraftResult[2];
ItemStack ResultItem = ItemStack.EMPTY;
if(Alloy.getItem() == item_recipe.RequiredItems()[0] && Alloy.getCount() >= item_recipe.RequiredItemCounts()[0]
&& Secondary.getItem() == item_recipe.RequiredItems()[1] && Secondary.getCount() >= item_recipe.RequiredItemCounts()[1]){
Alloy.setCount(Alloy.getCount() - item_recipe.RequiredItemCounts()[0]);
Secondary.setCount(Secondary.getCount() - item_recipe.RequiredItemCounts()[1]);
ResultItem = new ItemStack(item_recipe.primaryOutcomeItem(), 1);
}
forgeWorkbenchBlockEntity.setItem(2,ResultItem);
forgeWorkbenchBlockEntity.setItem(3,Alloy);
forgeWorkbenchBlockEntity.setItem(4,Slag);
}
}
}
}
}
}
}
@SubscribeEvent
public static void registerMessage(final RegisterPayloadHandlersEvent event) {
final PayloadRegistrar registrar = event.registrar("1.0.0");