diff --git a/src/main/java/gregtech/api/cover/Cover.java b/src/main/java/gregtech/api/cover/Cover.java index 8540d97fc1f..0257544c99a 100644 --- a/src/main/java/gregtech/api/cover/Cover.java +++ b/src/main/java/gregtech/api/cover/Cover.java @@ -113,10 +113,13 @@ default long getOffsetTimer() { /** * Called when the cover is first attached on the Server Side. - * Do NOT sync custom data to client here. It will overwrite the attach cover packet! + * Values set here will automatically be synced to the client, if you + * specify them in {@link #writeInitialSyncData}. + * + * @apiNote The CoverableView will not have your cover attached to it in this method. * - * @param coverableView the CoverableView this cover is attached to - * @param side the side this cover is attached to + * @param coverableView the CoverableView this cover will be attached to + * @param side the side this cover will be attached to * @param player the player attaching the cover * @param itemStack the item used to place the cover */ diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index 10ab6f243dd..f40f2df37bc 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -8,14 +8,22 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.IGuiHolder; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.value.sync.IntSyncValue; +import com.cleanroommc.modularui.widget.ParentWidget; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.ApiStatus; public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { @@ -46,7 +54,7 @@ default ModularScreen createScreen(SidedPosGuiData guiData, ModularPanel mainPan } default GTGuiTheme getUITheme() { - return GTGuiTheme.STANDARD; + return GTGuiTheme.COVER; } @Override @@ -68,4 +76,51 @@ default boolean isRemote() { default void markAsDirty() { getCoverableView().markDirty(); } + + /* Helper methods for UI creation with covers that are commonly used */ + + /** + * The color used for Cover UI titles, and used in {@link #createTitleRow}. + */ + int UI_TITLE_COLOR = 0xFF222222; + /** + * The color used for Cover UI text. Available for reference, but is + * handled automatically by the {@link GTGuiTheme#COVER} theme. + */ + int UI_TEXT_COLOR = 0xFF555555; + + /** + * Create the Title bar widget for a Cover. + */ + default Row createTitleRow() { + ItemStack item = getDefinition().getDropItemStack(); + return new Row() + .pos(4, 4) + .height(16).coverChildrenWidth() + .child(new ItemDrawable(getDefinition().getDropItemStack()).asWidget().size(16).marginRight(4)) + .child(IKey.str(item.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); + } + + /** + * Create a new settings row for a Cover setting. + */ + default ParentWidget createSettingsRow() { + return new ParentWidget<>().height(16).widthRel(1.0f).marginBottom(2); + } + + /** + * Get a BoolValue for use with toggle buttons which are "linked together," + * meaning only one of them can be pressed at a time. + */ + default > BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } + + /** + * Get a BoolValue for use with toggle buttons which are "linked together," + * meaning only one of them can be pressed at a time. + */ + default BoolValue.Dynamic boolValueOf(IntSyncValue syncValue, int value) { + return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); + } } diff --git a/src/main/java/gregtech/api/cover/CoverableView.java b/src/main/java/gregtech/api/cover/CoverableView.java index 0b7d6f33c68..8bebd97b26d 100644 --- a/src/main/java/gregtech/api/cover/CoverableView.java +++ b/src/main/java/gregtech/api/cover/CoverableView.java @@ -1,5 +1,6 @@ package gregtech.api.cover; +import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; @@ -87,4 +88,10 @@ default boolean hasCover(@NotNull EnumFacing side) { int getInputRedstoneSignal(@NotNull EnumFacing side, boolean ignoreCover); void writeCoverData(@NotNull Cover cover, int discriminator, @NotNull Consumer<@NotNull PacketBuffer> buf); + + /** + * @return an ItemStack representation of the CoverableView, or {@link ItemStack#EMPTY} if not possible. + */ + @NotNull + ItemStack getStackForm(); } diff --git a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java index 5feda5eac58..826e85d961d 100644 --- a/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java +++ b/src/main/java/gregtech/api/items/behavior/CoverItemBehavior.java @@ -56,8 +56,10 @@ public EnumActionResult onItemUseFirst(EntityPlayer player, @NotNull World world ItemStack itemStack = player.getHeldItem(hand); - coverHolder.addCover(coverSide, cover); + // Call onAttachment first so that the cover can set up any + // necessary variables needed for the S2C cover sync packet. cover.onAttachment(coverHolder, coverSide, player, itemStack); + coverHolder.addCover(coverSide, cover); AdvancementTriggers.FIRST_COVER_PLACE.trigger((EntityPlayerMP) player); diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 659460902b0..8b922ffc3f6 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -834,7 +834,8 @@ public final ItemStack getStackForm(int amount) { return new ItemStack(GregTechAPI.MACHINE, amount, metaTileEntityIntId); } - public final ItemStack getStackForm() { + @Override + public final @NotNull ItemStack getStackForm() { return getStackForm(1); } diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index d1f432c6c07..3c99abaee1e 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -19,6 +19,7 @@ public class GTGuiTextures { public static class IDs { public static final String STANDARD_BACKGROUND = "gregtech_standard_bg"; + public static final String COVER_BACKGROUND = "gregtech_cover_bg"; public static final String BRONZE_BACKGROUND = "gregtech_bronze_bg"; public static final String STEEL_BACKGROUND = "gregtech_steel_bg"; public static final String PRIMITIVE_BACKGROUND = "gregtech_primitive_bg"; @@ -34,9 +35,9 @@ public static class IDs { } // ICONS - /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */ + /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */ public static final UITexture GREGTECH_LOGO = fullImage("textures/gui/icon/gregtech_logo.png"); - /** @apiNote You may want {@link GTGuiTextures#getLogo()} instead. */ + /** @apiNote You may want {@link GTGuiTextures#getLogo} instead. */ public static final UITexture GREGTECH_LOGO_XMAS = fullImage("textures/gui/icon/gregtech_logo_xmas.png"); public static final UITexture GREGTECH_LOGO_DARK = fullImage("textures/gui/icon/gregtech_logo_dark.png"); // todo blinking GT logos @@ -61,6 +62,7 @@ public static class IDs { .location(GTValues.MODID, "textures/gui/base/background_popup.png") .imageSize(195, 136) .adaptable(4) + .name(IDs.COVER_BACKGROUND) .canApplyTheme() .build(); @@ -268,6 +270,19 @@ public static class IDs { .canApplyTheme() .build(); + public static final UITexture MC_BUTTON = new UITexture.Builder() + .location("modularui", "gui/widgets/mc_button.png") // todo + .imageSize(16, 32) + .uv(0.0f, 0.0f, 1.0f, 0.5f) + .adaptable(1) + .build(); + + public static final UITexture MC_BUTTON_DISABLED = new UITexture.Builder() + .location("modularui", "gui/widgets/mc_button_disabled.png") // todo + .imageSize(16, 16) + .adaptable(1) + .build(); + // BUTTON OVERLAYS public static final UITexture BUTTON_ITEM_OUTPUT = fullImage("textures/gui/widget/button_item_output_overlay.png"); @@ -277,6 +292,10 @@ public static class IDs { "textures/gui/widget/button_auto_collapse_overlay.png"); public static final UITexture BUTTON_X = fullImage("textures/gui/widget/button_x_overlay.png", true); + public static final UITexture BUTTON_CROSS = fullImage("textures/gui/widget/button_cross.png"); + public static final UITexture BUTTON_REDSTONE_ON = fullImage("textures/gui/widget/button_redstone_on.png"); + public static final UITexture BUTTON_REDSTONE_OFF = fullImage("textures/gui/widget/button_redstone_off.png"); + // PROGRESS BARS public static final UITexture PROGRESS_BAR_ARC_FURNACE = progressBar( "textures/gui/progress_bar/progress_bar_arc_furnace.png", true); diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index c3f80b09943..fce37223e96 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -1,5 +1,6 @@ package gregtech.api.mui; +import gregtech.api.cover.CoverWithUI; import gregtech.common.ConfigHolder; import net.minecraftforge.common.MinecraftForge; @@ -33,7 +34,15 @@ public class GTGuiTheme { ConfigHolder.client.defaultUIColor) .build(); - // TODO Cover theme to utilize the GT5u-like button textures vs the standard ones + public static final GTGuiTheme COVER = templateBuilder("gregtech_cover") + .panel(GTGuiTextures.IDs.COVER_BACKGROUND) + .itemSlot(GTGuiTextures.IDs.STANDARD_SLOT) + .fluidSlot(GTGuiTextures.IDs.STANDARD_FLUID_SLOT) + .color(ConfigHolder.client.defaultUIColor) + .textColor(CoverWithUI.UI_TEXT_COLOR) + .build(); + + // TODO Multiblock theme for display texture, logo changes public static final GTGuiTheme BRONZE = templateBuilder("gregtech_bronze") .panel(GTGuiTextures.IDs.BRONZE_BACKGROUND) diff --git a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java index 6be552bfc95..df20bd54bfb 100644 --- a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java +++ b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java @@ -85,7 +85,8 @@ public final void removeCover(@NotNull EnumFacing side) { } @SuppressWarnings("unchecked") - public ItemStack getStackForm() { + @Override + public @NotNull ItemStack getStackForm() { BlockPipe pipeBlock = holder.getPipeBlock(); return pipeBlock.getDropItem(holder); } diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 8814da16ca4..423a44fccd3 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -3,23 +3,36 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.capability.IControllable; import gregtech.api.cover.*; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.*; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.PacketBuffer; import net.minecraft.util.*; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraft.util.text.TextFormatting; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.ItemDrawable; +import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.SidedPosGuiData; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.value.BoolValue; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.EnumSyncValue; +import com.cleanroommc.modularui.value.sync.GuiSyncManager; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.layout.Column; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -28,23 +41,16 @@ public class CoverMachineController extends CoverBase implements CoverWithUI { - private int minRedstoneStrength; private boolean isInverted; private ControllerMode controllerMode; - private final ItemStackHandler displayInventory = new ItemStackHandler(1); public CoverMachineController(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide) { super(definition, coverableView, attachedSide); - this.minRedstoneStrength = 1; this.isInverted = false; this.controllerMode = ControllerMode.MACHINE; } - public int getMinRedstoneStrength() { - return minRedstoneStrength; - } - public ControllerMode getControllerMode() { return controllerMode; } @@ -53,12 +59,6 @@ public boolean isInverted() { return isInverted; } - public void setMinRedstoneStrength(int minRedstoneStrength) { - this.minRedstoneStrength = minRedstoneStrength; - updateRedstoneStatus(); - getCoverableView().markDirty(); - } - public void setInverted(boolean inverted) { isInverted = inverted; updateRedstoneStatus(); @@ -69,21 +69,12 @@ public void setControllerMode(ControllerMode controllerMode) { resetCurrentControllable(); this.controllerMode = controllerMode; updateRedstoneStatus(); - updateDisplayInventory(); getCoverableView().markDirty(); } - private void cycleNextControllerMode() { - List allowedModes = getAllowedModes(getCoverableView(), getAttachedSide()); - int nextIndex = allowedModes.indexOf(controllerMode) + 1; - if (!allowedModes.isEmpty()) { - setControllerMode(allowedModes.get(nextIndex % allowedModes.size())); - } - } - public List getAllowedModes(@NotNull CoverableView coverable, @NotNull EnumFacing side) { List results = new ArrayList<>(); - for (ControllerMode controllerMode : ControllerMode.values()) { + for (ControllerMode controllerMode : ControllerMode.VALUES) { IControllable controllable = null; if (controllerMode.side == null) { controllable = coverable.getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, side); @@ -115,21 +106,111 @@ public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing s } @Override - public ModularUI createUI(EntityPlayer player) { - updateDisplayInventory(); - return ModularUI.builder(GuiTextures.BACKGROUND, 176, 95) - .image(4, 4, 16, 16, GuiTextures.COVER_MACHINE_CONTROLLER) - .label(24, 8, "cover.machine_controller.title") - .widget(new SliderWidget("cover.machine_controller.redstone", 10, 24, 156, 20, 1.0f, 15.0f, - minRedstoneStrength, it -> setMinRedstoneStrength((int) it))) - .widget(new ClickButtonWidget(10, 48, 134, 18, "", data -> cycleNextControllerMode())) - .widget(new SimpleTextWidget(77, 58, "", 0xFFFFFF, () -> getControllerMode().getName()).setShadow(true)) - .widget(new SlotWidget(displayInventory, 0, 148, 48, false, false) - .setBackgroundTexture(GuiTextures.SLOT)) - .widget(new CycleButtonWidget(48, 70, 80, 18, this::isInverted, this::setInverted, - "cover.machine_controller.normal", "cover.machine_controller.inverted") - .setTooltipHoverString("cover.machine_controller.inverted.description")) - .build(this, player); + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(SidedPosGuiData guiData, GuiSyncManager guiSyncManager) { + EnumSyncValue controllerModeValue = new EnumSyncValue<>(ControllerMode.class, + this::getControllerMode, this::setControllerMode); + BooleanSyncValue invertedValue = new BooleanSyncValue(this::isInverted, this::setInverted); + + guiSyncManager.syncValue("controller_mode", controllerModeValue); + guiSyncManager.syncValue("inverted", invertedValue); + + return GTGuis.createPanel(this, 176, 112) + .child(createTitleRow()) + .child(new Column() + .widthRel(1.0f).margin(7, 0) + .top(24).coverChildrenHeight() + + // Inverted mode + .child(createSettingsRow() + .child(new ToggleButton() + .size(16).left(0) + .value(new BoolValue.Dynamic(invertedValue::getValue, + $ -> invertedValue.setValue(true))) + .overlay(GTGuiTextures.BUTTON_REDSTONE_ON) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED)) + .child(IKey.lang("cover.machine_controller.enable_with_redstone").asWidget() + .heightRel(1.0f).left(20))) + .child(createSettingsRow() + .child(new ToggleButton() + .size(16).left(0) + .value(new BoolValue.Dynamic(() -> !invertedValue.getValue(), + $ -> invertedValue.setValue(false))) + .overlay(GTGuiTextures.BUTTON_REDSTONE_OFF) + .selectedBackground(GTGuiTextures.MC_BUTTON_DISABLED)) + .child(IKey.lang("cover.machine_controller.disable_with_redstone").asWidget() + .heightRel(1.0f).left(20))) + + // Separating line + .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() + .height(1).widthRel(0.9f).alignX(0.5f).marginBottom(4).marginTop(4)) + + // Controlling selector + .child(createSettingsRow().height(16 + 2 + 16) + .child(new Column().heightRel(1.0f).coverChildrenWidth() + .child(IKey.lang("cover.machine_controller.control").asWidget() + .left(0).height(16).marginBottom(2)) + .child(modeButton(controllerModeValue, ControllerMode.MACHINE).left(0))) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_UP, IKey.str("U")) + .right(100)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_DOWN, IKey.str("D")) + .right(80)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_NORTH, IKey.str("N")) + .right(60)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_SOUTH, IKey.str("S")) + .right(40)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_EAST, IKey.str("E")) + .right(20)) + .child(modeColumn(controllerModeValue, ControllerMode.COVER_WEST, IKey.str("W")) + .right(0)))); + } + + private Column modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { + return new Column().coverChildrenHeight().width(18) + .child(title.asWidget().size(16).marginBottom(2).alignment(Alignment.Center)) + .child(modeButton(syncValue, mode)); + } + + private Widget modeButton(EnumSyncValue syncValue, ControllerMode mode) { + IControllable controllable = getControllable(mode); + if (controllable == null) { + // Nothing to control, put a placeholder widget + // 3 states possible here: + IKey detail; + if (mode.side == getAttachedSide()) { + // our own side, we can't control ourselves + detail = IKey.lang("cover.machine_controller.this_cover"); + } else if (mode.side != null) { + // some potential cover that either doesn't exist or isn't controllable + detail = IKey.lang("cover.machine_controller.cover_not_controllable"); + } else { + // cover holder is not controllable + detail = IKey.lang("cover.machine_controller.machine_not_controllable"); + } + + return GTGuiTextures.MC_BUTTON.asWidget().size(18) + .overlay(GTGuiTextures.BUTTON_CROSS) + .tooltip(t -> t.addLine(IKey.lang(mode.localeName)).addLine(detail)); + } + + ItemStack stack; + if (mode == ControllerMode.MACHINE) { + stack = getCoverableView().getStackForm(); + } else { + // this can't be null because we already checked IControllable, and it was not null + // noinspection ConstantConditions + stack = getCoverableView().getCoverAtSide(mode.side).getDefinition().getDropItemStack(); + } + + return new ToggleButton().size(18) + .value(boolValueOf(syncValue, mode)) + .overlay(new ItemDrawable(stack).asIcon().size(16)) + .tooltip(t -> t.addLine(IKey.lang(mode.localeName)) + .addLine(IKey.str(TextFormatting.GRAY + stack.getDisplayName()))); } @Override @@ -163,20 +244,8 @@ public void onRedstoneInputSignalChange(int newSignalStrength) { updateRedstoneStatus(); } - private void updateDisplayInventory() { - EnumFacing controlledSide = getControllerMode().side; - ItemStack resultStack = ItemStack.EMPTY; - if (controlledSide != null) { - Cover cover = getCoverableView().getCoverAtSide(controlledSide); - if (cover != null) { - resultStack = cover.getDefinition().getDropItemStack(); - } - } - this.displayInventory.setStackInSlot(0, resultStack); - } - - private @Nullable IControllable getControllable() { - EnumFacing side = controllerMode.side; + private @Nullable IControllable getControllable(ControllerMode mode) { + EnumFacing side = mode.side; if (side == null) { return getCoverableView().getCapability(GregtechTileCapabilities.CAPABILITY_CONTROLLABLE, getAttachedSide()); @@ -190,24 +259,22 @@ private void updateDisplayInventory() { } private void resetCurrentControllable() { - IControllable controllable = getControllable(); + IControllable controllable = getControllable(controllerMode); if (controllable != null) { controllable.setWorkingEnabled(doesOtherAllowingWork()); } } private void updateRedstoneStatus() { - IControllable controllable = getControllable(); + IControllable controllable = getControllable(controllerMode); if (controllable != null) { controllable.setWorkingEnabled(shouldAllowWorking() && doesOtherAllowingWork()); } } private boolean shouldAllowWorking() { - boolean shouldAllowWorking = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true) < - minRedstoneStrength; - // noinspection SimplifiableConditionalExpression - return isInverted ? !shouldAllowWorking : shouldAllowWorking; + int inputSignal = getCoverableView().getInputRedstoneSignal(getAttachedSide(), true); + return isInverted ? inputSignal > 0 : inputSignal == 0; } private boolean doesOtherAllowingWork() { @@ -228,7 +295,6 @@ private boolean doesOtherAllowingWork() { @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); - tagCompound.setInteger("MinRedstoneStrength", minRedstoneStrength); tagCompound.setBoolean("Inverted", isInverted); tagCompound.setInteger("ControllerMode", controllerMode.ordinal()); } @@ -236,9 +302,22 @@ public void writeToNBT(@NotNull NBTTagCompound tagCompound) { @Override public void readFromNBT(@NotNull NBTTagCompound tagCompound) { super.readFromNBT(tagCompound); - this.minRedstoneStrength = tagCompound.getInteger("MinRedstoneStrength"); this.isInverted = tagCompound.getBoolean("Inverted"); - this.controllerMode = ControllerMode.values()[tagCompound.getInteger("ControllerMode")]; + this.controllerMode = ControllerMode.VALUES[tagCompound.getInteger("ControllerMode")]; + } + + @Override + public void writeInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.writeInitialSyncData(packetBuffer); + packetBuffer.writeBoolean(isInverted); + packetBuffer.writeShort(controllerMode.ordinal()); + } + + @Override + public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { + super.readInitialSyncData(packetBuffer); + this.isInverted = packetBuffer.readBoolean(); + this.controllerMode = ControllerMode.VALUES[packetBuffer.readShort()]; } public enum ControllerMode implements IStringSerializable { @@ -254,6 +333,8 @@ public enum ControllerMode implements IStringSerializable { public final String localeName; public final EnumFacing side; + public static final ControllerMode[] VALUES = values(); + ControllerMode(String localeName, EnumFacing side) { this.localeName = localeName; this.side = side; diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index f4525a2dc5c..df5124812b5 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1304,11 +1304,6 @@ cover.fluid_regulator.transfer_mode.description=§eTransfer Any§r - in this mod cover.fluid_regulator.supply_exact=Supply Exact: %s cover.fluid_regulator.keep_exact=Keep Exact: %s -cover.machine_controller.title=Machine Controller Settings -cover.machine_controller.normal=Normal -cover.machine_controller.inverted=Inverted -cover.machine_controller.inverted.description=§eNormal§r - in this mode, the cover will require a signal weaker than the set redstone level to run/n§eInverted§r - in this mode, the cover will require a signal stronger than the set redstone level to run -cover.machine_controller.redstone=Min Redstone Strength: %,d cover.machine_controller.mode.machine=Control Machine cover.machine_controller.mode.cover_up=Control Cover (Top) cover.machine_controller.mode.cover_down=Control Cover (Bottom) @@ -1316,6 +1311,12 @@ cover.machine_controller.mode.cover_south=Control Cover (South) cover.machine_controller.mode.cover_north=Control Cover (North) cover.machine_controller.mode.cover_east=Control Cover (East) cover.machine_controller.mode.cover_west=Control Cover (West) +cover.machine_controller.this_cover=§cThis cover +cover.machine_controller.cover_not_controllable=§cNo controllable cover +cover.machine_controller.machine_not_controllable=§cMachine not controllable +cover.machine_controller.control=Control: +cover.machine_controller.enable_with_redstone=Enable with Redstone +cover.machine_controller.disable_with_redstone=Disable with Redstone cover.ender_fluid_link.title=Ender Fluid Link cover.ender_fluid_link.iomode.enabled=I/O Enabled diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png new file mode 100644 index 00000000000..863553adbdc Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_cross.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png new file mode 100644 index 00000000000..e51d4534755 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_off.png differ diff --git a/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png new file mode 100644 index 00000000000..44d6e446b72 Binary files /dev/null and b/src/main/resources/assets/gregtech/textures/gui/widget/button_redstone_on.png differ