Skip to content

Commit f656e66

Browse files
committed
Small enhancement of showing the recipes via a button in the UI.
1 parent e9609e6 commit f656e66

File tree

16 files changed

+273
-216
lines changed

16 files changed

+273
-216
lines changed

src/main/java/dev/technici4n/moderndynamics/attachment/IoAttachmentItem.java

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -89,29 +89,5 @@ public void appendHoverText(ItemStack itemStack, TooltipContext context, Tooltip
8989
builder
9090
.accept(Component.translatable("gui.moderndynamics.tooltip.attachment_upgrades")
9191
.setStyle(Style.EMPTY.withColor(ChatFormatting.GOLD)));
92-
/*
93-
* if (level != null && level.isClientSide()) {
94-
* if (MdProxy.INSTANCE.isShiftDown()) {
95-
* MutableComponent filters = null;
96-
* for (var setting : getSupportedSettings()) {
97-
* if (setting.isFilter()) {
98-
* if (filters == null) {
99-
* filters = setting.getTooltipName().copy();
100-
* } else {
101-
* filters.append(", ").append(setting.getTooltipName());
102-
* }
103-
* }
104-
* }
105-
* if (filters != null) {
106-
* filters.withStyle(ChatFormatting.WHITE);
107-
* tooltipComponents.add(Component.translatable("gui.moderndynamics.tooltip.filters", filters).withStyle(ChatFormatting.GRAY));
108-
* }
109-
* } else {
110-
* var keyText = Component.translatable("gui.moderndynamics.tooltip.more_info_key").withStyle(ChatFormatting.YELLOW,
111-
* ChatFormatting.ITALIC);
112-
* tooltipComponents.add(Component.translatable("gui.moderndynamics.tooltip.more_info", keyText).withStyle(ChatFormatting.GRAY));
113-
* }
114-
* }
115-
*/
11692
}
11793
}

src/main/java/dev/technici4n/moderndynamics/attachment/attached/FluidAttachedIo.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,13 @@ public FluidAttachedIo(IoAttachmentItem item, ValueInput configData, Runnable se
5050
super(item, configData, setChangedCallback);
5151

5252
this.filters = NonNullList.withSize(Constants.Upgrades.MAX_FILTER, FluidResource.EMPTY);
53-
var filterTags = configData.read("filters", FILTER_LIST_CODEC);
54-
filterTags.ifPresent(filters::addAll);
53+
configData.read("filters", FILTER_LIST_CODEC).ifPresent(filterList -> {
54+
for (int i = 0; i < filterList.size(); i++) {
55+
if (i < filters.size()) {
56+
filters.set(i, filterList.get(i));
57+
}
58+
}
59+
});
5560
}
5661

5762
@Override
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Modern Dynamics
3+
* Copyright (C) 2021 shartte & Technici4n
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
package dev.technici4n.moderndynamics.client.compat;
20+
21+
import java.util.Objects;
22+
import org.jspecify.annotations.Nullable;
23+
24+
public interface RecipeViewer {
25+
static RecipeViewer current() {
26+
return Objects.requireNonNullElse(RecipeViewerHolder.current, NoOpRecipeViewer.INSTANCE);
27+
}
28+
29+
static void setCurrent(@Nullable RecipeViewer current) {
30+
RecipeViewerHolder.current = current;
31+
}
32+
33+
default boolean canShowUpgradeRecipes() {
34+
return false;
35+
}
36+
37+
default void showUpgradeRecipes() {
38+
}
39+
}
40+
41+
class RecipeViewerHolder {
42+
static RecipeViewer current;
43+
}
44+
45+
final class NoOpRecipeViewer implements RecipeViewer {
46+
static final RecipeViewer INSTANCE = new NoOpRecipeViewer();
47+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Modern Dynamics
3+
* Copyright (C) 2021 shartte & Technici4n
4+
*
5+
* This program is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 3 of the License, or (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18+
*/
19+
package dev.technici4n.moderndynamics.client.compat.jei;
20+
21+
import dev.technici4n.moderndynamics.client.compat.RecipeViewer;
22+
import java.util.List;
23+
import mezz.jei.api.runtime.IJeiRuntime;
24+
25+
public class JeiRecipeViewer implements RecipeViewer {
26+
private final IJeiRuntime jeiRuntime;
27+
28+
public JeiRecipeViewer(IJeiRuntime jeiRuntime) {
29+
this.jeiRuntime = jeiRuntime;
30+
}
31+
32+
@Override
33+
public boolean canShowUpgradeRecipes() {
34+
return true;
35+
}
36+
37+
@Override
38+
public void showUpgradeRecipes() {
39+
jeiRuntime.getRecipesGui().showTypes(List.of(UpgradeCategory.TYPE));
40+
}
41+
}

src/main/java/dev/technici4n/moderndynamics/client/compat/jei/MdJeiPlugin.java

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,19 @@
1919
package dev.technici4n.moderndynamics.client.compat.jei;
2020

2121
import dev.technici4n.moderndynamics.attachment.upgrade.LoadedUpgrades;
22+
import dev.technici4n.moderndynamics.client.compat.RecipeViewer;
2223
import dev.technici4n.moderndynamics.client.screen.AttachedIoScreen;
2324
import dev.technici4n.moderndynamics.gui.menu.FluidConfigSlot;
2425
import dev.technici4n.moderndynamics.init.MdItems;
2526
import dev.technici4n.moderndynamics.util.MdId;
2627
import java.util.ArrayList;
2728
import java.util.List;
2829
import java.util.Optional;
29-
import java.util.function.Function;
3030
import mezz.jei.api.IModPlugin;
3131
import mezz.jei.api.JeiPlugin;
32+
import mezz.jei.api.gui.builder.IClickableIngredientFactory;
3233
import mezz.jei.api.gui.handlers.IGuiContainerHandler;
33-
import mezz.jei.api.helpers.IPlatformFluidHelper;
34-
import mezz.jei.api.ingredients.ITypedIngredient;
34+
import mezz.jei.api.neoforge.NeoForgeTypes;
3535
import mezz.jei.api.registration.IGuiHandlerRegistration;
3636
import mezz.jei.api.registration.IRecipeCatalystRegistration;
3737
import mezz.jei.api.registration.IRecipeCategoryRegistration;
@@ -40,21 +40,23 @@
4040
import mezz.jei.api.runtime.IJeiRuntime;
4141
import net.minecraft.client.renderer.Rect2i;
4242
import net.minecraft.resources.Identifier;
43-
import net.minecraft.world.inventory.Slot;
4443
import net.minecraft.world.item.ItemStack;
4544

4645
@JeiPlugin
4746
public class MdJeiPlugin implements IModPlugin {
48-
private IPlatformFluidHelper<?> platformFluidHelper;
49-
5047
@Override
5148
public Identifier getPluginUid() {
5249
return MdId.of("jei");
5350
}
5451

5552
@Override
5653
public void onRuntimeAvailable(IJeiRuntime jeiRuntime) {
57-
this.platformFluidHelper = jeiRuntime.getJeiHelpers().getPlatformFluidHelper();
54+
RecipeViewer.setCurrent(new JeiRecipeViewer(jeiRuntime));
55+
}
56+
57+
@Override
58+
public void onRuntimeUnavailable() {
59+
RecipeViewer.setCurrent(null);
5860
}
5961

6062
@Override
@@ -89,34 +91,20 @@ public List<Rect2i> getGuiExtraAreas(AttachedIoScreen<?> screen) {
8991
}
9092

9193
@Override
92-
public Optional<IClickableIngredient<?>> getClickableIngredientUnderMouse(AttachedIoScreen<?> screen, double mouseX, double mouseY) {
94+
public Optional<? extends IClickableIngredient<?>> getClickableIngredientUnderMouse(IClickableIngredientFactory builder,
95+
AttachedIoScreen<?> screen, double mouseX, double mouseY) {
9396
// Ensures that users can press R, U, etc... on fluid config slots.
9497
if (screen.getHoveredSlot() instanceof FluidConfigSlot fluidConfig) {
9598
var resource = fluidConfig.getFilter();
9699
if (!resource.isEmpty()) {
97-
var ing = registration.getJeiHelpers().getIngredientManager();
98-
return ing.createTypedIngredient(resource.toStack(1))
99-
.map(slotArea(screen, fluidConfig));
100+
var slotArea = new Rect2i(screen.getLeftPos() + fluidConfig.x, screen.getTopPos() + fluidConfig.y, 16, 16);
101+
return builder.createBuilder(NeoForgeTypes.FLUID_STACK, resource.toStack(1))
102+
.buildWithArea(slotArea);
100103
}
101104
}
102105

103106
return Optional.empty();
104107
}
105-
106-
private static <T> Function<ITypedIngredient<T>, IClickableIngredient<T>> slotArea(AttachedIoScreen<?> screen, Slot slot) {
107-
var area = new Rect2i(screen.getLeftPos() + slot.x, screen.getTopPos() + slot.y, 16, 16);
108-
return ing -> new IClickableIngredient<>() {
109-
@Override
110-
public ITypedIngredient<T> getTypedIngredient() {
111-
return ing;
112-
}
113-
114-
@Override
115-
public Rect2i getArea() {
116-
return area;
117-
}
118-
};
119-
}
120108
});
121109

122110
// Allows slots to be locked by dragging from REI

src/main/java/dev/technici4n/moderndynamics/client/screen/AttachedIoScreen.java

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import dev.technici4n.moderndynamics.attachment.Setting;
2222
import dev.technici4n.moderndynamics.attachment.settings.RedstoneMode;
23+
import dev.technici4n.moderndynamics.client.compat.RecipeViewer;
2324
import dev.technici4n.moderndynamics.gui.menu.AttachedIoMenu;
2425
import dev.technici4n.moderndynamics.gui.menu.ConfigSlot;
2526
import dev.technici4n.moderndynamics.gui.menu.FluidConfigSlot;
@@ -33,6 +34,7 @@
3334
import net.minecraft.ChatFormatting;
3435
import net.minecraft.client.gui.GuiGraphics;
3536
import net.minecraft.client.gui.components.AbstractWidget;
37+
import net.minecraft.client.gui.components.Button;
3638
import net.minecraft.client.gui.components.Renderable;
3739
import net.minecraft.client.gui.components.events.GuiEventListener;
3840
import net.minecraft.client.gui.narration.NarratableEntry;
@@ -76,6 +78,9 @@ public class AttachedIoScreen<T extends AttachedIoMenu<?>> extends AbstractConta
7678
private final RedstoneModeButton redstoneModeHigh;
7779
private final List<RedstoneModeButton> redstoneButtons;
7880

81+
private final boolean showUpgradesButtonEnabled;
82+
private ScreenRectangle upgradePanelBounds;
83+
7984
public AttachedIoScreen(T abstractContainerMenu, Inventory inventory, Component component) {
8085
this(abstractContainerMenu, inventory, component, 176, 166);
8186
}
@@ -87,12 +92,15 @@ public AttachedIoScreen(T abstractContainerMenu, Inventory inventory, Component
8792
this.redstoneModeLow = new RedstoneModeButton(RedstoneMode.REQUIRES_LOW, menu::getRedstoneMode, menu::setRedstoneMode);
8893
this.redstoneModeHigh = new RedstoneModeButton(RedstoneMode.REQUIRES_HIGH, menu::getRedstoneMode, menu::setRedstoneMode);
8994
this.redstoneButtons = List.of(this.redstoneModeIgnored, this.redstoneModeLow, this.redstoneModeHigh);
95+
this.showUpgradesButtonEnabled = RecipeViewer.current().canShowUpgradeRecipes();
9096
}
9197

9298
@Override
9399
protected void init() {
94100
super.init();
95101

102+
this.upgradePanelBounds = UpgradePanel.getRect(leftPos, topPos, showUpgradesButtonEnabled);
103+
96104
// Center the title
97105
titleLabelX = (imageWidth - font.width(title)) / 2;
98106

@@ -126,6 +134,14 @@ protected void init() {
126134

127135
// After the buttons, add a handler for opening and closing the tab
128136
addRenderableWidget(new RedstoneTabOpenCloseHandler());
137+
138+
if (showUpgradesButtonEnabled) {
139+
addRenderableWidget(Button.builder(Component.literal("?"), _ -> {
140+
RecipeViewer.current().showUpgradeRecipes();
141+
})
142+
.bounds(upgradePanelBounds.left() + 7, upgradePanelBounds.bottom() - 19, 14, 14)
143+
.build());
144+
}
129145
}
130146

131147
@Override
@@ -180,17 +196,16 @@ protected void renderBg(GuiGraphics guiGraphics, float partialTick, int mouseX,
180196
guiGraphics.blit(
181197
RenderPipelines.GUI_TEXTURED,
182198
TEXTURE,
183-
leftPos + UpgradePanel.START_LEFT, topPos + UpgradePanel.START_TOP,
199+
upgradePanelBounds.left(), upgradePanelBounds.top(),
184200
0, 0,
185-
UpgradePanel.WIDTH, UpgradePanel.HEIGHT - 5,
201+
upgradePanelBounds.width(), upgradePanelBounds.height() - 5,
186202
256, 256);
187-
// Render last 5 rows with a different offset to have a proper corner
188203
guiGraphics.blit(
189204
RenderPipelines.GUI_TEXTURED,
190205
TEXTURE,
191-
leftPos + UpgradePanel.START_LEFT, topPos + UpgradePanel.START_TOP + UpgradePanel.HEIGHT - 5,
206+
upgradePanelBounds.left(), upgradePanelBounds.bottom() - 5,
192207
0, 199,
193-
UpgradePanel.WIDTH, 5,
208+
upgradePanelBounds.width(), 5,
194209
256, 256);
195210

196211
// Draw each slot's background
@@ -264,7 +279,7 @@ private void renderRedstoneTabBg(GuiGraphics guiGraphics, float partialTicks) {
264279

265280
public void appendExclusionZones(Consumer<Rect2i> consumer) {
266281
// Upgrades
267-
consumer.accept(new Rect2i(leftPos + UpgradePanel.START_LEFT, topPos + UpgradePanel.START_TOP, UpgradePanel.WIDTH, UpgradePanel.HEIGHT));
282+
consumer.accept(new Rect2i(upgradePanelBounds.left(), upgradePanelBounds.top(), upgradePanelBounds.width(), upgradePanelBounds.height()));
268283
// Redstone tab
269284
consumer.accept(redstoneTabRect);
270285
}
@@ -337,7 +352,7 @@ protected boolean hasClickedOutside(double mx, double my, int xo, int yo) {
337352
return false;
338353
}
339354

340-
return !UpgradePanel.isInside(mx - leftPos, my - topPos) && !isInRedstoneTabRect(mx, my);
355+
return !upgradePanelBounds.containsPoint((int) mx, (int) my) && !isInRedstoneTabRect(mx, my);
341356
}
342357

343358
private boolean isInRedstoneTabRect(double mouseX, double mouseY) {

src/main/java/dev/technici4n/moderndynamics/compat/mi/MIAbsentProxy.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,20 @@
2222
import dev.technici4n.moderndynamics.util.MdId;
2323
import net.minecraft.core.Direction;
2424
import net.neoforged.neoforge.capabilities.BlockCapability;
25-
import net.neoforged.neoforge.energy.IEnergyStorage;
25+
import net.neoforged.neoforge.transfer.energy.EnergyHandler;
2626

2727
public class MIAbsentProxy implements MIProxy {
28-
private static final BlockCapability<? extends IEnergyStorage, Direction> MISSING_LOOKUP = BlockCapability.createSided(
28+
private static final BlockCapability<? extends EnergyHandler, Direction> MISSING_LOOKUP = BlockCapability.createSided(
2929
MdId.of("mi_energy_missing"),
30-
IEnergyStorage.class);
30+
EnergyHandler.class);
3131

3232
@Override
33-
public BlockCapability<? extends IEnergyStorage, Direction> getLookup() {
33+
public BlockCapability<? extends EnergyHandler, Direction> getLookup() {
3434
return MISSING_LOOKUP;
3535
}
3636

3737
@Override
38-
public boolean canConnect(IEnergyStorage storage, MICableTier tier) {
38+
public boolean canConnect(EnergyHandler storage, MICableTier tier) {
3939
return false;
4040
}
4141
}

src/main/java/dev/technici4n/moderndynamics/compat/mi/MIAvailableProxy.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,34 +24,34 @@
2424
import java.lang.invoke.MethodType;
2525
import net.minecraft.core.Direction;
2626
import net.neoforged.neoforge.capabilities.BlockCapability;
27-
import net.neoforged.neoforge.energy.IEnergyStorage;
27+
import net.neoforged.neoforge.transfer.energy.EnergyHandler;
2828

2929
public class MIAvailableProxy implements MIProxy {
30-
private static final BlockCapability<? extends IEnergyStorage, Direction> LOOKUP;
30+
private static final BlockCapability<? extends EnergyHandler, Direction> LOOKUP;
3131
private static final MethodHandle CAN_CONNECT;
3232

3333
static {
3434
try {
3535
// noinspection unchecked,rawtypes
36-
LOOKUP = (BlockCapability<? extends IEnergyStorage, Direction>) Class.forName("aztech.modern_industrialization.api.energy.EnergyApi")
36+
LOOKUP = (BlockCapability<? extends EnergyHandler, Direction>) Class.forName("aztech.modern_industrialization.api.energy.EnergyApi")
3737
.getField("SIDED").get(null);
3838

3939
var miEnergyStorage = Class.forName("aztech.modern_industrialization.api.energy.MIEnergyStorage");
4040
var rawMethod = MethodHandles.lookup().findVirtual(miEnergyStorage, "canConnect", MethodType.methodType(boolean.class, String.class));
4141
// Convert first argument to EnergyStorage because that's what we'll be passing in the invokeExact call.
42-
CAN_CONNECT = rawMethod.asType(rawMethod.type().changeParameterType(0, IEnergyStorage.class));
42+
CAN_CONNECT = rawMethod.asType(rawMethod.type().changeParameterType(0, EnergyHandler.class));
4343
} catch (ReflectiveOperationException exception) {
4444
throw new RuntimeException("Failed to initialize Modern Dynamics MI proxy", exception);
4545
}
4646
}
4747

4848
@Override
49-
public BlockCapability<? extends IEnergyStorage, Direction> getLookup() {
49+
public BlockCapability<? extends EnergyHandler, Direction> getLookup() {
5050
return LOOKUP;
5151
}
5252

5353
@Override
54-
public boolean canConnect(IEnergyStorage storage, MICableTier tier) {
54+
public boolean canConnect(EnergyHandler storage, MICableTier tier) {
5555
try {
5656
return (boolean) CAN_CONNECT.invokeExact(storage, tier.getName());
5757
} catch (Throwable throwable) {

0 commit comments

Comments
 (0)