|
| 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