Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.inventory.AbstractContainerMenu;
import com.mojang.datafixers.util.Either;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -76,12 +78,13 @@ public default void drawInstance(GuiGraphics guiGraphics, T instance, long maxQu
* @param mouseX The mouse X position.
* @param mouseY The mouse Y position.
* @param additionalTooltipLines The additional tooltip lines to add.
* @param additionalTooltipComponent An optional visual tooltip component to render below the tooltip lines.
* @param additionalTooltipElements Optional elements to render below the tooltip lines,
* which can mix text and visual components.
*/
@OnlyIn(Dist.CLIENT)
public void drawInstance(GuiGraphics guiGraphics, T instance, long maxQuantity, @Nullable String label, AbstractContainerScreen gui, ContainerScreenTerminalStorage.DrawLayer layer, float partialTick, int x, int y,
int mouseX, int mouseY, @Nullable List<Component> additionalTooltipLines,
@Nullable TooltipComponent additionalTooltipComponent);
@Nullable List<Either<FormattedText, TooltipComponent>> additionalTooltipElements);

/**
* Show the quantity of the given instance on the second tooltip line.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.cyclops.integratedterminals.api.terminalstorage.crafting;

import net.minecraft.world.item.ItemStack;
import org.cyclops.commoncapabilities.api.ingredient.IIngredientMatcher;
import org.cyclops.commoncapabilities.api.ingredient.IPrototypedIngredient;
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
Expand Down Expand Up @@ -59,6 +60,15 @@ public interface ITerminalCraftingOption<T> extends Comparable<ITerminalCrafting
*/
public <T1, M> Collection<T1> getInputs(IngredientComponent<T1, M> ingredientComponent);

/**
* Item representations of the machines that this crafting job option is crafted in.
*
* @return The crafting machines, can be empty if they are unknown.
*/
public default List<ItemStack> getCraftingMachines() {
return Collections.emptyList();
}

/**
* The inputs of this crafting job option for the given ingredient component,
* where each input can be fulfilled by any of its alternatives.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.Slot;
import com.mojang.datafixers.util.Either;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
Expand Down Expand Up @@ -67,7 +69,7 @@ public ItemStack getIcon() {
public void drawInstance(GuiGraphics guiGraphics, Long instance, long maxQuantity, @Nullable String label, AbstractContainerScreen gui,
ContainerScreenTerminalStorage.DrawLayer layer, float partialTick, int x, int y,
int mouseX, int mouseY, @Nullable List<Component> additionalTooltipLines,
@Nullable TooltipComponent additionalTooltipComponent) {
@Nullable List<Either<FormattedText, TooltipComponent>> additionalTooltipElements) {
if (instance > 0) {
if (layer == ContainerScreenTerminalStorage.DrawLayer.BACKGROUND){

Expand Down Expand Up @@ -103,7 +105,7 @@ public void drawInstance(GuiGraphics guiGraphics, Long instance, long maxQuantit
lines.addAll(additionalTooltipLines);
}
return lines;
}, additionalTooltipComponent);
}, additionalTooltipElements);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.Slot;
import com.mojang.datafixers.util.Either;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
Expand Down Expand Up @@ -74,7 +76,7 @@ public void drawInstance(GuiGraphics guiGraphics, FluidStack instance, long maxQ
ContainerScreenTerminalStorage.DrawLayer layer, float partialTick,
int x, int y, int mouseX, int mouseY,
@Nullable List<Component> additionalTooltipLines,
@Nullable TooltipComponent additionalTooltipComponent) {
@Nullable List<Either<FormattedText, TooltipComponent>> additionalTooltipElements) {
if (instance != null) {
if (layer == ContainerScreenTerminalStorage.DrawLayer.BACKGROUND) {
// Draw fluid
Expand All @@ -92,7 +94,7 @@ public void drawInstance(GuiGraphics guiGraphics, FluidStack instance, long maxQ
lines.addAll(additionalTooltipLines);
}
return lines;
}, additionalTooltipComponent);
}, additionalTooltipElements);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.Slot;
import com.mojang.datafixers.util.Either;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
Expand Down Expand Up @@ -70,7 +72,7 @@ public ItemStack getIcon() {
public void drawInstance(GuiGraphics guiGraphics, ItemStack instance, long maxQuantity, @Nullable String label, AbstractContainerScreen gui,
ContainerScreenTerminalStorage.DrawLayer layer, float partialTick, int x, int y,
int mouseX, int mouseY, @Nullable List<Component> additionalTooltipLines,
@Nullable TooltipComponent additionalTooltipComponent) {
@Nullable List<Either<FormattedText, TooltipComponent>> additionalTooltipElements) {
// Make a copy of the item to make sure that any changes in the NBT tag that the mod may make during rendering
// does not propagate into our client-side index. Otherwise, the client may think it has different items than
// the server, which will cause these items not to be extractable by the client from the terminal.
Expand Down Expand Up @@ -98,7 +100,7 @@ public void drawInstance(GuiGraphics guiGraphics, ItemStack instance, long maxQu
}
addQuantityTooltip(lines, instanceCopy);
return lines;
}, additionalTooltipComponent);
}, additionalTooltipElements);
}
Lighting.setupForFlatItems();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,96 +1,34 @@
package org.cyclops.integratedterminals.client.gui.tooltip;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.cyclops.commoncapabilities.api.ingredient.IPrototypedIngredient;
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
import org.cyclops.integratedterminals.Capabilities;
import org.cyclops.integratedterminals.client.gui.container.ContainerScreenTerminalStorage;

import javax.annotation.Nullable;
import java.util.List;

/**
* Renders the ingredients of a {@link CraftingOptionIngredientsTooltip} as a grid of icons.
*
* The grid wraps after {@link #MAX_COLUMNS} icons,
* and inputs that accept multiple alternatives are cycled through within their own slot.
* Inputs that accept multiple alternatives are cycled through within their own slot.
*
* @author rubensworks
*/
@OnlyIn(Dist.CLIENT)
public class ClientCraftingOptionIngredientsTooltip implements ClientTooltipComponent {

private static final ResourceLocation SLOT_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/slot");
private static final int SLOT_WIDTH = 18;
private static final int SLOT_HEIGHT = 20;
private static final int MAX_COLUMNS = 9;
private static final int MARGIN_Y = 2;

/**
* The number of ticks an alternative is shown before cycling to the next one.
*/
private static final int TICK_DELAY = 30;
public class ClientCraftingOptionIngredientsTooltip extends ClientCraftingOptionSlotsTooltip {

private final List<List<IPrototypedIngredient<?, ?>>> ingredients;
private final int columns;
private final int rows;

public ClientCraftingOptionIngredientsTooltip(CraftingOptionIngredientsTooltip tooltip) {
super(tooltip.ingredients().size());
this.ingredients = tooltip.ingredients();
// Spread the ingredients evenly over as few rows as possible
this.rows = Math.max(1, (int) Math.ceil((double) this.ingredients.size() / MAX_COLUMNS));
this.columns = Math.max(1, (int) Math.ceil((double) this.ingredients.size() / this.rows));
}

@Override
public int getHeight() {
return this.rows * SLOT_HEIGHT + MARGIN_Y;
}

@Override
public int getWidth(Font font) {
return this.columns * SLOT_WIDTH;
}

@Override
public void renderImage(Font font, int x, int y, GuiGraphics guiGraphics) {
int tick = getTick();
for (int i = 0; i < this.ingredients.size(); i++) {
List<IPrototypedIngredient<?, ?>> alternatives = this.ingredients.get(i);
int slotX = x + (i % this.columns) * SLOT_WIDTH;
int slotY = y + (i / this.columns) * SLOT_HEIGHT;
guiGraphics.blitSprite(SLOT_SPRITE, slotX, slotY, SLOT_WIDTH, SLOT_HEIGHT);
// Cycle over the alternatives of this input
drawIngredient(guiGraphics, alternatives.get(tick % alternatives.size()), slotX + 1, slotY + 1);
}
}

protected static <T, M> void drawIngredient(GuiGraphics guiGraphics, IPrototypedIngredient<T, M> ingredient, int x, int y) {
IngredientComponent<T, M> ingredientComponent = ingredient.getComponent();
long quantity = ingredientComponent.getMatcher().getQuantity(ingredient.getPrototype());
ingredientComponent.getCapability(Capabilities.IngredientComponentTerminalStorageHandler.INGREDIENT)
.ifPresent(handler -> handler.drawInstance(guiGraphics, ingredient.getPrototype(), quantity, null,
getContainerScreen(), ContainerScreenTerminalStorage.DrawLayer.BACKGROUND, 0,
x, y, 0, 0, null));
}

@Nullable
protected static AbstractContainerScreen<?> getContainerScreen() {
Screen screen = Minecraft.getInstance().screen;
return screen instanceof AbstractContainerScreen<?> containerScreen ? containerScreen : null;
}

protected static int getTick() {
Minecraft minecraft = Minecraft.getInstance();
return minecraft.level == null ? 0 : (int) (minecraft.level.getGameTime() / TICK_DELAY);
protected void drawSlot(GuiGraphics guiGraphics, int slot, int x, int y) {
// Cycle over the alternatives of this input
List<IPrototypedIngredient<?, ?>> alternatives = this.ingredients.get(slot);
drawIngredient(guiGraphics, alternatives.get(getTick() % alternatives.size()), x, y);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.cyclops.integratedterminals.client.gui.tooltip;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;

import java.util.List;

/**
* Renders the machines of a {@link CraftingOptionMachinesTooltip} as a grid of icons.
*
* @author rubensworks
*/
@OnlyIn(Dist.CLIENT)
public class ClientCraftingOptionMachinesTooltip extends ClientCraftingOptionSlotsTooltip {

private final List<ItemStack> machines;

public ClientCraftingOptionMachinesTooltip(CraftingOptionMachinesTooltip tooltip) {
super(tooltip.machines().size());
this.machines = tooltip.machines();
}

@Override
protected void drawSlot(GuiGraphics guiGraphics, int slot, int x, int y) {
guiGraphics.renderItem(this.machines.get(slot), x, y);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package org.cyclops.integratedterminals.client.gui.tooltip;

import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import org.cyclops.commoncapabilities.api.ingredient.IPrototypedIngredient;
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
import org.cyclops.integratedterminals.Capabilities;
import org.cyclops.integratedterminals.client.gui.container.ContainerScreenTerminalStorage;

import javax.annotation.Nullable;

/**
* Base class for tooltip components that render a grid of slots.
*
* The grid wraps after {@link #MAX_COLUMNS} slots,
* and is spread evenly over as few rows as possible.
*
* @author rubensworks
*/
@OnlyIn(Dist.CLIENT)
public abstract class ClientCraftingOptionSlotsTooltip implements ClientTooltipComponent {

protected static final ResourceLocation SLOT_SPRITE = ResourceLocation.withDefaultNamespace("container/bundle/slot");
protected static final int SLOT_WIDTH = 18;
protected static final int SLOT_HEIGHT = 20;
protected static final int MAX_COLUMNS = 9;
protected static final int MARGIN_Y = 2;

/**
* The number of ticks an alternative is shown before cycling to the next one.
*/
protected static final int TICK_DELAY = 30;

private final int slots;
private final int columns;
private final int rows;

public ClientCraftingOptionSlotsTooltip(int slots) {
this.slots = slots;
this.rows = Math.max(1, (int) Math.ceil((double) slots / MAX_COLUMNS));
this.columns = Math.max(1, (int) Math.ceil((double) slots / this.rows));
}

/**
* Draw the contents of the slot at the given index.
* @param guiGraphics The gui graphics.
* @param slot The slot index.
* @param x The X position to draw at.
* @param y The Y position to draw at.
*/
protected abstract void drawSlot(GuiGraphics guiGraphics, int slot, int x, int y);

@Override
public int getHeight() {
return this.rows * SLOT_HEIGHT + MARGIN_Y;
}

@Override
public int getWidth(Font font) {
return this.columns * SLOT_WIDTH;
}

@Override
public void renderImage(Font font, int x, int y, GuiGraphics guiGraphics) {
for (int i = 0; i < this.slots; i++) {
int slotX = x + (i % this.columns) * SLOT_WIDTH;
int slotY = y + (i / this.columns) * SLOT_HEIGHT;
guiGraphics.blitSprite(SLOT_SPRITE, slotX, slotY, SLOT_WIDTH, SLOT_HEIGHT);
drawSlot(guiGraphics, i, slotX + 1, slotY + 1);
}
}

protected static <T, M> void drawIngredient(GuiGraphics guiGraphics, IPrototypedIngredient<T, M> ingredient, int x, int y) {
IngredientComponent<T, M> ingredientComponent = ingredient.getComponent();
long quantity = ingredientComponent.getMatcher().getQuantity(ingredient.getPrototype());
ingredientComponent.getCapability(Capabilities.IngredientComponentTerminalStorageHandler.INGREDIENT)
.ifPresent(handler -> handler.drawInstance(guiGraphics, ingredient.getPrototype(), quantity, null,
getContainerScreen(), ContainerScreenTerminalStorage.DrawLayer.BACKGROUND, 0,
x, y, 0, 0, null));
}

@Nullable
protected static AbstractContainerScreen<?> getContainerScreen() {
Screen screen = Minecraft.getInstance().screen;
return screen instanceof AbstractContainerScreen<?> containerScreen ? containerScreen : null;
}

protected static int getTick() {
Minecraft minecraft = Minecraft.getInstance();
return minecraft.level == null ? 0 : (int) (minecraft.level.getGameTime() / TICK_DELAY);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.cyclops.integratedterminals.client.gui.tooltip;

import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;

import java.util.List;

/**
* A tooltip component holding the machines that a crafting option is crafted in.
*
* @param machines The crafting machines.
* @author rubensworks
*/
public record CraftingOptionMachinesTooltip(List<ItemStack> machines) implements TooltipComponent {
}
Loading
Loading