filename:
common/src/main/java/rearth/oritech/init/compat/rei/Screens/OritechReiDisplay.java
branch:
1.21
back to repo
package rearth.oritech.init.compat.rei.Screens;
import dev.architectury.hooks.fluid.FluidStackHooks;
import io.wispforest.owo.compat.rei.ReiUIAdapter;
import io.wispforest.owo.ui.component.Components;
import io.wispforest.owo.ui.container.Containers;
import io.wispforest.owo.ui.container.FlowLayout;
import io.wispforest.owo.ui.core.*;
import me.shedaniel.math.Point;
import me.shedaniel.math.Rectangle;
import me.shedaniel.rei.api.client.gui.Renderer;
import me.shedaniel.rei.api.client.gui.widgets.Widget;
import me.shedaniel.rei.api.client.gui.widgets.Widgets;
import me.shedaniel.rei.api.client.registry.display.DisplayCategory;
import me.shedaniel.rei.api.common.category.CategoryIdentifier;
import me.shedaniel.rei.api.common.display.Display;
import me.shedaniel.rei.api.common.util.EntryStacks;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.ItemConvertible;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import rearth.oritech.block.base.entity.MachineBlockEntity;
import rearth.oritech.block.base.entity.UpgradableGeneratorBlockEntity;
import rearth.oritech.init.compat.rei.OritechDisplay;
import rearth.oritech.init.recipes.OritechRecipeType;
import rearth.oritech.util.InventorySlotAssignment;
import rearth.oritech.util.ScreenProvider;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import static rearth.oritech.client.ui.BasicMachineScreen.GUI_COMPONENTS;
public class OritechReiDisplay implements DisplayCategory<Display> {
protected final OritechRecipeType recipeType;
private final Boolean isGenerator;
private final List<ScreenProvider.GuiSlot> slots;
private final InventorySlotAssignment slotOffsets;
protected final ItemConvertible icon;
public OritechReiDisplay(OritechRecipeType recipeType, Class<? extends MachineBlockEntity> screenProviderSource, ItemConvertible icon) {
var blockState = Blocks.STONE.getDefaultState();
if (icon instanceof Block blockItem)
blockState = blockItem.getDefaultState();
var finalBlockState = blockState;
this.recipeType = recipeType;
try {
var screenProvider = screenProviderSource.getDeclaredConstructor(BlockPos.class, BlockState.class).newInstance(new BlockPos(0, 0, 0), finalBlockState);
this.isGenerator = screenProvider instanceof UpgradableGeneratorBlockEntity;
this.slots = screenProvider.getGuiSlots();
this.slotOffsets = screenProvider.getSlotAssignments();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
this.icon = icon;
}
public OritechReiDisplay(OritechRecipeType recipeType, ItemConvertible icon, boolean isGenerator, List<ScreenProvider.GuiSlot> slots, InventorySlotAssignment assignments) {
this.recipeType = recipeType;
this.icon = icon;
this.isGenerator = isGenerator;
this.slots = slots;
this.slotOffsets = assignments;
}
@Override
public List<Widget> setupDisplay(Display display, Rectangle bounds) {
var adapter = new ReiUIAdapter<>(bounds, Containers::verticalFlow);
var root = adapter.rootComponent();
root.horizontalAlignment(HorizontalAlignment.CENTER)
.surface(Surface.PANEL)
.padding(Insets.of(4));
fillDisplay(root, (OritechDisplay) display, adapter);
adapter.prepare();
return List.of(adapter);
}
public void fillDisplay(FlowLayout root, OritechDisplay display, ReiUIAdapter<FlowLayout> adapter) {
var offsetX = 23;
var offsetY = 17;
// inputs
var inputEntries = display.getInputEntries();
for (int i = 0; i < inputEntries.size(); i++) {
var entry = inputEntries.get(i);
if (entry.isEmpty()) continue;
var pos = slots.get(slotOffsets.inputStart() + i);
root.child(
adapter.wrap(Widgets.createSlot(new Point(0, 0)).entries(entry).markInput())
.positioning(Positioning.absolute(pos.x() - offsetX, pos.y() - offsetY)));
}
// arrow
if (isGenerator) {
root.child(adapter.wrap(Widgets.createBurningFire(new Point(0, 0))).positioning(Positioning.absolute(77 - offsetX, 42 - offsetY)));
} else {
root.child(adapter.wrap(Widgets.createArrow(new Point(0, 0))).positioning(Positioning.absolute(80 - offsetX, 39 - offsetY)));
}
// outputs
var outputEntries = display.getOutputEntries();
for (int i = 0; i < outputEntries.size(); i++) {
var entry = outputEntries.get(i);
if (entry.isEmpty()) continue;
var pos = slots.get(slotOffsets.outputStart() + i);
root.child(
adapter.wrap(Widgets.createSlot(new Point(0, 0)).entry(entry.get(0)).markOutput())
.positioning(Positioning.absolute(pos.x() - offsetX, pos.y() - offsetY)));
}
// data
var duration = String.format("%.0f", display.getEntry().value().getTime() / 20f);
root.child(
Components.label(Text.translatable("rei.title.oritech.cookingtime", duration, display.getEntry().value().getTime())).lineHeight(7)
.positioning(Positioning.relative(35, 97))
);
// fluids
if (display.entry.value().getFluidInput() != null && display.entry.value().getFluidInput().getAmount() > 0) {
var fluid = display.entry.value().getFluidInput().getFluid();
var amount = display.entry.value().getFluidInput().getAmount();
root.child(rearth.oritech.client.ui.BasicMachineScreen.createFluidRenderer(display.entry.value().getFluidInput(), new ScreenProvider.BarConfiguration(4, 5, 16, 50)));
var text = amount > 0
? Text.translatable("tooltip.oritech.fluid_content", amount * 1000 / FluidStackHooks.bucketAmount(), FluidStackHooks.getName(display.entry.value().getFluidInput()).getString())
: Text.translatable("tooltip.oritech.fluid_empty");
var foreGround = Components.texture(GUI_COMPONENTS, 48, 0, 14, 50, 98, 96);
foreGround.sizing(Sizing.fixed(18), Sizing.fixed(52));
foreGround.positioning(Positioning.absolute(3, 4));
foreGround.tooltip(text);
root.child(foreGround);
}
if (display.entry.value().getFluidOutput() != null && display.entry.value().getFluidOutput().getAmount() > 0) {
var fluid = display.entry.value().getFluidOutput().getFluid();
var amount = display.entry.value().getFluidOutput().getAmount();
root.child(rearth.oritech.client.ui.BasicMachineScreen.createFluidRenderer(display.entry.value().getFluidOutput(), new ScreenProvider.BarConfiguration(123, 5, 16, 50)));
var text = amount > 0
? Text.translatable("tooltip.oritech.fluid_content", amount * 1000 / FluidStackHooks.bucketAmount(), FluidStackHooks.getName(display.entry.value().getFluidOutput()).getString())
: Text.translatable("tooltip.oritech.fluid_empty");
var foreGround = Components.texture(GUI_COMPONENTS, 48, 0, 14, 50, 98, 96);
foreGround.sizing(Sizing.fixed(18), Sizing.fixed(52));
foreGround.positioning(Positioning.absolute(122, 4));
foreGround.tooltip(text);
root.child(foreGround);
}
}
@Override
public CategoryIdentifier<? extends Display> getCategoryIdentifier() {
return CategoryIdentifier.of(recipeType.getIdentifier());
}
@Override
public Text getTitle() {
return Text.translatable("rei.process." + recipeType.getIdentifier());
}
@Override
public Renderer getIcon() {
return EntryStacks.of(icon);
}
}