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
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "gtceu:item/gui_module"
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.gregtechceu.gtceu.api.item.component;

import com.gregtechceu.gtceu.api.mui.base.IPanelHandler;
import com.gregtechceu.gtceu.api.mui.value.sync.PanelSyncManager;
import com.gregtechceu.gtceu.client.mui.screen.ModularPanel;
import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer;
import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine;
import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup;

import com.lowdragmc.lowdraglib.gui.widget.Widget;

import net.minecraft.world.item.ItemStack;

public interface IMonitorModuleItem extends IItemComponent {
Expand All @@ -14,7 +15,8 @@ default void tick(ItemStack stack, CentralMonitorMachine machine, MonitorGroup g

IMonitorRenderer getRenderer(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group);

Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group);
ModularPanel createModularPanel(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group,
PanelSyncManager syncManager, IPanelHandler panelHandler);

default String getType() {
return "unknown";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.gregtechceu.gtceu.api.mui;

import com.gregtechceu.gtceu.api.mui.factory.GuiData;
import com.gregtechceu.gtceu.client.mui.screen.ModularContainerMenu;
import com.gregtechceu.gtceu.client.mui.screen.ModularScreen;

import net.minecraft.client.gui.screens.Screen;
import net.minecraftforge.eventbus.api.Event;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
public class InWorldMUIOpenEvent extends Event {

@Getter
private final GuiData guiData;

@Getter
private final Screen vanillaScreen;

@Getter
private final ModularScreen screen;

@Getter
private final ModularContainerMenu menu;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.gregtechceu.gtceu.api.mui;

import net.minecraft.client.gui.GuiGraphics;
import net.minecraftforge.eventbus.api.Event;

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class InWorldMUIRenderEvent extends Event {

private final GuiGraphics graphics;
private final float partialTick;
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

public class AnimatorManager {

public static final AnimatorManager INSTANCE = new AnimatorManager();

private static final List<IAnimator> animators = new ArrayList<>(16);
private static final List<IAnimator> queuedAnimators = new ArrayList<>(8);
private static long lastTime = 0;
Expand All @@ -25,7 +27,7 @@ static void startAnimation(IAnimator animator) {
private AnimatorManager() {}

public static void init() {
MinecraftForge.EVENT_BUS.register(new AnimatorManager());
MinecraftForge.EVENT_BUS.register(INSTANCE);
}

@SubscribeEvent(priority = EventPriority.HIGHEST)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.gregtechceu.gtceu.api.mui.factory;

import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.mui.InWorldMUIOpenEvent;
import com.gregtechceu.gtceu.api.mui.base.IMuiScreen;
import com.gregtechceu.gtceu.api.mui.base.MCHelper;
import com.gregtechceu.gtceu.api.mui.base.UIFactory;
Expand All @@ -9,6 +10,7 @@
import com.gregtechceu.gtceu.api.mui.widget.WidgetTree;
import com.gregtechceu.gtceu.client.mui.screen.*;
import com.gregtechceu.gtceu.common.network.GTNetwork;
import com.gregtechceu.gtceu.common.network.InWorldContainerSynchronizer;
import com.gregtechceu.gtceu.common.network.packets.ui.OpenGuiPacket;

import net.minecraft.client.gui.screens.Screen;
Expand Down Expand Up @@ -45,6 +47,8 @@ public class GuiManager {
16);

private static final List<Player> openedContainers = new ArrayList<>(4);
private static final Object2ObjectMap<ServerPlayer, List<ModularContainerMenu>> openedInWorldContainers = new Object2ObjectOpenHashMap<>();
private static final List<ModularContainerMenu> clientInWorldContainers = new ArrayList<>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this leak old client levels if an in world gui is opened and then the player goes to another dimension?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why would it do that?


public static void registerFactory(UIFactory<?> factory) {
Objects.requireNonNull(factory);
Expand All @@ -67,8 +71,13 @@ public static boolean hasFactory(ResourceLocation name) {

public static <T extends GuiData> void open(@NotNull UIFactory<T> factory, @NotNull T guiData,
ServerPlayer player) {
open(factory, false, guiData, player);
}

public static <T extends GuiData> void open(@NotNull UIFactory<T> factory, boolean inWorldUI, @NotNull T guiData,
ServerPlayer player) {
if (player instanceof FakePlayer || openedContainers.contains(player)) return;
openedContainers.add(player);
if (!inWorldUI) openedContainers.add(player);
// create panel, collect sync handlers and create menu
UISettings settings = new UISettings(XeiSettings.DUMMY);
settings.defaultCanInteractWith(factory, guiData);
Expand All @@ -78,7 +87,7 @@ public static <T extends GuiData> void open(@NotNull UIFactory<T> factory, @NotN

// create the menu
player.nextContainerCounter();
if (player.containerMenu != player.inventoryMenu) {
if (player.containerMenu != player.inventoryMenu && !inWorldUI) {
player.closeContainer();
}
int windowId = player.containerCounter;
Expand All @@ -89,20 +98,29 @@ public static <T extends GuiData> void open(@NotNull UIFactory<T> factory, @NotN
// sync to client
FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer());
factory.writeGuiData(guiData, buffer);
GTNetwork.sendToPlayer(player, new OpenGuiPacket<>(windowId, factory, buffer));
GTNetwork.sendToPlayer(player, new OpenGuiPacket<>(windowId, factory, buffer, inWorldUI));
// open the menu // this mimics forge behaviour
player.initMenu(menu);
player.containerMenu = menu;
if (!inWorldUI) {
player.initMenu(menu);
player.containerMenu = menu;
} else {
List<ModularContainerMenu> tmp = openedInWorldContainers.computeIfAbsent(player, p -> new ArrayList<>());
menu.inWorldID = tmp.size();
tmp.add(menu);
menu.setSynchronizer(new InWorldContainerSynchronizer(player));
}
// finally invoke event
MinecraftForge.EVENT_BUS.post(new PlayerContainerEvent.Open(player, menu));
}

@ApiStatus.Internal
@OnlyIn(Dist.CLIENT)
public static <T extends GuiData> void openFromClient(int windowId, @NotNull UIFactory<T> factory,
public static <T extends GuiData> void openFromClient(int windowId, boolean inWorldUI,
@NotNull UIFactory<T> factory,
@NotNull FriendlyByteBuf data, @NotNull LocalPlayer player) {
T guiData = factory.readGuiData(player, data);
UISettings settings = new UISettings();
if (inWorldUI) settings.getXeiSettings().forceDisabled();
settings.defaultCanInteractWith(factory, guiData);
PanelSyncManager syncManager = new PanelSyncManager(true);
ModularPanel panel = factory.createPanel(guiData, syncManager, settings);
Expand All @@ -118,15 +136,28 @@ public static <T extends GuiData> void openFromClient(int windowId, @NotNull UIF
}
if (guiContainer.getMenu() != container)
throw new IllegalStateException("Custom Containers are not yet allowed!");
MCHelper.setScreen(wrapper.getWrappedScreen());
player.containerMenu = guiContainer.getMenu();
if (inWorldUI) {
container.inWorldID = clientInWorldContainers.size();
clientInWorldContainers.add(container);
MinecraftForge.EVENT_BUS
.post(new InWorldMUIOpenEvent(guiData, wrapper.getWrappedScreen(), screen, container));
} else {
MCHelper.setScreen(wrapper.getWrappedScreen());
player.containerMenu = guiContainer.getMenu();
}
}

@OnlyIn(Dist.CLIENT)
public static <T extends GuiData> void openFromClient(@NotNull UIFactory<T> factory, @NotNull T guiData) {
openFromClient(factory, guiData, false);
}

@OnlyIn(Dist.CLIENT)
public static <T extends GuiData> void openFromClient(@NotNull UIFactory<T> factory, @NotNull T guiData,
boolean inWorldUI) {
FriendlyByteBuf buffer = new FriendlyByteBuf(Unpooled.buffer());
factory.writeGuiData(guiData, buffer);
GTNetwork.sendToServer(new OpenGuiPacket<>(0, factory, buffer));
GTNetwork.sendToServer(new OpenGuiPacket<>(0, factory, buffer, inWorldUI));
}

@OnlyIn(Dist.CLIENT)
Expand All @@ -152,6 +183,16 @@ static void openScreen(ModularScreen screen, UISettings settings) {
public static void onTick(TickEvent.ServerTickEvent event) {
if (event.phase == TickEvent.Phase.END) {
openedContainers.clear();
openedInWorldContainers.values().forEach(arr -> arr.forEach(ModularContainerMenu::onUpdate));
openedInWorldContainers.values().forEach(arr -> arr.forEach(ModularContainerMenu::broadcastChanges));
}
}

@SubscribeEvent
public static void onClientTick(TickEvent.ClientTickEvent event) {
if (event.phase == TickEvent.Phase.END) {
clientInWorldContainers.forEach(ModularContainerMenu::onUpdate);
clientInWorldContainers.forEach(ModularContainerMenu::broadcastChanges);
}
}

Expand All @@ -168,4 +209,12 @@ public static void onCloseContainer(PlayerContainerEvent.Close event) {
modularContainer.removed();
}
}

public static ModularContainerMenu getClientInWorldMenu(int inWorldID) {
return clientInWorldContainers.get(inWorldID);
}

public static ModularContainerMenu getServerInWorldMenu(ServerPlayer player, int inWorldID) {
return openedInWorldContainers.get(player).get(inWorldID);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ private void putSyncValue(String name, int id, SyncHandler syncHandler) {
if (!currentKey.equals(key)) {
boolean auto = name.startsWith(ModularSyncManager.AUTO_SYNC_PREFIX);
if (auto != currentKey.startsWith(ModularSyncManager.AUTO_SYNC_PREFIX)) {
throw new IllegalStateException("Old and new sync handler must both be either not auto or auto!");
throw new IllegalStateException(
"Old and new sync handler must both be either not auto or auto! (old key = \"%s\", new key = \"%s\""
.formatted(currentKey, key));
}
if (auto && !currentKey.startsWith(name)) {
throw new IllegalStateException("Sync Handler was previously added with a different panel!");
Expand Down Expand Up @@ -410,7 +412,8 @@ public PanelSyncManager registerSyncedAction(String mapKey, boolean executeClien

public void callSyncedAction(String mapKey, FriendlyByteBuf packet) {
if (invokeSyncedAction(mapKey, packet)) {
SyncHandlerPacket packetSyncHandler = new SyncHandlerPacket(this.panelName, mapKey, true, packet);
SyncHandlerPacket packetSyncHandler = new SyncHandlerPacket(this.getContainer().inWorldID, this.panelName,
mapKey, true, packet);
if (isClient()) {
GTNetwork.sendToServer(packetSyncHandler);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,8 @@ public static void sendToClient(String panel, FriendlyByteBuf buffer, SyncHandle
throw new IllegalStateException();
}
GTNetwork.sendToPlayer((ServerPlayer) syncHandler.syncManager.getPlayer(),
new SyncHandlerPacket(panel, syncHandler.getKey(), false, buffer));
new SyncHandlerPacket(syncHandler.syncManager.getContainer().inWorldID, panel, syncHandler.getKey(),
false, buffer));
}

public static void sendToServer(String panel, FriendlyByteBuf buffer, SyncHandler syncHandler) {
Expand All @@ -182,6 +183,7 @@ public static void sendToServer(String panel, FriendlyByteBuf buffer, SyncHandle
if (!syncHandler.isValid()) {
throw new IllegalStateException();
}
GTNetwork.sendToServer(new SyncHandlerPacket(panel, syncHandler.getKey(), false, buffer));
GTNetwork.sendToServer(new SyncHandlerPacket(syncHandler.syncManager.getContainer().inWorldID, panel,
syncHandler.getKey(), false, buffer));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import it.unimi.dsi.fastutil.chars.Char2IntOpenHashMap;
import it.unimi.dsi.fastutil.chars.Char2ObjectMap;
import it.unimi.dsi.fastutil.chars.Char2ObjectOpenHashMap;
import lombok.Getter;

import java.util.ArrayList;
import java.util.Collections;
Expand All @@ -17,6 +18,9 @@

public class SlotGroupWidget extends ParentWidget<SlotGroupWidget> {

@Getter
private boolean playerInventory = false;

public static SlotGroupWidget playerInventory(boolean positioned) {
return positioned ? playerInventory(7, true) : playerInventory((index, slot) -> slot);
}
Expand All @@ -43,6 +47,7 @@ public static SlotGroupWidget playerInventory(int bottom, boolean horizontalCent
*/
public static SlotGroupWidget playerInventory(SlotConsumer slotConsumer) {
SlotGroupWidget slotGroupWidget = new SlotGroupWidget();
slotGroupWidget.playerInventory = true;
slotGroupWidget.coverChildren();
slotGroupWidget.name("player_inventory");
String key = "player";
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/gregtechceu/gtceu/client/CharTypedEvent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gregtechceu.gtceu.client;

import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* Fired when the corresponding GLFW event is triggered, before Minecraft's handling.
* Cancelling this event will also cancel further handling by Minecraft, like firing the
* {@link net.minecraftforge.client.event.ScreenEvent.CharacterTyped} event.
*/
@AllArgsConstructor
@Getter
@Cancelable
public class CharTypedEvent extends Event {

private final char codepoint;
private final int modifiers;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.gregtechceu.gtceu.client;

import net.minecraftforge.client.event.InputEvent.Key;
import net.minecraftforge.client.event.ScreenEvent.KeyPressed;
import net.minecraftforge.eventbus.api.Cancelable;
import net.minecraftforge.eventbus.api.Event;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* Fired when the corresponding GLFW event is triggered, before Minecraft's handling.
* Cancelling this event will also cancel further handling by Minecraft, like detecting
* ESC to pause the game, other controls, and firing the {@link Key} and {@link KeyPressed}
* events.
*/
@AllArgsConstructor
@Getter
@Cancelable
public class EarlyKeyPressEvent extends Event {

private final int key;
private final int scanCode;
private final int action;
private final int modifiers;
}
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,9 @@ private static boolean doAction(@Nullable ModularScreen muiScreen, Predicate<Mod
/**
* This replicates vanilla behavior while also injecting custom behavior for consistency
*/
private static boolean handleKeyboardInput(@Nullable ModularScreen muiScreen, Screen mcScreen,
boolean isPress, InputPhase inputPhase,
int keyCode, int scanCode, int modifiers) {
public static boolean handleKeyboardInput(@Nullable ModularScreen muiScreen, Screen mcScreen,
boolean isPress, InputPhase inputPhase,
int keyCode, int scanCode, int modifiers) {
if (isPress) {
// pressing a key
return inputPhase.isEarly() ? doAction(muiScreen, ms -> ms.keyPressed(keyCode, scanCode, modifiers)) :
Expand Down Expand Up @@ -676,7 +676,7 @@ public static GuiContext getBestContext() {
return defaultContext;
}

private enum InputPhase {
public enum InputPhase {

// for mui interactions
EARLY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public static ModularContainerMenu getCurrent(Player player) {
@OnlyIn(Dist.CLIENT)
private ModularScreen optionalScreen;

public int inWorldID = -1;

public ModularContainerMenu(int containerId) {
super(GTMenuTypes.MODULAR_CONTAINER.get(), containerId);
}
Expand Down
Loading