Skip to content

Commit 0d8ecc0

Browse files
committed
Base functionality done, todo item collapsing, auto pull/push, and proper front textures
1 parent 185c399 commit 0d8ecc0

File tree

3 files changed

+400
-0
lines changed

3 files changed

+400
-0
lines changed

src/main/java/gregtech/common/metatileentities/MetaTileEntities.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityCleaningMaintenanceHatch;
7878
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityComputationHatch;
7979
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDataAccessHatch;
80+
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityDualHatch;
8081
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityEnergyHatch;
8182
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityFluidHatch;
8283
import gregtech.common.metatileentities.multi.multiblockpart.MetaTileEntityItemBus;
@@ -261,6 +262,8 @@ public class MetaTileEntities {
261262
public static MetaTileEntityHPCACooler HPCA_HEAT_SINK_COMPONENT;
262263
public static MetaTileEntityHPCACooler HPCA_ACTIVE_COOLER_COMPONENT;
263264
public static MetaTileEntityHPCABridge HPCA_BRIDGE_COMPONENT;
265+
public static MetaTileEntityDualHatch[] DUAL_INPUT_HATCH = new MetaTileEntityDualHatch[GTValues.V.length - 1];
266+
public static MetaTileEntityDualHatch[] DUAL_OUTPUT_HATCH = new MetaTileEntityDualHatch[GTValues.V.length - 1];
264267

265268
// Used for addons if they wish to disable certain tiers of machines
266269
private static final Map<String, Boolean> MID_TIER = new HashMap<>();
@@ -1218,6 +1221,20 @@ public static void init() {
12181221

12191222
// 1820-1849 are taken for UHV+ 4A/16A/64A Energy/Dynamo Hatches
12201223
// 1850-1869 are taken for UHV+ Input/Output Buses/Hatches
1224+
1225+
// Dual Input Hatches
1226+
for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) {
1227+
String voltageName = GTValues.VN[tier].toLowerCase();
1228+
DUAL_INPUT_HATCH[tier] = registerMetaTileEntity(1879 + tier, new MetaTileEntityDualHatch(
1229+
gregtechId(String.format("%s.%s", "dual_input_hatch", voltageName)), tier, false));
1230+
}
1231+
1232+
// Dual Output Hatches
1233+
for (int tier = GTValues.ULV; tier <= (GregTechAPI.isHighTier() ? GTValues.OpV : GTValues.UHV); tier++) {
1234+
String voltageName = GTValues.VN[tier].toLowerCase();
1235+
DUAL_INPUT_HATCH[tier] = registerMetaTileEntity(1893 + tier, new MetaTileEntityDualHatch(
1236+
gregtechId(String.format("%s.%s", "dual_output_hatch", voltageName)), tier, true));
1237+
}
12211238
}
12221239

12231240
private static void registerSimpleMetaTileEntity(SimpleMachineMetaTileEntity[] machines,
Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
package gregtech.common.metatileentities.multi.multiblockpart;
2+
3+
import gregtech.api.GTValues;
4+
import gregtech.api.capability.DualHandler;
5+
import gregtech.api.capability.GregtechDataCodes;
6+
import gregtech.api.capability.IControllable;
7+
import gregtech.api.capability.IGhostSlotConfigurable;
8+
import gregtech.api.capability.impl.FluidTankList;
9+
import gregtech.api.capability.impl.GhostCircuitItemStackHandler;
10+
import gregtech.api.capability.impl.ItemHandlerList;
11+
import gregtech.api.capability.impl.NotifiableFluidTank;
12+
import gregtech.api.capability.impl.NotifiableItemStackHandler;
13+
import gregtech.api.items.itemhandlers.GTItemStackHandler;
14+
import gregtech.api.metatileentity.MetaTileEntity;
15+
import gregtech.api.metatileentity.interfaces.IGregTechTileEntity;
16+
import gregtech.api.metatileentity.multiblock.AbilityInstances;
17+
import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart;
18+
import gregtech.api.metatileentity.multiblock.MultiblockAbility;
19+
import gregtech.api.mui.GTGuiTextures;
20+
import gregtech.api.mui.GTGuis;
21+
import gregtech.api.mui.widget.GhostCircuitSlotWidget;
22+
import gregtech.client.renderer.texture.Textures;
23+
import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer;
24+
import gregtech.common.mui.widget.GTFluidSlot;
25+
26+
import net.minecraft.client.resources.I18n;
27+
import net.minecraft.item.ItemStack;
28+
import net.minecraft.nbt.NBTTagCompound;
29+
import net.minecraft.network.PacketBuffer;
30+
import net.minecraft.util.ResourceLocation;
31+
import net.minecraft.world.World;
32+
import net.minecraftforge.fluids.IFluidTank;
33+
import net.minecraftforge.items.IItemHandlerModifiable;
34+
35+
import codechicken.lib.render.CCRenderState;
36+
import codechicken.lib.render.pipeline.IVertexOperation;
37+
import codechicken.lib.vec.Matrix4;
38+
import com.cleanroommc.modularui.api.drawable.IKey;
39+
import com.cleanroommc.modularui.api.widget.IWidget;
40+
import com.cleanroommc.modularui.factory.PosGuiData;
41+
import com.cleanroommc.modularui.screen.ModularPanel;
42+
import com.cleanroommc.modularui.value.BoolValue;
43+
import com.cleanroommc.modularui.value.sync.BooleanSyncValue;
44+
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
45+
import com.cleanroommc.modularui.value.sync.SyncHandlers;
46+
import com.cleanroommc.modularui.widget.Widget;
47+
import com.cleanroommc.modularui.widgets.ItemSlot;
48+
import com.cleanroommc.modularui.widgets.SlotGroupWidget;
49+
import com.cleanroommc.modularui.widgets.ToggleButton;
50+
import com.cleanroommc.modularui.widgets.layout.Flow;
51+
import com.cleanroommc.modularui.widgets.layout.Grid;
52+
import org.jetbrains.annotations.NotNull;
53+
import org.jetbrains.annotations.Nullable;
54+
55+
import java.util.ArrayList;
56+
import java.util.Arrays;
57+
import java.util.List;
58+
59+
public class MetaTileEntityDualHatch extends MetaTileEntityMultiblockNotifiablePart implements
60+
IMultiblockAbilityPart<IItemHandlerModifiable>,
61+
IControllable,
62+
IGhostSlotConfigurable {
63+
64+
@Nullable
65+
protected GhostCircuitItemStackHandler circuitInventory;
66+
@Nullable
67+
private IItemHandlerModifiable actualImportItems;
68+
private DualHandler dualHandler;
69+
70+
private boolean workingEnabled;
71+
private boolean autoCollapse;
72+
73+
public MetaTileEntityDualHatch(ResourceLocation metaTileEntityId, int tier, boolean isExportHatch) {
74+
super(metaTileEntityId, tier, isExportHatch);
75+
initializeInventory();
76+
}
77+
78+
@Override
79+
public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) {
80+
return new MetaTileEntityDualHatch(metaTileEntityId, getTier(), isExportHatch);
81+
}
82+
83+
@Override
84+
protected void initializeInventory() {
85+
super.initializeInventory();
86+
if (hasGhostCircuitInventory()) {
87+
circuitInventory = new GhostCircuitItemStackHandler(this);
88+
circuitInventory.addNotifiableMetaTileEntity(this);
89+
actualImportItems = new ItemHandlerList(Arrays.asList(super.getImportItems(), circuitInventory));
90+
} else {
91+
actualImportItems = null;
92+
}
93+
dualHandler = new DualHandler(isExportHatch ? getExportItems() : getImportItems(),
94+
isExportHatch ? getExportFluids() : getImportFluids(), isExportHatch);
95+
}
96+
97+
@Override
98+
public IItemHandlerModifiable getImportItems() {
99+
return actualImportItems == null ? super.getImportItems() : actualImportItems;
100+
}
101+
102+
protected IFluidTank[] createTanks() {
103+
int size = 1 + Math.min(GTValues.UHV, getTier());
104+
IFluidTank[] tanks = new IFluidTank[size];
105+
for (int index = 0; index < tanks.length; index++) {
106+
tanks[index] = new NotifiableFluidTank(getTankSize(), null, isExportHatch);
107+
}
108+
return tanks;
109+
}
110+
111+
protected int getItemSize() {
112+
int sizeRoot = 1 + Math.min(GTValues.UHV, getTier());
113+
return sizeRoot * sizeRoot;
114+
}
115+
116+
protected int getTankSize() {
117+
return 8_000 * Math.min(Integer.MAX_VALUE, 1 << getTier());
118+
}
119+
120+
@Override
121+
protected IItemHandlerModifiable createImportItemHandler() {
122+
return isExportHatch ? new GTItemStackHandler(this, 0) :
123+
new NotifiableItemStackHandler(this, getItemSize(), null, false);
124+
}
125+
126+
@Override
127+
protected IItemHandlerModifiable createExportItemHandler() {
128+
return isExportHatch ? new NotifiableItemStackHandler(this, getItemSize(), null, true) :
129+
new GTItemStackHandler(this, 0);
130+
}
131+
132+
@Override
133+
protected FluidTankList createImportFluidHandler() {
134+
return isExportHatch ? new FluidTankList(false) : new FluidTankList(false, createTanks());
135+
}
136+
137+
@Override
138+
protected FluidTankList createExportFluidHandler() {
139+
return isExportHatch ? new FluidTankList(false, createTanks()) : new FluidTankList(false);
140+
}
141+
142+
@Override
143+
public boolean hasGhostCircuitInventory() {
144+
return !this.isExportHatch;
145+
}
146+
147+
@Override
148+
public void setGhostCircuitConfig(int config) {
149+
if (this.circuitInventory == null || this.circuitInventory.getCircuitValue() == config) {
150+
return;
151+
}
152+
this.circuitInventory.setCircuitValue(config);
153+
if (!getWorld().isRemote) {
154+
markDirty();
155+
}
156+
}
157+
158+
@Override
159+
public @Nullable MultiblockAbility<IItemHandlerModifiable> getAbility() {
160+
return isExportHatch ? MultiblockAbility.EXPORT_ITEMS : MultiblockAbility.IMPORT_ITEMS;
161+
}
162+
163+
@Override
164+
public void registerAbilities(@NotNull AbilityInstances abilityInstances) {
165+
abilityInstances.add(dualHandler);
166+
}
167+
168+
@Override
169+
public boolean usesMui2() {
170+
return true;
171+
}
172+
173+
@SuppressWarnings("DuplicatedCode")
174+
@Override
175+
public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) {
176+
int rowSize = (int) Math.sqrt(getItemSize());
177+
guiSyncManager.registerSlotGroup("item_inv", rowSize);
178+
179+
int backgroundWidth = Math.max(
180+
9 * 18 + 18 + 14 + 5, // Player Inv width
181+
rowSize * 18 + 14 + 18); // Bus Inv width
182+
int backgroundHeight = 18 + 18 * rowSize + 94;
183+
184+
List<List<IWidget>> widgets = new ArrayList<>();
185+
for (int i = 0; i < rowSize; i++) {
186+
widgets.add(new ArrayList<>());
187+
for (int j = 0; j < rowSize; j++) {
188+
int index = i * rowSize + j;
189+
IItemHandlerModifiable handler = isExportHatch ? exportItems : importItems;
190+
widgets.get(i).add(new ItemSlot()
191+
.slot(SyncHandlers.itemSlot(handler, index)
192+
.slotGroup("item_inv")
193+
.changeListener((newItem, onlyAmountChanged, client, init) -> {
194+
if (onlyAmountChanged &&
195+
handler instanceof GTItemStackHandler gtHandler) {
196+
gtHandler.onContentsChanged(index);
197+
}
198+
})
199+
.accessibility(!isExportHatch, true)));
200+
}
201+
202+
IFluidTank tankHandler = (isExportHatch ? exportFluids : importFluids).getTankAt(i);
203+
widgets.get(i).add(new GTFluidSlot()
204+
.syncHandler(GTFluidSlot.sync(tankHandler)
205+
.accessibility(true, !isExportHatch)));
206+
}
207+
208+
BooleanSyncValue workingStateValue = new BooleanSyncValue(() -> workingEnabled, val -> workingEnabled = val);
209+
guiSyncManager.syncValue("working_state", workingStateValue);
210+
BooleanSyncValue collapseStateValue = new BooleanSyncValue(() -> autoCollapse, val -> autoCollapse = val);
211+
guiSyncManager.syncValue("collapse_state", collapseStateValue);
212+
213+
boolean hasGhostCircuit = hasGhostCircuitInventory() && this.circuitInventory != null;
214+
215+
return GTGuis.createPanel(this, backgroundWidth, backgroundHeight)
216+
.child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5))
217+
.child(SlotGroupWidget.playerInventory().left(7).bottom(7)).child(new Grid()
218+
.top(18).height(rowSize * 18)
219+
.minElementMargin(0, 0)
220+
.minColWidth(18).minRowHeight(18)
221+
.alignX(0.5f)
222+
.matrix(widgets))
223+
.child(Flow.column()
224+
.pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5)
225+
.width(18).height(18 * 4 + 5)
226+
.child(GTGuiTextures.getLogo(getUITheme()).asWidget().size(17).top(18 * 3 + 5))
227+
.child(new ToggleButton()
228+
.top(18 * 2)
229+
.value(new BoolValue.Dynamic(workingStateValue::getBoolValue,
230+
workingStateValue::setBoolValue))
231+
.overlay(GTGuiTextures.BUTTON_ITEM_OUTPUT)
232+
.tooltipBuilder(t -> t.setAutoUpdate(true)
233+
.addLine(isExportHatch ?
234+
(workingStateValue.getBoolValue() ?
235+
IKey.lang("gregtech.gui.item_auto_output.tooltip.enabled") :
236+
IKey.lang("gregtech.gui.item_auto_output.tooltip.disabled")) :
237+
(workingStateValue.getBoolValue() ?
238+
IKey.lang("gregtech.gui.item_auto_input.tooltip.enabled") :
239+
IKey.lang("gregtech.gui.item_auto_input.tooltip.disabled")))))
240+
.child(new ToggleButton()
241+
.top(18)
242+
.value(new BoolValue.Dynamic(collapseStateValue::getBoolValue,
243+
collapseStateValue::setBoolValue))
244+
.overlay(GTGuiTextures.BUTTON_AUTO_COLLAPSE)
245+
.tooltipBuilder(t -> t.setAutoUpdate(true)
246+
.addLine(collapseStateValue.getBoolValue() ?
247+
IKey.lang("gregtech.gui.item_auto_collapse.tooltip.enabled") :
248+
IKey.lang("gregtech.gui.item_auto_collapse.tooltip.disabled"))))
249+
.childIf(hasGhostCircuit, new GhostCircuitSlotWidget()
250+
.slot(SyncHandlers.itemSlot(circuitInventory, 0))
251+
.background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY))
252+
.childIf(!hasGhostCircuit, new Widget<>()
253+
.background(GTGuiTextures.SLOT, GTGuiTextures.BUTTON_X)
254+
.tooltip(t -> t.addLine(
255+
IKey.lang("gregtech.gui.configurator_slot.unavailable.tooltip")))));
256+
}
257+
258+
@Override
259+
public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) {
260+
super.renderMetaTileEntity(renderState, translation, pipeline);
261+
SimpleOverlayRenderer renderer = isExportHatch ? Textures.PIPE_OUT_OVERLAY : Textures.PIPE_IN_OVERLAY;
262+
renderer.renderSided(getFrontFacing(), renderState, translation, pipeline);
263+
SimpleOverlayRenderer overlay = isExportHatch ? Textures.ITEM_HATCH_OUTPUT_OVERLAY :
264+
Textures.ITEM_HATCH_INPUT_OVERLAY;
265+
overlay.renderSided(getFrontFacing(), renderState, translation, pipeline);
266+
}
267+
268+
@Override
269+
public void writeInitialSyncData(PacketBuffer buf) {
270+
super.writeInitialSyncData(buf);
271+
buf.writeBoolean(workingEnabled);
272+
buf.writeBoolean(autoCollapse);
273+
}
274+
275+
@Override
276+
public void receiveInitialSyncData(PacketBuffer buf) {
277+
super.receiveInitialSyncData(buf);
278+
this.workingEnabled = buf.readBoolean();
279+
this.autoCollapse = buf.readBoolean();
280+
}
281+
282+
@Override
283+
public void setWorkingEnabled(boolean workingEnabled) {
284+
this.workingEnabled = workingEnabled;
285+
World world = getWorld();
286+
if (world != null && !world.isRemote) {
287+
writeCustomData(GregtechDataCodes.WORKING_ENABLED, buf -> buf.writeBoolean(workingEnabled));
288+
}
289+
}
290+
291+
@Override
292+
public boolean isWorkingEnabled() {
293+
return workingEnabled;
294+
}
295+
296+
@Override
297+
public void receiveCustomData(int dataId, PacketBuffer buf) {
298+
super.receiveCustomData(dataId, buf);
299+
if (dataId == GregtechDataCodes.WORKING_ENABLED) {
300+
this.workingEnabled = buf.readBoolean();
301+
} else if (dataId == GregtechDataCodes.TOGGLE_COLLAPSE_ITEMS) {
302+
this.autoCollapse = buf.readBoolean();
303+
}
304+
}
305+
306+
@Override
307+
public NBTTagCompound writeToNBT(NBTTagCompound data) {
308+
super.writeToNBT(data);
309+
310+
data.setBoolean("workingEnabled", workingEnabled);
311+
data.setBoolean("autoCollapse", autoCollapse);
312+
313+
if (circuitInventory != null) {
314+
circuitInventory.write(data);
315+
}
316+
317+
return data;
318+
}
319+
320+
@Override
321+
public void readFromNBT(NBTTagCompound data) {
322+
super.readFromNBT(data);
323+
324+
this.workingEnabled = data.getBoolean("workingEnabled");
325+
this.autoCollapse = data.getBoolean("autoCollapse");
326+
327+
if (circuitInventory != null) {
328+
circuitInventory.read(data);
329+
}
330+
}
331+
332+
@Override
333+
public void addInformation(ItemStack stack, @Nullable World player, @NotNull List<String> tooltip,
334+
boolean advanced) {
335+
if (this.isExportHatch)
336+
tooltip.add(I18n.format("gregtech.machine.item_bus.export.tooltip"));
337+
else
338+
tooltip.add(I18n.format("gregtech.machine.item_bus.import.tooltip"));
339+
tooltip.add(I18n.format("gregtech.universal.tooltip.item_storage_capacity", getItemSize()));
340+
tooltip.add(I18n.format("gregtech.universal.tooltip.fluid_storage_capacity", getTankSize()));
341+
tooltip.add(I18n.format("gregtech.universal.enabled"));
342+
}
343+
344+
@Override
345+
public void addToolUsages(ItemStack stack, @Nullable World world, List<String> tooltip, boolean advanced) {
346+
tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers"));
347+
tooltip.add(I18n.format("gregtech.tool_action.screwdriver.auto_collapse"));
348+
tooltip.add(I18n.format("gregtech.tool_action.wrench.set_facing"));
349+
super.addToolUsages(stack, world, tooltip, advanced);
350+
}
351+
}

0 commit comments

Comments
 (0)