Forge, Slag, almost forge functionality
This commit is contained in:
@@ -65,13 +65,13 @@ public class AlloyFurnaceGUIScreen extends AbstractContainerScreen<AlloyFurnaceG
|
||||
int bellowPush = this.menu.getSyncedVariable(3);
|
||||
int blowerSprite = (int)Math.clamp(3 * (float)bellowPush/(float)MAX_BELLOW,0,2);
|
||||
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, BELLOW_SPRITE_SHEET, this.leftPos + 9, this.topPos + 58, 0, 20 * blowerSprite, 35, 20, 35, 60);
|
||||
int CookProgress = GetMoltenProgress(world,x,y,z,19,0,0);
|
||||
int CookProgress = GetMoltenProgress(world,x,y,z,19,0,0,100f);
|
||||
if(CookProgress > 0) guiGraphics.blit(RenderPipelines.GUI_TEXTURED, MOLTEN_FILL_SPRITE, this.leftPos + 100, this.topPos + 36 + (19 - CookProgress), 0, 0, 17, CookProgress, 17, 19);
|
||||
int FuelProgress = GetMoltenProgress(world,x,y,z,21,0,1);
|
||||
int FuelProgress = GetMoltenProgress(world,x,y,z,21,0,1,this.menu.getSyncedVariable(4));
|
||||
if(FuelProgress > 0) guiGraphics.blit(RenderPipelines.GUI_TEXTURED, FLAME_SPRITE, this.leftPos + 47, this.topPos + 54 + (21 - FuelProgress), 0, 21 - FuelProgress, 14, FuelProgress, 14, 21);
|
||||
}
|
||||
|
||||
private int GetMoltenProgress(Level world, int x, int y, int z, int FullHeight, int MinimumHeight, int ElementVariable){
|
||||
private int GetMoltenProgress(Level world, int x, int y, int z, int FullHeight, int MinimumHeight, int ElementVariable, float MaxValue){
|
||||
BlockState state = world.getBlockState(new BlockPos(x,y,z));
|
||||
BlockPos position = new BlockPos(x,y,z);
|
||||
if(state.getBlock().getName().getString().equals(ModBlocks.ALLOY_FURNACE.get().getName().getString())) {
|
||||
@@ -81,7 +81,7 @@ public class AlloyFurnaceGUIScreen extends AbstractContainerScreen<AlloyFurnaceG
|
||||
// if(position == null) return MinimumHeight;
|
||||
// }
|
||||
int cookProgress = this.menu.getSyncedVariable(ElementVariable);
|
||||
float Multipler = Math.min((float)cookProgress/100.0f,1.0f);
|
||||
float Multipler = Math.min((float)cookProgress/MaxValue,1.0f);
|
||||
int TargetHeight = (int)Math.ceil((float)FullHeight*Multipler);
|
||||
return Math.clamp(TargetHeight,MinimumHeight,FullHeight);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
package net.halbear.aotg.custom.GuiScreens;
|
||||
|
||||
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;
|
||||
import net.minecraft.client.gui.components.WidgetSprites;
|
||||
@@ -15,10 +20,15 @@ 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;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbenchGUI> implements ModScreens.ScreenAccessor {
|
||||
private final Level world;
|
||||
@@ -26,11 +36,28 @@ public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbe
|
||||
private final Player entity;
|
||||
private boolean menuStateUpdateActive = false;
|
||||
private ImageButton Blower;
|
||||
private static final Identifier BACKGROUND = Identifier.parse("ageofthegods:textures/screens/alloy_furnace_gui.png");
|
||||
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");
|
||||
private static final Identifier FLAME_SPRITE = Identifier.parse("ageofthegods:textures/screens/alloy_furnace_flame_gui.png");
|
||||
public ForgeItemsScrollList scrollList;
|
||||
private ItemStack hoveredStack = ItemStack.EMPTY;
|
||||
private ItemStack selectedStack = ItemStack.EMPTY;
|
||||
|
||||
public void setHoveredStack(ItemStack stack) {
|
||||
this.hoveredStack = stack;
|
||||
}
|
||||
public void setSelectedStack(ItemStack stack) {
|
||||
this.selectedStack = stack;
|
||||
}
|
||||
|
||||
public void onItemClicked(ItemStack clickedStack) {
|
||||
if (this.minecraft.player != null) {
|
||||
this.minecraft.player.sendOverlayMessage(
|
||||
Component.literal("Selected: ").append(clickedStack.getHoverName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public ForgeWorkbenchGUIScreen(ForgeWorkbenchGUI container, Inventory inventory, Component text) {
|
||||
super(container, inventory, text, 176, 166);
|
||||
@@ -49,12 +76,25 @@ public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbe
|
||||
@Override
|
||||
public void extractRenderState(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTicks) {
|
||||
super.extractRenderState(guiGraphics, mouseX, mouseY, partialTicks);
|
||||
if(selectedStack != ItemStack.EMPTY){
|
||||
guiGraphics.fakeItem(selectedStack,this.leftPos + 115, this.topPos + 13);
|
||||
}
|
||||
ForgeItemRecipe.RecipeSet set = menu.GetRecipes();
|
||||
List<ItemStack> previewList = new ArrayList<>();
|
||||
set.AlloyRecipes().forEach(forgedAlloyRecipe -> {
|
||||
previewList.add(new ItemStack(forgedAlloyRecipe.OutcomeItem()));
|
||||
});
|
||||
set.ItemRecipes().forEach(forgedAlloyRecipe -> {
|
||||
previewList.add(new ItemStack(forgedAlloyRecipe.primaryOutcomeItem()));
|
||||
});
|
||||
this.scrollList.refreshItems(previewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extractBackground(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY, float partialTicks) {
|
||||
super.extractBackground(guiGraphics, mouseX, mouseY, partialTicks);
|
||||
guiGraphics.blit(RenderPipelines.GUI_TEXTURED, BACKGROUND, this.leftPos, this.topPos, 0, 0, this.imageWidth, this.imageHeight, this.imageWidth, this.imageHeight);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,14 +107,51 @@ public class ForgeWorkbenchGUIScreen extends AbstractContainerScreen<ForgeWorkbe
|
||||
return super.keyPressed(event);
|
||||
}
|
||||
|
||||
public void SetScrollListItems(List<ItemStack>itemStacks){
|
||||
List<ItemStack> previewList = new ArrayList<>();
|
||||
previewList.addAll(itemStacks);
|
||||
this.scrollList.refreshItems(previewList);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void extractLabels(GuiGraphicsExtractor guiGraphics, int mouseX, int mouseY) {
|
||||
guiGraphics.text(this.font, Component.translatable("gui.ageofthegods.forge_workbench.title"), 90, 6, -12829636, false);
|
||||
guiGraphics.text(this.font, Component.translatable("gui.ageofthegods.forge_workbench.title"), 114, 61, -12829636, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
int listWidth = 66;
|
||||
int listHeight = 74;
|
||||
int topOffset = this.topPos;
|
||||
this.scrollList = new ForgeItemsScrollList(this, this.minecraft, listWidth, listHeight, topOffset, 18);
|
||||
|
||||
this.scrollList.setPosition( this.leftPos + 29, topOffset + 6);
|
||||
|
||||
List<ItemStack> previewList = new ArrayList<>();
|
||||
previewList.add(new ItemStack(ModItems.XIPHOS_SWORD.asItem()));
|
||||
previewList.add(new ItemStack(ModItems.BRONZE_INGOT.asItem()));
|
||||
previewList.add(new ItemStack(ModItems.ORICHALCUM_INGOT.asItem()));
|
||||
previewList.add(new ItemStack(ModItems.ELECTRUM_INGOT.asItem()));
|
||||
previewList.add(new ItemStack(ModItems.HEPATIZON_INGOT.asItem()));
|
||||
|
||||
this.scrollList.refreshItems(previewList);
|
||||
this.addRenderableWidget(this.scrollList);
|
||||
this.addWidget(this.scrollList);
|
||||
|
||||
Blower = 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);
|
||||
}) {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -22,9 +22,11 @@ import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.FuelValues;
|
||||
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.storage.ValueInput;
|
||||
@@ -46,6 +48,7 @@ public class AlloyFurnaceBlockEntity extends RandomizableContainerBlockEntity im
|
||||
private boolean isFormed = false;
|
||||
private float Fuel = 0.0f;
|
||||
private float CookProcess = 0.0f;
|
||||
private float CurrentFuelTime = 0.0f;
|
||||
private float TemperatureC = 0.0f;
|
||||
private float BellowPush = 0.0f;
|
||||
private boolean AbleToCook = false;
|
||||
@@ -63,6 +66,8 @@ public class AlloyFurnaceBlockEntity extends RandomizableContainerBlockEntity im
|
||||
public void SetFuel(int Fuel){this.Fuel = Fuel ;}
|
||||
public int GetTemperatureC(){return (int) TemperatureC;}
|
||||
public void SetTemperatureC(int Temp){this.TemperatureC = Temp ;}
|
||||
public int GetCurrentFuelTime(){return (int) CurrentFuelTime;}
|
||||
public void SetCurrentFuelTime(int Temp){this.CurrentFuelTime = Temp ;}
|
||||
|
||||
public AlloyFurnaceBlockEntity(BlockPos worldPosition, BlockState blockState) {
|
||||
super(ALLOY_FURNACE_BLOCK_ENTITY.get(), worldPosition, blockState);
|
||||
@@ -119,6 +124,7 @@ public class AlloyFurnaceBlockEntity extends RandomizableContainerBlockEntity im
|
||||
if(blockEntity.pushBellow && blockEntity.BellowPush < MAX_BELLOW){
|
||||
blockEntity.BellowPush += 1;
|
||||
} else if(blockEntity.pushBellow) blockEntity.pushBellow = false;
|
||||
blockEntity.Fuel = Math.max(blockEntity.Fuel - 1f, 0);
|
||||
if (level.getGameTime() % 5 == 0) {
|
||||
if (level.getGameTime() % 20 == 0) {
|
||||
blockEntity.isFormed = blockEntity.UpdateCompleteStructure(level,pos,state,blockEntity.checkStructure(level, pos, state));
|
||||
@@ -141,7 +147,8 @@ public class AlloyFurnaceBlockEntity extends RandomizableContainerBlockEntity im
|
||||
blockEntity.CookProcess = Math.min(blockEntity.CookProcess + 1f + blockEntity.BellowPush,100);
|
||||
} else blockEntity.CookProcess = 0;
|
||||
} else if(!blockEntity.items.get(3).isEmpty() && ((!blockEntity.items.get(0).isEmpty() || !blockEntity.items.get(1).isEmpty() ) && !blockEntity.items.get(2).isEmpty() || (!blockEntity.items.get(5).isEmpty() || !blockEntity.items.get(6).isEmpty() ) && !blockEntity.items.get(7).isEmpty())){
|
||||
blockEntity.Fuel = 100f;
|
||||
blockEntity.Fuel = blockEntity.items.get(3).getBurnTime(RecipeType.SMELTING, level.fuelValues());
|
||||
blockEntity.SetCurrentFuelTime((int)blockEntity.Fuel);
|
||||
blockEntity.items.get(3).setCount(Math.max(blockEntity.items.get(3).getCount() - 1,0));
|
||||
}
|
||||
if (blockEntity.CookProcess >= 100f) {
|
||||
@@ -156,7 +163,6 @@ public class AlloyFurnaceBlockEntity extends RandomizableContainerBlockEntity im
|
||||
} else{
|
||||
blockEntity.CookProcess = 0f;
|
||||
}
|
||||
blockEntity.Fuel = Math.max(blockEntity.Fuel - 1f, 0);
|
||||
blockEntity.AbleToCook = blockEntity.items.get(4).isEmpty() ;
|
||||
blockEntity.AbleToStartCooking = blockEntity.items.get(2).getItem().equals(Items.DECORATED_POT) && (!blockEntity.items.get(0).isEmpty()||!blockEntity.items.get(1).isEmpty());
|
||||
blockEntity.setChanged();
|
||||
|
||||
@@ -89,12 +89,23 @@ public class AlloyFurnaceGUI extends AbstractContainerMenu implements ModMenus.M
|
||||
private final int slot = 2;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
private final int maxLimit = 1;
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return Blocks.DECORATED_POT.asItem() == stack.getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return this.maxLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize(ItemStack stack) {
|
||||
return Math.min(this.maxLimit, super.getMaxStackSize(stack));
|
||||
}
|
||||
|
||||
}));
|
||||
this.customSlots.put(3, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 3, 64, 58) {
|
||||
private final int slot = 3;
|
||||
@@ -140,6 +151,9 @@ public class AlloyFurnaceGUI extends AbstractContainerMenu implements ModMenus.M
|
||||
case 3:
|
||||
returnVal = alloyFurnaceBlockEntity.GetBellowPush();
|
||||
break;
|
||||
case 4:
|
||||
returnVal = alloyFurnaceBlockEntity.GetCurrentFuelTime();
|
||||
break;
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
@@ -159,12 +173,15 @@ public class AlloyFurnaceGUI extends AbstractContainerMenu implements ModMenus.M
|
||||
case 3:
|
||||
alloyFurnaceBlockEntity.SetBellowPush(value);
|
||||
break;
|
||||
case 4:
|
||||
alloyFurnaceBlockEntity.SetCurrentFuelTime(value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return 4;
|
||||
return 5;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package net.halbear.aotg.custom.blocks.Forge;
|
||||
|
||||
import net.halbear.aotg.registries.ModItems;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
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 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<>();
|
||||
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();
|
||||
}
|
||||
|
||||
public static void CompileReverseLookupMap(){
|
||||
ITEM_RECIPE_REVERSE_LOOKUP.clear();
|
||||
FORGE_ITEM_RECIPE_MAP.forEach((name, recipe)->{
|
||||
Arrays.stream(recipe.RequiredItems).toList().forEach(item -> {
|
||||
if(!ITEM_RECIPE_REVERSE_LOOKUP.containsKey(item)){
|
||||
ITEM_RECIPE_REVERSE_LOOKUP.put(item, new ArrayList<>());
|
||||
}
|
||||
ITEM_RECIPE_REVERSE_LOOKUP.get(item).add(name);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static List<ForgeItemRecipe> GetRecipesContainingItem(Item item){
|
||||
List<Item> Metal1Recipes = ITEM_RECIPE_REVERSE_LOOKUP.get(item);
|
||||
List<ForgeItemRecipe> overlapping = new ArrayList<>();
|
||||
if(Metal1Recipes != null) {
|
||||
for (int i = 0; i < Metal1Recipes.size(); i++) {
|
||||
if(Metal1Recipes.get(i) == null) continue;
|
||||
overlapping.add(FORGE_ITEM_RECIPE_MAP.get(Metal1Recipes.get(i)));
|
||||
}
|
||||
}
|
||||
return overlapping;
|
||||
}
|
||||
|
||||
public static List<ForgeItemRecipe> GetValidRecipesFromContainer(ItemStack Pot, ItemStack Secondary){
|
||||
return GetAllValidRecipesFromContainer(Pot,Secondary).ItemRecipes;
|
||||
}
|
||||
|
||||
public static RecipeSet GetAllValidRecipesFromContainer(ItemStack Pot, ItemStack Secondary){
|
||||
List<ForgedAlloyRecipe> availableAlloyRecipes = ForgedAlloyRecipe.GetValidRecipesFromContainer(Pot);
|
||||
List<Item> ItemsToSearchWith = new ArrayList<>();
|
||||
ItemsToSearchWith.add(Secondary.getItem());
|
||||
availableAlloyRecipes.forEach(forgedAlloyRecipe -> {
|
||||
ItemsToSearchWith.add(forgedAlloyRecipe.OutcomeItem());
|
||||
});
|
||||
Set<ForgeItemRecipe> ValidRecipeSet = new LinkedHashSet<>();
|
||||
ItemsToSearchWith.forEach(item->{
|
||||
ValidRecipeSet.addAll(GetRecipesContainingItem(item));
|
||||
});
|
||||
return new RecipeSet(availableAlloyRecipes, new ArrayList<>(ValidRecipeSet));
|
||||
}
|
||||
|
||||
|
||||
public record RecipeSet(List<ForgedAlloyRecipe> AlloyRecipes, List<ForgeItemRecipe> ItemRecipes){}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package net.halbear.aotg.custom.blocks.Forge;
|
||||
|
||||
import net.halbear.aotg.custom.GuiScreens.ForgeWorkbenchGUIScreen;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphicsExtractor;
|
||||
import net.minecraft.client.gui.components.ObjectSelectionList;
|
||||
import net.minecraft.client.gui.components.events.GuiEventListener;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.jspecify.annotations.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ForgeItemsScrollList extends ObjectSelectionList<ForgeItemsScrollList.ItemEntry> {
|
||||
private final ForgeWorkbenchGUIScreen parent;
|
||||
public ForgeItemsScrollList(ForgeWorkbenchGUIScreen parent, Minecraft minecraft, int width, int height, int y, int itemHeight) {
|
||||
super(minecraft, width, height, y, itemHeight);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void refreshItems(List<ItemStack> items) {
|
||||
this.clearEntries();
|
||||
for (ItemStack stack : items) {
|
||||
this.addEntry(new ItemEntry(this.parent, stack));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowWidth() {
|
||||
return 68 - this.scrollbarWidth();
|
||||
}
|
||||
@Override
|
||||
public void setSelected(ForgeItemsScrollList.ItemEntry entry) {
|
||||
super.setSelected(entry);
|
||||
|
||||
if (entry != null) {
|
||||
this.parent.onItemClicked(entry.getItemStack());
|
||||
parent.setSelectedStack(entry.getItemStack());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double scrollX, double scrollY) {
|
||||
if (parent.scrollList != null && parent.scrollList.mouseScrolled(mouseX, mouseY, scrollX, scrollY)) {
|
||||
return true;
|
||||
}
|
||||
return super.mouseScrolled(mouseX, mouseY, scrollX, scrollY);
|
||||
}
|
||||
@Override
|
||||
protected int scrollBarX() {
|
||||
return this.getX() + this.getRowWidth();
|
||||
}
|
||||
|
||||
public static class ItemEntry extends ObjectSelectionList.Entry<ItemEntry> implements GuiEventListener {
|
||||
private final ForgeWorkbenchGUIScreen parent;
|
||||
private final ItemStack itemStack;
|
||||
|
||||
public ItemEntry(ForgeWorkbenchGUIScreen parent, ItemStack stack) {
|
||||
this.parent = parent;
|
||||
this.itemStack = stack;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(){return itemStack;}
|
||||
|
||||
@Override
|
||||
public Component getNarration() {
|
||||
return this.itemStack.getDisplayName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void extractContent(@NonNull GuiGraphicsExtractor graphics, int mouseX, int mouseY, boolean isHovered, float partialTick) {
|
||||
int left = this.getX();
|
||||
int top = this.getY();
|
||||
int rowWidth = this.getWidth();
|
||||
int rowHeight = this.getHeight();
|
||||
|
||||
if (isHovered) {
|
||||
graphics.fill(left, top, left + rowWidth, top + rowHeight, 0x22FFFFFF);
|
||||
}
|
||||
List<ItemStack> recipeItems = new ArrayList<>();
|
||||
ForgedAlloyRecipe alloy_recipe = ForgedAlloyRecipe.RecipeMap.get(this.itemStack.getItem());
|
||||
ForgeItemRecipe item_recipe = ForgeItemRecipe.FORGE_ITEM_RECIPE_MAP.get(this.itemStack.getItem());
|
||||
if(alloy_recipe != null){
|
||||
recipeItems.add(new ItemStack(alloy_recipe.RequiredMetal1(), alloy_recipe.AlloyRatio() < 1 ? 1 : (int)alloy_recipe.AlloyRatio()));
|
||||
recipeItems.add(new ItemStack(alloy_recipe.RequiredMetal2(), alloy_recipe.AlloyRatio() < 1 ? 1/(int)alloy_recipe.AlloyRatio() : 1));
|
||||
}
|
||||
if(item_recipe != null){
|
||||
for(int i = 0; i < item_recipe.RequiredItems().length; i++){
|
||||
recipeItems.add(new ItemStack(item_recipe.RequiredItems()[i], item_recipe.RequiredItemCounts()[i]));
|
||||
}
|
||||
}
|
||||
graphics.fakeItem(this.itemStack, left + 4, top);
|
||||
graphics.pose().pushMatrix();
|
||||
graphics.pose().translate(left + 28, top + 2);
|
||||
graphics.pose().scale(0.75f, 0.75f);
|
||||
for(int i = 0; i < recipeItems.size(); i++){
|
||||
graphics.fakeItem(recipeItems.get(i), (i * 20),1);
|
||||
graphics.text(parent.getFont(), "" + recipeItems.get(i).getCount(), (i * 20) + 17 - parent.getFont().width("" + recipeItems.get(i).getCount()), 9, -1, true);
|
||||
}
|
||||
graphics.pose().popMatrix();
|
||||
|
||||
if (isHovered && mouseX >= left && mouseX <= left + rowWidth && mouseY >= top && mouseY <= top + rowHeight) {
|
||||
this.parent.setHoveredStack(this.itemStack);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ import static net.halbear.aotg.registries.ModBlockEntities.FORGE_WORKBENCH_BLOCK
|
||||
public class ForgeWorkbenchBlockEntity extends RandomizableContainerBlockEntity implements MenuProvider, WorldlyContainer {
|
||||
|
||||
private int ForgeLevel = 0;
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(3, ItemStack.EMPTY);
|
||||
private NonNullList<ItemStack> items = NonNullList.withSize(5, ItemStack.EMPTY);
|
||||
|
||||
public int GetForgeLevel(){return (int)ForgeLevel;}
|
||||
public void SetForgeLevel(int BellowPush){this.ForgeLevel = BellowPush ;}
|
||||
|
||||
@@ -13,12 +13,14 @@ import net.minecraft.world.inventory.ContainerLevelAccess;
|
||||
import net.minecraft.world.inventory.Slot;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.neoforged.neoforge.transfer.ResourceHandler;
|
||||
import net.neoforged.neoforge.transfer.item.*;
|
||||
import net.neoforged.neoforge.transfer.transaction.Transaction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -43,8 +45,9 @@ public class ForgeWorkbenchGUI extends AbstractContainerMenu implements ModMenus
|
||||
private Supplier<Boolean> boundItemMatcher = null;
|
||||
private BlockEntity boundBlockEntity = null;
|
||||
private final ContainerData data;
|
||||
private ForgeItemRecipe.RecipeSet Recipes = new ForgeItemRecipe.RecipeSet(new ArrayList<>(), new ArrayList<>());
|
||||
|
||||
|
||||
public ForgeItemRecipe.RecipeSet GetRecipes(){return Recipes;}
|
||||
|
||||
public ForgeWorkbenchGUI(int containerId, Inventory playerInv, FriendlyByteBuf buffer) {
|
||||
super(ModMenus.FORGE_WORKBENCH_GUI.get(), containerId);
|
||||
@@ -68,10 +71,71 @@ public class ForgeWorkbenchGUI extends AbstractContainerMenu implements ModMenus
|
||||
this.bound = true;
|
||||
}
|
||||
}
|
||||
this.customSlots.put(0, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 0, 37, 16) {
|
||||
ForgeWorkbenchGUI currentGUI = this;
|
||||
currentGUI.Recipes = ForgeItemRecipe.GetAllValidRecipesFromContainer(currentGUI.getSlot(0).getItem(), currentGUI.getSlot(1).getItem());
|
||||
this.customSlots.put(0, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 0, 8, 37) {
|
||||
private final int slot = 0;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
private final int maxLimit = 1;
|
||||
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return Blocks.DECORATED_POT.asItem() == stack.getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize() {
|
||||
return this.maxLimit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxStackSize(ItemStack stack) {
|
||||
return Math.min(this.maxLimit, super.getMaxStackSize(stack));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setByPlayer(ItemStack newStack, ItemStack oldStack) {
|
||||
super.setByPlayer(newStack, oldStack);
|
||||
currentGUI.Recipes = ForgeItemRecipe.GetAllValidRecipesFromContainer(newStack, currentGUI.getSlot(1).getItem());
|
||||
}
|
||||
}));
|
||||
this.customSlots.put(1, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 1, 8, 63) {
|
||||
private final int slot = 1;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
@Override
|
||||
public void setByPlayer(ItemStack newStack, ItemStack oldStack) {
|
||||
super.setByPlayer(newStack, oldStack);
|
||||
currentGUI.Recipes = ForgeItemRecipe.GetAllValidRecipesFromContainer( currentGUI.getSlot(0).getItem(), newStack);
|
||||
}
|
||||
}));
|
||||
this.customSlots.put(2, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 2, 152, 37) {
|
||||
private final int slot = 2;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
this.customSlots.put(3, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 3, 152, 17) {
|
||||
private final int slot = 3;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
this.customSlots.put(4, this.addSlot(new ResourceHandlerSlot(internal, this::setItemInSlot, 4, 152, 57) {
|
||||
private final int slot = 4;
|
||||
private int x = this.x;
|
||||
private int y = this.y;
|
||||
@Override
|
||||
public boolean mayPlace(ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package net.halbear.aotg.custom.blocks.Forge;
|
||||
|
||||
import net.halbear.aotg.AgeoftheGods;
|
||||
import net.halbear.aotg.registries.ModItems;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
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.material.Fluids;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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<>();
|
||||
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));
|
||||
RecipeMap.put(ModItems.ORICHALCUM_INGOT.asItem(), new ForgedAlloyRecipe(ModItems.ORICHALCUM_INGOT.asItem(), Items.COPPER_INGOT, ModItems.ZINC_INGOT.asItem(),4f));
|
||||
RecipeMap.put(ModItems.HEPATIZON_INGOT.asItem(), new ForgedAlloyRecipe(ModItems.HEPATIZON_INGOT.asItem(), Items.COPPER_INGOT, Items.GOLD_INGOT,9f));
|
||||
CompileReverseLookupMap();
|
||||
}
|
||||
|
||||
public static void CompileReverseLookupMap(){
|
||||
ReverseLookupRecipeMap.clear();
|
||||
RecipeMap.forEach((name, recipe)->{
|
||||
Item item1 = recipe.RequiredMetal1;
|
||||
Item item2 = recipe.RequiredMetal2;
|
||||
if(!ReverseLookupRecipeMap.containsKey(item1)){
|
||||
ReverseLookupRecipeMap.put(item1, new ArrayList<>());
|
||||
}
|
||||
if(!ReverseLookupRecipeMap.containsKey(item2)){
|
||||
ReverseLookupRecipeMap.put(item2, new ArrayList<>());
|
||||
}
|
||||
ReverseLookupRecipeMap.get(item1).add(name);
|
||||
ReverseLookupRecipeMap.get(item2).add(name);
|
||||
});
|
||||
}
|
||||
|
||||
public static List<ForgedAlloyRecipe> GetRecipesContainingMetals(Item Metal1, Item Metal2){
|
||||
List<Item> Metal1Recipes = ReverseLookupRecipeMap.get(Metal1);
|
||||
List<Item> Metal2Recipes = ReverseLookupRecipeMap.get(Metal2);
|
||||
List<ForgedAlloyRecipe> overlapping = new ArrayList<>();
|
||||
if(Metal1Recipes != null && Metal2Recipes != null) {
|
||||
for (Item metal1Recipe : Metal1Recipes) {
|
||||
if (metal1Recipe == null) continue;
|
||||
if (Metal2Recipes.contains(metal1Recipe)) overlapping.add(RecipeMap.get(metal1Recipe));
|
||||
}
|
||||
}
|
||||
return overlapping;
|
||||
}
|
||||
|
||||
public static List<ForgedAlloyRecipe> GetValidRecipesFromContainer(ItemStack Pot){
|
||||
List<ForgedAlloyRecipe> availableRecipes = new ArrayList<>();
|
||||
List<ForgedAlloyRecipe> ValidRecipes = new ArrayList<>();
|
||||
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());
|
||||
if (hasMarker) {
|
||||
ItemStack AlloyMetal1 = potContents.getStackInSlot(1);
|
||||
ItemStack AlloyMetal2 = potContents.getStackInSlot(2);
|
||||
availableRecipes = GetRecipesContainingMetals(AlloyMetal1.getItem(),AlloyMetal2.getItem());
|
||||
availableRecipes.forEach(forgedAlloyRecipe -> {
|
||||
if(Math.floor((float) AlloyMetal1.getCount() /(float)AlloyMetal2.getCount()) == Math.floor(forgedAlloyRecipe.AlloyRatio)) {
|
||||
ValidRecipes.add(forgedAlloyRecipe);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return ValidRecipes;
|
||||
}
|
||||
|
||||
public static List<ForgedAlloyRecipe> GetAvailableRecipesFromContainer(ItemStack Pot){
|
||||
List<ForgedAlloyRecipe> availableRecipes = new ArrayList<>();
|
||||
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());
|
||||
if (hasMarker) {
|
||||
ItemStack AlloyMetal1 = potContents.getStackInSlot(1);
|
||||
ItemStack AlloyMetal2 = potContents.getStackInSlot(2);
|
||||
return GetRecipesContainingMetals(AlloyMetal1.getItem(),AlloyMetal2.getItem());
|
||||
}
|
||||
}
|
||||
}
|
||||
return availableRecipes;
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ public class ModItems {
|
||||
public static final DeferredItem<Item> ORICHALCUM_INGOT = RegisterItem("orichalcum_ingot", Item::new);
|
||||
public static final DeferredItem<Item> HEPATIZON_INGOT = RegisterItem("hepatizon_ingot", Item::new);
|
||||
public static final DeferredItem<Item> SILVER_INGOT = RegisterItem("silver_ingot", Item::new);
|
||||
public static final DeferredItem<Item> HARDENED_SLAG = RegisterItem("slag", Item::new);
|
||||
|
||||
public static final DeferredItem<Item> XIPHOS_SWORD = RegisterItem("xiphos",
|
||||
properties -> new Item(properties
|
||||
|
||||
@@ -49,5 +49,6 @@ public class ModTabs {
|
||||
output.accept(ELECTRUM_INGOT.get());
|
||||
output.accept(HEPATIZON_INGOT.get());
|
||||
output.accept(ORICHALCUM_INGOT.get());
|
||||
output.accept(HARDENED_SLAG.get());
|
||||
}).build());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
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.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
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.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
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;
|
||||
|
||||
@EventBusSubscriber
|
||||
public record ForgeWorkbenchGuiButtonHandler(int buttonID, 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.writeInt(message.x);
|
||||
buffer.writeInt(message.y);
|
||||
buffer.writeInt(message.z);
|
||||
}, (RegistryFriendlyByteBuf buffer) -> new ForgeWorkbenchGuiButtonHandler(buffer.readInt(), buffer.readInt(), buffer.readInt(), buffer.readInt()));
|
||||
|
||||
@Override
|
||||
public Type<ForgeWorkbenchGuiButtonHandler> type() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
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 -> {
|
||||
context.connection().disconnect(Component.literal(e.getMessage()));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleButtonAction(Player entity, int buttonID, int x, int y, int z) {
|
||||
Level world = entity.level();
|
||||
if (!world.getChunkSource().hasChunk(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(z)))
|
||||
return;
|
||||
if (buttonID == 0) {
|
||||
|
||||
}
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void registerMessage(final RegisterPayloadHandlersEvent event) {
|
||||
final PayloadRegistrar registrar = event.registrar("1.0.0");
|
||||
|
||||
registrar.playToServer(
|
||||
ForgeWorkbenchGuiButtonHandler.TYPE,
|
||||
ForgeWorkbenchGuiButtonHandler.STREAM_CODEC,
|
||||
ForgeWorkbenchGuiButtonHandler::handleData
|
||||
);
|
||||
}
|
||||
@SubscribeEvent
|
||||
public static void registerMessage(FMLCommonSetupEvent event) {
|
||||
AgeoftheGods.addNetworkMessage(ForgeWorkbenchGuiButtonHandler.TYPE, ForgeWorkbenchGuiButtonHandler.STREAM_CODEC, ForgeWorkbenchGuiButtonHandler::handleData);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"model": {
|
||||
"type": "minecraft:model",
|
||||
"model": "ageofthegods:item/slag"
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,7 @@
|
||||
"item.ageofthegods.hepatizon_ingot": "Hepatizon Ingot",
|
||||
"item.ageofthegods.orichalcum_ingot": "Orichalcum Ingot",
|
||||
"item.ageofthegods.fluid_indicator_debug_item": "Molten Alloy Mixture: ",
|
||||
"item.ageofthegods.slag": "Hardened Slag",
|
||||
|
||||
"ageofthegods.configuration.title": "Age of the Gods Configs",
|
||||
"ageofthegods.configuration.section.ageofthegods.common.toml": "Age of the Gods Configs",
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "ageofthegods:item/slag"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 444 B |
Binary file not shown.
|
After Width: | Height: | Size: 96 B |
Binary file not shown.
|
After Width: | Height: | Size: 122 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
Reference in New Issue
Block a user