Basic development

This commit is contained in:
XevianLight
2026-01-16 17:51:41 -07:00
parent b0131011e5
commit 48e5499ad3
119 changed files with 3613 additions and 185 deletions

View File

@@ -0,0 +1,131 @@
package net.xevianlight.aphelion.screen;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.Container;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerData;
import net.minecraft.world.inventory.SimpleContainerData;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.items.SlotItemHandler;
import net.xevianlight.aphelion.Aphelion;
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
import net.xevianlight.aphelion.util.EnergyItemSlot;
import net.xevianlight.aphelion.util.ExtractOnlySlot;
import org.jetbrains.annotations.NotNull;
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
public final ElectricArcFurnaceEntity blockEntity;
private final Level level;
private final ContainerData data;
public ElectricArcFurnaceMenu(int i, Inventory inventory, FriendlyByteBuf extraData) {
this(i, inventory, inventory.player.level().getBlockEntity(extraData.readBlockPos()), new SimpleContainerData(4));
}
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
this.blockEntity = ((ElectricArcFurnaceEntity) blockEntity);
this.level = inventory.player.level();
this.data = data;
addPlayerInventory(inventory);
addPlayerHotbar(inventory);
this.addSlot(new EnergyItemSlot(this.blockEntity.inventory, 3, 8, 54));
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 0, 63, 35));
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 1, 40, 35));
this.addSlot(new ExtractOnlySlot(this.blockEntity.inventory, 2, 125, 35));
addDataSlots(data);
}
@Override
public boolean stillValid(Player player) {
return true;
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 3; // must be the number of slots you have!
@Override
public @NotNull ItemStack quickMoveStack(Player playerIn, int pIndex) {
Slot sourceSlot = slots.get(pIndex);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
blockEntity.sendUpdate();
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
blockEntity.sendUpdate();
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + pIndex);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
blockEntity.sendUpdate();
} else {
blockEntity.sendUpdate();
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
blockEntity.sendUpdate();
return copyOfSourceStack;
}
public int getScaledArrowProgress() {
int progress = this.data.get(0);
int maxProgress = this.data.get(1);
int arrowPixelSize = 24;
return maxProgress != 0 && progress != 0 ? progress * arrowPixelSize / maxProgress : 0;
}
private void addPlayerInventory(Inventory playerInventory) {
for (int i = 0; i < 3; ++i) {
for (int l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18));
}
}
}
private void addPlayerHotbar(Inventory playerInventory) {
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
}
}

View File

@@ -0,0 +1,111 @@
package net.xevianlight.aphelion.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.xevianlight.aphelion.Aphelion;
import net.xevianlight.aphelion.screen.renderer.EnergyDisplayTooltipArea;
import net.xevianlight.aphelion.util.MouseUtil;
import java.util.Optional;
public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricArcFurnaceMenu> {
private static final ResourceLocation GUI_TEXTURE =
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "textures/gui/electric_arc_furnace/gui.png");
private static final ResourceLocation ARROW_TEXTURE =
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID,"textures/gui/base/arrow_progress.png");
private EnergyDisplayTooltipArea energyInfoArea;
public ElectricArcFurnaceScreen(ElectricArcFurnaceMenu menu, Inventory playerInventory, Component title) {
super(menu, playerInventory, title);
}
@Override
protected void init() {
super.init();
// Gets rid of labels
this.inventoryLabelY = 73;
this.titleLabelY = 5;
this.titleLabelX = 35;
assignEnergyInfoArea();
}
@Override
protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, GUI_TEXTURE);
int x = (width - imageWidth) / 2;
int y = (height - imageHeight) / 2;
guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight);
renderProgressArrow(guiGraphics, x, y);
if (menu.blockEntity.getBlockState().getValue(BlockStateProperties.LIT)) {
guiGraphics.blit(GUI_TEXTURE, x + 54, y + 14, 176, 75, 13, 18);
}
renderEnergyBar(guiGraphics, x , y);
}
private void renderProgressArrow(GuiGraphics guiGraphics, int x, int y) {
guiGraphics.blit(ARROW_TEXTURE,x + 88, y + 35, 0, 0, menu.getScaledArrowProgress(), 16, 24, 16);
}
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
int stored = menu.blockEntity.getEnergyStorage(null).getEnergyStored();
int max = menu.blockEntity.getEnergyStorage(null).getMaxEnergyStored();
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
h = Math.max(0, Math.min(42, h));
int w = 14;
int drawX = x + 9;
int drawY = y + 9 + (42 - h); // move up as it fills
int u = 176;
int v = 15 + (42 - h); // sample lower part of bar texture
guiGraphics.blit(GUI_TEXTURE, drawX, drawY, u, v, w, h);
}
private void assignEnergyInfoArea() {
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getEnergyStorage(null), 14, 42);
}
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
if(isMouseAboveArea(pMouseX, pMouseY, x, y, 9, 9, 14, 42)) {
guiGraphics.renderTooltip(this.font, energyInfoArea.getTooltips(),
Optional.empty(), pMouseX - x, pMouseY - y);
}
}
@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
renderBackground(guiGraphics, mouseX, mouseY, delta);
super.render(guiGraphics, mouseX, mouseY, delta);
renderTooltip(guiGraphics, mouseX, mouseY);
}
@Override
protected void renderLabels(GuiGraphics guiGraphics, int mouseX, int mouseY) {
super.renderLabels(guiGraphics, mouseX, mouseY);
int x = (width - imageWidth) / 2;
int y = (height - imageHeight) / 2;
renderEnergyAreaTooltip(guiGraphics, mouseX, mouseY, x, y);
}
public static boolean isMouseAboveArea(int pMouseX, int pMouseY, int x, int y, int offsetX, int offsetY, int width, int height) {
return MouseUtil.isMouseOver(pMouseX, pMouseY, x + offsetX, y + offsetY, width, height);
}
}

View File

@@ -0,0 +1,30 @@
package net.xevianlight.aphelion.screen;
import net.minecraft.core.registries.Registries;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MenuType;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
import net.neoforged.neoforge.network.IContainerFactory;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.xevianlight.aphelion.Aphelion;
public class ModMenuTypes {
public static final DeferredRegister<MenuType<?>> MENUS =
DeferredRegister.create(Registries.MENU, Aphelion.MOD_ID);
public static DeferredHolder<MenuType<?>,MenuType<TestBlockMenu>> TEST_BLOCK_MENU =
registerMenuType("test_block_menu", TestBlockMenu::new);
public static DeferredHolder<MenuType<?>,MenuType<ElectricArcFurnaceMenu>> ELECTRIC_ARC_FURNACE_MENU =
registerMenuType("electric_arc_furnace_menu", ElectricArcFurnaceMenu::new);
private static <T extends AbstractContainerMenu>DeferredHolder<MenuType<?>, MenuType<T>> registerMenuType(String name,
IContainerFactory<T> factory) {
return MENUS.register(name, () -> IMenuTypeExtension.create(factory));
}
public static void register(IEventBus eventBus) {
MENUS.register(eventBus);
}
}

View File

@@ -0,0 +1,107 @@
package net.xevianlight.aphelion.screen;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.items.SlotItemHandler;
import net.xevianlight.aphelion.block.entity.custom.TestBlockEntity;
import org.jetbrains.annotations.NotNull;
public class TestBlockMenu extends AbstractContainerMenu {
public final TestBlockEntity blockEntity;
private final Level level;
public TestBlockMenu(int i, Inventory inventory, FriendlyByteBuf extraData) {
this(i, inventory, inventory.player.level().getBlockEntity(extraData.readBlockPos()));
}
public TestBlockMenu(int i, Inventory inventory, BlockEntity blockEntity) {
super(ModMenuTypes.TEST_BLOCK_MENU.get(), i);
this.blockEntity = ((TestBlockEntity) blockEntity);
this.level = inventory.player.level();
addPlayerInventory(inventory);
addPlayerHotbar(inventory);
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, 0, 80, 35));
}
@Override
public boolean stillValid(Player player) {
return true;
}
// CREDIT GOES TO: diesieben07 | https://github.com/diesieben07/SevenCommons
// must assign a slot number to each of the slots used by the GUI.
// For this container, we can see both the tile inventory's slots as well as the player inventory slots and the hotbar.
// Each time we add a Slot to the container, it automatically increases the slotIndex, which means
// 0 - 8 = hotbar slots (which will map to the InventoryPlayer slot numbers 0 - 8)
// 9 - 35 = player inventory slots (which map to the InventoryPlayer slot numbers 9 - 35)
// 36 - 44 = TileInventory slots, which map to our TileEntity slot numbers 0 - 8)
private static final int HOTBAR_SLOT_COUNT = 9;
private static final int PLAYER_INVENTORY_ROW_COUNT = 3;
private static final int PLAYER_INVENTORY_COLUMN_COUNT = 9;
private static final int PLAYER_INVENTORY_SLOT_COUNT = PLAYER_INVENTORY_COLUMN_COUNT * PLAYER_INVENTORY_ROW_COUNT;
private static final int VANILLA_SLOT_COUNT = HOTBAR_SLOT_COUNT + PLAYER_INVENTORY_SLOT_COUNT;
private static final int VANILLA_FIRST_SLOT_INDEX = 0;
private static final int TE_INVENTORY_FIRST_SLOT_INDEX = VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT;
// THIS YOU HAVE TO DEFINE!
private static final int TE_INVENTORY_SLOT_COUNT = 1; // must be the number of slots you have!
@Override
public @NotNull ItemStack quickMoveStack(Player playerIn, int pIndex) {
Slot sourceSlot = slots.get(pIndex);
if (sourceSlot == null || !sourceSlot.hasItem()) return ItemStack.EMPTY; //EMPTY_ITEM
ItemStack sourceStack = sourceSlot.getItem();
ItemStack copyOfSourceStack = sourceStack.copy();
// Check if the slot clicked is one of the vanilla container slots
if (pIndex < VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT) {
// This is a vanilla container slot so merge the stack into the tile inventory
if (!moveItemStackTo(sourceStack, TE_INVENTORY_FIRST_SLOT_INDEX, TE_INVENTORY_FIRST_SLOT_INDEX
+ TE_INVENTORY_SLOT_COUNT, false)) {
blockEntity.sendUpdate();
return ItemStack.EMPTY; // EMPTY_ITEM
}
} else if (pIndex < TE_INVENTORY_FIRST_SLOT_INDEX + TE_INVENTORY_SLOT_COUNT) {
// This is a TE slot so merge the stack into the players inventory
if (!moveItemStackTo(sourceStack, VANILLA_FIRST_SLOT_INDEX, VANILLA_FIRST_SLOT_INDEX + VANILLA_SLOT_COUNT, false)) {
blockEntity.sendUpdate();
return ItemStack.EMPTY;
}
} else {
System.out.println("Invalid slotIndex:" + pIndex);
return ItemStack.EMPTY;
}
// If stack size == 0 (the entire stack was moved) set slot contents to null
if (sourceStack.getCount() == 0) {
sourceSlot.set(ItemStack.EMPTY);
blockEntity.sendUpdate();
} else {
blockEntity.sendUpdate();
sourceSlot.setChanged();
}
sourceSlot.onTake(playerIn, sourceStack);
blockEntity.sendUpdate();
return copyOfSourceStack;
}
private void addPlayerInventory(Inventory playerInventory) {
for (int i = 0; i < 3; ++i) {
for (int l = 0; l < 9; ++l) {
this.addSlot(new Slot(playerInventory, l + i * 9 + 9, 8 + l * 18, 84 + i * 18));
}
}
}
private void addPlayerHotbar(Inventory playerInventory) {
for (int i = 0; i < 9; ++i) {
this.addSlot(new Slot(playerInventory, i, 8 + i * 18, 142));
}
}
}

View File

@@ -0,0 +1,47 @@
package net.xevianlight.aphelion.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
import net.xevianlight.aphelion.Aphelion;
public class TestBlockScreen extends AbstractContainerScreen<TestBlockMenu> {
private static final ResourceLocation GUI_TEXTURE =
ResourceLocation.fromNamespaceAndPath(Aphelion.MOD_ID, "textures/gui/test_block/gui.png");
public TestBlockScreen(TestBlockMenu menu, Inventory playerInventory, Component title) {
super(menu, playerInventory, title);
}
@Override
protected void init() {
super.init();
// Gets rid of labels
this.inventoryLabelY = 73;
this.titleLabelY = 5;
}
@Override
protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, GUI_TEXTURE);
int x = (width - imageWidth) / 2;
int y = (height - imageHeight) / 2;
pGuiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, imageWidth, imageHeight);
}
@Override
public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) {
renderBackground(guiGraphics, mouseX, mouseY, delta);
super.render(guiGraphics, mouseX, mouseY, delta);
renderTooltip(guiGraphics, mouseX, mouseY);
}
}

View File

@@ -0,0 +1,46 @@
package net.xevianlight.aphelion.screen.renderer;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.network.chat.Component;
import net.neoforged.neoforge.energy.IEnergyStorage;
import java.util.List;
/*
* BluSunrize
* Copyright (c) 2021
*
* This code is licensed under "Blu's License of Common Sense"
* https://github.com/BluSunrize/ImmersiveEngineering/blob/1.19.2/LICENSE
*
* Slightly Modified Version by: Kaupenjoe
*/
public class EnergyDisplayTooltipArea {
private final int xPos;
private final int yPos;
private final int width;
private final int height;
private final IEnergyStorage energy;
public EnergyDisplayTooltipArea(int xMin, int yMin, IEnergyStorage energy) {
this(xMin, yMin, energy,8,64);
}
public EnergyDisplayTooltipArea(int xMin, int yMin, IEnergyStorage energy, int width, int height) {
xPos = xMin;
yPos = yMin;
this.width = width;
this.height = height;
this.energy = energy;
}
public List<Component> getTooltips() {
return List.of(Component.literal(energy.getEnergyStored()+" / "+energy.getMaxEnergyStored()+" FE"));
}
public void render(GuiGraphics guiGraphics) {
int stored = (int)(height * (energy.getEnergyStored() / (float)energy.getMaxEnergyStored()));
guiGraphics.fillGradient(xPos,yPos + (height - stored),xPos + width,
yPos + height,0xffb51500, 0xff600b00);
}
}