aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gregtech/api/gui/modularui/GT_UIInfos.java
blob: 89a0835f13587012a34a0b513f53e5c10fdbf14b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package gregtech.api.gui.modularui;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;

import com.gtnewhorizons.modularui.api.UIInfos;
import com.gtnewhorizons.modularui.api.screen.ITileWithModularUI;
import com.gtnewhorizons.modularui.api.screen.ModularUIContext;
import com.gtnewhorizons.modularui.api.screen.ModularWindow;
import com.gtnewhorizons.modularui.api.screen.UIBuildContext;
import com.gtnewhorizons.modularui.common.builder.UIBuilder;
import com.gtnewhorizons.modularui.common.builder.UIInfo;
import com.gtnewhorizons.modularui.common.internal.network.NetworkUtils;
import com.gtnewhorizons.modularui.common.internal.wrapper.ModularGui;
import com.gtnewhorizons.modularui.common.internal.wrapper.ModularUIContainer;

import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import gregtech.api.enums.GT_Values;
import gregtech.api.interfaces.tileentity.ICoverable;
import gregtech.api.interfaces.tileentity.IHasWorldObjectAndCoords;
import gregtech.api.net.GT_Packet_SendCoverData;
import gregtech.api.util.GT_CoverBehaviorBase;

public class GT_UIInfos {

    public static void init() {}

    /**
     * Generator for {@link UIInfo} which is responsible for registering and opening UIs. Unlike
     * {@link com.gtnewhorizons.modularui.api.UIInfos#TILE_MODULAR_UI}, this accepts custom constructors for UI. <br>
     * Do NOT run {@link UIBuilder#build} on-the-fly, otherwise MP client won't register UIs. Instead, store to static
     * field, just like {@link #GTTileEntityDefaultUI}. Such mistake can be easily overlooked by testing only SP.
     */
    public static final Function<ContainerConstructor, UIInfo<?, ?>> GTTileEntityUIFactory = containerConstructor -> UIBuilder
        .of()
        .container((player, world, x, y, z) -> {
            TileEntity te = world.getTileEntity(x, y, z);
            if (te instanceof ITileWithModularUI mui) {
                return createTileEntityContainer(player, mui::createWindow, te::markDirty, containerConstructor);
            }
            return null;
        })
        .gui(((player, world, x, y, z) -> {
            if (!world.isRemote) return null;
            TileEntity te = world.getTileEntity(x, y, z);
            if (te instanceof ITileWithModularUI mui) {
                return createTileEntityGuiContainer(player, mui::createWindow, containerConstructor);
            }
            return null;
        }))
        .build();

    private static final UIInfo<?, ?> GTTileEntityDefaultUI = GTTileEntityUIFactory.apply(ModularUIContainer::new);

    private static final Map<ForgeDirection, UIInfo<?, ?>> coverUI = new HashMap<>();

    static {
        for (final ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) {
            coverUI.put(
                side,
                UIBuilder.of()
                    .container((player, world, x, y, z) -> {
                        final TileEntity te = world.getTileEntity(x, y, z);
                        if (!(te instanceof ICoverable gtTileEntity)) return null;
                        final GT_CoverBehaviorBase<?> cover = gtTileEntity.getCoverBehaviorAtSideNew(side);
                        return createCoverContainer(
                            player,
                            cover::createWindow,
                            te::markDirty,
                            gtTileEntity.getCoverIDAtSide(side),
                            side,
                            gtTileEntity);
                    })
                    .gui((player, world, x, y, z) -> {
                        if (!world.isRemote) return null;
                        final TileEntity te = world.getTileEntity(x, y, z);
                        if (!(te instanceof ICoverable gtTileEntity)) return null;
                        final GT_CoverBehaviorBase<?> cover = gtTileEntity.getCoverBehaviorAtSideNew(side);
                        return createCoverGuiContainer(
                            player,
                            cover::createWindow,
                            gtTileEntity.getCoverIDAtSide(side),
                            side,
                            gtTileEntity);
                    })
                    .build());
        }
    }

    /**
     * Opens TileEntity UI, created by {@link ITileWithModularUI#createWindow}.
     */
    public static void openGTTileEntityUI(IHasWorldObjectAndCoords aTileEntity, EntityPlayer aPlayer) {
        if (aTileEntity.isClientSide()) return;
        GTTileEntityDefaultUI.open(
            aPlayer,
            aTileEntity.getWorld(),
            aTileEntity.getXCoord(),
            aTileEntity.getYCoord(),
            aTileEntity.getZCoord());
    }

    /**
     * Opens cover UI, created by {@link GT_CoverBehaviorBase#createWindow}.
     */
    public static void openCoverUI(ICoverable tileEntity, EntityPlayer player, ForgeDirection side) {
        if (tileEntity.isClientSide()) return;

        GT_Values.NW.sendToPlayer(
            new GT_Packet_SendCoverData(
                side,
                tileEntity.getCoverIDAtSide(side),
                tileEntity.getComplexCoverDataAtSide(side),
                tileEntity),
            (EntityPlayerMP) player);

        coverUI.get(side)
            .open(
                player,
                tileEntity.getWorld(),
                tileEntity.getXCoord(),
                tileEntity.getYCoord(),
                tileEntity.getZCoord());
    }

    /**
     * Opens UI for player's item, created by
     * {@link com.gtnewhorizons.modularui.api.screen.IItemWithModularUI#createWindow}.
     */
    public static void openPlayerHeldItemUI(EntityPlayer player) {
        if (NetworkUtils.isClient()) return;
        UIInfos.PLAYER_HELD_ITEM_UI.open(player);
    }

    private static ModularUIContainer createTileEntityContainer(EntityPlayer player,
        Function<UIBuildContext, ModularWindow> windowCreator, Runnable onWidgetUpdate,
        ContainerConstructor containerCreator) {
        final UIBuildContext buildContext = new UIBuildContext(player);
        final ModularWindow window = windowCreator.apply(buildContext);
        if (window == null) return null;
        return containerCreator.of(new ModularUIContext(buildContext, onWidgetUpdate), window);
    }

    @SideOnly(Side.CLIENT)
    private static ModularGui createTileEntityGuiContainer(EntityPlayer player,
        Function<UIBuildContext, ModularWindow> windowCreator, ContainerConstructor containerConstructor) {
        final ModularUIContainer container = createTileEntityContainer(
            player,
            windowCreator,
            null,
            containerConstructor);
        if (container == null) return null;
        return new ModularGui(container);
    }

    private static ModularUIContainer createCoverContainer(EntityPlayer player,
        Function<GT_CoverUIBuildContext, ModularWindow> windowCreator, Runnable onWidgetUpdate, int coverID,
        ForgeDirection side, ICoverable tile) {
        final GT_CoverUIBuildContext buildContext = new GT_CoverUIBuildContext(player, coverID, side, tile, false);
        final ModularWindow window = windowCreator.apply(buildContext);
        if (window == null) return null;
        return new ModularUIContainer(new ModularUIContext(buildContext, onWidgetUpdate), window);
    }

    @SideOnly(Side.CLIENT)
    private static ModularGui createCoverGuiContainer(EntityPlayer player,
        Function<GT_CoverUIBuildContext, ModularWindow> windowCreator, int coverID, ForgeDirection side,
        ICoverable tile) {
        final ModularUIContainer container = createCoverContainer(player, windowCreator, null, coverID, side, tile);
        if (container == null) {
            return null;
        }
        return new ModularGui(container);
    }

    @FunctionalInterface
    public interface ContainerConstructor {

        ModularUIContainer of(ModularUIContext context, ModularWindow mainWindow);
    }
}