From 185bd5a4903f19642dfd792a64680e4558f474f0 Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Thu, 5 Dec 2024 17:32:16 -0700 Subject: [PATCH 1/7] Rework Filters as Cover and Fluid Pipes with Covers (#2640) --- .../common/covers/CoverFluidFilter.java | 66 ++++++++++++++----- .../common/covers/CoverItemFilter.java | 60 +++++++++++++---- .../tile/TileEntityFluidPipeTickable.java | 3 +- .../resources/assets/gregtech/lang/en_us.lang | 4 ++ 4 files changed, 99 insertions(+), 34 deletions(-) diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index a103076e938..85b39ca1a9d 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -32,14 +32,19 @@ 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.Rectangle; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,7 +56,8 @@ public class CoverFluidFilter extends CoverBase implements CoverWithUI { protected final SimpleOverlayRenderer texture; protected final FluidFilterContainer fluidFilterContainer; protected FluidFilterMode filterMode; - protected FluidHandlerFiltered fluidHandler; + protected boolean allowFlow = false; + protected FluidHandlerDelegate fluidHandler; public CoverFluidFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { @@ -146,7 +152,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan this.fluidFilterContainer.setMaxTransferSize(1); return getFilter().createPanel(guiSyncManager) - .size(176, 194).padding(7) + .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack())) .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(FluidFilterMode.class) @@ -154,6 +160,24 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) + .child(new Row() + .marginBottom(2) + .widthRel(1f) + .coverChildrenHeight() + .setEnabledIf(b -> getFilterMode() != FluidFilterMode.FILTER_BOTH) + .child(new ToggleButton() + .overlay(IKey.dynamic(() -> IKey.lang(allowFlow ? + "cover.generic.enabled" : + "cover.generic.disabled").get()) + .color(Color.WHITE.main).shadow(false)) + .tooltip(tooltip -> tooltip + .addLine(IKey.lang("cover.filter.allow_flow.tooltip"))) + .size(72, 18) + .value(new BooleanSyncValue(() -> allowFlow, b -> allowFlow = b))) + .child(IKey.lang("cover.filter.allow_flow.label") + .asWidget() + .height(18) + .alignX(1f))) .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() .height(1).widthRel(0.95f).margin(0, 4)) .child(getFilter().createWidgets(guiSyncManager))) @@ -207,30 +231,36 @@ public FluidHandlerFiltered(@NotNull IFluidHandler delegate) { } public int fill(FluidStack resource, boolean doFill) { - if (getFilterMode() == FluidFilterMode.FILTER_DRAIN || !fluidFilterContainer.test(resource)) { - return 0; - } - return super.fill(resource, doFill); + // set to drain, but filling is allowed + if (getFilterMode() == FluidFilterMode.FILTER_DRAIN && allowFlow) + return super.fill(resource, doFill); + + // if set to insert or both, test the stack + if (getFilterMode() != FluidFilterMode.FILTER_DRAIN && fluidFilterContainer.test(resource)) + return super.fill(resource, doFill); + + // otherwise fail + return 0; } @Nullable public FluidStack drain(FluidStack resource, boolean doDrain) { - if (getFilterMode() == FluidFilterMode.FILTER_FILL || !fluidFilterContainer.test(resource)) { - return null; - } - return super.drain(resource, doDrain); + // set to fill, draining is allowed + if (getFilterMode() == FluidFilterMode.FILTER_FILL && allowFlow) + return super.drain(resource, doDrain); + + // if set to extract or both, test stack + if (getFilterMode() != FluidFilterMode.FILTER_FILL && fluidFilterContainer.test(resource)) + return super.drain(resource, doDrain); + + // otherwise fail + return null; } @Nullable public FluidStack drain(int maxDrain, boolean doDrain) { - if (getFilterMode() != FluidFilterMode.FILTER_FILL) { - FluidStack result = super.drain(maxDrain, false); - if (result == null || result.amount <= 0 || !fluidFilterContainer.test(result)) { - return null; - } - return doDrain ? super.drain(maxDrain, true) : result; - } - return super.drain(maxDrain, doDrain); + var f = super.drain(maxDrain, false); + return drain(f, doDrain); } } } diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 043729ad075..18e6432bc07 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -31,14 +31,19 @@ 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.Rectangle; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; import com.cleanroommc.modularui.value.sync.EnumSyncValue; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Row; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -50,7 +55,8 @@ public class CoverItemFilter extends CoverBase implements CoverWithUI { protected final SimpleOverlayRenderer texture; protected final ItemFilterContainer itemFilterContainer; protected ItemFilterMode filterMode = ItemFilterMode.FILTER_INSERT; - protected ItemHandlerFiltered itemHandler; + protected boolean allowFlow = false; + protected ItemHandlerDelegate itemHandler; public CoverItemFilter(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, String titleLocale, SimpleOverlayRenderer texture) { @@ -148,7 +154,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan guiSyncManager.syncValue("filtering_mode", filteringMode); return getFilter().createPanel(guiSyncManager) - .size(176, 194).padding(7) + .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack()).left(4)) .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(ItemFilterMode.class) @@ -156,6 +162,24 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) + .child(new Row() + .marginBottom(2) + .widthRel(1f) + .coverChildrenHeight() + .setEnabledIf(b -> getFilterMode() != ItemFilterMode.FILTER_BOTH) + .child(new ToggleButton() + .overlay(IKey.dynamic(() -> IKey.lang(allowFlow ? + "cover.generic.enabled" : + "cover.generic.disabled").get()) + .color(Color.WHITE.main).shadow(false)) + .tooltip(tooltip -> tooltip + .addLine(IKey.lang("cover.filter.allow_flow.tooltip"))) + .size(72, 18) + .value(new BooleanSyncValue(() -> allowFlow, b -> allowFlow = b))) + .child(IKey.lang("cover.filter.allow_flow.label") + .asWidget() + .height(18) + .alignX(1f))) .child(new Rectangle().setColor(UI_TEXT_COLOR).asWidget() .height(1).widthRel(0.95f).margin(0, 4)) .child(getFilter().createWidgets(guiSyncManager).left(0))) @@ -212,23 +236,31 @@ public ItemHandlerFiltered(IItemHandler delegate) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT || !itemFilterContainer.test(stack)) { - return stack; - } - return super.insertItem(slot, stack, simulate); + // set to extract, but insertion is allowed + if (getFilterMode() == ItemFilterMode.FILTER_EXTRACT && allowFlow) + return super.insertItem(slot, stack, simulate); + + // if set to insert or both, test the stack + if (getFilterMode() != ItemFilterMode.FILTER_EXTRACT && itemFilterContainer.test(stack)) + return super.insertItem(slot, stack, simulate); + + // otherwise fail + return stack; } @NotNull @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (getFilterMode() != ItemFilterMode.FILTER_INSERT) { - ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !itemFilterContainer.test(result)) { - return ItemStack.EMPTY; - } - return simulate ? result : super.extractItem(slot, amount, false); - } - return super.extractItem(slot, amount, simulate); + // set to insert, but extraction is allowed + if (getFilterMode() == ItemFilterMode.FILTER_INSERT && allowFlow) + return super.extractItem(slot, amount, simulate); + + // if set to extract or both, test stack + if (getFilterMode() != ItemFilterMode.FILTER_INSERT && itemFilterContainer.test(getStackInSlot(slot))) + return super.extractItem(slot, amount, simulate); + + // otherwise fail + return ItemStack.EMPTY; } } } diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java b/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java index 038fef391f8..0fb23e4c309 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/tile/TileEntityFluidPipeTickable.java @@ -13,7 +13,6 @@ import gregtech.api.util.EntityDamageUtil; import gregtech.api.util.TextFormattingUtil; import gregtech.common.covers.CoverPump; -import gregtech.common.covers.ManualImportExportMode; import gregtech.common.pipelike.fluidpipe.net.PipeTankList; import net.minecraft.entity.EntityLivingBase; @@ -202,7 +201,7 @@ private boolean checkForPumpCover(@Nullable Cover cover) { if (coverPump.getTransferRate() > pipeThroughput) { coverPump.setTransferRate(pipeThroughput); } - return coverPump.getManualImportExportMode() == ManualImportExportMode.DISABLED; + return true; // disable pushing completely if there's a pump } return false; } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 389d68cd3ce..484c7e258ff 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -1280,6 +1280,8 @@ cover.filter.mode.title=Filter Mode cover.filter.mode.filter_insert=Filter Insert cover.filter.mode.filter_extract=Filter Extract cover.filter.mode.filter_both=Filter Insert/Extract +cover.filter.allow_flow.label=Allow Flow +cover.filter.allow_flow.tooltip=By default, Items/Fluids can only move in the direction\nof the filter with respect to the filter's setting.\n\nIf Enabled, Items/Fluids are allowed to pass unfiltered\nthrough the opposite direction of this filter. cover.item_filter.ignore_damage.enabled=Ignore Damage cover.item_filter.ignore_damage.disabled=Respect Damage cover.item_filter.ignore_nbt.enabled=Ignore NBT @@ -1309,6 +1311,8 @@ cover.smart_item_filter.filtering_mode.centrifuge=Centrifuge cover.smart_item_filter.filtering_mode.sifter=Sifter cover.smart_item_filter.filtering_mode.description=Select Machine this Smart Filter will use for filtering./nIt will automatically pick right portions of items for robotic arm. +cover.generic.disabled=Disabled +cover.generic.enabled=Enabled cover.generic.transfer_mode=Transfer Mode cover.generic.manual_io=Manual IO Mode cover.generic.io=IO Mode From 4d4f6e001f9e7a5b9632be348d01fb766146dbb0 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Thu, 2 Jan 2025 00:51:11 -0500 Subject: [PATCH 2/7] Remove fluid input text from Distillation Towers GUIs since it's been broken for six years. (#2691) --- .../MetaTileEntityDistillationTower.java | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java index 2c7eea8410a..886cd35353d 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java +++ b/src/main/java/gregtech/common/metatileentities/multi/electric/MetaTileEntityDistillationTower.java @@ -15,9 +15,7 @@ import gregtech.api.recipes.Recipe; import gregtech.api.recipes.RecipeMaps; import gregtech.api.util.GTTransferUtils; -import gregtech.api.util.GTUtility; import gregtech.api.util.RelativeDirection; -import gregtech.api.util.TextComponentUtil; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.common.blocks.BlockMetalCasing.MetalCasingType; @@ -28,15 +26,11 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; -import java.util.List; import java.util.function.Function; import static gregtech.api.util.RelativeDirection.*; @@ -86,22 +80,6 @@ public boolean allowsExtendedFacing() { return false; } - @Override - protected void addDisplayText(List textList) { - if (isStructureFormed()) { - FluidStack stackInTank = importFluids.drain(Integer.MAX_VALUE, false); - if (stackInTank != null && stackInTank.amount > 0) { - ITextComponent fluidName = TextComponentUtil.setColor(GTUtility.getFluidTranslation(stackInTank), - TextFormatting.AQUA); - textList.add(TextComponentUtil.translationWithColor( - TextFormatting.GRAY, - "gregtech.multiblock.distillation_tower.distilling_fluid", - fluidName)); - } - } - super.addDisplayText(textList); - } - @Override protected void formStructure(PatternMatchContext context) { super.formStructure(context); From c97df1c47ad5bb1520ab44535d52648fd9facbbf Mon Sep 17 00:00:00 2001 From: marisathewitch Date: Mon, 6 Jan 2025 06:39:12 +0400 Subject: [PATCH 3/7] Update lang files for ru_ru and uk_ua (#2653) Co-authored-by: Western01 Co-authored-by: German Khris Co-authored-by: Anonymous Co-authored-by: Voldemar --- .../resources/assets/gregtech/lang/ru_ru.lang | 201 +++--- .../gregtech/lang/{uk_UA.lang => uk_ua.lang} | 647 +++++++++++++++++- 2 files changed, 762 insertions(+), 86 deletions(-) rename src/main/resources/assets/gregtech/lang/{uk_UA.lang => uk_ua.lang} (66%) diff --git a/src/main/resources/assets/gregtech/lang/ru_ru.lang b/src/main/resources/assets/gregtech/lang/ru_ru.lang index 971b6fc8d3a..177e32d52e9 100644 --- a/src/main/resources/assets/gregtech/lang/ru_ru.lang +++ b/src/main/resources/assets/gregtech/lang/ru_ru.lang @@ -75,7 +75,7 @@ gregtech.top.link_cover.color=Цвет: gregtech.top.mode.export=Экспорт gregtech.top.mode.import=Импорт gregtech.top.unit.items=Предметы -gregtech.top.unit.fluid_milibuckets=mB +gregtech.top.unit.fluid_milibuckets=Л gregtech.top.unit.fluid_buckets=B gregtech.top.block_drops=Добыча gregtech.top.ld_pipe_no_network=Трубопровод не найден @@ -93,7 +93,7 @@ gregtech.waila.progress_sec=Прогресс: %d s / %d s gregtech.multiblock.title=Шаблон многоблочной структуры gregtech.multiblock.primitive_blast_furnace.bronze.description=Примитивная доменная печь (ПДП) - это многоблочная структура, используемая для изготовления стали в ранней стадии игры. Не очень быстрая, но обеспечивает вас сталью на первое время. gregtech.multiblock.coke_oven.description=Коксовая печь - это многоблочная структура, используемая для получения кокосового угля и креозота на ранней стадии игры. Не требует топлива и имеет внутренний бак на 32 ведра креозота. Доступ к инвентарю можно получить через Люк коксовой печи. -gregtech.multiblock.vacuum_freezer.description=Вакуумный морозильник - это многоблочная структура, в основном используемая для охлаждения горячих слитков в обычные слитки. Тем не менее, он также может охлаждать другие вещества, к примеру воду. +gregtech.multiblock.vacuum_freezer.description=Вакуумный холодильник - это многоблочная структура, в основном используемая для охлаждения горячих слитков в обычные слитки. Тем не менее, он также может охлаждать другие вещества, к примеру воду. gregtech.multiblock.implosion_compressor.description=Детонационный компрессор - это многоблочная структура, в которой используются взрывчатые вещества для превращения пыли в соответствующие камни. gregtech.multiblock.pyrolyse_oven.description=Пиролизная печь - это многоблочная структура, используемая для пиролиза древесины в древесный уголь и креозот, либо в золу и тяжелую нефть. gregtech.multiblock.cracker.description=Крекинговая установка - это многоблочная структура, используемая для высокотемпературной переработки нефти и её фракций с целью получения продуктов меньшей молекулярной массы. @@ -111,8 +111,8 @@ gregtech.multiblock.fusion_reactor.uv.description=Термоядерный ре gregtech.multiblock.fusion_reactor.heat=Нагрев: %d gregtech.multiblock.large_chemical_reactor.description=Многоблочная версия химического реактора выполняющий операции в больших объёмах с удвоенной эффективностью. Ускорение умножает скорость и энергию на 4. Для мультиблочной структуры требуется ровно 1 блок купроникелевой катушки, который должен быть размещен рядом с корпусом ПТФЭ трубы, расположенным в центре. gregtech.multiblock.primitive_water_pump.description=Примитивная водяная помпа — это многоблочная структура до Паровой Эпохи, который собирает воду раз в секунду, в зависимости от биома, в котором он находится. Он может использовать насос, выходной люк ULV или LV, увеличивая кол-во воды от уровня. Выполняется по формуле: Коэф. биома * Множитель люка. -gregtech.multiblock.primitive_water_pump.extra1=Коэф. биома:/n Океан, Река: 1000 Л/с/n Болото: 800 Л/с/n Джунгли: 350 Л/с/n Снежный: 300 Л/с/н Равнины, Лес: 250 Л/с/n Тайга : 175 Л/с/n Пляж: 170 Л/с/n Другое: 100 Л/с -gregtech.multiblock.primitive_water_pump.extra2=Множители люка:/n Люк насоса: 1x/n Выходной люк ULV: 2x/n LV Выходной люк: 4xn/nВо время дождя в биомах работы насоса добыча воды будет увеличена на 50%%. +gregtech.multiblock.primitive_water_pump.extra1=Коэф. биома:/n Океан, Река: 1000 Л/с/n Болото: 800 Л/с/n Джунгли: 350 Л/с/n Снежный: 300 Л/с/n Равнины, Лес: 250 Л/с/n Тайга: 175 Л/с/n Пляж: 170 Л/с/n Другое: 100 Л/с +gregtech.multiblock.primitive_water_pump.extra2=Множители люка:/n Люк насоса: 1x/n ULV Выходной люк : 2x/n LV Выходной люк: 4x/nВо время дождя в биомах работы насоса добыча воды будет увеличена на 50%%. gregtech.multiblock.processing_array.description=Массив машин объединяет до 16 одноблочных машин в одном многоблоке. gregtech.multiblock.advanced_processing_array.description=Массив машин объединяет до 64 одноблочных машин в одном многоблоке. item.invalid.name=Недопустимый предмет @@ -159,7 +159,7 @@ metaitem.power_unit.mv.name=Блок питания (§bMV§r) metaitem.power_unit.hv.name=Блок питания (§6HV§r) metaitem.power_unit.ev.name=Блок питания (§5EV§r) metaitem.power_unit.iv.name=Блок питания (§1IV§r) -metaitem.nano_saber.name=Нано-cабля +metaitem.nano_saber.name=Нано-сабля metaitem.nano_saber.tooltip=Ryujin no ken wo kurae! metaitem.shape.mold.plate.name=Форма (Пластина) metaitem.shape.mold.plate.tooltip=Форма для изготовления пластин @@ -237,8 +237,8 @@ metaitem.shape.extruder.gear.name=Форма экструдера (Шестер metaitem.shape.extruder.gear.tooltip=Форма экструдера для изготовления шестерней metaitem.shape.extruder.bottle.name=Форма экструдера (Бутылка) metaitem.shape.extruder.bottle.tooltip=Форма экструдера для изготовления бутылок -metaitem.shape.extruder.gear_small.name=Форма экструдера (маленькая шестеренка) -metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестереней +metaitem.shape.extruder.gear_small.name=Форма экструдера (Маленькая шестеренка) +metaitem.shape.extruder.gear_small.tooltip=Форма экструдера для производства маленьких шестерней metaitem.shape.extruder.foil.name=Форма экструдера (Фольга) metaitem.shape.extruder.foil.tooltip=Форма экструдера для производства фольги из неметаллов metaitem.shape.extruder.rod_long.name=Форма экструдера (Длинный прут) @@ -485,7 +485,7 @@ metaitem.glass_lens.yellow.name=Стеклянная линза (Желтый) metaitem.glass_lens.lime.name=Стеклянная линза (Лаймовый) metaitem.glass_lens.pink.name=Стеклянная линза (Розовый) metaitem.glass_lens.gray.name=Стеклянная линза (Серый) -metaitem.glass_lens.light_gray.name=Стеклянная линза (Cветло-серый) +metaitem.glass_lens.light_gray.name=Стеклянная линза (Светло-серый) metaitem.glass_lens.cyan.name=Стеклянная линза (Бирюзовый) metaitem.glass_lens.purple.name=Стеклянная линза (Фиолетовый) metaitem.glass_lens.blue.name=Стеклянная линза (Синий) @@ -507,7 +507,7 @@ metaitem.wafer.silicon.name=Кремниевая пластина metaitem.wafer.silicon.tooltip=Необработанная схема metaitem.wafer.phosphorus.name=Пластина легированная фосфором metaitem.wafer.phosphorus.tooltip=Необработанная схема -metaitem.wafer.naquadah.name=Плаcтина легированная наквадой +metaitem.wafer.naquadah.name=Пластина легированная наквадой metaitem.wafer.naquadah.tooltip=Необработанная схема metaitem.wafer.neutronium.name=Пластина легированная нейтронием metaitem.wafer.neutronium.tooltip=Необработанная схема @@ -694,7 +694,7 @@ metaitem.circuit.quantum_processor.name=Квантовый процессор metaitem.circuit.quantum_processor.tooltip=Квантовые вычисления оживают!/n§aEV уровень metaitem.circuit.quantum_assembly.name=Квантовый вычислительный блок metaitem.circuit.quantum_assembly.tooltip=Квантовые вычисления оживают!/n§aIV уровень -metaitem.circuit.quantum_computer.name=Квантовый cуперкомпьютер +metaitem.circuit.quantum_computer.name=Квантовый суперкомпьютер metaitem.circuit.quantum_computer.tooltip=Квантовые вычисления оживают!/n§aLuV уровень metaitem.circuit.quantum_mainframe.name=Квантовый мейнфрейм metaitem.circuit.quantum_mainframe.tooltip=Квантовые вычисления оживают!/n§aZPM уровень @@ -846,7 +846,7 @@ item.gt.tool.behavior.shield_disable=§7Брут: §fИгнорирует щит item.gt.tool.behavior.relocate_mining=§2Магнитный: §fПеремещает добытые блоки item.gt.tool.behavior.aoe_mining=§5Добыча по области: §f%sx%sx%s item.gt.tool.behavior.ground_tilling=§eФермер: Вспашка земли -item.gt.tool.behavior.grass_path=§eДекоратор:Создаёт тропу +item.gt.tool.behavior.grass_path=§eДекоратор: §fСоздаёт тропу item.gt.tool.behavior.rail_rotation=§eЖелезнодорожник: §fВращает рельсы item.gt.tool.behavior.crop_harvesting=§aКомбайн: §fСбор урожая item.gt.tool.behavior.plunger=§9Сантехник: §fОткачивает жидкости @@ -1054,7 +1054,7 @@ metaitem.blacklight.tooltip=Источник длинноволнового §d gui.widget.incrementButton.default_tooltip=Удерживайте Shift, Ctrl или оба, чтобы изменить кол-во gui.widget.recipeProgressWidget.default_tooltip=Показать рецепт gregtech.recipe_memory_widget.tooltip.2=§7Нажмите Shift, чтобы заблокировать/разблокировать этот рецепт -gregtech.recipe_memory_widget.tooltip.1=§7Щелкните левой кнопкой мыши, чтобы автоматически добавить этот рецепт в сетку крафта +gregtech.recipe_memory_widget.tooltip.1=§7Щелкните левой кнопкой мыши, чтобы автоматически добавить этот рецепт в Сетку создания cover.filter.blacklist.disabled=Белый список cover.filter.blacklist.enabled=Черный список cover.ore_dictionary_filter.title=Фильтр по словарю руд @@ -1494,7 +1494,7 @@ gregtech.material.vanadium_gallium=Ванадий-Галлий gregtech.material.wrought_iron=Кованое железо gregtech.material.wulfenite=Вульфенит gregtech.material.yellow_limonite=Желтый лимонит -gregtech.material.yttrium_barium_cuprate=Купрат иттрий-барийя +gregtech.material.yttrium_barium_cuprate=Оксид иттрия-бария-меди gregtech.material.nether_quartz=Адский кварц gregtech.material.certus_quartz=Истинный кварц gregtech.material.quartzite=Кварцит @@ -1556,7 +1556,7 @@ gregtech.material.nitric_acid=Азотная кислота gregtech.material.sulfuric_acid=Серная кислота gregtech.material.phosphoric_acid=Фосфорная кислота gregtech.material.sulfur_trioxide=Триоксид серы -gregtech.material.sulfur_dioxide=Дииоксид серы +gregtech.material.sulfur_dioxide=Диоксид серы gregtech.material.carbon_monoxide=Монооксид углерода gregtech.material.hypochlorous_acid=Соляная кислота gregtech.material.ammonia=Аммиак @@ -1613,7 +1613,7 @@ gregtech.material.polyvinyl_acetate=Поливинилацетат gregtech.material.reinforced_epoxy_resin=Укрепленная эпоксидная смола gregtech.material.polyvinyl_chloride=Поливинилхлорид (ПВХ) gregtech.material.polyphenylene_sulfide=Полифениленсульфид -gregtech.material.glyceryl_trinitrate=Глицерил тринитрат +gregtech.material.glyceryl_trinitrate=Нитроглицерин gregtech.material.polybenzimidazole=Полибензимидазол (ПБИ) gregtech.material.polydimethylsiloxane=Полидиметилсилоксан gregtech.material.plastic=Полиэтилен @@ -1627,7 +1627,7 @@ gregtech.material.monochloramine=Хлорамин gregtech.material.chloroform=Хлороформ gregtech.material.cumene=Кумола gregtech.material.tetrafluoroethylene=Тетрафторэтилен -gregtech.material.chloromethane=Хлорометан +gregtech.material.chloromethane=Хлорметан gregtech.material.allyl_chloride=Аллилхлорид gregtech.material.isoprene=Изопрен gregtech.material.propane=Пропан @@ -1763,7 +1763,7 @@ gregtech.material.coal_gas=Угольный газ gregtech.material.coal_tar=Каменноугольная смола gregtech.material.gunpowder=Порох gregtech.material.oilsands=Нефтеносный песок -gregtech.material.rare_earth=Редкая земля +gregtech.material.rare_earth=Редкоземельные элементы gregtech.material.stone=Камень gregtech.material.lava=Лава gregtech.material.glowstone=Светокамень @@ -1918,12 +1918,12 @@ gregtech.material.maximum=Максимальный item.gregtech.material.nether_quartz.oreNetherrack=Кварцевая руда Нижнего мира item.gregtech.material.gunpowder.dustTiny=Крошечная кучка пороха item.gregtech.material.gunpowder.dustSmall=Маленькая кучка пороха -item.gregtech.material.paper.dustTiny=Крошечная куча целюлозы -item.gregtech.material.paper.dustSmall=Маленькая кучка целюлозы -item.gregtech.material.paper.dust=Целюлоза -item.gregtech.material.rare_earth.dustTiny=Крошечная кучка редкой земли -item.gregtech.material.rare_earth.dustSmall=Маленькая кучка редкой земли -item.gregtech.material.rare_earth.dust=Редкая земля +item.gregtech.material.paper.dustTiny=Крошечная куча целлюлозы +item.gregtech.material.paper.dustSmall=Маленькая кучка целлюлозы +item.gregtech.material.paper.dust=Целлюлоза +item.gregtech.material.rare_earth.dustTiny=Крошечная кучка редкоземельных элементов +item.gregtech.material.rare_earth.dustSmall=Маленькая кучка редкоземельных элементов +item.gregtech.material.rare_earth.dust=Редкоземельные элементы item.gregtech.material.ash.dustTiny=Крошечная кучка золы item.gregtech.material.ash.dustSmall=Маленькая кучка золы item.gregtech.material.ash.dust=Зола @@ -1931,7 +1931,7 @@ item.gregtech.material.bone.dustTiny=Крошечная кучка костно item.gregtech.material.bone.dustSmall=Маленькая кучка костной муки item.gregtech.material.bone.dust=Костная пыль item.gregtech.material.cassiterite_sand.crushedCentrifuged=Центрифугированный касситеритовый песок -item.gregtech.material.cassiterite_sand.crushedPurified=Очищеный касситеритовый песок +item.gregtech.material.cassiterite_sand.crushedPurified=Очищенный касситеритовый песок item.gregtech.material.cassiterite_sand.crushed=Дробленный касситеритовый песок item.gregtech.material.cassiterite_sand.dustTiny=Крошечная кучка касситеритного песка item.gregtech.material.cassiterite_sand.dustSmall=Маленькая кучка касситеритного песка @@ -1950,12 +1950,12 @@ item.gregtech.material.sugar.gem=Сахарный кубик item.gregtech.material.rock_salt.dustTiny=Крошечная кучка каменной соли item.gregtech.material.rock_salt.dustSmall=Маленькая кучка каменной соли item.gregtech.material.rock_salt.dustImpure=Грязная кучка каменной соли -item.gregtech.material.rock_salt.dustPure=Очищеный кучка каменной соли +item.gregtech.material.rock_salt.dustPure=Очищенная кучка каменной соли item.gregtech.material.rock_salt.dust=Каменная соль item.gregtech.material.salt.dustTiny=Крошечная кучка соли item.gregtech.material.salt.dustSmall=Маленькая кучка соли item.gregtech.material.salt.dustImpure=Грязная кучка соли -item.gregtech.material.salt.dustPure=Очищеный кучка соли +item.gregtech.material.salt.dustPure=Очищенная кучка соли item.gregtech.material.salt.dust=Кучка соли item.gregtech.material.wood.dustTiny=Крошечная кучка древесных опилок item.gregtech.material.wood.dustSmall=Маленькая кучка древесных опилок @@ -1997,26 +1997,26 @@ item.gregtech.material.glauconite_sand.dustSmall=Маленькая кучка item.gregtech.material.glauconite_sand.dustTiny=Крошечная кучка глауконитового песка item.gregtech.material.bentonite.crushed=Измельченный бентонит item.gregtech.material.bentonite.crushedCentrifuged=Центрифугированный бентонит -item.gregtech.material.bentonite.crushedPurified=Очищеный бентонит +item.gregtech.material.bentonite.crushedPurified=Очищенный бентонит item.gregtech.material.bentonite.dustImpure=Грязная кучка бентонита -item.gregtech.material.bentonite.dustPure=Очищеный кучка бентонита +item.gregtech.material.bentonite.dustPure=Очищенная кучка бентонита item.gregtech.material.bentonite.dustSmall=Маленькая кучка бентонита item.gregtech.material.bentonite.dustTiny=Крошечная кучка бентонита item.gregtech.material.bentonite.dust=Бентонит item.gregtech.material.fullers_earth.dustSmall=Маленькая кучка смектической глины -item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка cмектической глины +item.gregtech.material.fullers_earth.dustTiny=Крошечная кучка смектической глины item.gregtech.material.fullers_earth.dust=Смектическая глина item.gregtech.material.pitchblende.crushed=Измельчённый уранит item.gregtech.material.pitchblende.crushedCentrifuged=Центрифугированный уранит -item.gregtech.material.pitchblende.crushedPurified=Очищеный уранит +item.gregtech.material.pitchblende.crushedPurified=Очищенный уранит item.gregtech.material.pitchblende.dustImpure=Грязная кучка уранита -item.gregtech.material.pitchblende.dustPure=Очищеный кучка уранита +item.gregtech.material.pitchblende.dustPure=Очищенная кучка уранита item.gregtech.material.pitchblende.dustSmall=Маленькая кучка уранита item.gregtech.material.pitchblende.dustTiny=Крошечная кучка уранита item.gregtech.material.pitchblende.dust=Уранит item.gregtech.material.talc.crushed=Дробленный тальк item.gregtech.material.talc.crushedCentrifuged=Центрифугированный тальк -item.gregtech.material.talc.crushedPurified=Очищеный тальк +item.gregtech.material.talc.crushedPurified=Очищенный тальк item.gregtech.material.talc.dustImpure=Грязная кучка талька item.gregtech.material.talc.dustPure=Очищеная кучка талька item.gregtech.material.talc.dustSmall=Маленькая кучка талька @@ -2204,7 +2204,7 @@ metaitem.item_magnet.lv.name=Магнит (§7LV§r) metaitem.item_magnet.hv.name=Магнит (§6HV§r) behavior.item_magnet.enabled=§aМагнитное поле включено behavior.item_magnet.disabled=§cМагнитное поле отключено -behavior.data_item.assemblyline.title=§nДанные для Сборочного конвеера: +behavior.data_item.assemblyline.title=§nДанные для Сборочного конвейера: behavior.data_item.assemblyline.data=- §a%s metaitem.rubber_wood_boat.name=Каучуковая лодка metaitem.treated_wood_boat.name=Обработанная деревянная лодка @@ -3781,8 +3781,8 @@ gregtech.machine.battery_buffer.opv.16.name=Батарейный буфер (16 gregtech.machine.battery_buffer.max.4.name=Батарейный буфер (4 ячейки §cMAX§r) gregtech.machine.battery_buffer.max.8.name=Батарейный буфер (8 ячеек §cMAX§r) gregtech.machine.battery_buffer.max.16.name=Батарейный буфер (16 ячеек §cMAX§r) -gregtech.battery_buffer.average_output=Выход в среднем: %s EU/t -gregtech.battery_buffer.average_input=Ввод в среднем: %s EU/t +gregtech.battery_buffer.average_output=Сред. вывод: %s EU/t: %s EU/t +gregtech.battery_buffer.average_input=Сред. ввод: %s EU/t # Transformers gregtech.machine.transformer.description=Преобразует энергию между уровнями напряжения @@ -4336,7 +4336,7 @@ behaviour.paintspray.solvent.tooltip=Может удалить цвет с ве behaviour.paintspray.white.tooltip=Может окрасить в Белый behaviour.paintspray.orange.tooltip=Может окрасить в Оранжевый behaviour.paintspray.magenta.tooltip=Может окрасить в Пурпурный -behaviour.paintspray.lightBlue.tooltip=Может окрасить в Cветло-синий +behaviour.paintspray.lightBlue.tooltip=Может окрасить в Светло-синий behaviour.paintspray.yellow.tooltip=Может окрасить в Желтый behaviour.paintspray.lime.tooltip=Может окрасить в Лаймовый behaviour.paintspray.pink.tooltip=Может окрасить в Розовый @@ -4377,7 +4377,7 @@ gregtech.machine.large_chemical_reactor.name=Большой химический gregtech.machine.large_combustion_engine.name=Большой дизельный генератор gregtech.machine.extreme_combustion_engine.name=Улучшенный дизельный генератор gregtech.machine.large_combustion_engine.tooltip.boost_regular=Подавайте §f20 Л/с§7 кислорода для получения до §f%s§7 EU/t при §а2x§7 расходе топлива. -gregtech.machine.large_combustion_engine.tooltip.boost_extreme=Подавайте §e80 л/с§7 жидкого кислорода для получения до §f%s§7 EU/t при §а2x§7 расходе топлива. +gregtech.machine.large_combustion_engine.tooltip.boost_extreme=Подавайте §e80 Л/с§7 жидкого кислорода для получения до §f%s§7 EU/t при §а2x§7 расходе топлива. gregtech.machine.large_turbine.steam.name=Большая паровая турбина gregtech.machine.large_turbine.gas.name=Большая газовая турбина gregtech.machine.large_turbine.plasma.name=Большая плазменная турбина @@ -4397,7 +4397,7 @@ gregtech.machine.fusion_reactor.overclocking=Ускорение требует gregtech.machine.miner.lv.name=Обычный шахтер gregtech.machine.miner.mv.name=Улучшенный шахтер gregtech.machine.miner.hv.name=Улучшенный шахтер II -gregtech.machine.miner.tooltip=Добывает руды ТОЛЬКО ниже шахтера! Начинет работу в §f%sx%s §7области +gregtech.machine.miner.tooltip=Добывает руды ТОЛЬКО ниже шахтера! Начнет работу в §f%sx%s §7области gregtech.machine.miner.per_block=§7тратит §f%,dсек §7на блок gregtech.machine.large_miner.ev.name=Обычная буровая установка gregtech.machine.large_miner.iv.name=Улучшенная буровая установка @@ -4436,14 +4436,14 @@ gregtech.machine.cleanroom.tooltip.8=Подавайте питание чере gregtech.machine.cleanroom.tooltip.9=Отправляйте предметы и жидкости с помощью §fСквозных люков§7в стенах. gregtech.machine.cleanroom.tooltip.ae2.channels=Отправляйте до §f8 AE2 каналов §7через §fОболочку§7 в стенах. gregtech.machine.cleanroom.tooltip.ae2.no_channels=Отправляйте §aAE2 сеть§7 через §fОболочку§7 в стенах. -gregtech.multiblock.cleanroom.dirty_state=Статус: §4ЗАГРЯЗНЕНА -gregtech.multiblock.cleanroom.clean_state=Статус: §aЧИСТАЯ +gregtech.multiblock.cleanroom.dirty_state=ЗАГРЯЗНЕНА (%s%%) +gregtech.multiblock.cleanroom.clean_state=ЧИСТАЯ (%s%%) gregtech.machine.charcoal_pile.name=Воспламенитель угольной ямы -gregtech.machine.charcoal_pile.tooltip.1=§cПережигает§7 древесину в §aДревеный уголь§7. +gregtech.machine.charcoal_pile.tooltip.1=§cПережигает§7 древесину в §aДревесный уголь§7. gregtech.machine.charcoal_pile.tooltip.2=Щелкните правой кнопкой мыши предметом, зажигающим огонь, чтобы начать. gregtech.machine.charcoal_pile.tooltip.3=Прожиг происходит на расстоянии до §b9x4x9§7 под ним. gregtech.machine.charcoal_pile.tooltip.4=Древесина не должна подвергаться воздействию §eВоздуха§7! -gregtech.multiblock.charcoal_pile.description=Пережигает древесину в Древеный уголь.\n\nПол ямы должен быть сделан из кирпича, а для стен и крыши можно использовать любой блок земли. Внутри ямы не должно быть воздуха.\n\nБольшие ямы требуют больше времени для обработки древесины, но более эффективны. +gregtech.multiblock.charcoal_pile.description=Пережигает древесину в Древесный уголь.\n\nПол ямы должен быть сделан из кирпича, а для стен и крыши можно использовать любой блок земли. Внутри ямы не должно быть воздуха.\n\nБольшие ямы требуют больше времени для обработки древесины, но более эффективны. gregtech.machine.data_bank.name=Хранилище Данных gregtech.machine.data_bank.tooltip.1=Твой личный NAS gregtech.machine.data_bank.tooltip.2=Массовое хранение данных. Передача только по оптическим кабелям. @@ -4478,7 +4478,7 @@ gregtech.machine.high_performance_computing_array.name=Высокопроизв gregtech.machine.high_performance_computing_array.tooltip.1=Просто самый обычный Суперкомпьютер gregtech.machine.high_performance_computing_array.tooltip.2=Используется для генерации §fВычислений§7 (и тепла). gregtech.machine.high_performance_computing_array.tooltip.3=Требуются компоненты HPCA для создания §fCWU/t§7 (Вычислительные Рабочие Единицы). -gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное ко-во вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения. +gregtech.multiblock.high_performance_computing_array.description=Высокопроизводительный Вычислительный Массив (HPCA) представляет собой многоблочную структуру, используемую для создания Вычислительные Рабочие Единицы (CWU/t) для более Сложных Данных Исследования Cборочной Линии. Структура имеет гибкую область 3x3, которая может быть заполнена компонентами HPCA любым способом. Различные компоненты могут обеспечивать разное кол-во вычислений, охлаждения, а также затрат на энергию, стоимость охлаждающей жидкости и производство тепла. При использовании с компонентом моста HPCA может подключаться к сетевым коммутаторам для объединения и маршрутизации вычислений из нескольких источников в одно или несколько мест назначения. gregtech.machine.central_monitor.name=Центральный монитор gregtech.multiblock.central_monitor.low_power=Недостаточно энергии gregtech.multiblock.central_monitor.height=Высота экрана: @@ -4520,7 +4520,7 @@ gregtech.machine.large_turbine.steam.tooltip=Не суй свою голову gregtech.machine.large_turbine.gas.tooltip=Не Реактивный двигатель gregtech.machine.large_turbine.plasma.tooltip=Вытягиватель энергии из Плазмы gregtech.machine.large_boiler.bronze.tooltip=Нужно больше ПАРА! -gregtech.machine.large_boiler.steel.tooltip=Сжигатель древесного уголя +gregtech.machine.large_boiler.steel.tooltip=Сжигатель древесного угля gregtech.machine.large_boiler.titanium.tooltip=Где найти Магическое Супер-Топливо? gregtech.machine.large_boiler.tungstensteel.tooltip=Как вообще заправлять эту штуку? gregtech.machine.coke_oven.tooltip=Создание лучшего топлива для Стали и Энергии @@ -4737,7 +4737,7 @@ gregtech.machine.computation_hatch.receiver.tooltip=Вход Данных Выч gregtech.machine.research_station.object_holder.name=Держатель объекта gregtech.machine.research_station.object_holder.tooltip=Улучшенный держатель объекта для Станций исследований gregtech.machine.fluid_tank.max_multiblock=Максимальный размер: %,dx%,dx%,d -gregtech.machine.fluid_tank.fluid=Содержит %s mB %s +gregtech.machine.fluid_tank.fluid=Содержит %s мВ %s gregtech.machine.me_export_fluid_hatch.name=ME Выходной жидкостный люк gregtech.machine.me_export_item_bus.name=ME Выходной предметный люк gregtech.machine.me_import_fluid_hatch.name=ME Накопительный жидкостный люк @@ -4771,7 +4771,7 @@ gregtech.universal.tooltip.fluid_storage_capacity=§9Объем жидкости gregtech.universal.tooltip.fluid_storage_capacity_mult=§9Объем жидкости: §f%,d §7Хранилища, §f%,d Л §7каждое gregtech.universal.tooltip.fluid_stored=§dОбъем жидкости: §f%s, %,d Л gregtech.universal.tooltip.fluid_transfer_rate=§bСкорость передачи: §f%,d Л/т -gregtech.universal.tooltip.parallel=§dПаралеллей: §f%d +gregtech.universal.tooltip.parallel=§dПараллелей: §f%d gregtech.universal.tooltip.working_area=§bРабочая область: §f%,dx%,d gregtech.universal.tooltip.working_area_max=§bМакс. рабочая область: §f%,dx%,d gregtech.universal.tooltip.working_area_chunks_max=§bMax Working Area: §f%,dx%,d Chunks @@ -4789,7 +4789,7 @@ gregtech.block.tooltip.no_mob_spawning=§bМонстры не могут поя gregtech.recipe.total=Всего: %d EU gregtech.recipe.eu=Потребление: %d EU/т (%s§r) gregtech.recipe.eu_inverted=Производство: %d EU/т -gregtech.recipe.duration=Длительность: %s secs +gregtech.recipe.duration=Длительность: %s сек gregtech.recipe.amperage=Сила тока: %d gregtech.recipe.not_consumed=Не расходуется gregtech.recipe.chance=Шанс: %s%% +%s%%/уровень @@ -4802,9 +4802,9 @@ gregtech.recipe.cleanroom.display_name=Чистая комната gregtech.recipe.cleanroom_sterile.display_name=Стерильная чистая комната gregtech.recipe.research=Требует Исследование gregtech.recipe.computation_per_tick=Мин. Вычисления: %,d CWU/t -gregtech.fluid.click_to_fill=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7резервуар. +gregtech.fluid.click_to_fill=§7Нажмите с хранилищем для жидкости, чтобы §bзаполнить §7резервуар. gregtech.fluid.click_to_empty=§7Нажмите с хралищем для жидкости, чтобы §cопустошить §7резервуар. -gregtech.fluid.click_combined=§7Нажмите с хралищем для жидкости, чтобы §bзаполнить §7или §cопустошить §7резервуар. +gregtech.fluid.click_combined=§7Нажмите с хранилищем для жидкости, чтобы §bзаполнить §7или §cопустошить §7резервуар. gregtech.tool_action.show_tooltips=Зажмите SHIFT для Информации о Инструменте gregtech.tool_action.screwdriver.auto_output=§8Используйте отвертку, чтобы переключить Авто-Вывод gregtech.tool_action.screwdriver.toggle_mode_covers=§8Используйте отвертку, чтобы переключить Режим или настроить улучшения @@ -4846,7 +4846,7 @@ gregtech.gui.fluid_auto_output.tooltip.disabled=Авто. вывод жидко gregtech.gui.item_auto_output.tooltip.enabled=Авто. вывод предметов включен gregtech.gui.item_auto_output.tooltip.disabled=Авто. вывод предметов отключен gregtech.gui.charger_slot.tooltip=§fСлот двухстороннего питания§r/n§7Может потреблять энергию от %s §7аккумуляторов либо-же отдавать -gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r\n§aУстановить Значение: §f%d§7\n\n§7ЛКМ/ПКМ/Прокрутка для переключения по листу\n§7Shift-ЛКМ чтобы выбрать селектор\n§7Shift-ПКМ для очистка +gregtech.gui.configurator_slot.tooltip=§fСлот Конфигурации§r/n§aУстановленное значение: §f%d§7/n/n§7ЛКМ/ПКМ/Прокрутка для переключения по листу/n§7Shift-ЛКМ чтобы выбрать селектор/n§7Shift-ПКМ для очистки gregtech.gui.fluid_lock.tooltip.enabled=Блокировка жидкости включена gregtech.gui.fluid_lock.tooltip.disabled=Блокировка жидкости выключена gregtech.gui.fluid_voiding.tooltip.enabled=Удаление избытков жидкости Включен @@ -4869,7 +4869,7 @@ gregtech.jei.ore.surface_rock_2=Их можно разбить на 3 Кроше gregtech.jei.ore.biome_weighting_title=§dОбщий вес модифицированного биома gregtech.jei.ore.biome_weighting=§d%s Объем: §3%d gregtech.jei.ore.biome_weighting_no_spawn=%s Объем: Не может появиться -gregtech.jei.ore.ore_weight=Обьём в жиле: %d%% +gregtech.jei.ore.ore_weight=Объем в жиле: %d%% gregtech.jei.ore.primary_1=Верхняя руда gregtech.jei.ore.primary_2=Появляется в верхних %d слоях жилы gregtech.jei.ore.secondary_1=Нижняя руда @@ -4933,7 +4933,7 @@ gregtech.multiblock.universal.problem.wire_cutter=%s§7Проводка пере gregtech.multiblock.universal.problem.crowbar=%s§7Что-то попало внутрь. (§aМонтировка§7) gregtech.multiblock.universal.muffler_obstructed=Что то мешает Люку глушителя. gregtech.multiblock.universal.distinct_enabled=Раздельные люки: §aВключено§r/nКаждый входной люк будет рассматриваться отдельно друг от друга для поиска рецепта. Полезно, например, для форм экструдера, лазерных линз и т.д. -gregtech.multiblock.universal.distinct_disabled=Раздельные люки: §aВsключено§r/nКаждый входной люк будет рассматриваться как комбинированный ввод для поиска рецепта. +gregtech.multiblock.universal.distinct_disabled=Раздельные люки: §aВключено§r/nКаждый входной люк будет рассматриваться как комбинированный ввод для поиска рецепта. gregtech.multiblock.universal.distinct_not_supported=Эту структура не поддерживает Раздельные Люки gregtech.multiblock.universal.no_flex_button=Эта структура не имеет дополнительных функций с этой кнопкой. gregtech.multiblock.parallel=Макс. Параллелей: %s @@ -4942,7 +4942,7 @@ gregtech.multiblock.multiple_recipemaps.tooltip=Нажмите отвёртко gregtech.multiblock.multiple_recipemaps_recipes.tooltip=Режим машин: §e%s§r gregtech.multiblock.multiple_recipemaps.switch_message=Для переключения режимов машина должна быть выключена! gregtech.multiblock.energy_stored=Энергия: %s EU / %s EU -gregtech.multiblock.preview.zoom=Используйте колёсико мыши или Shift+RMB для масштаба +gregtech.multiblock.preview.zoom=Используйте колёсико мыши или Shift+ПКМ для масштаба gregtech.multiblock.preview.rotate=Нажмите и вращайте для поворота gregtech.multiblock.preview.select=Правой кнопкой по блоку вы можете посмотреть варианты gregtech.multiblock.pattern.error_message_header=Возможная ошибка структуры: @@ -4966,16 +4966,16 @@ gregtech.multiblock.blast_furnace.max_temperature=Максимальная те gregtech.multiblock.multi_furnace.heating_coil_discount=EU усиление нагревательной катушки: %sx gregtech.multiblock.distillation_tower.distilling_fluid=Дистилляция %s gregtech.multiblock.large_combustion_engine.no_lubricant=Нет Смазки. -gregtech.multiblock.large_combustion_engine.lubricant_amount=Кол-во смазки: %smB -gregtech.multiblock.large_combustion_engine.oxygen_amount=Кол-во кислорода: %smB -gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Кол-во жид. кислорода: %smB +gregtech.multiblock.large_combustion_engine.lubricant_amount=Кол-во смазки: %s +gregtech.multiblock.large_combustion_engine.oxygen_amount=Кол-во кислорода: %s +gregtech.multiblock.large_combustion_engine.liquid_oxygen_amount=Кол-во жид. кислорода: %s gregtech.multiblock.large_combustion_engine.oxygen_boosted=§bКислород добавлен. -gregtech.multiblock.large_combustion_engine.liquid_oxygen_boosted=§bЖидкий кислород добавлен. +gregtech.multiblock.large_combustion_engine.liquid_oxygen_boosted=§bЖид. кислород добавлен. gregtech.multiblock.large_combustion_engine.supply_oxygen_to_boost=Принимает кислород для ускорения. -gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=Принимает жидкий кислород для ускорения. +gregtech.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost=Принимает жид. кислород для ускорения. gregtech.multiblock.large_combustion_engine.obstructed=Что-то мешает воздухозаборнику двигателя. -gregtech.multiblock.turbine.fuel_amount=Топлива: %smB (%s) -gregtech.multiblock.turbine.rotor_speed=Скорость: %s/%s об/мин +gregtech.multiblock.turbine.fuel_amount=Топлива: %sмВ (%s) +gregtech.multiblock.turbine.rotor_speed=Скорость: %s gregtech.multiblock.turbine.rotor_durability=Прочность ротора: %s gregtech.multiblock.turbine.rotor_durability_low=Прочность ротора низкая! gregtech.multiblock.turbine.no_rotor=Нет Ротора в Держателе ротора. @@ -5037,7 +5037,7 @@ gregtech.multiblock.hpca.warning_temperature_active_cool=Полное испол gregtech.multiblock.hpca.warning_structure_header=Подсказки по структуре: gregtech.multiblock.hpca.warning_multiple_bridges=- Множество мостов в структуре (не дают дополнительных преимущество) gregtech.multiblock.hpca.warning_no_computation=- Не проводятся вычисления -gregtech.multiblock.hpca.warning_low_cooling=- Не достаточно хладогента +gregtech.multiblock.hpca.warning_low_cooling=- Не достаточно хладагента gregtech.command.usage=Применение: /gregtech gregtech.command.worldgen.usage=Применение: /gregtech worldgen gregtech.command.worldgen.reload.usage=Применение: /gregtech worldgen reload @@ -5071,7 +5071,7 @@ gregtech.creative.chest.item=Предмет gregtech.creative.chest.ipc=Предметов за цикл gregtech.creative.chest.tpc=Тиков в цикле gregtech.creative.tank.fluid=Жидкость -gregtech.creative.tank.mbpc=mB за цикл +gregtech.creative.tank.mbpc=мВ за цикл gregtech.creative.tank.tpc=Тиков в цикле gregtech.creative.energy.amperage=Сила тока gregtech.creative.energy.voltage=Вольтаж @@ -5116,7 +5116,7 @@ texture.modify_gui_texture.missing=Отсутствует текстура texture.url_texture.fail=Загрузка не удалась terminal.hw.battery=Аккумулятор terminal.hw.device=Устройство -terminal.os.shutdown_confirm=Завершение работы (Нажмите ESC что-бы завершить) +terminal.os.shutdown_confirm=Завершение работы (Нажмите ESC чтобы завершить) terminal.os.hw_demand=Нет нужного оборудования: terminal.system_call.null=NULL terminal.system_call.call_menu=Боковая панель @@ -5300,7 +5300,7 @@ gregtech.subtitle.tick.forge_hammer=Кувалда крушит gregtech.subtitle.tick.macerator=Предмет измельчается gregtech.subtitle.tick.chemical_reactor=Химикаты реагируют gregtech.subtitle.tick.assembler=Предмет собирается -gregtech.subtitle.tick.centrifuge=Предметы расщипляются +gregtech.subtitle.tick.centrifuge=Предметы расщепляются gregtech.subtitle.tick.compressor=Предмет сжимается gregtech.subtitle.tick.electrolyzer=Элементы электризуются gregtech.subtitle.tick.mixer=Пыль смешивается @@ -5322,7 +5322,7 @@ gregtech.subtitle.use.soft_hammer=Блок размолот gregtech.subtitle.use.drill=Бур засверлил gregtech.subtitle.use.plunger=Вантуз пробил gregtech.subtitle.use.file=Напильник отшлифовал -gregtech.subtitle.use.saw=Дерево рапилилось +gregtech.subtitle.use.saw=Дерево распилилось gregtech.subtitle.use.screwdriver=Болт закрутился gregtech.subtitle.use.chainsaw=Бензопила рычит gregtech.subtitle.use.wirecutter=Щелчок проводов @@ -5549,7 +5549,7 @@ tile.studs.silver.name=Светло-серая перегородка tile.studs.cyan.name=Бирюзовая перегородка tile.studs.purple.name=Фиолетовая перегородка gregtech.scanner.copy_stick_from=§oСкопировать Флешку -gregtech.scanner.copy_stick_to=§oСкопирова в Флешку +gregtech.scanner.copy_stick_to=§oСкопировать в Флешку gregtech.scanner.copy_stick_empty=§oПустая флешка gregtech.material.rtm_alloy=РВМ Сплав tile.metal_sheet.red.name=Красный лист металла @@ -5566,9 +5566,9 @@ tile.large_metal_sheet.green.name=Крупный зеленый лист мет gregtech.machine.alarm.name=Тревога gregtech.machine.world_accelerator.mv.tooltip=Тик ускоряет блоки gregtech.machine.world_accelerator.ev.tooltip=Тик ускоряет блоки -gregtech.machine.world_accelerator.iv.tooltip=Время в §mБутылке§r§7 Блоке -gregtech.machine.world_accelerator.luv.tooltip=Время в §mБутылке§r§7 Блоке -gregtech.machine.world_accelerator.zpm.tooltip=Время в §mБутылке§r§7 Блоке +gregtech.machine.world_accelerator.iv.tooltip=Время в §mБутылке§r§7 в Блоке +gregtech.machine.world_accelerator.luv.tooltip=Время в §mБутылке§r§7 в Блоке +gregtech.machine.world_accelerator.zpm.tooltip=Время в §mБутылке§r§7 в Блоке gregtech.machine.world_accelerator.uv.tooltip=Временная аномалия tile.wire_coil.rtm_alloy.name=Катушка из РВМ Сплава tile.metal_sheet.green.name=Зеленый лист металла @@ -5717,8 +5717,8 @@ gregtech.multiblock.fluid_rig.fluid_amount=Скорость добычи: %s gregtech.multiblock.fluid_rig.vein_depletion=Размер: %s gregtech.multiblock.fluid_rig.vein_depleted=Жила опустошена. gregtech.multiblock.miner.drilling=Бурение. -gregtech.multiblock.hpca.info_max_cooling_demand=Потребность в хладогенте: %s -gregtech.multiblock.hpca.info_max_coolant_required=Хладогента требуется: %s +gregtech.multiblock.hpca.info_max_cooling_demand=Потребность в хладагенте: %s +gregtech.multiblock.hpca.info_max_coolant_required=Хладагента требуется: %s gregtech.multiblock.hpca.info_coolant_name=Хладоген (ПХД) gregtech.multiblock.hpca.info_bridging_enabled=Мост Включен gregtech.multiblock.hpca.info_bridging_disabled=Мост Выключен @@ -5741,11 +5741,11 @@ item.gt.comb.ash.name=Пепельные соты item.gt.comb.biomass.name=Соты биомассы item.gt.comb.energy.name=Энергетические соты item.gt.comb.lapotron.name=Лапотронные соты -item.gt.comb.stainlesssteel.name=Соты нержавеки +item.gt.comb.stainlesssteel.name=Соты нержавейки item.gt.comb.stone.name=Каменные соты item.gt.comb.certus.name=Кварцевые соты item.gt.comb.redstone.name=Редстоун соты -item.gt.comb.rareearth.name=Соты редкой земли +item.gt.comb.rareearth.name=Соты редкоземельных элементов item.gt.comb.ruby.name=Рубиновые соты item.gt.comb.sapphire.name=Сапфировые соты item.gt.comb.diamond.name=Алмазные соты @@ -5810,7 +5810,7 @@ for.bees.species.lead=Свинцовая for.bees.species.iron=Железная for.bees.species.nickel=Никелевая for.bees.species.zinc=Цинковая -for.bees.species.silver=Серебрянная +for.bees.species.silver=Серебряная for.bees.species.gold=Золотая for.bees.species.arsenic=Мышьяковая for.bees.species.titanium=Титановая @@ -5866,7 +5866,7 @@ gregtech.veins.ore.raw_oil_sphere=Залежь нефти gregtech.veins.fluid.natural_gas_nether=Залежь природного газа Нижнего мира gregtech.multiblock.multi_furnace.heating_coil_discount_hover=Множитель энергопотребления задается уровнем катушки gregtech.multiblock.large_combustion_engine.liquid_oxygen_boost_disallowed=Улучшите выходной разъем, чтобы включить жидкостный форсаж. -gregtech.multiblock.hpca.info_max_cooling_available=Хладогента доступно: %s +gregtech.multiblock.hpca.info_max_cooling_available=Хладагента доступно: %s gregtech.creative.energy.sink=Разряд metaitem.electrode.copper.name=Медный электрод item.gt.tool.behavior.scoop=§dЛовец: §fЛовит бабочек при ЛКМ @@ -5876,7 +5876,7 @@ item.gt.comb.lapis.name=Ляписовые соты item.gt.comb.emerald.name=Изумрудные соты item.gt.comb.tin.name=Оловянные соты item.gt.comb.steel.name=Стальные соты -item.gt.comb.silver.name=Серебрянные соты +item.gt.comb.silver.name=Серебряные соты item.gt.comb.magnesium.name=Магниевые соты item.gt.comb.molybdenum.name=Молибденовые соты item.gt.comb.uranium.name=Урановые соты @@ -5924,11 +5924,11 @@ cover.bucket.mode.milli_bucket_exact=Л option.gregtech.converter=Энерго-преобразователи option.gregtech.energy=Энергохранилища option.gregtech.block_lamp=Лампы -option.gregtech.maintenance=Неисправености +option.gregtech.maintenance=Неисправности option.gregtech.block_ore=Блоки руды option.gregtech.controllable=Управляемые машины option.gregtech.multiblock=Мультиблочные структуры -cover.conveyor.distribution.name=Режим распространения +cover.conveyor.distribution.name=Режим распределения cover.bucket.mode.milli_bucket_rate=Л/с gregtech.machine.me.stocking_item.tooltip=Извлекает предметы непосредственно из сети ME gregtech.machine.me_import_item_hatch.configs.tooltip=Держит 16 предметов в наличии @@ -6003,3 +6003,48 @@ gregtech.command.datafix.bqu.failed=Перенос Базы данных Кве behavior.tricorder.mte_owner=Владелец: %s behavior.tricorder.mte_owner_offline=Владелец Не в сети или Не в этом мире! behavior.tricorder.mte_owner_null=Это установлено не игроком! +cover.ender_fluid_link.transfer_unit=Л/т +cover.generic.ender.known_channels=Известные каналы +cover.generic.ender.open_selector=Открыть выбор +cover.generic.ender.set_description.tooltip=Описание +cover.generic.ender.set_description.title=Описание [%s] +cover.generic.ender.delete_entry=Удалить запись +gregtech.machine.me.extra_connections.disabled=Разрешить соединения только с лицевой стороны +gregtech.machine.me.extra_connections.enabled=Разрешить соединения со всех сторон +gregtech.waila.energy_input=Вход: %s EU/т +gregtech.waila.energy_output=Выход: %s EU/т +gregtech.battery_buffer.average_input.top=Ввод: %s +gregtech.battery_buffer.average_output.top=Выход: %s +gregtech.multiblock.active_transformer.max_in=Макс. вход: %s +gregtech.multiblock.active_transformer.max_out=Макс. выход: %s +gregtech.multiblock.active_transformer.average_io=Сред. Вх./Вых.: %s +gregtech.machine.me.extra_connections.tooltip=ПКМ с кусачками, чтобы разрешить подключение к AE2 с любых сторон +gregtech.waila.active_transformer.average_io=Сред. Вх./Вых.: %s EU/т +gregtech.top.quantum_controller.no_hatches=§cНет подключенных энергетических разъемов +behavior.tricorder.quantum_storage.usage=Используется %s EU/т Квантовым контроллером +gregtech.machine.super_tank.ulv.name=Простой резервуар I +gregtech.jei.ct_recipe.tooltip=CraftTweaker рецепт +gregtech.machine.super_chest.ulv.name=Простой сундук I +gregtech.machine.quantum_storage_extender.tooltip=Расширяет сеть квантового хранилища к другим сундукам/резервуарам +gregtech.machine.quantum_storage_controller.tooltip=Сердце сети квантового хранилища/nПодключите Энергетические разьемы для включения Сети квантового хранилища +gregtech.jei.gs_recipe.tooltip=GroovyScript рецепт +gregtech.top.quantum_status.label=Статус: +gregtech.top.quantum_status.powered=§bВ сети +gregtech.top.quantum_status.connected=§сНе в сети +gregtech.top.quantum_status.disconnected=Не подключено +gregtech.top.quantum_controller.no_power=§сНет энергии +gregtech.jei.remove_recipe.tooltip=Копирует фрагмент %s, чтобы удалить этот рецепт +gregtech.top.steam_cooling_down=Охлаждение +behavior.tricorder.quantum_controller.usage=Используется: %s EU/т (%s) +behavior.tricorder.quantum_controller.connected_items=Подключено хранилищ: %s +behavior.tricorder.quantum_controller.connected_fluids=Подключено резервуаров: %s +gregtech.machine.quantum_storage_controller.name=Контроллер квантового хранилища +gregtech.machine.quantum_storage_proxy.name=Прокси квантового хранилища +gregtech.machine.quantum_storage_proxy.tooltip=Прокси разьем квантового хранилища +gregtech.machine.quantum_storage_extender.name=Расширитель квантового хранилища +gregtech.machine.quantum_storage.connected=Подключено к Квантовому контроллеру в [%d, %d, %d]/n/nНажмите, чтобы выделить контроллер +gregtech.machine.quantum_storage.disconnected=Не подключено +cover.filter.allow_flow.tooltip=По умолчанию предметы/жидкости могут перемещаться\nтолько в направлении фильтра в соответствии с его настройками.\n\nЕсли включено, предметы/жидкости могут проходить\nбез фильтрации в противоположном направлении от этого фильтра. +cover.generic.disabled=Выключено +cover.generic.enabled=Включено +cover.filter.allow_flow.label=Разрешено diff --git a/src/main/resources/assets/gregtech/lang/uk_UA.lang b/src/main/resources/assets/gregtech/lang/uk_ua.lang similarity index 66% rename from src/main/resources/assets/gregtech/lang/uk_UA.lang rename to src/main/resources/assets/gregtech/lang/uk_ua.lang index 46667cc7db0..972e9e985bb 100644 --- a/src/main/resources/assets/gregtech/lang/uk_UA.lang +++ b/src/main/resources/assets/gregtech/lang/uk_ua.lang @@ -1,6 +1,6 @@ -death.attack.heat= +death.attack.heat=%s зварили живцем death.attack.chemical=%s потрапив у хімічний інцидент death.attack.electric=%s був убитий струмом death.attack.radiation=%s тепер світиться від радості @@ -39,7 +39,7 @@ gregtech.top.energy_production=Виготовляє gregtech.top.transform_down=Знижувати gregtech.top.transform_input=Вхід: gregtech.top.transform_output=Вихід: -gregtech.top.steam_heating_up=Нагрівання +gregtech.top.steam_heating_up=Нагрівання: gregtech.top.steam_no_water=Немає води gregtech.top.convert_fe=Конвертація §cFE§r -> §eEU§r gregtech.top.invalid_structure=Структура незавершена @@ -134,7 +134,7 @@ option.gregtech.controllable=Керовані машини option.gregtech.maintenance=Проблеми з технічним обслуговуванням option.gregtech.recipe_logic=Рецепти option.gregtech.steam_boiler=Парові котли -gregtech.waila.energy_stored=Енергія: %d EU / %d EU +gregtech.waila.energy_stored=Енергія: %s EU / %s EU death.attack.spade=%s був розкопаний з допомогою %s death.attack.screwdriver_lv=Гвинти %s були відкручені з допомогою %s gregtech.top.energy_consumption=Використовує @@ -633,7 +633,7 @@ metaitem.plate.integrated_logic_circuit.name=Вбудована схема metaitem.plate.integrated_logic_circuit.tooltip=Вбудована логічна схема metaitem.plate.central_processing_unit.name=ЦП metaitem.plate.central_processing_unit.tooltip=Центральний процесор -metaitem.plate.high_power_integrated_circuit.name=ВСВН +metaitem.plate.high_power_integrated_circuit.name=HPIC metaitem.plate.high_power_integrated_circuit.tooltip=Вбудована схема високої напруги metaitem.plate.ultra_high_power_integrated_circuit.tooltip=Вбудована схема надвисокої напруги metaitem.plate.ultra_high_power_integrated_circuit.name=ВСНВН @@ -959,12 +959,12 @@ metaarmor.nms.nightvision.enabled=NanoMuscle™ Костюм: Увімкнено metaarmor.nms.nightvision.disabled=NanoMuscle™ Костюм: Вимкнено нічне бачення metaitem.cover.controller.tooltip=§fВКЛ/ВИКЛ§7 машину працює як §fПокращення§7. metaitem.cover.activity.detector_advanced.tooltip=Видає §fПрогрес роботи§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. -metaitem.cover.item.detector.advanced.tooltip=Видає §fСтатус зберігання предметів§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fRS-Latch§7. -metaitem.cover.energy.detector.advanced.tooltip=Дає §fRS-Latch§7 контроль за §fСтатусом енергії§7 за допомогою Редстоуну, працює як §fПокращення§7. +metaitem.cover.item.detector.advanced.tooltip=Видає §fСтатус зберігання предметів§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fРедстоун трігеру§7. +metaitem.cover.energy.detector.advanced.tooltip=Дає §fРедстоун трігеру§7 контроль за §fСтатусом енергії§7 за допомогою Редстоуну, працює як §fПокращення§7. metaitem.cover.energy.detector.name=Датчик енергії metaarmor.nms.nightvision.error=NanoMuscle™ Костюм: §cНедостатньо енергії! metaarmor.qts.nightvision.enabled=QuarkTech™ Костюм: Увімкнено нічне бачення -metaitem.cover.fluid.detector.advanced.tooltip=Видає §fСтатус зберігання рідини§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fRS-Latch§7. +metaitem.cover.fluid.detector.advanced.tooltip=Видає §fСтатус зберігання рідини§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7, з можливістю контролювати з допомогою §fРедстоун трігеру§7. metaitem.cover.energy.detector.tooltip=Видає §fКількість енергії§7 у вигляді сигналу Редстоуна, працює як §fПокращення§7. metaitem.cover.fluid.voiding.advanced.tooltip=Видаляє §fРідини§7, з контролем кількості, працює як §fПокращення§7./nАктивується за допомогою §fМ'якої киянки§7 після розміщення. metaarmor.qts.nightvision.disabled=QuarkTech™ Костюм: Вимкнено нічне бачення @@ -1077,7 +1077,7 @@ item.gt.tool.wire_cutter_iv.name=%s Кусачки (IV) item.gt.tool.tooltip.crafting_uses=§aЗалишилося застосувань: %s item.gt.tool.harvest_level.1=§7Камінь item.gt.tool.mining_hammer.tooltip=§8Видобуває велику площу за один раз (якщо тільки ви не присідаєте) -item.gt.tool.wrench_lv.name= +item.gt.tool.wrench_lv.name=%s Електроключ (LV) item.gt.tool.wrench_hv.tooltip=§8Утримуйте ЛКМ, щоб демонтувати машини item.gt.tool.buzzsaw.tooltip=§8Не підходить для добування блоків item.gt.tool.tooltip.harvest_level=§eРівень збору: %s @@ -1088,3 +1088,634 @@ metaarmor.qts.nightvision.error=QuarkTech™ Костюм: §cНедостатн gregtech.recipe_memory_widget.tooltip.2=§7Нажміть Shift, щоб заблокувати/розблокувати цей рецепт metaitem.qts.boots.name=QuarkTech™ Чоботи metaitem.tool.multiblock_builder.tooltip2=SHIFT-ПКМ по контролеру мультиблочної структури, щоб автоматично побудувати її +cover.item_filter.ignore_damage.disabled=Враховувати пошкодження +cover.ore_dictionary_filter.preview.and=все що... +cover.ore_dictionary_filter.preview.nand=все що не... +cover.ore_dictionary_filter.preview.and.entry= +cover.ore_dictionary_filter.preview.and.entry.start= +cover.ore_dictionary_filter.preview.xor=тільки одиз з... +cover.ore_dictionary_filter.preview.xnor=обидва чи нічого з... +cover.ore_dictionary_filter.preview.xor.entry= +cover.ore_dictionary_filter.preview.everything=будьщо +cover.ore_dictionary_filter.preview.impossible=(неможливо зрівняти) +cover.ore_dictionary_filter.preview.nonempty=щось +cover.ore_dictionary_filter.preview.empty=нічого +cover.ore_dictionary_filter.preview.error=ПОМИЛКА! +cover.ore_dictionary_filter.compile.eof=** Кінець рядка ** +cover.ore_dictionary_filter.compile.error.unexpected_eof=Несподіване закінчення виразу +cover.ore_dictionary_filter.compile.error.unexpected_token=Неочікуваний токен '%s' +cover.ore_dictionary_filter.compile.error.unexpected_token_after_eof=Неочікуваний токен '%s' після кінця виразу +cover.ore_dictionary_filter.compile.error.unexpected_compilation_flag=Прапори компіляції в середині виразу +cover.ore_dictionary_filter.compile.error.empty_compilation_flag=Прапори компіляції не задано +cover.ore_dictionary_filter.compile.error.unknown_compilation_flag=Невідомий прапор компіляції '%s' +cover.ore_dictionary_filter.compile.error.redundant_compilation_flag=Прапор компіляції '%s' написано двічі +cover.ore_dictionary_filter.compile.error.eof_after_escape=Кінець файлу після символу екранування ('') +cover.ore_dictionary_filter.compile.error.invalid_char=Неприпустимий символ U+%s('%s') +cover.ore_dictionary_filter.compile.warn.nested_negation=Вкладені заперечення можуть бути неінтуїтивно зрозумілими. Подумайте про використання груп ( () ) для усунення неоднозначності. +cover.ore_dictionary_filter.compile.warn.consecutive_negation=Послідовні заперечення можуть бути неінтуїтивно зрозумілими. Будь ласка, перевірте, чи бажаний результат оцінювання. +cover.fluid_filter.title=Фільтр для рідини +cover.fluid_filter.config_amount=Колесо прокрутки вгору збільшує кількість, вниз - зменшує./nShift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]/nПКМ збільшує кількість, ЛКМ зменшує./nТримайте SHIFT щоб збільшити/зменшити вдвічі./nСКМ для очищення +cover.item_filter.title=Фільтр предметів +cover.filter.mode.title=Режим фільтрації +cover.filter.mode.filter_insert=Фільтрує вхідні предмети +cover.fluid_filter.mode.filter_fill=Фільтрує вхідні рідини +cover.fluid_filter.mode.filter_drain=Фільтрує вихідні рідини +cover.fluid_filter.mode.filter_both=Фільтрує рідини на виході та вході +cover.filter.mode.filter_extract=Фільтрує вихідні предмети +cover.filter.mode.filter_both=Фільтрує предмети на виході та вході +cover.item_filter.ignore_damage.enabled=Ігнорувати пошкодження +cover.item_filter.ignore_nbt.enabled=Ігнорувати NBT +cover.item_filter.ignore_nbt.disabled=Враховувати NBT +cover.item_filter.config_amount=Прокручування колесика вгору збільшує суму, вниз зменшує.\nShift[§6x4§r], Ctrl[§ex16§r], Alt[§ax64§r]\nПКМ щоб збільшити, ЛКМ щоб зменшити.\nShift-ЛКМ щоб очистити +cover.voiding.voiding_mode.void_any=Видаляти відповідності +cover.voiding.voiding_mode.void_overflow=Видаляти надлишки +cover.voiding.voiding_mode=Режим видалення +cover.fluid.voiding.title=Налаштування видалення рідини +cover.fluid.voiding.advanced.title=Покращені налаштування видалення рідини +cover.item.voiding.title=Налаштування видалення предметів +cover.item.voiding.advanced.title=Покращені налаштування видалення предметів +cover.voiding.label.disabled=Вимкнено +cover.voiding.label.enabled=Увімкнено +cover.voiding.message.disabled=Видалення вимкнено +cover.voiding.message.enabled=Видалення увімкнено +cover.shutter.message.disabled=Затвор вимкнено +cover.shutter.message.enabled=Затвор увімкнено +cover.smart_item_filter.title=Розумний фільтр предметів +cover.smart_item_filter.filtering_mode.electrolyzer=Електролізер +cover.smart_item_filter.filtering_mode.centrifuge=Центрифуга +cover.smart_item_filter.filtering_mode.sifter=Просіювач +cover.generic.transfer_mode=Режим передавання +cover.generic.manual_io=Ручний режим вводу-виводу +cover.generic.io=Режим вводу-виводу +cover.pump.mode=Режим насоса +cover.conveyor.title=Налаштування покращення конвеєра (%s) +cover.conveyor.transfer_rate=§7 предметів/сек +cover.conveyor.mode.export=Режим: Експорт +cover.conveyor.mode.import=Режим: Імпорт +cover.conveyor.distribution.name=Режим розповсюдження +cover.conveyor.distribution.round_robin=§bЦиклічне планування§r з пріоритетом\n§7Намагається розділити предмети порівну на всі інвентарні +cover.conveyor.distribution.first_insert=§bПерша вставка§r\n§7Вставить у перший знайдений інвентар +cover.conveyor.blocks_input.disabled=Якщо увімкнено, предмети не вставлятимуться, коли покращення встановлено для витягування предметів з інвентарю у трубу./n§cВимкнено +cover.universal.manual_import_export.mode.disabled=Ручний ввід/вивід: Вимкнено +cover.universal.manual_import_export.mode.filtered=Ручний ввід/вивід: Фільтрація +cover.conveyor.item_filter.title=Фільтр предметів +cover.conveyor.ore_dictionary.title=Назва за словником руд +cover.conveyor.ore_dictionary.title2=(використовуйте * для підстановки символів) +cover.robotic_arm.title=Налаштування роботизованої руки (%s) +cover.robotic_arm.exact=§7предмети +cover.robotic_arm.transfer_mode.transfer_any=Перемістити будь-яку к-сть +cover.robotic_arm.transfer_mode.transfer_exact=Перемістити рівно +cover.robotic_arm.transfer_mode.keep_exact=Дотримуватися рівно +cover.pump.title=Налаштування для покращення помпи (%s) +cover.pump.transfer_rate=%s +cover.pump.mode.export=Режим: Експорт +cover.pump.mode.import=Режим: Імпорт +cover.bucket.mode.bucket=Режим ковша: кЛ +cover.bucket.mode.milli_bucket=Режим ковша: Л +cover.bucket.mode.bucket_rate=кЛ/с +cover.bucket.mode.bucket_exact=кЛ +cover.bucket.mode.milli_bucket_rate=Л/с +cover.bucket.mode.milli_bucket_exact=Л +cover.smart_item_filter.filtering_mode.description=Виберіть Машину, яку розумний фільтр буде використовувати для фільтрації./nВін автоматично вибере правильні порції елементів для роботизованої руки. +cover.conveyor.distribution.round_robin_enhanced=§bЦиклічне планування§r\n§7Розподіляє предмети порівну на всі інвентарні +cover.voiding.voiding_mode.description=§eВидаляти відповідності§r вилучить все, що відповідає фільтру. /n§eВидаляти надлишки§r вилучить все, що відповідає фільтру, до вказаної суми. +cover.voiding.tooltip=§cУВАГА!§7 Встановлення цього параметра на «Увімкнено» означає, що рідини або предмети БУДУТЬ видалені. +cover.conveyor.blocks_input.enabled=Якщо увімкнено, предмети не вставлятимуться, коли покращення встановлено для витягування предметів з інвентарю у трубу./n§aУвімкнено +cover.universal.manual_import_export.mode.unfiltered=Ручний ввід/вивід: Без фільтрації +cover.universal.manual_import_export.mode.description=§eВимкнено§r - Предмети/рідини переміщуватимуться лише так, як зазначено в покращенні і її фільтрі. /n§eДозволити фільтровані§r - Придмети/рідини будуть переміщуватися незалежно від налаштувань покращення, якщо його фільтр збігається (якщо наявний). /n§eДозволити нефільтровані§r - Предмети/рідини будуть переміщуватися незалежно від налаштувань покращення. Фільтр застосовується до об'єктів, вставлених або витягнутих цим покращенням +cover.fluid_regulator.title=Налаштування регулятора рідини (%s) +cover.pump.fluid_filter.title=Фільтр для рідини +death.attack.crowbar=%s відчув себе комбайном після зустрічі з %s +item.gt.tool.wrench_iv.name=%s Електроключ (IV) +cover.ore_dictionary_filter.button.match_all.enabled=Всі записи зі словника руд +cover.fluid_regulator.keep_exact=Зберігати точно: %s +cover.machine_controller.mode.cover_down=Керувати покращенням (Знизу) +cover.machine_controller.mode.cover_up=Керувати покращенням (Зверху) +cover.machine_controller.mode.cover_south=Керувати покращенням (Південь) +cover.machine_controller.mode.cover_north=Керувати покращенням (Північ) +cover.machine_controller.mode.cover_east=Керувати покращенням (Схід) +cover.machine_controller.mode.cover_west=Керувати покращенням (Захід) +cover.machine_controller.this_cover=§cЦе покращення +cover.machine_controller.cover_not_controllable=§cНе кероване покращення +cover.machine_controller.machine_not_controllable=§cМашина не керована +cover.machine_controller.control=Керування: +cover.ender_fluid_link.title=Ендовий рідиний зв'язок +gregtech.waila.energy_output=Вихід: %s EU/t +metaitem.wafer.qbit_central_processing_unit.tooltip=Необроблена кубітня схема +metaitem.wafer.integrated_logic_circuit.name=ІС Пластина +metaitem.wafer.integrated_logic_circuit.tooltip=Необроблена інтегрована схема +metaitem.rubber_drop.name=Смола +metaitem.plant_ball.name=Рослинна куля +cover.ender_fluid_link.iomode.enabled=Вхід/Вихід Увімкнено +cover.ender_fluid_link.iomode.disabled=Вхід/Вихід Вимкнено +cover.generic.ender.known_channels=Відомі канали +cover.generic.ender.set_description.tooltip=Опис +cover.generic.ender.set_description.title=Опис [%s] +cover.generic.ender.delete_entry=Видалити запис +cover.generic.advanced_detector.latched=Замкнений +cover.generic.advanced_detector.continuous=Безперервний +cover.generic.advanced_detector.latch_label=Поведінка: +cover.advanced_energy_detector.label=Покращений датчик енергії +cover.advanced_energy_detector.min=Мінімум: +cover.advanced_energy_detector.inverted=Інвертований +cover.advanced_fluid_detector.max=Максимум рідини: +item.material.oreprefix.oreBasalt=%s (Базальтова руда) +item.material.oreprefix.oreSand=%s (Піщана руда) +item.material.oreprefix.oreRedSand=%s (Червона піщана руда) +item.material.oreprefix.oreNether=%s (Пекельна руда) +item.material.oreprefix.oreEndstone=%s (Ендова руда) +item.material.oreprefix.oreEnd=%s (Ендова руда) +gregtech.waila.energy_input=Вхід: %s EU/t +metaitem.wafer.highly_advanced_system_on_chip.name=Пластина HASoC +metaitem.gelled_toluene.name=Гелеподібний толуол +item.gt.tool.behavior.torch_place=§eСпелеолог: §fРозміщення смолоскипів на ПКМ +item.gt.tool.behavior.aoe_mining=§5Зона дії: §f%sx%sx%s +item.gt.tool.behavior.crop_harvesting=§aЖниварка: §fЗбирає врожай +cover.machine_controller.enable_with_redstone=Увімкнути від Редстоуну +cover.ender_fluid_link.incomplete_hex=Введений колір неповний!/nЙого буде застосовано після завершення (всі 8 шістнадцяткових цифр)/nЯкщо ви закриєте інтерфейс, правки буде втрачено! +cover.ender_fluid_link.transfer_unit=Л/t +cover.advanced_energy_detector.max=Максимум: +cover.advanced_fluid_detector.min=Мінімально рідини: +item.gt.tool.spade.name=Заступ (%s) +metaitem.battery.charge_detailed=%,d/%,d EU - Tier %s §7(§%c%,d%s залишилось§7) +metaitem.circuit_board.wetware.name=Відмінна друкована плата +metaitem.wafer.high_power_integrated_circuit.name=Пластина HPIC +metaitem.wafer.qbit_central_processing_unit.name=Пластина кубітного процесора +metaitem.plate.qbit_central_processing_unit.name=Кубітний процесор +metaitem.plate.qbit_central_processing_unit.tooltip=Кубітовий центральний процесор +item.gt.tool.scythe.tooltip=§8Зійде для косплею смерті +item.gt.tool.wrench_hv.name=%s Електроключ (HV) +metaarmor.hud.gravi_engine=Граві-двигун: %s +cover.ore_dictionary_filter.button.match_all.disabled=Будь-який запис зі словника руд +cover.fluid_regulator.supply_exact=Постачати точно: %s +cover.machine_controller.disable_with_redstone=Вимкнути від Редстоуну +cover.ender_fluid_link.private.tooltip.disabled=Перемкнути в режим приватного резервуара\nПриватний режим використовує гравця, який поставив покращення +cover.ender_fluid_link.private.tooltip.enabled=Перемкнути в режим публічного резервуара +cover.generic.advanced_detector.invert_label=Вивід редстоуна: +cover.generic.advanced_detector.invert_tooltip=Перемкніть, щоб інвертувати логіку редстоуна +cover.advanced_energy_detector.normal=Звичайний +cover.advanced_energy_detector.modes_label=Режим: +cover.advanced_energy_detector.mode_percent=Відсоток +item.material.oreprefix.oreMarble=%s (Мармурна руда) +item.material.oreprefix.ore=%s (Руда) +gt.tool.class.grafter=Щепальний ніж +item.material.oreprefix.oreNetherrack=%s (Пекельна руда) +gregtech.waila.active_transformer.average_io=Середній Вхід/Вихід: %s EU/t +metaitem.power_thruster.name=Силовий двигун +metaitem.power_thruster_advanced.name=Покращений силовий двигун +cover.machine_controller.mode.machine=Контролює машину +cover.ore_dictionary_filter.info=§bПриймає складні вирази\n§6a & b§r = AND\n§6a | b§r = OR\n§6a ^ b§r = XOR\n§6! abc§r = NOT\n§6( abc )§r для групування\n§6*§r для підстановочного символу (тобто 0 або більше символів)\n§6?§r для будь-якого 1 символу\n§6()§r для збігу з порожнім записом (включно з елементами, для яких немає словника руд)\n§bПриклад:\n§6dust*Gold | (plate* & !*Double*)\nПідходить для будь-якого золотого пилу всіх розмірів або для всіх пластин, але не для подвійних пластин +cover.robotic_arm.transfer_mode.description=§eПередача будь-чого§r - в цьому режимі, покращення передаватеме якомога більше елементів, що відповідають його фільтру./n§eПостачати рівно§r - в цьому режимі, покращення передаватеме пропорціями які вказані у слотах фільтра (або змінною під цією кнопкою для фільтра словника руд). Якщо кількість предметів менша за розмір порції, предмети не буде переміщено. Якщо є §bРозумний фільтр предметів§r, змінна під цією кнопкою діятиме як множник./n§eЗберігати рівно§r - в цьому режимі, покращення буде зберігати вказану кулькість предметів в інвентарі призначення, поставляючи додаткову кількість предметів, якщо потрібно./n§7Порада: ЛКМ/ПКМ по слотах фільтра, щоб змінити кількість предметів, використовуйте SHIFT, щоб змінити кількість швидше. +cover.fluid_regulator.transfer_mode.description=§eПередача будь-чого§r - в цьому режимі, покращення передаватеме якомога більше рідин, що відповідають його фільтру./n§eПостачати рівно§r - в цьому режимі, покращення передаватеме пропорціями які вказані у змінній під цією кнопкою. Якщо кількість рідини менша за розмір порції, рідину не буде переміщено./n§eЗберігати рівно§r - в цьому режимі, покращення буде зберігати вказану кулькість рідин в інвентарі призначення, поставляючи додаткову кількість рідин, якщо потрібно./n§7Порада: використовуйте SHIFT та ЛКМ/ПКМ щоб змінити кількість на 10, і CTRL щоб помножити на 100. +death.attack.screwdriver=%s крутив мізки %s останій раз! +item.material.oreprefix.oreBlackgranite=%s (Чорно-гранітова руда) +item.material.oreprefix.nugget=%s (Самородок) +item.material.oreprefix.plateDense=%s (Щільна пластина) +item.material.oreprefix.gear=%s (Шестерня) +item.material.oreprefix.pipeHugeRestrictive=%s (Величезна обмежувальна труба для предметів) +item.material.oreprefix.polymer.nugget=%s (Самородок) +item.material.oreprefix.polymer.plateDense=%s (Щільний лист) +item.material.oreprefix.polymer.plateDouble=%s (Подвійний лист) +item.material.oreprefix.polymer.dustTiny=%s (Крихітна купка) +item.material.oreprefix.polymer.dust=%s (Пил) +item.material.oreprefix.polymer.ingot=%s (Злиток) +gregtech.material.actinium=Актиній +gregtech.material.aluminium=Алюміній +cover.generic.ender.open_selector=Відкрити список записів +cover.advanced_energy_detector.modes_tooltip=Перемикання між використанням точних значень EU або відсотків для порівняння мін/макс з підключеним накопичувачем енергії. +cover.advanced_energy_detector.mode_eu=Точне значення +cover.advanced_fluid_detector.label=Покращений датчик рідини +cover.advanced_item_detector.label=Покращений датчик предметів +cover.advanced_item_detector.invert_tooltip=Перемкніть, щоб інвертувати логіку редстоуну/nЗа замовчуванням, редстоун видає сигнал коли предметів менше ніж мін, і зупиняє коли значення предметів більше ніж макс +cover.advanced_item_detector.max=Максимум предметів: +cover.advanced_item_detector.min=Мінімум предметів: +cover.storage.title=Сховище (Покращення) +item.material.oreprefix.oreRedgranite=%s (Червоно-гранітова руда) +item.material.oreprefix.oreGranite=%s (Гранітова руда) +item.material.oreprefix.oreDiorite=%s (Діоритова руда) +item.material.oreprefix.oreAndesite=%s (Андезитова руда) +item.material.oreprefix.crushedCentrifuged=%s (Центрифугований руда) +item.material.oreprefix.crushedPurified=%s (Очищена руда) +item.material.oreprefix.crushed=%s (Подрібнена руда) +item.material.oreprefix.ingotHot=%s (Гарячий зливок) +item.material.oreprefix.ingot=%s (Злиток) +item.material.oreprefix.gem=%s +item.material.oreprefix.gemChipped=%s (Самородок) +item.material.oreprefix.gemFlawed=%s (Неповноцінний) +item.material.oreprefix.gemFlawless=%s (Бездоганний) +item.material.oreprefix.gemExquisite=%s (Вишуканий) +item.material.oreprefix.dustTiny=%s (Крихітна купка пилу) +item.material.oreprefix.dustSmall=%s (Маленька купка пилу) +item.material.oreprefix.dustImpure=%s (Нечиста купка пилу) +item.material.oreprefix.dustPure=%s (Очищена купка пилу) +item.material.oreprefix.dust=%s (Пил) +item.material.oreprefix.plateDouble=%s (Подвійна пластина) +item.material.oreprefix.plate=%s (Пластина) +item.material.oreprefix.plank=%s (Дошки) +item.material.oreprefix.foil=%s (Фольга) +item.material.oreprefix.stick=%s (Стержень) +item.material.oreprefix.round=%s (Куля) +item.material.oreprefix.bolt=%s (Болт) +item.material.oreprefix.screw=%s (Гвинт) +item.material.oreprefix.ring=%s (Кільце) +item.material.oreprefix.springSmall=%s (Мала пружина) +item.material.oreprefix.wireFine=%s (Тонкий дріт) +item.material.oreprefix.rotor=%s (Ротор) +item.material.oreprefix.gearSmall=%s (Маленька шестерня) +item.material.oreprefix.lens=%s (Лінза) +item.material.oreprefix.toolHeadSword=%s (Лезо меча) +item.material.oreprefix.toolHeadPickaxe=%s (Головка кайла) +item.material.oreprefix.toolHeadShovel=%s (Головка лопати) +item.material.oreprefix.toolHeadAxe=%s (Головка сокири) +item.material.oreprefix.toolHeadHoe=%s (Головка мотики) +item.material.oreprefix.toolHeadScythe=%s (Лезо коси) +item.material.oreprefix.toolHeadFile=%s (Головка напилка) +item.material.oreprefix.toolHeadHammer=%s (Головка молотка) +item.material.oreprefix.toolHeadSaw=%s (Лезо пилки) +item.material.oreprefix.toolHeadBuzzSaw=%s (Лезо пили) +item.material.oreprefix.toolHeadScrewdriver=%s (Наконечник для викрутки) +item.material.oreprefix.toolHeadDrill=%s (Наконечник для бура) +item.material.oreprefix.toolHeadChainsaw=%s (Наконечник для бензопили) +item.material.oreprefix.toolHeadWrench=%s (Наконечник гайкового ключа) +item.material.oreprefix.turbineBlade=%s (Лопатка турбіни) +item.material.oreprefix.block=%s (Блок) +item.material.oreprefix.frameGt=%s (Каркас) +item.material.oreprefix.pipeTinyFluid=%s (Крихітна трубка для рідини) +item.material.oreprefix.pipeSmallFluid=%s (Маленька труба для рідини) +item.material.oreprefix.pipeNormalFluid=%s (Труба для рідини) +item.material.oreprefix.pipeLargeFluid=%s (Велика труба для рідини) +item.material.oreprefix.pipeQuadrupleFluid=%s (Четверна труба для рідини) +item.material.oreprefix.pipeNonupleFluid=%s (Дев'ятисекційна рідинна труба) +item.material.oreprefix.pipeTinyItem=%s (Крихітна труба для предметів) +item.material.oreprefix.pipeNormalItem=%s (Труба для предметів) +item.material.oreprefix.pipeLargeItem=%s (Велика труба для предметів) +item.material.oreprefix.pipeHugeItem=%s (Величезна труба для предметів) +item.material.oreprefix.pipeSmallRestrictive=%s (Маленька обмежувальна труба для предметів) +item.material.oreprefix.pipeNormalRestrictive=%s (Обмежувальна труба для предметів) +item.material.oreprefix.pipeLargeRestrictive=%s (Велика обмежувальна труба для предметів) +item.material.oreprefix.wireGtHex=%s (16x Дріт) +item.material.oreprefix.wireGtOctal=%s (8x Дріт) +item.material.oreprefix.wireGtQuadruple=%s (4x Дріт) +item.material.oreprefix.wireGtDouble=%s (2x Wire) +item.material.oreprefix.wireGtSingle=%s (1x Дріт) +item.material.oreprefix.cableGtHex=%s (16x Кабель) +item.material.oreprefix.cableGtOctal=%s (8x Cable) +item.material.oreprefix.cableGtQuadruple=%s (4x Кабель) +item.material.oreprefix.cableGtDouble=%s (2x Кабель) +item.material.oreprefix.cableGtSingle=%s (1x Кабель) +item.material.oreprefix.polymer.plate=%s (Лист) +item.material.oreprefix.polymer.foil=%s (Тонкий лист) +cover.generic.advanced_detector.latch_tooltip=Змінити поведінку редстоуна цього покращення. /n§eБезперервний§7 - За замовчуванням; значення менше мінімального виходу 0; значення більше максимального виходу 15; значення між мінімальним і максимальним виходом від 0 до 15 /n§eЗамкнений§7 - виводити 15, поки не перевищить макс, потім виводити 0, поки не стане менше мін +cover.advanced_energy_detector.invert_tooltip=Перемкніть, щоб інвертувати логіку редстоуну/nЗа замовчуванням, редстоун видає сигнал коли енергії менше ніж мін EU, і зупиняє коли значення енергії більше ніж макс EU +item.material.oreprefix.stickLong=%s (Довгий стержень) +item.material.oreprefix.pipeHugeFluid=%s (Величезна труба для рідини) +item.material.oreprefix.spring=%s (Пружина) +item.material.oreprefix.pipeSmallItem=%s (Маленька труба для предметів) +item.material.oreprefix.pipeTinyRestrictive=%s (Крихітна обмежувальна труба для предметів) +item.material.oreprefix.polymer.dustSmall=%s (Маленька купка) +gregtech.material.naquadah_enriched=Збагачений наквада +gregtech.material.praseodymium=Празеодим +gregtech.material.promethium=Прометій +gregtech.material.protactinium=Протактиній +gregtech.material.radon=Радон +gregtech.material.radium=Радій +gregtech.material.rhenium=Реній +gregtech.material.rhodium=Родій +gregtech.material.sodium=Натрій +gregtech.material.strontium=Стронцій +gregtech.material.sulfur=Сірка +gregtech.material.tantalum=Тантал +gregtech.material.technetium=Технецій +gregtech.material.tellurium=Телур +gregtech.material.uranium=Уран +gregtech.material.emerald=Смарагд +gregtech.material.deuterium=Дейтерій +gregtech.material.dubnium=Дубній +gregtech.material.dysprosium=Диспрозій +gregtech.material.einsteinium=Ейнштейній +gregtech.material.hydrogen=Водень +gregtech.material.helium=Гелій +gregtech.material.helium_3=Гелій-3 +gregtech.material.lead=Свинець +gregtech.material.lithium=Літій +gregtech.material.lutetium=Лютецій +gregtech.material.magnesium=Магній +gregtech.material.mendelevium=Менделевій +gregtech.material.manganese=Манґан +gregtech.material.mercury=Ртуть +gregtech.material.livermorium=Ліверморій +gregtech.material.meitnerium=Майтнерій +gregtech.material.moscovium=Московій +gregtech.material.molybdenum=Молібден +gregtech.material.oxygen=Кисень +gregtech.material.osmium=Осмій +gregtech.material.palladium=Паладій +gregtech.material.duranium=Дураніум +gregtech.material.trinium=Трініум +gregtech.material.almandine=Альмандин +gregtech.material.andradite=Андрадит +gregtech.material.annealed_copper=Відпалена мідь +gregtech.material.asbestos=Азбест +gregtech.material.ash=Попіл +gregtech.material.banded_iron=Стрічкове залізо +gregtech.material.battery_alloy=Батарейний сплав +gregtech.material.blue_topaz=Синій топаз +gregtech.material.bone=Кость +gregtech.material.brass=Латунь +gregtech.material.bronze=Бронза +gregtech.material.brown_limonite=Коричновий лімоніт +gregtech.material.calcite=Кальцит +gregtech.material.cinnabar=Кіновар +gregtech.material.water=Вода +gregtech.material.coal=Вугілля +gregtech.material.cobaltite=Кобальтин +gregtech.material.cooperite=Шелдоніт +gregtech.material.cupronickel=Купронікель +gregtech.material.dark_ash=Темний попіл +gregtech.material.diamond=Діамант +gregtech.material.electrum=Електрум +gregtech.material.galena=Галеніт +gregtech.material.garnierite=Гарнієрит +gregtech.creative.energy.voltage=Вольтаж +for.bees.species.clay=Глина +gregtech.jei.ct_recipe.tooltip=Рецепт CraftTweaker +gregtech.jei.gs_recipe.tooltip=Рецепт GroovyScript +gregtech.material.darmstadtium=Дармштадтій +gregtech.material.erbium=Ербій +gregtech.material.europium=Європій +gregtech.material.fermium=Фермій +gregtech.material.flerovium=Флеровій +gregtech.material.fluorine=Фтор +gregtech.material.francium=Францій +gregtech.material.gadolinium=Гадоліній +gregtech.material.gallium=Галій +gregtech.material.germanium=Германій +gregtech.material.gold=Золото +gregtech.material.hafnium=Гафній +gregtech.material.hassium=Гасій +gregtech.material.iodine=Йод +gregtech.material.iron=Залізо +gregtech.material.krypton=Криптон +gregtech.material.lanthanum=Лантан +gregtech.material.lawrencium=Лоуренсій +gregtech.material.neodymium=Неодим +gregtech.material.neon=Неон +gregtech.material.neptunium=Нептуній +gregtech.material.nickel=Нікель +gregtech.material.nihonium=Ніхоній +gregtech.material.oganesson=Оґанесон +gregtech.material.phosphorus=Фосфор +gregtech.material.polonium=Полоній +gregtech.material.platinum=Платина +gregtech.material.plutonium=Плутоній +gregtech.material.plutonium_239=Плутоній 239 +gregtech.material.plutonium_241=Плутоній 241 +gregtech.material.potassium=Калій +gregtech.material.roentgenium=Рентгеній +gregtech.material.rubidium=Рубідій +gregtech.material.ruthenium=Рутеній +gregtech.material.rutherfordium=Резерфордій +gregtech.material.samarium=Самарій +gregtech.material.scandium=Скандій +gregtech.material.seaborgium=Сіборгій +gregtech.material.selenium=Селен +gregtech.material.silicon=Кремній +gregtech.material.silver=Срібло +gregtech.material.tennessine=Теннессин +gregtech.material.terbium=Тербій +gregtech.material.thorium=Торій +gregtech.material.thallium=Талій +gregtech.material.thulium=Тулій +gregtech.material.tin=Олово +gregtech.material.titanium=Титан +gregtech.material.tritium=Тритій +gregtech.material.tungsten=Вольфрам +gregtech.material.uranium_235=Уран 235 +gregtech.material.uranium_238=Уран 238 +gregtech.material.vanadium=Ванадій +gregtech.material.xenon=Ксенон +gregtech.material.ytterbium=Ітербій +gregtech.material.yttrium=Ітрій +gregtech.material.zinc=Цинк +gregtech.material.zirconium=Цирконій +gregtech.material.naquadah=Наквада +gregtech.material.naquadria=Наквадрія +gregtech.material.neutronium=Нейтроній +gregtech.material.tritanium=Тританій +gregtech.material.cassiterite=Каситерит +gregtech.material.cassiterite_sand=Каситеритовий пісок +gregtech.material.chalcopyrite=Халькопірит +gregtech.material.charcoal=Деревне вугілля +gregtech.material.green_sapphire=Зелений сапфір +gregtech.material.grossular=Гросуляр +for.bees.species.nitrogen=Азот +metaitem.coin.doge.tooltip=Вау скільки коінів, як багато грошей кріпта пліз я дуже богатий вау +gregtech.material.holmium=Гольмій +gregtech.material.indium=Індій +gregtech.material.niobium=Ніобій +gregtech.material.chromite=Хроміт +gregtech.material.chromium_dioxide=Діоксид хрому +gregtech.material.liquid_oxygen=Рідкий кисень +gregtech.material.iridium=Ірідіум +gregtech.material.nitrogen=Азот +gregtech.material.nobelium=Нобелій +gregtech.material.americium=Америцій +gregtech.material.antimony=Стибій +gregtech.material.astatine=Астат +gregtech.material.bromine=Бром +gregtech.material.caesium=Цезій +gregtech.material.calcium=Кальцій +gregtech.material.californium=Каліфорній +gregtech.material.carbon=Вуглець +gregtech.material.cadmium=Кадмій +gregtech.material.cerium=Церій +gregtech.material.cobalt=Кобальт +gregtech.top.quantum_status.label=Статус: +gregtech.top.quantum_status.powered=§bОнлайн +gregtech.top.quantum_status.connected=§cНемає енергії +gregtech.top.quantum_status.disconnected=Не підключено +gregtech.top.quantum_controller.no_power=§cНемає енергії +gregtech.top.steam_cooling_down=Охолодження +gregtech.material.argon=Аргон +gregtech.material.arsenic=Арсен +gregtech.material.barium=Барій +gregtech.material.berkelium=Берклій +gregtech.material.beryllium=Берилій +gregtech.material.bismuth=Бісмут +gregtech.material.bohrium=Борій +gregtech.material.boron=Бор +gregtech.material.chlorine=Хлор +gregtech.material.chrome=Хром +gregtech.material.copernicium=Коперницій +gregtech.material.copper=Мідь +gregtech.material.curium=Кюрій +gregtech.material.magnalium=Магналій +gregtech.material.niobium_nitride=Нітрид ніобію +gregtech.material.kanthal=Канталь +gregtech.material.lazurite=Лазурит +gregtech.material.liquid_helium=Рідкий гелій +gregtech.material.magnesite=Магнезит +gregtech.material.magnetite=Магнетит +gregtech.material.molybdenite=Молібденіт +gregtech.material.nichrome=Ніхром +gregtech.material.niobium_titanium=Ніобій-Титан +gregtech.material.obsidian=Обсидіан +gregtech.material.phosphate=Фосфат +gregtech.material.ice=Лід +gregtech.material.ilmenite=Ільменіт +gregtech.material.rutile=Рутил +gregtech.material.bauxite=Боксити +gregtech.material.invar=Інвар +gregtech.material.sterling_silver=Стерлінгове срібло +gregtech.material.rose_gold=Рожеве золото +gregtech.material.black_bronze=Чорна бронза +gregtech.material.bismuth_bronze=Вісмутовая бронза +gregtech.material.biotite=Біотит +gregtech.material.powellite=Повеліт +gregtech.material.pyrite=Пірит +gregtech.material.pyrolusite=Піролюзит +gregtech.material.pyrope=Піроп +gregtech.material.rock_salt=Кам'яна сіль +gregtech.material.ruridit=Руридит +gregtech.material.wulfenite=Вульфеніт +gregtech.material.rubber=Гума +gregtech.material.ruby=Рубін +gregtech.material.salt=Сіль +gregtech.material.saltpeter=Селітра +gregtech.material.aluminium_sulfite=Сульфіт алюмінію +gregtech.material.sapphire=Сапфір +gregtech.material.tin_alloy=Олов'яний сплав +gregtech.material.topaz=Топаз +gregtech.material.tungstate=Вольфрамат +gregtech.material.ultimet=Ультімет +gregtech.material.tantalite=Танталіт +gregtech.material.coke=Кокс +gregtech.material.soldering_alloy=Паяльний сплав +gregtech.material.spessartine=Спесартин +gregtech.material.sphalerite=Сфалерит +gregtech.material.stainless_steel=Нержавіюча сталь +gregtech.material.steel=Сталь +gregtech.material.stibnite=Антимоніт +gregtech.material.tetrahedrite=Тетраедрит +gregtech.material.uraninite=Уранініт +gregtech.material.uvarovite=Уваровіт +gregtech.material.vanadium_gallium=Ванадій-галій +gregtech.material.wrought_iron=Ковке залізо +gregtech.material.yellow_limonite=Жовтий лімоніт +gregtech.material.quartzite=Кварцит +gregtech.material.graphite=Графіт +gregtech.material.graphene=Графен +gregtech.material.scheelite=Шеєліт +gregtech.material.sodalite=Содаліт +gregtech.material.yttrium_barium_cuprate=Ітрій-барій купрат +gregtech.material.nether_quartz=Незерський кварц +gregtech.material.certus_quartz=Справжний кварц +gregtech.material.tungstic_acid=Вольфрамова кислота +gregtech.material.osmiridium=Осмистий іридій +gregtech.material.calcium_chloride=Хлорид кальцію +gregtech.material.lithium_chloride=Хлорид літію +gregtech.material.bornite=Борніт +gregtech.material.chalcocite=Халькозин +gregtech.material.inert_metal_mixture=Суміш інертних металів +gregtech.material.nickel_zinc_ferrite=Ферит цинко нікелю +gregtech.material.silicon_dioxide=Діоксид кремнію +gregtech.material.ferrosilite=Феросиліт +gregtech.material.iron_magnetic=Магнітне залізо +gregtech.material.carbon_dioxide=Діоксид вуглецю +gregtech.material.titanium_tetrachloride=Тетрахлорид титану +gregtech.material.nitrogen_dioxide=Діоксид азоту +gregtech.material.hydrogen_sulfide=Сірководень +gregtech.material.sulfuric_acid=Сульфатна кислота +gregtech.material.massicot=Масикот +gregtech.material.uranium_triplatinum=Триплатинауран +gregtech.material.samarium_iron_arsenic_oxide=Самарій залізо арсен оксид +gregtech.material.indium_tin_barium_titanium_cuprate=Індій олово барій титан купорос +gregtech.material.rtm_alloy=Сплав RTM +gregtech.material.zirconia=Оксид цирконію +gregtech.material.zirconium_tetrachloride=Хлорид цирконію +gregtech.material.hafnia=Гафнія +gregtech.material.platinum_group_sludge=Мул платинової групи +gregtech.material.cobalt_oxide=Оксид кобальту +gregtech.material.lepidolite=Лепідоліт +gregtech.material.tungsten_carbide=Карбід вольфраму +gregtech.material.nitric_acid=Нітратна кислота +gregtech.material.hypochlorous_acid=Гіпохлоритна кислота +gregtech.material.calcium_phosphide=Фосфід кальцію +gregtech.material.arsenic_trioxide=Триоксид арсену +gregtech.material.enriched_uranium_hexafluoride=Гексафторид збагаченого урану +gregtech.material.mercury_barium_calcium_cuprate=Ртутно-барієво-кальцієвий купорос +gregtech.material.ruthenium_tetroxide=Чотириокис рутенію +gregtech.material.zinc_sulfide=Сульфід цинку +gregtech.material.ilmenite_slag=Ільменітовий шлак +gregtech.material.hafnium_tetrachloride=Тетрахлорид гафнію +gregtech.material.zircon=Циркон +gregtech.material.gallium_arsenide=Арсенід галію +gregtech.material.potash=Карбонат калію +gregtech.material.soda_ash=Кальцинована сода +gregtech.material.indium_gallium_phosphide=Фосфід індію та галію +gregtech.material.magnesium_chloride=Хлорид магнію +gregtech.material.sodium_sulfide=Сульфід натрію +gregtech.material.phosphorus_pentoxide=Оксид фосфору +gregtech.material.quicklime=Негашене вапно +gregtech.material.sodium_bisulfate=Бісульфат натрію +gregtech.material.ferrite_mixture=Феритова суміш +gregtech.material.magnesia=Магнезія +gregtech.material.realgar=Реальгар +gregtech.material.sodium_bicarbonate=Гідрокарбонат натрію +gregtech.material.potassium_dichromate=Дихромат калію +gregtech.material.chromium_trioxide=Триоксид хрому +gregtech.material.antimony_trioxide=Сенармонтит +gregtech.material.zincite=Цинкіт +gregtech.material.cupric_oxide=Оксид міді +gregtech.material.metal_mixture=Суміш металів +gregtech.material.sodium_hydroxide=Гідроксид натрію +gregtech.material.sodium_persulfate=Персульфат натрію +gregtech.material.bastnasite=Бастнезит +gregtech.material.pentlandite=Пентландит +gregtech.material.spodumene=Сподумен +gregtech.material.glauconite_sand=Глауконітовий пісок +gregtech.material.malachite=Малахіт +gregtech.material.mica=Слюда +gregtech.material.barite=Барит +gregtech.material.alunite=Алуніт +gregtech.material.talc=Тальк +gregtech.material.soapstone=Жировик +gregtech.material.kyanite=Кіаніт +gregtech.material.phosphoric_acid=Ортофосфатна кислота +gregtech.material.sulfur_trioxide=Триоксид сірки +gregtech.material.sulfur_dioxide=Діоксид сірки +gregtech.material.carbon_monoxide=Монооксид вуглецю +gregtech.material.ammonia=Аміак +gregtech.material.hydrofluoric_acid=Флуоридна кислота +gregtech.material.nitric_oxide=Оксид азоту +gregtech.material.iron_iii_chloride=Хлорид заліза(III) +gregtech.material.uranium_hexafluoride=Гексафторид урану +gregtech.material.depleted_uranium_hexafluoride=Гексафторид збідненого урану +gregtech.material.nitrous_oxide=Оксид нітрогену +gregtech.material.ender_pearl=Перлина Енду +gregtech.material.potassium_feldspar=Польовий шпат калію +gregtech.material.neodymium_magnetic=Магніт неодимовий +gregtech.material.hydrochloric_acid=Хлоридна кислота +gregtech.material.steam=Пар +gregtech.material.distilled_water=Дистильована вода +gregtech.material.sodium_potassium=Натрій калію +gregtech.material.samarium_magnetic=Магнітний самарій +gregtech.material.manganese_phosphide=Фосфід мангану +gregtech.material.magnesium_diboride=Диборид магнію +gregtech.material.uranium_rhodium_dinaquadide=Динаквадид урану та родію +gregtech.material.enriched_naquadah_trinium_europium_duranide=Збагачений наквада-дуранід тринію європію +gregtech.material.ruthenium_trinium_americium_neutronate=Нейтронат рутенію тринію америцію +gregtech.material.platinum_raw=Необроболена платина +gregtech.material.rhodium_sulfate=Сульфат родію +gregtech.material.osmium_tetroxide=Тетроксид осмію +gregtech.material.iridium_chloride=Хлорид іридію +gregtech.material.fluoroantimonic_acid=Фторантимонова кислота +gregtech.material.titanium_trifluoride=Трифторид титану +gregtech.material.indium_phosphide=Фосфід індію +gregtech.material.barium_sulfide=Сульфід барію +gregtech.material.trinium_sulfide=Сульфід трініуму +gregtech.material.gallium_sulfide=Сульфід галію +gregtech.material.antimony_trifluoride=Трифторид стибію +gregtech.material.enriched_naquadah_sulfate=Збагачений сульфат наквади +gregtech.material.naquadria_sulfate=Сульфат наквади +gregtech.material.pyrochlore=Пірохлор From 3e35cc9fdc67c770847f4e5c6bc9832473fe134d Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:07:24 -0500 Subject: [PATCH 4/7] Allow diode blocks to be toggled (#2679) --- .../electric/MetaTileEntityDiode.java | 59 +++++++++++++++---- .../resources/assets/gregtech/lang/en_us.lang | 4 +- 2 files changed, 51 insertions(+), 12 deletions(-) diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java index 2bbf645a517..c19b1797f96 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityDiode.java @@ -1,8 +1,12 @@ package gregtech.common.metatileentities.electric; import gregtech.api.GTValues; +import gregtech.api.capability.GregtechDataCodes; +import gregtech.api.capability.GregtechTileCapabilities; +import gregtech.api.capability.IControllable; import gregtech.api.capability.IEnergyContainer; import gregtech.api.capability.impl.EnergyContainerHandler; +import gregtech.api.metatileentity.MTETrait; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; @@ -22,6 +26,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; +import net.minecraftforge.common.capabilities.Capability; import codechicken.lib.raytracer.CuboidRayTraceResult; import codechicken.lib.render.CCRenderState; @@ -34,19 +39,23 @@ import java.util.List; import static gregtech.api.capability.GregtechDataCodes.AMP_INDEX; +import static gregtech.api.capability.GregtechDataCodes.WORKING_ENABLED; public class MetaTileEntityDiode extends MetaTileEntityMultiblockPart - implements IPassthroughHatch, IMultiblockAbilityPart { + implements IPassthroughHatch, IMultiblockAbilityPart, + IControllable { protected IEnergyContainer energyContainer; private static final String AMP_NBT_KEY = "amp_mode"; private int amps; + private boolean isWorkingEnabled; public MetaTileEntityDiode(ResourceLocation metaTileEntityId, int tier) { super(metaTileEntityId, tier); amps = 1; reinitializeEnergyContainer(); + isWorkingEnabled = true; } @Override @@ -58,6 +67,7 @@ public MetaTileEntity createMetaTileEntity(IGregTechTileEntity tileEntity) { public NBTTagCompound writeToNBT(NBTTagCompound data) { super.writeToNBT(data); data.setInteger(AMP_NBT_KEY, amps); + data.setBoolean("IsWorkingEnabled", isWorkingEnabled); return data; } @@ -65,6 +75,9 @@ public NBTTagCompound writeToNBT(NBTTagCompound data) { public void readFromNBT(NBTTagCompound data) { super.readFromNBT(data); this.amps = data.getInteger(AMP_NBT_KEY); + if (data.hasKey("IsWorkingEnabled")) { + this.isWorkingEnabled = data.getBoolean("IsWorkingEnabled"); + } reinitializeEnergyContainer(); } @@ -72,12 +85,14 @@ public void readFromNBT(NBTTagCompound data) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeInt(amps); + buf.writeBoolean(isWorkingEnabled); } @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); this.amps = buf.readInt(); + this.isWorkingEnabled = buf.readBoolean(); } @Override @@ -85,6 +100,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == AMP_INDEX) { this.amps = buf.readInt(); + } else if (dataId == WORKING_ENABLED) { + this.isWorkingEnabled = buf.readBoolean(); } } @@ -120,13 +137,8 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, } @Override - public boolean isValidFrontFacing(EnumFacing facing) { - return true; - } - - @Override - public boolean onSoftMalletClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, - CuboidRayTraceResult hitResult) { + public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFacing facing, + CuboidRayTraceResult hitResult) { if (getWorld().isRemote) { scheduleRenderUpdate(); return true; @@ -153,9 +165,9 @@ public void addInformation(ItemStack stack, @Nullable World player, @NotNull Lis @Override public void addToolUsages(ItemStack stack, @Nullable World world, List tooltip, boolean advanced) { - tooltip.add(I18n.format("gregtech.tool_action.screwdriver.access_covers")); + tooltip.add(I18n.format("gregtech.machine.diode.tooltip_tool_usage_screwdriver")); tooltip.add(I18n.format("gregtech.tool_action.wrench.set_facing")); - tooltip.add(I18n.format("gregtech.tool_action.soft_mallet.toggle_mode")); + tooltip.add(I18n.format("gregtech.tool_action.soft_mallet.reset")); super.addToolUsages(stack, world, tooltip, advanced); } @@ -174,4 +186,31 @@ public void registerAbilities(@NotNull List abilityList) { public Class getPassthroughType() { return IEnergyContainer.class; } + + @Override + protected boolean shouldUpdate(MTETrait trait) { + return !(trait instanceof EnergyContainerHandler) || isWorkingEnabled; + } + + @Override + public T getCapability(Capability capability, EnumFacing side) { + if (capability == GregtechTileCapabilities.CAPABILITY_CONTROLLABLE) { + return GregtechTileCapabilities.CAPABILITY_CONTROLLABLE.cast(this); + } + + return super.getCapability(capability, side); + } + + @Override + public boolean isWorkingEnabled() { + return isWorkingEnabled; + } + + @Override + public void setWorkingEnabled(boolean isWorkingAllowed) { + this.isWorkingEnabled = isWorkingAllowed; + if (getWorld().isRemote) { + writeCustomData(GregtechDataCodes.WORKING_ENABLED, buf -> buf.writeBoolean(isWorkingAllowed)); + } + } } diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index 484c7e258ff..b7222c164cd 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -4244,9 +4244,9 @@ gregtech.machine.transformer.adjustable.opv.name=Overpowered Voltage Power Trans # Diodes gregtech.machine.diode.message=Max Amperage throughput: %s -gregtech.machine.diode.tooltip_tool_usage=Hit with a Soft Mallet to change Amperage flow. +gregtech.machine.diode.tooltip_tool_usage_screwdriver=§8Use Screwdriver to change Amperage flow or access Covers gregtech.machine.diode.tooltip_general=Allows Energy Flow in one direction and limits Amperage -gregtech.machine.diode.tooltip_starts_at=Starts as §f1A§7, use Soft Mallet to change +gregtech.machine.diode.tooltip_starts_at=Starts as §f1A§7, use Screwdriver to change gregtech.machine.diode.ulv.name=Ultra Low Voltage Diode gregtech.machine.diode.lv.name=Low Voltage Diode From 9646d3a3139dba5ab1636dc11b75d619ad81c718 Mon Sep 17 00:00:00 2001 From: Tian mi <35869948+MCTian-mi@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:08:26 +0800 Subject: [PATCH 5/7] Add terrain resist tooltips to multiblocks (#2620) --- .../api/metatileentity/MetaTileEntity.java | 5 ++++- .../api/metatileentity/TieredMetaTileEntity.java | 16 ---------------- .../electric/MetaTileEntityBlockBreaker.java | 2 +- .../electric/MetaTileEntityFisher.java | 2 +- .../electric/MetaTileEntityPump.java | 4 +--- .../MetaTileEntityLongDistanceEndpoint.java | 5 +---- .../resources/assets/gregtech/lang/en_us.lang | 2 +- 7 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index b0648610103..0ba5fd53e73 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -235,7 +235,10 @@ public void addDebugInfo(List list) {} @SideOnly(Side.CLIENT) public void addInformation(ItemStack stack, @Nullable World world, @NotNull List tooltip, - boolean advanced) {} + boolean advanced) { + if (ConfigHolder.machines.doTerrainExplosion && getIsWeatherOrTerrainResistant()) + tooltip.add(I18n.format("gregtech.universal.tooltip.terrain_resist")); + } /** * Override this to add extended tool information to the "Hold SHIFT to show Tool Info" tooltip section. diff --git a/src/main/java/gregtech/api/metatileentity/TieredMetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/TieredMetaTileEntity.java index 0c03b3bc794..3cf30dd6480 100644 --- a/src/main/java/gregtech/api/metatileentity/TieredMetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/TieredMetaTileEntity.java @@ -7,13 +7,9 @@ import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; -import gregtech.common.ConfigHolder; import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.I18n; -import net.minecraft.item.ItemStack; import net.minecraft.util.ResourceLocation; -import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -23,10 +19,6 @@ import codechicken.lib.vec.Matrix4; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.List; public abstract class TieredMetaTileEntity extends MetaTileEntity implements IEnergyChangeListener, ITieredMetaTileEntity { @@ -57,14 +49,6 @@ protected SimpleSidedCubeRenderer getBaseRenderer() { return Textures.VOLTAGE_CASINGS[tier]; } - @Override - public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, - boolean advanced) { - super.addInformation(stack, player, tooltip, advanced); - if (ConfigHolder.machines.doTerrainExplosion && getIsWeatherOrTerrainResistant()) - tooltip.add(I18n.format("gregtech.universal.tooltip.terrain_resist")); - } - @Override @SideOnly(Side.CLIENT) public Pair getParticleTexture() { diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java index b88ca1418d3..52855de6e03 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityBlockBreaker.java @@ -270,6 +270,7 @@ public boolean getIsWeatherOrTerrainResistant() { @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.block_breaker.tooltip")); tooltip.add(I18n.format("gregtech.universal.tooltip.uses_per_op", getEnergyPerBlockBreak())); tooltip.add(I18n.format("gregtech.universal.tooltip.voltage_in", energyContainer.getInputVoltage(), @@ -279,7 +280,6 @@ public void addInformation(ItemStack stack, @Nullable World player, List tooltip.add(I18n.format("gregtech.universal.tooltip.item_storage_capacity", getInventorySize())); tooltip.add(I18n.format("gregtech.machine.block_breaker.speed_bonus", (int) (getEfficiencyMultiplier() * 100))); tooltip.add(I18n.format("gregtech.universal.tooltip.requires_redstone")); - super.addInformation(stack, player, tooltip, advanced); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java index 076cc395674..d0c2f925a81 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityFisher.java @@ -142,6 +142,7 @@ public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.fisher.tooltip")); tooltip.add(I18n.format("gregtech.machine.fisher.speed", fishingTicks)); tooltip.add(I18n.format("gregtech.machine.fisher.requirement", (int) Math.sqrt(WATER_CHECK_SIZE), @@ -150,7 +151,6 @@ public void addInformation(ItemStack stack, @Nullable World player, List GTValues.VNF[getTier()])); tooltip.add( I18n.format("gregtech.universal.tooltip.energy_storage_capacity", energyContainer.getEnergyCapacity())); - super.addInformation(stack, player, tooltip, advanced); } @Override diff --git a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityPump.java b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityPump.java index 454c29bb848..d268521db3c 100644 --- a/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityPump.java +++ b/src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityPump.java @@ -11,7 +11,6 @@ import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.util.GTUtility; import gregtech.client.renderer.texture.Textures; -import gregtech.common.ConfigHolder; import net.minecraft.block.BlockLiquid; import net.minecraft.block.state.IBlockState; @@ -398,9 +397,8 @@ public void readFromNBT(NBTTagCompound data) { @Override public void addInformation(ItemStack stack, @Nullable World player, List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.pump.tooltip")); - if (ConfigHolder.machines.doTerrainExplosion) - tooltip.add(I18n.format("gregtech.universal.tooltip.terrain_resist")); tooltip.add( I18n.format("gregtech.universal.tooltip.uses_per_op", GTValues.V[getTier()] * 2) + TextFormatting.GRAY + ", " + I18n.format("gregtech.machine.pump.tooltip_buckets", getPumpingCycleLength())); diff --git a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityLongDistanceEndpoint.java b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityLongDistanceEndpoint.java index 600092ddb2b..84ce773b017 100644 --- a/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityLongDistanceEndpoint.java +++ b/src/main/java/gregtech/common/metatileentities/storage/MetaTileEntityLongDistanceEndpoint.java @@ -5,7 +5,6 @@ import gregtech.api.pipenet.longdist.ILDEndpoint; import gregtech.api.pipenet.longdist.LongDistanceNetwork; import gregtech.api.pipenet.longdist.LongDistancePipeType; -import gregtech.common.ConfigHolder; import net.minecraft.client.resources.I18n; import net.minecraft.entity.player.EntityPlayer; @@ -213,15 +212,13 @@ protected boolean openGUIOnRightClick() { @Override public void addInformation(ItemStack stack, @Nullable World player, @NotNull List tooltip, boolean advanced) { + super.addInformation(stack, player, tooltip, advanced); tooltip.add(I18n.format("gregtech.machine.endpoint.tooltip.1")); tooltip.add(I18n.format("gregtech.machine.endpoint.tooltip.2")); tooltip.add(I18n.format("gregtech.machine.endpoint.tooltip.3")); if (pipeType.getMinLength() > 0) { tooltip.add(I18n.format("gregtech.machine.endpoint.tooltip.min_length", pipeType.getMinLength())); } - if (ConfigHolder.machines.doTerrainExplosion && getIsWeatherOrTerrainResistant()) { - tooltip.add(I18n.format("gregtech.universal.tooltip.terrain_resist")); - } } @Override diff --git a/src/main/resources/assets/gregtech/lang/en_us.lang b/src/main/resources/assets/gregtech/lang/en_us.lang index b7222c164cd..639b092efac 100644 --- a/src/main/resources/assets/gregtech/lang/en_us.lang +++ b/src/main/resources/assets/gregtech/lang/en_us.lang @@ -5420,7 +5420,7 @@ gregtech.universal.tooltip.uses_per_op=Uses §f%,d EU/operation gregtech.universal.tooltip.base_production_eut=§eBase Production: §f%,d EU/t gregtech.universal.tooltip.base_production_fluid=§eBase Production: §f%,d L/t gregtech.universal.tooltip.produces_fluid=§eProduces: §f%,d L/t -gregtech.universal.tooltip.terrain_resist=This Machine will not explode when exposed to the Elements +gregtech.universal.tooltip.terrain_resist=§eThis Machine will not explode when exposed to the Elements gregtech.universal.tooltip.requires_redstone=§4Requires Redstone power gregtech.block.tooltip.no_mob_spawning=§bMobs cannot spawn on this block From d5b4f1121363179459fb93da389b8f1bbf18355a Mon Sep 17 00:00:00 2001 From: Ghzdude <44148655+ghzdude@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:33:23 -0700 Subject: [PATCH 6/7] Update MUI2 dep to RC2 (#2622) --- dependencies.gradle | 2 +- .../java/gregtech/api/cover/CoverWithUI.java | 16 +- .../java/gregtech/api/mui/GTGuiTextures.java | 1 + .../java/gregtech/api/mui/GTGuiTheme.java | 6 +- src/main/java/gregtech/api/mui/GTGuis.java | 45 ++- .../java/gregtech/api/mui/StateOverlay.java | 22 ++ src/main/java/gregtech/api/mui/UnboxFix.java | 8 + .../api/mui/sync/FixedFluidSlotSH.java | 150 -------- .../api/mui/sync/GTFluidSyncHandler.java | 320 ++++++++++++++-- .../mui/widget/GhostCircuitSlotWidget.java | 80 ++-- .../gregtech/common/covers/CoverConveyor.java | 15 +- .../common/covers/CoverFluidFilter.java | 7 +- .../common/covers/CoverFluidRegulator.java | 5 +- .../common/covers/CoverFluidVoiding.java | 9 +- .../covers/CoverFluidVoidingAdvanced.java | 5 +- .../common/covers/CoverItemFilter.java | 7 +- .../common/covers/CoverItemVoiding.java | 10 +- .../covers/CoverItemVoidingAdvanced.java | 10 +- .../common/covers/CoverMachineController.java | 10 +- .../gregtech/common/covers/CoverPump.java | 26 +- .../common/covers/CoverRoboticArm.java | 10 +- .../covers/ender/CoverAbstractEnderLink.java | 342 +++++++----------- .../covers/ender/CoverEnderFluidLink.java | 42 +-- .../common/covers/filter/BaseFilter.java | 3 +- .../covers/filter/BaseFilterContainer.java | 22 +- .../filter/OreDictionaryItemFilter.java | 19 +- .../covers/filter/SimpleFluidFilter.java | 13 +- .../covers/filter/SimpleItemFilter.java | 15 +- .../common/covers/filter/SmartItemFilter.java | 7 +- .../items/behaviors/IntCircuitBehaviour.java | 6 +- .../MetaTileEntityFluidHatch.java | 199 +++++----- .../multiblockpart/MetaTileEntityItemBus.java | 4 +- .../MetaTileEntityMultiFluidHatch.java | 58 ++- .../common/mui/widget/GTFluidSlot.java | 157 +++++--- .../mui/widget/HighlightedTextField.java | 12 +- .../common/mui/widget/InteractableText.java | 5 + .../widget/orefilter/OreFilterTestSlot.java | 4 +- .../GregTechLateMixinLoadingPlugin.java | 1 + .../mixins/jei/IngredientGridMixin.java | 30 ++ .../mixins/mui2/ClientEventHandlerMixin.java | 79 ++++ .../gregtech/mixins/mui2/ItemSlotSHMixin.java | 141 ++++++++ .../mixins/mui2/PanelSyncHandlerMixin.java | 47 +++ .../mixins/mui2/PanelSyncManagerMixin.java | 36 ++ .../gregtech/mixins/mui2/StyledTextMixin.java | 119 ++++++ .../gregtech/mixins/mui2/TextWidgetMixin.java | 57 +++ .../mixins/mui2/ToggleButtonMixin.java | 22 ++ .../gregtech/mixins/mui2/TooltipMixin.java | 100 +++++ src/main/resources/mixins.gregtech.jei.json | 17 +- src/main/resources/mixins.gregtech.mui2.json | 24 ++ 49 files changed, 1590 insertions(+), 755 deletions(-) create mode 100644 src/main/java/gregtech/api/mui/StateOverlay.java create mode 100644 src/main/java/gregtech/api/mui/UnboxFix.java delete mode 100644 src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java create mode 100644 src/main/java/gregtech/mixins/jei/IngredientGridMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/StyledTextMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java create mode 100644 src/main/java/gregtech/mixins/mui2/TooltipMixin.java create mode 100644 src/main/resources/mixins.gregtech.mui2.json diff --git a/dependencies.gradle b/dependencies.gradle index 9ccd17cb2c0..91d6a5d5c7e 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -40,7 +40,7 @@ dependencies { // Published dependencies api("codechicken:codechickenlib:3.2.3.358") - api("com.cleanroommc:modularui:2.5.0-rc1") { transitive = false } + api("com.cleanroommc:modularui:2.5.0-rc2") { transitive = false } api("com.cleanroommc:groovyscript:1.2.0-hotfix1") { transitive = false } api("CraftTweaker2:CraftTweaker2-MC1120-Main:1.12-4.1.20.700") api("appeng:ae2-uel:v0.56.4") { transitive = false } diff --git a/src/main/java/gregtech/api/cover/CoverWithUI.java b/src/main/java/gregtech/api/cover/CoverWithUI.java index d1c6fa0d0c8..6c288e08137 100644 --- a/src/main/java/gregtech/api/cover/CoverWithUI.java +++ b/src/main/java/gregtech/api/cover/CoverWithUI.java @@ -22,6 +22,7 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.screen.ModularScreen; import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.BoolValue; import com.cleanroommc.modularui.value.sync.EnumSyncValue; @@ -29,7 +30,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.ApiStatus; public interface CoverWithUI extends Cover, IUIHolder, IGuiHolder { @@ -98,12 +99,14 @@ default void markAsDirty() { /** * Create the Title bar widget for a Cover. */ - static Row createTitleRow(ItemStack stack) { - return new Row() + static Flow createTitleRow(ItemStack stack) { + return Flow.row() .pos(4, 4) .height(16).coverChildrenWidth() .child(new ItemDrawable(stack).asWidget().size(16).marginRight(4)) - .child(IKey.str(stack.getDisplayName()).color(UI_TITLE_COLOR).asWidget().heightRel(1.0f)); + .child(IKey.str(stack.getDisplayName()) + .color(UI_TITLE_COLOR) + .asWidget().heightRel(1.0f)); } /** @@ -135,6 +138,7 @@ default IKey createAdjustOverlay(boolean increment) { scale = 0.5f; } return IKey.str(builder.toString()) + .color(Color.WHITE.main) .scale(scale); } @@ -204,8 +208,8 @@ private BoolValue.Dynamic boolValueOf(EnumSyncValue syncValue, T value) { return new BoolValue.Dynamic(() -> syncValue.getValue() == value, $ -> syncValue.setValue(value)); } - public Row build() { - var row = new Row().marginBottom(2).coverChildrenHeight().widthRel(1f); + public Flow build() { + var row = Flow.row().marginBottom(2).coverChildrenHeight().widthRel(1f); if (this.enumValue != null && this.syncValue != null) { for (var enumVal : enumValue.getEnumConstants()) { var button = new ToggleButton().size(18).marginRight(2) diff --git a/src/main/java/gregtech/api/mui/GTGuiTextures.java b/src/main/java/gregtech/api/mui/GTGuiTextures.java index 4f0345f49fc..2fecf35642e 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTextures.java +++ b/src/main/java/gregtech/api/mui/GTGuiTextures.java @@ -167,6 +167,7 @@ public static class IDs { public static final UITexture[] BUTTON_MATCH_ALL = slice("textures/gui/widget/ore_filter/button_match_all.png", 16, 32, 16, 16, true); + public static final UITexture BUTTON_LOCK = fullImage("textures/gui/widget/button_lock.png"); public static final UITexture OREDICT_ERROR = fullImage("textures/gui/widget/ore_filter/error.png"); public static final UITexture OREDICT_INFO = fullImage("textures/gui/widget/ore_filter/info.png"); diff --git a/src/main/java/gregtech/api/mui/GTGuiTheme.java b/src/main/java/gregtech/api/mui/GTGuiTheme.java index 3ed22931d18..4a6c2c2d4dd 100644 --- a/src/main/java/gregtech/api/mui/GTGuiTheme.java +++ b/src/main/java/gregtech/api/mui/GTGuiTheme.java @@ -9,7 +9,7 @@ import com.cleanroommc.modularui.api.ITheme; import com.cleanroommc.modularui.api.IThemeApi; import com.cleanroommc.modularui.drawable.UITexture; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.theme.ReloadThemeEvent; import com.cleanroommc.modularui.utils.JsonBuilder; import org.jetbrains.annotations.Nullable; @@ -108,7 +108,7 @@ public static void onReloadThemes(ReloadThemeEvent.Pre event) { public static Builder templateBuilder(String themeId) { Builder builder = new Builder(themeId); builder.openCloseAnimation(0); - builder.tooltipPos(Tooltip.Pos.NEXT_TO_MOUSE); + builder.tooltipPos(RichTooltip.Pos.NEXT_TO_MOUSE); builder.smoothProgressBar(true); return builder; } @@ -163,7 +163,7 @@ public Builder smoothProgressBar(boolean smoothBar) { } /** Set the tooltip pos for this theme. Overrides global cfg. */ - public Builder tooltipPos(Tooltip.Pos tooltipPos) { + public Builder tooltipPos(RichTooltip.Pos tooltipPos) { theme.elementBuilder.add(b -> b.add("tooltipPos", tooltipPos.name())); return this; } diff --git a/src/main/java/gregtech/api/mui/GTGuis.java b/src/main/java/gregtech/api/mui/GTGuis.java index 614f6a08f1b..9f9989b2601 100644 --- a/src/main/java/gregtech/api/mui/GTGuis.java +++ b/src/main/java/gregtech/api/mui/GTGuis.java @@ -9,7 +9,6 @@ import net.minecraft.item.ItemStack; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.factory.GuiManager; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Alignment; @@ -19,6 +18,8 @@ public class GTGuis { + public static final int DEFAULT_WIDTH = 176, DEFAULT_HIEGHT = 166; + @ApiStatus.Internal public static void registerFactories() { GuiManager.registerFactory(MetaTileEntityGuiFactory.INSTANCE); @@ -39,9 +40,35 @@ public static ModularPanel createPanel(Cover cover, int width, int height) { } public static ModularPanel createPanel(ItemStack stack, int width, int height) { - MetaItem.MetaValueItem valueItem = ((MetaItem) stack.getItem()).getItem(stack); - if (valueItem == null) throw new IllegalArgumentException("Item must be a meta item!"); - return createPanel(valueItem.unlocalizedName, width, height); + String locale; + if (stack.getItem() instanceof MetaItemmetaItem) { + var valueItem = metaItem.getItem(stack); + if (valueItem == null) throw new IllegalArgumentException("Item must be a meta item!"); + locale = valueItem.unlocalizedName; + } else { + locale = stack.getTranslationKey(); + } + return createPanel(locale, width, height); + } + + public static ModularPanel createPanel(String name) { + return ModularPanel.defaultPanel(name, DEFAULT_WIDTH, DEFAULT_HIEGHT); + } + + public static ModularPanel defaultPanel(MetaTileEntity mte) { + return createPanel(mte.metaTileEntityId.getPath()); + } + + public static ModularPanel defaultPanel(Cover cover) { + return createPanel(cover.getDefinition().getResourceLocation().getPath()); + } + + public static ModularPanel defaultPanel(ItemStack stack) { + return createPanel(stack, DEFAULT_WIDTH, DEFAULT_HIEGHT); + } + + public static ModularPanel defaultPanel(MetaItem.MetaValueItem valueItem) { + return createPanel(valueItem.unlocalizedName); } public static ModularPanel createPopupPanel(String name, int width, int height) { @@ -53,6 +80,15 @@ public static ModularPanel createPopupPanel(String name, int width, int height, return new PopupPanel(name, width, height, disableBelow, closeOnOutsideClick); } + public static ModularPanel defaultPopupPanel(String name) { + return defaultPopupPanel(name, false, false); + } + + public static ModularPanel defaultPopupPanel(String name, boolean disableBelow, + boolean closeOnOutsideClick) { + return new PopupPanel(name, DEFAULT_WIDTH, DEFAULT_HIEGHT, disableBelow, closeOnOutsideClick); + } + private static class PopupPanel extends ModularPanel { private final boolean disableBelow; @@ -67,7 +103,6 @@ public PopupPanel(@NotNull String name, int width, int height, boolean disableBe .onMousePressed(mouseButton -> { if (mouseButton == 0 || mouseButton == 1) { this.closeIfOpen(true); - Interactable.playButtonClickSound(); return true; } return false; diff --git a/src/main/java/gregtech/api/mui/StateOverlay.java b/src/main/java/gregtech/api/mui/StateOverlay.java new file mode 100644 index 00000000000..fefdc7fc477 --- /dev/null +++ b/src/main/java/gregtech/api/mui/StateOverlay.java @@ -0,0 +1,22 @@ +package gregtech.api.mui; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.widgets.ToggleButton; + +import java.util.function.Consumer; + +public interface StateOverlay { + + StateOverlay overlay(boolean selected, IDrawable... overlay); + + StateOverlay hoverOverlay(boolean selected, IDrawable... overlay); + + static ToggleButton cast(ToggleButton button, Consumer function) { + function.accept((StateOverlay) button); + return button; + } + + static ToggleButton create(Consumer function) { + return cast(new ToggleButton(), function); + } +} diff --git a/src/main/java/gregtech/api/mui/UnboxFix.java b/src/main/java/gregtech/api/mui/UnboxFix.java new file mode 100644 index 00000000000..48f1bda2f20 --- /dev/null +++ b/src/main/java/gregtech/api/mui/UnboxFix.java @@ -0,0 +1,8 @@ +package gregtech.api.mui; + +public interface UnboxFix { + + void gregTech$useDefaultTextColor(boolean b); + + void gregTech$useDefaultShadow(boolean b); +} diff --git a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java b/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java deleted file mode 100644 index bf3c6c581d7..00000000000 --- a/src/main/java/gregtech/api/mui/sync/FixedFluidSlotSH.java +++ /dev/null @@ -1,150 +0,0 @@ -package gregtech.api.mui.sync; - -import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemStack; -import net.minecraft.network.PacketBuffer; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandlerItem; - -import com.cleanroommc.modularui.utils.MouseData; -import com.cleanroommc.modularui.value.sync.FluidSlotSyncHandler; -import org.jetbrains.annotations.Nullable; - -public class FixedFluidSlotSH extends FluidSlotSyncHandler { - - @Nullable - private FluidStack lastStoredPhantomFluid; - - public FixedFluidSlotSH(IFluidTank fluidTank) { - super(fluidTank); - if (this.updateCacheFromSource(true) && fluidTank.getFluid() != null) { - this.lastStoredPhantomFluid = fluidTank.getFluid().copy(); - } - } - - @Override - public void readOnServer(int id, PacketBuffer buf) { - super.readOnServer(id, buf); - if (id == 0) { - var fluid = getFluidTank().getFluid(); - if (this.lastStoredPhantomFluid == null && fluid != null || - (this.lastStoredPhantomFluid != null && !this.lastStoredPhantomFluid.isFluidEqual(fluid))) { - this.lastStoredPhantomFluid = fluid; - } - } - } - - @Override - public void setValue(@Nullable FluidStack value, boolean setSource, boolean sync) { - super.setValue(value, setSource, sync); - if (setSource) { - this.getFluidTank().drain(Integer.MAX_VALUE, true); - if (!isFluidEmpty(value)) { - this.getFluidTank().fill(value.copy(), true); - } - } - } - - @Override - public void tryClickPhantom(MouseData mouseData) { - EntityPlayer player = getSyncManager().getPlayer(); - ItemStack currentStack = player.inventory.getItemStack(); - FluidStack currentFluid = this.getFluidTank().getFluid(); - IFluidHandlerItem fluidHandlerItem = currentStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); - - if (mouseData.mouseButton == 0) { - if (currentStack.isEmpty() || fluidHandlerItem == null) { - if (this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - } else { - FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); - if ((this.controlsAmount() || currentFluid == null) && cellFluid != null) { - if (this.canFillSlot()) { - if (!this.controlsAmount()) { - cellFluid.amount = 1; - } - if (this.getFluidTank().fill(cellFluid, true) > 0) { - this.lastStoredPhantomFluid = cellFluid.copy(); - } - } - } else { - if (this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - } - } - } else if (mouseData.mouseButton == 1) { - if (this.canFillSlot()) { - if (currentFluid != null) { - if (this.controlsAmount()) { - FluidStack toFill = currentFluid.copy(); - toFill.amount = 1000; - this.getFluidTank().fill(toFill, true); - } - } else if (this.lastStoredPhantomFluid != null) { - FluidStack toFill = this.lastStoredPhantomFluid.copy(); - toFill.amount = this.controlsAmount() ? 1 : toFill.amount; - this.getFluidTank().fill(toFill, true); - } - } - } else if (mouseData.mouseButton == 2 && currentFluid != null && this.canDrainSlot()) { - this.getFluidTank().drain(mouseData.shift ? Integer.MAX_VALUE : 1000, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - } - - @Override - public void tryScrollPhantom(MouseData mouseData) { - FluidStack currentFluid = this.getFluidTank().getFluid(); - int amount = mouseData.mouseButton; - if (!this.controlsAmount()) { - var fluid = getFluidTank().getFluid(); - int newAmt = amount == 1 ? 1 : 0; - if (fluid != null && fluid.amount != newAmt) { - fluid.amount = newAmt; - setValue(fluid, true, true); - return; - } - } - if (mouseData.shift) { - amount *= 10; - } - if (mouseData.ctrl) { - amount *= 100; - } - if (mouseData.alt) { - amount *= 1000; - } - if (currentFluid == null) { - if (amount > 0 && this.lastStoredPhantomFluid != null) { - FluidStack toFill = this.lastStoredPhantomFluid.copy(); - toFill.amount = this.controlsAmount() ? amount : 1; - this.getFluidTank().fill(toFill, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - return; - } - if (amount > 0) { - FluidStack toFill = currentFluid.copy(); - toFill.amount = amount; - this.getFluidTank().fill(toFill, true); - } else if (amount < 0) { - this.getFluidTank().drain(-amount, true); - } - this.setValue(this.getFluidTank().getFluid(), false, true); - } - - @Override - public boolean controlsAmount() { - if (getFluidTank() instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { - return writableFluidTank.showAmount(); - } - return super.controlsAmount(); - } -} diff --git a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java index b5be013da18..1886be86d31 100644 --- a/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java +++ b/src/main/java/gregtech/api/mui/sync/GTFluidSyncHandler.java @@ -1,6 +1,7 @@ package gregtech.api.mui.sync; import gregtech.api.util.GTUtility; +import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; @@ -9,36 +10,117 @@ import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTank; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandlerItem; import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.utils.BooleanConsumer; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.SyncHandler; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.BooleanSupplier; +import java.util.function.Consumer; +import java.util.function.Supplier; public class GTFluidSyncHandler extends SyncHandler { - private static final int TRY_CLICK_CONTAINER = 1; + public static final int TRY_CLICK_CONTAINER = 1; + public static final int UPDATE_TANK = 2; + public static final int UPDATE_AMOUNT = 3; + public static final int PHANTOM_SCROLL = 4; + public static final int LOCK_FLUID = 5; private final IFluidTank tank; + private Consumer jeiHandler; + private BooleanConsumer lockHandler; + private Supplier lockedFluid; + private FluidStack lastFluid; + private FluidStack phantomFluid; private boolean canDrainSlot = true; private boolean canFillSlot = true; + private boolean phantom; + private BooleanSupplier showAmount = () -> true; public GTFluidSyncHandler(IFluidTank tank) { this.tank = tank; } + @Override + public void detectAndSendChanges(boolean init) { + var current = getFluid(); + if (current == null && lastFluid == null) return; + if (current == null || lastFluid == null || lastFluid.getFluid() != current.getFluid()) { + lastFluid = current == null ? null : current.copy(); + syncToClient(UPDATE_TANK, buffer -> NetworkUtils.writeFluidStack(buffer, current)); + } else if (current.amount != lastFluid.amount) { + lastFluid.amount = current.amount; + syncToClient(UPDATE_AMOUNT, buffer -> buffer.writeInt(current.amount)); + } + } + + public void lockFluid(FluidStack stack, boolean sync) { + if (!canLockFluid()) return; + this.jeiHandler.accept(stack); + if (sync) sync(LOCK_FLUID, buffer -> { + buffer.writeBoolean(stack != null); + NetworkUtils.writeFluidStack(buffer, stack); + }); + } + + public void lockFluid(boolean locked, boolean sync) { + this.lockHandler.accept(locked); + if (sync) sync(LOCK_FLUID, buffer -> { + buffer.writeBoolean(locked); + NetworkUtils.writeFluidStack(buffer, null); + }); + } + + public GTFluidSyncHandler handleLocking(Supplier lockedFluid, Consumer jeiHandler, + BooleanConsumer lockHandler) { + this.lockedFluid = lockedFluid; + this.jeiHandler = jeiHandler; + this.lockHandler = lockHandler; + return this; + } + public FluidStack getFluid() { return this.tank.getFluid(); } + public void setFluid(FluidStack fluid) { + if (tank instanceof FluidTank fluidTank) { + fluidTank.setFluid(fluid); + } else { + tank.drain(Integer.MAX_VALUE, true); + tank.fill(fluid, true); + } + if (!isPhantom() || fluid == null) return; + if (this.phantomFluid == null || this.phantomFluid.getFluid() != fluid.getFluid()) { + this.phantomFluid = fluid; + } + } + + public void setAmount(int amount) { + if (this.tank instanceof SimpleFluidFilterReader.WritableFluidTank writableFluidTank) { + writableFluidTank.setFluidAmount(amount); + return; + } + FluidStack stack = getFluid(); + if (stack == null) return; + stack.amount = amount; + } + public int getCapacity() { return this.tank.getCapacity(); } - public GTFluidSyncHandler canDrainSlot(boolean canDrainSlot) { - this.canDrainSlot = canDrainSlot; + public GTFluidSyncHandler accessibility(boolean canDrain, boolean canFill) { + this.canDrainSlot = canDrain; + this.canFillSlot = canFill; return this; } @@ -46,28 +128,183 @@ public boolean canDrainSlot() { return this.canDrainSlot; } - public GTFluidSyncHandler canFillSlot(boolean canFillSlot) { - this.canFillSlot = canFillSlot; + public boolean canFillSlot() { + return this.canFillSlot; + } + + public GTFluidSyncHandler phantom(boolean phantom) { + this.phantom = phantom; + if (phantom && this.tank.getFluid() != null) + this.phantomFluid = this.tank.getFluid().copy(); return this; } - public boolean canFillSlot() { - return this.canFillSlot; + public boolean isPhantom() { + return phantom; + } + + public GTFluidSyncHandler showAmount(boolean showAmount) { + this.showAmount = () -> showAmount; + return this; + } + + public GTFluidSyncHandler showAmount(BooleanSupplier showAmount) { + this.showAmount = showAmount; + return this; + } + + public boolean showAmount() { + if (!isPhantom() && phantomFluid != null) + return false; + return this.showAmount.getAsBoolean(); + } + + public @NotNull String getFormattedFluidAmount() { + var tankFluid = this.tank.getFluid(); + return String.format("%,d", tankFluid == null ? 0 : tankFluid.amount); + } + + public @Nullable String getFluidLocalizedName() { + var tankFluid = this.tank.getFluid(); + if (tankFluid == null && canLockFluid()) + tankFluid = this.lockedFluid.get(); + + return tankFluid == null ? null : tankFluid.getLocalizedName(); } @Override public void readOnClient(int id, PacketBuffer buf) { - if (id == TRY_CLICK_CONTAINER) { - replaceCursorItemStack(NetworkUtils.readItemStack(buf)); + switch (id) { + case TRY_CLICK_CONTAINER -> replaceCursorItemStack(NetworkUtils.readItemStack(buf)); + case UPDATE_TANK -> setFluid(NetworkUtils.readFluidStack(buf)); + case UPDATE_AMOUNT -> setAmount(buf.readInt()); + case LOCK_FLUID -> lockFluid(NetworkUtils.readFluidStack(buf), false); } } + public void handlePhantomScroll(MouseData data) { + syncToServer(PHANTOM_SCROLL, data::writeToPacket); + } + + public void handleClick(MouseData data) { + syncToServer(TRY_CLICK_CONTAINER, data::writeToPacket); + } + @Override public void readOnServer(int id, PacketBuffer buf) { if (id == TRY_CLICK_CONTAINER) { - var stack = tryClickContainer(buf.readBoolean()); - if (!stack.isEmpty()) - syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, stack)); + var data = MouseData.readPacket(buf); + if (isPhantom()) { + tryClickPhantom(data); + } else { + var stack = tryClickContainer(data.mouseButton == 0); + if (!stack.isEmpty()) + syncToClient(TRY_CLICK_CONTAINER, buffer -> NetworkUtils.writeItemStack(buffer, stack)); + } + } else if (id == UPDATE_TANK) { + var fluid = NetworkUtils.readFluidStack(buf); + setFluid(fluid); + } else if (id == PHANTOM_SCROLL) { + tryScrollPhantom(MouseData.readPacket(buf)); + } else if (id == LOCK_FLUID) { + boolean locked = buf.readBoolean(); + var fluidStack = NetworkUtils.readFluidStack(buf); + if (fluidStack == null) { + this.lockHandler.accept(locked); + } else { + this.jeiHandler.accept(fluidStack); + } + } + } + + public void tryClickPhantom(MouseData data) { + EntityPlayer player = getSyncManager().getPlayer(); + ItemStack currentStack = player.inventory.getItemStack(); + FluidStack currentFluid = this.tank.getFluid(); + if (currentStack.getCount() > 1) currentStack = GTUtility.copy(1, currentStack); + var fluidHandlerItem = FluidUtil.getFluidHandler(currentStack); + + switch (data.mouseButton) { + case 0 -> { + if (currentStack.isEmpty() || fluidHandlerItem == null) { + if (this.canDrainSlot()) { + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } else { + FluidStack cellFluid = fluidHandlerItem.drain(Integer.MAX_VALUE, false); + if ((this.showAmount.getAsBoolean() || currentFluid == null) && cellFluid != null) { + if (this.canFillSlot()) { + if (!this.showAmount.getAsBoolean()) { + cellFluid.amount = 1; + } + if (this.tank.fill(cellFluid, true) > 0) { + this.phantomFluid = cellFluid.copy(); + } + } + } else { + if (this.canDrainSlot()) { + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + } + case 1 -> { + if (this.canFillSlot()) { + if (currentFluid != null) { + if (this.showAmount.getAsBoolean()) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = 1000; + this.tank.fill(toFill, true); + } + } else if (this.phantomFluid != null) { + FluidStack toFill = this.phantomFluid.copy(); + toFill.amount = this.showAmount.getAsBoolean() ? 1 : toFill.amount; + this.tank.fill(toFill, true); + } + } + } + case 2 -> { + if (currentFluid != null && canDrainSlot()) + this.tank.drain(data.shift ? Integer.MAX_VALUE : 1000, true); + } + } + } + + public void tryScrollPhantom(MouseData mouseData) { + FluidStack currentFluid = this.tank.getFluid(); + int amount = mouseData.mouseButton; + if (!this.showAmount()) { + int newAmt = amount == 1 ? 1 : 0; + if (newAmt == 0) { + setFluid(null); + } else if (currentFluid != null && currentFluid.amount != newAmt) { + setAmount(newAmt); + } + return; + } + if (mouseData.shift) { + amount *= 10; + } + if (mouseData.ctrl) { + amount *= 100; + } + if (mouseData.alt) { + amount *= 1000; + } + if (currentFluid == null) { + if (amount > 0 && this.phantomFluid != null) { + FluidStack toFill = this.phantomFluid.copy(); + toFill.amount = this.showAmount() ? amount : 1; + this.tank.fill(toFill, true); + } + return; + } + if (amount > 0) { + FluidStack toFill = currentFluid.copy(); + toFill.amount = amount; + this.tank.fill(toFill, true); + } else if (amount < 0) { + this.tank.drain(-amount, true); } } @@ -77,8 +314,7 @@ public ItemStack tryClickContainer(boolean tryFillAll) { return ItemStack.EMPTY; ItemStack useStack = GTUtility.copy(1, playerHeldStack); - IFluidHandlerItem fluidHandlerItem = useStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + var fluidHandlerItem = FluidUtil.getFluidHandler(useStack); if (fluidHandlerItem == null) return ItemStack.EMPTY; FluidStack tankFluid = tank.getFluid(); @@ -88,20 +324,24 @@ public ItemStack tryClickContainer(boolean tryFillAll) { if (tankFluid == null && heldFluid == null) return ItemStack.EMPTY; + ItemStack returnable = ItemStack.EMPTY; + // tank is empty, try to fill tank if (canFillSlot && tankFluid == null) { - return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + returnable = fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); // hand is empty, try to drain tank } else if (canDrainSlot && heldFluid == null) { - return drainTankFromStack(fluidHandlerItem, tankFluid, tryFillAll); + returnable = drainTankIntoStack(fluidHandlerItem, tankFluid, tryFillAll); // neither is empty but tank is not full, try to fill tank } else if (canFillSlot && tank.getFluidAmount() < tank.getCapacity() && heldFluid != null) { - return fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); + returnable = fillTankFromStack(fluidHandlerItem, heldFluid, tryFillAll); } - return ItemStack.EMPTY; + syncToClient(UPDATE_TANK, buffer -> NetworkUtils.writeFluidStack(buffer, tank.getFluid())); + + return returnable; } private ItemStack fillTankFromStack(IFluidHandlerItem fluidHandler, @NotNull FluidStack heldFluid, @@ -141,30 +381,31 @@ private ItemStack fillTankFromStack(IFluidHandlerItem fluidHandler, @NotNull Flu return itemStackEmptied; } - private ItemStack drainTankFromStack(IFluidHandlerItem fluidHandler, FluidStack tankFluid, boolean tryFillAll) { + private ItemStack drainTankIntoStack(IFluidHandlerItem fluidHandler, FluidStack tankFluid, boolean tryFillAll) { ItemStack heldItem = getSyncManager().getCursorItem(); if (heldItem.isEmpty()) return ItemStack.EMPTY; - ItemStack fluidContainer = fluidHandler.getContainer(); + ItemStack fluidContainer = ItemStack.EMPTY; int filled = fluidHandler.fill(tankFluid, false); + int stored = tankFluid.amount; if (filled > 0) { - tank.drain(filled, true); fluidHandler.fill(tankFluid, true); + tank.drain(filled, true); + fluidContainer = fluidHandler.getContainer(); if (tryFillAll) { // Determine how many more items we can fill. One item is already filled. // Integer division means it will round down, so it will only fill equivalent fluid amounts. // For example: // Click with 3 cells, with 2500L of fluid in the tank. // 2 cells will be filled, and 500L will be left behind in the tank. - int additional = Math.min(heldItem.getCount(), tankFluid.amount / filled) - 1; + int additional = Math.min(heldItem.getCount(), stored / filled) - 1; tank.drain(filled * additional, true); fluidContainer.grow(additional); } replaceCursorItemStack(fluidContainer); playSound(tankFluid, false); - return fluidContainer; } - return ItemStack.EMPTY; + return fluidContainer; } /** @@ -221,4 +462,33 @@ private void playSound(FluidStack fluid, boolean fill) { player.world.playSound(null, player.posX, player.posY + 0.5, player.posZ, soundEvent, SoundCategory.PLAYERS, 1.0F, 1.0F); } + + public FluidStack getPhantomFluid() { + return isPhantom() ? phantomFluid : null; + } + + public FluidStack getLockedFluid() { + return !isPhantom() && canLockFluid() ? lockedFluid.get() : null; + } + + public boolean canLockFluid() { + return jeiHandler != null && lockHandler != null && lockedFluid != null; + } + + public void toggleLockFluid() { + var cursorItem = getSyncManager().getCursorItem(); + if (getLockedFluid() == null) { + if (cursorItem.isEmpty()) return; + if (cursorItem.getCount() > 1) cursorItem = GTUtility.copy(1, cursorItem); + + var fluidHandler = FluidUtil.getFluidHandler(cursorItem); + if (fluidHandler == null) return; + + var fluidStack = fluidHandler.getTankProperties()[0].getContents(); + if (fluidStack == null) return; + lockFluid(fluidStack.copy(), true); + } else if (cursorItem.isEmpty()) { + lockFluid(null, true); + } + } } diff --git a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java index 448740e7147..aa692fd8583 100644 --- a/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java +++ b/src/main/java/gregtech/api/mui/widget/GhostCircuitSlotWidget.java @@ -6,17 +6,16 @@ import gregtech.api.recipes.ingredients.IntCircuitIngredient; import gregtech.client.utils.TooltipHelper; -import net.minecraft.item.ItemStack; import net.minecraft.network.PacketBuffer; -import net.minecraft.util.text.TextComponentTranslation; import net.minecraftforge.items.IItemHandler; import com.cleanroommc.modularui.api.IPanelHandler; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.screen.ModularScreen; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.value.sync.ItemSlotSH; import com.cleanroommc.modularui.widgets.ButtonWidget; @@ -27,7 +26,6 @@ import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class GhostCircuitSlotWidget extends ItemSlot { @@ -35,6 +33,7 @@ public class GhostCircuitSlotWidget extends ItemSlot { private static final int SYNC_CIRCUIT_INDEX = 10; public GhostCircuitSlotWidget() { + super(); tooltipBuilder(this::getCircuitSlotTooltip); } @@ -67,21 +66,15 @@ public ItemSlot slot(ModularSlot slot) { return this; } - @Override - protected List getItemTooltip(ItemStack stack) { - // we don't want the item tooltip - return Collections.emptyList(); - } - - protected void getCircuitSlotTooltip(@NotNull Tooltip tooltip) { + protected void getCircuitSlotTooltip(@NotNull RichTooltip tooltip) { String configString; int value = getSyncHandler().getGhostCircuitHandler().getCircuitValue(); if (value == GhostCircuitItemStackHandler.NO_CONFIG) { - configString = new TextComponentTranslation("gregtech.gui.configurator_slot.no_value").getFormattedText(); + configString = IKey.lang("gregtech.gui.configurator_slot.no_value").get(); } else { configString = String.valueOf(value); } - + tooltip.clearText(); tooltip.addLine(IKey.lang("gregtech.gui.configurator_slot.tooltip", configString)); } @@ -105,37 +98,38 @@ private boolean isSelectorPanelOpen() { private void createSelectorPanel() { ItemDrawable circuitPreview = new ItemDrawable(getSyncHandler().getSlot().getStack()); - List> options = new ArrayList<>(); - for (int i = 0; i < 4; i++) { - options.add(new ArrayList<>()); - for (int j = 0; j < 9; j++) { - int index = i * 9 + j; - if (index > 32) break; - options.get(i).add(new ButtonWidget<>() - .size(18) - .background(GTGuiTextures.SLOT, new ItemDrawable( - IntCircuitIngredient.getIntegratedCircuit(index)).asIcon()) - .disableHoverBackground() - .onMousePressed(mouseButton -> { - getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index)); - circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index)); - return true; - })); + IPanelHandler.simple(getPanel(), (mainPanel, player) -> { + var panel = GTGuis.createPopupPanel("circuit_selector", 176, 120); + List> options = new ArrayList<>(); + for (int i = 0; i < 4; i++) { + options.add(new ArrayList<>()); + for (int j = 0; j < 9; j++) { + int index = i * 9 + j; + if (index > 32) break; + options.get(i).add(new ButtonWidget<>() + .size(18) + .background(GTGuiTextures.SLOT, new ItemDrawable( + IntCircuitIngredient.getIntegratedCircuit(index)).asIcon()) + .disableHoverBackground() + .onMousePressed(mouseButton -> { + getSyncHandler().syncToServer(SYNC_CIRCUIT_INDEX, buf -> buf.writeShort(index)); + circuitPreview.setItem(IntCircuitIngredient.getIntegratedCircuit(index)); + if (Interactable.hasShiftDown()) panel.animateClose(); + return true; + })); + } } - } - - IPanelHandler.simple(getPanel(), (mainPanel, player) -> GTGuis.createPopupPanel("circuit_selector", 176, 120) - .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) - .child(circuitPreview.asIcon().size(16).asWidget() - .size(18) - .top(19).alignX(0.5f) - .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) - .child(new Grid() - .left(7).right(7).top(41).height(4 * 18) - .matrix(options) - .minColWidth(18).minRowHeight(18) - .minElementMargin(0, 0))) - .openPanel(); + return panel.child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) + .child(circuitPreview.asIcon().size(16).asWidget() + .size(18) + .top(19).alignX(0.5f) + .background(GTGuiTextures.SLOT, GTGuiTextures.INT_CIRCUIT_OVERLAY)) + .child(new Grid() + .left(7).right(7).top(41).height(4 * 18) + .matrix(options) + .minColWidth(18).minRowHeight(18) + .minElementMargin(0, 0)); + }, true).openPanel(); } private static class GhostCircuitSyncHandler extends ItemSlotSH { diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 798c0000e8c..1fa4e43dffe 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -45,6 +45,7 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -55,8 +56,7 @@ import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.IntArrayList; @@ -510,12 +510,12 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan getItemFilterContainer().setMaxTransferSize(getMaxStackSize()); return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createUI(panel, guiSyncManager)) + .child(createUI(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { - var column = new Column().top(24).margin(7, 0) + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { + var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); EnumSyncValue manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, @@ -525,7 +525,6 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager this::getConveyorMode, this::setConveyorMode); IntSyncValue throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - throughput.updateCacheFromSource(true); StringSyncValue formattedThroughput = new StringSyncValue(throughput::getStringValue, throughput::setStringValue); @@ -539,7 +538,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager.syncValue("throughput", throughput); if (createThroughputRow()) - column.child(new Row().coverChildrenHeight() + column.child(Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ButtonWidget<>() .left(0).width(18) @@ -567,7 +566,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); if (createFilterRow()) - column.child(getItemFilterContainer().initUI(mainPanel, guiSyncManager)); + column.child(getItemFilterContainer().initUI(data, guiSyncManager)); if (createManualIOModeRow()) column.child(new EnumRowBuilder<>(ManualImportExportMode.class) diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index 85b39ca1a9d..a0b6585ebd7 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -43,8 +43,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -154,13 +153,13 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return getFilter().createPanel(guiSyncManager) .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack())) - .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(Flow.column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(FluidFilterMode.class) .value(filteringMode) .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) - .child(new Row() + .child(Flow.row() .marginBottom(2) .widthRel(1f) .coverChildrenHeight() diff --git a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java index 27122cdfa7a..141b51e0552 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidRegulator.java +++ b/src/main/java/gregtech/common/covers/CoverFluidRegulator.java @@ -20,6 +20,7 @@ import net.minecraftforge.fml.relauncher.SideOnly; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -247,7 +248,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); transferMode.updateCacheFromSource(true); syncManager.syncValue("transfer_mode", transferMode); @@ -259,7 +260,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync var filterTransferSize = new StringSyncValue(this::getStringTransferRate, this::setStringTransferRate); filterTransferSize.updateCacheFromSource(true); - return super.createUI(mainPanel, syncManager) + return super.createUI(data, syncManager) .child(new EnumRowBuilder<>(TransferMode.class) .value(transferMode) .lang("cover.generic.transfer_mode") diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index c6aa519660c..4bd8472b55f 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -25,6 +25,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -32,7 +33,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverFluidVoiding extends CoverPump { @@ -76,11 +77,11 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); - return super.createUI(mainPanel, syncManager) - .child(new Row().height(18).widthRel(1f) + return super.createUI(data, syncManager) + .child(Flow.row().height(18).widthRel(1f) .marginBottom(2) .child(new ToggleButton() .value(isWorking) diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index 80b7bb45564..b6a9e1cd1e5 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -20,6 +20,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -105,7 +106,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); syncManager.syncValue("voiding_mode", voidingMode); @@ -118,7 +119,7 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync transferTextField.setEnabled(this.fluidFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW); - return super.createUI(mainPanel, syncManager) + return super.createUI(data, syncManager) .child(new EnumRowBuilder<>(VoidingMode.class) .value(voidingMode) .lang("cover.voiding.voiding_mode") diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index 18e6432bc07..8c667ad8ce7 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -42,8 +42,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,13 +155,13 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return getFilter().createPanel(guiSyncManager) .size(176, 212).padding(7) .child(CoverWithUI.createTitleRow(getFilterContainer().getFilterStack()).left(4)) - .child(new Column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() + .child(Flow.column().widthRel(1f).align(Alignment.TopLeft).top(22).coverChildrenHeight() .child(new EnumRowBuilder<>(ItemFilterMode.class) .value(filteringMode) .lang("cover.filter.mode.title") .overlay(16, GTGuiTextures.FILTER_MODE_OVERLAY) .build()) - .child(new Row() + .child(Flow.row() .marginBottom(2) .widthRel(1f) .coverChildrenHeight() diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index 35a64252725..e8129ec11f3 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -22,6 +22,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -29,8 +30,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; public class CoverItemVoiding extends CoverConveyor { @@ -78,11 +78,11 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { var isWorking = new BooleanSyncValue(this::isWorkingEnabled, this::setWorkingEnabled); - return super.createUI(mainPanel, guiSyncManager) - .child(new Row().height(18).widthRel(1f) + return super.createUI(data, guiSyncManager) + .child(Flow.row().height(18).widthRel(1f) .marginBottom(2) .child(new ToggleButton() .value(isWorking) diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index 4a062735ae3..b739e7e6e1f 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -17,6 +17,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -24,8 +25,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -94,7 +94,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { var voidingMode = new EnumSyncValue<>(VoidingMode.class, this::getVoidingMode, this::setVoidingMode); guiSyncManager.syncValue("voiding_mode", voidingMode); @@ -106,13 +106,13 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager transferTextField.setEnabled(this.itemFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW); - return super.createUI(mainPanel, guiSyncManager) + return super.createUI(data, guiSyncManager) .child(new EnumRowBuilder<>(VoidingMode.class) .value(voidingMode) .lang("cover.voiding.voiding_mode") .overlay(16, GTGuiTextures.VOIDING_MODE_OVERLAY) .build()) - .child(new Row().right(0).coverChildrenHeight() + .child(Flow.row().right(0).coverChildrenHeight() .child(transferTextField .setEnabledIf(w -> this.itemFilterContainer.showGlobalTransferLimitSlider() && this.voidingMode == VoidingMode.VOID_OVERFLOW) diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 2626d8f3acd..545f3cde52e 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -32,7 +32,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -121,7 +121,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan return GTGuis.createPanel(this, 176, 112) .child(CoverWithUI.createTitleRow(getPickItem())) - .child(new Column() + .child(Flow.column() .widthRel(1.0f).margin(7, 0) .top(24).coverChildrenHeight() @@ -151,7 +151,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan // Controlling selector .child(createSettingsRow().height(16 + 2 + 16) - .child(new Column().heightRel(1.0f).coverChildrenWidth() + .child(Flow.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))) @@ -169,8 +169,8 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan .right(0)))); } - private Column modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { - return new Column().coverChildrenHeight().width(18) + private Flow modeColumn(EnumSyncValue syncValue, ControllerMode mode, IKey title) { + return Flow.column().coverChildrenHeight().width(18) .child(title.asWidget().size(16).marginBottom(2).alignment(Alignment.Center)) .child(modeButton(syncValue, mode)); } diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index 2fdb55e2cdd..b57e5a33545 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -43,6 +43,7 @@ import com.cleanroommc.modularui.api.drawable.IDrawable; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.DynamicDrawable; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -53,8 +54,7 @@ import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; import com.cleanroommc.modularui.widgets.ButtonWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -196,41 +196,36 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan getFluidFilterContainer().setMaxTransferSize(getMaxTransferRate()); return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createUI(panel, guiSyncManager)) + .child(createUI(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager syncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager syncManager) { var manualIOmode = new EnumSyncValue<>(ManualImportExportMode.class, this::getManualImportExportMode, this::setManualImportExportMode); - manualIOmode.updateCacheFromSource(true); var throughput = new IntSyncValue(this::getTransferRate, this::setTransferRate); - throughput.updateCacheFromSource(true); var throughputString = new StringSyncValue( - throughput::getStringValue, - throughput::setStringValue); - throughputString.updateCacheFromSource(true); + throughput::getStringValue, throughput::setStringValue); var pumpMode = new EnumSyncValue<>(PumpMode.class, this::getPumpMode, this::setPumpMode); - pumpMode.updateCacheFromSource(true); syncManager.syncValue("manual_io", manualIOmode); syncManager.syncValue("pump_mode", pumpMode); syncManager.syncValue("throughput", throughput); - var column = new Column().top(24).margin(7, 0) + var column = Flow.column().top(24).margin(7, 0) .widthRel(1f).coverChildrenHeight(); if (createThroughputRow()) - column.child(new Row().coverChildrenHeight() + column.child(Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ButtonWidget<>() .left(0).width(18) .onMousePressed(mouseButton -> { int val = throughput.getValue() - getIncrementValue(MouseData.create(mouseButton)); - throughput.setValue(val, true, true); + throughput.setValue(val); Interactable.playButtonClickSound(); return true; }) @@ -245,15 +240,14 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager sync .right(0).width(18) .onMousePressed(mouseButton -> { int val = throughput.getValue() + getIncrementValue(MouseData.create(mouseButton)); - throughput.setValue(val, true, true); + throughput.setValue(val); Interactable.playButtonClickSound(); return true; }) .onUpdateListener(w -> w.overlay(createAdjustOverlay(true))))); if (createFilterRow()) - column.child(getFluidFilterContainer() - .initUI(mainPanel, syncManager)); + column.child(getFluidFilterContainer().initUI(data, syncManager)); if (createManualIOModeRow()) column.child(new EnumRowBuilder<>(ManualImportExportMode.class) diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 22047e6db2e..b1b99657adf 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -19,6 +19,7 @@ import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.utils.Color; @@ -26,8 +27,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widget.ParentWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; @@ -197,7 +197,7 @@ public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncMan } @Override - protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager guiSyncManager) { + protected ParentWidget createUI(GuiData data, PanelSyncManager guiSyncManager) { EnumSyncValue transferMode = new EnumSyncValue<>(TransferMode.class, this::getTransferMode, this::setTransferMode); guiSyncManager.syncValue("transfer_mode", transferMode); @@ -207,13 +207,13 @@ protected ParentWidget createUI(ModularPanel mainPanel, PanelSyncManager s -> this.itemFilterContainer.setTransferSize(Integer.parseInt(s))); filterTransferSize.updateCacheFromSource(true); - return super.createUI(mainPanel, guiSyncManager) + return super.createUI(data, guiSyncManager) .child(new EnumRowBuilder<>(TransferMode.class) .value(transferMode) .lang("cover.generic.transfer_mode") .overlay(GTGuiTextures.TRANSFER_MODE_OVERLAY) .build()) - .child(new Row().right(0).coverChildrenHeight() + .child(Flow.row().right(0).coverChildrenHeight() .child(new TextFieldWidget().widthRel(0.5f).right(0) .setEnabledIf(w -> shouldDisplayAmountSlider()) .setNumbers(0, Integer.MAX_VALUE) diff --git a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java index eb5c6a81d9d..53701cacd6b 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverAbstractEnderLink.java @@ -30,6 +30,7 @@ import com.cleanroommc.modularui.drawable.DynamicDrawable; import com.cleanroommc.modularui.drawable.GuiTextures; import com.cleanroommc.modularui.drawable.Rectangle; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.factory.SidedPosGuiData; import com.cleanroommc.modularui.network.NetworkUtils; import com.cleanroommc.modularui.screen.ModularPanel; @@ -38,19 +39,17 @@ import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.StringSyncValue; +import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.ListWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Row; import com.cleanroommc.modularui.widgets.textfield.TextFieldWidget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.lwjgl.input.Keyboard; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Objects; import java.util.Set; import java.util.UUID; @@ -141,18 +140,20 @@ public boolean usesMui2() { public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager) { var panel = GTGuis.createPanel(this, 176, 192); + this.playerUUID = guiData.getPlayer().getUniqueID(); + return panel.child(CoverWithUI.createTitleRow(getPickItem())) - .child(createWidgets(panel, guiSyncManager)) + .child(createWidgets(guiData, guiSyncManager)) .bindPlayerInventory(); } - protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { var name = new StringSyncValue(this::getColorStr, this::updateColor); - var entrySelectorSH = createEntrySelector(panel); - syncManager.syncValue("entry_selector", entrySelectorSH); + // todo unneeded cast in mui2 rc3 + var entrySelectorSH = (PanelSyncHandler) syncManager.panel("entry_selector", entrySelector(getType()), true); - return new Column().coverChildrenHeight().top(24) + return Flow.column().coverChildrenHeight().top(24) .margin(7, 0).widthRel(1f) .child(new Row().marginBottom(2) .coverChildrenHeight() @@ -176,18 +177,14 @@ protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) } else { entrySelectorSH.openPanel(); } - Interactable.playButtonClickSound(); return true; }))) .child(createIoRow()); } - protected abstract PanelSyncHandler createEntrySelector(ModularPanel panel); - protected abstract IWidget createEntrySlot(); protected IWidget createColorIcon() { - // todo color selector popup panel return new DynamicDrawable(() -> new Rectangle() .setColor(this.activeEntry.getColor()) .asIcon().size(16)) @@ -198,10 +195,8 @@ protected IWidget createColorIcon() { } protected IWidget createPrivateButton() { - var isPrivate = new BooleanSyncValue(this::isPrivate, this::setPrivate); - isPrivate.updateCacheFromSource(true); - return new ToggleButton() + .value(new BooleanSyncValue(this::isPrivate, this::setPrivate)) .tooltip(tooltip -> tooltip.setAutoUpdate(true)) .background(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) .hoverBackground(GTGuiTextures.PRIVATE_MODE_BUTTON[0]) @@ -210,17 +205,14 @@ protected IWidget createPrivateButton() { .tooltipBuilder(tooltip -> tooltip.addLine(IKey.lang(this.isPrivate ? "cover.ender_fluid_link.private.tooltip.enabled" : "cover.ender_fluid_link.private.tooltip.disabled"))) - .marginRight(2) - .value(isPrivate); + .marginRight(2); } protected IWidget createIoRow() { - var ioEnabled = new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled); - - return new Row().marginBottom(2) + return Flow.row().marginBottom(2) .coverChildrenHeight() .child(new ToggleButton() - .value(ioEnabled) + .value(new BooleanSyncValue(this::isIoEnabled, this::setIoEnabled)) .overlay(IKey.dynamic(() -> IKey.lang(this.ioEnabled ? "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled").get()) @@ -291,45 +283,16 @@ public void writeToNBT(@NotNull NBTTagCompound nbt) { nbt.setInteger("Frequency", activeEntry.getColor()); } - protected abstract class EntrySelectorSH extends PanelSyncHandler { - - private static final int TRACK_SUBPANELS = 3; - private static final int DELETE_ENTRY = 1; - private final EntryTypes type; - private final ModularPanel mainPanel; - private static final String PANEL_NAME = "entry_selector"; - private final Set opened = new HashSet<>(); - protected UUID playerUUID; - - protected EntrySelectorSH(ModularPanel mainPanel, EntryTypes type) { - super(mainPanel, EntrySelectorSH::defaultPanel); - this.type = type; - this.mainPanel = mainPanel; - } - - @Override - public void init(String key, PanelSyncManager syncManager) { - super.init(key, syncManager); - this.playerUUID = syncManager.getPlayer().getUniqueID(); - } - - private static ModularPanel defaultPanel(PanelSyncManager syncManager, PanelSyncHandler syncHandler) { - return GTGuis.createPopupPanel(PANEL_NAME, 168, 112); - } - - public UUID getPlayerUUID() { - return isPrivate ? playerUUID : null; - } - - @Override - public ModularPanel createUI(PanelSyncManager syncManager) { - List names = new ArrayList<>(VirtualEnderRegistry.getEntryNames(getPlayerUUID(), type)); - return super.createUI(syncManager) + protected PanelSyncHandler.IPanelBuilder entrySelector(EntryTypes type) { + return (syncManager, syncHandler) -> { + Set names = VirtualEnderRegistry.getEntryNames(getOwner(), type); + return GTGuis.createPopupPanel("entry_selector", 168, 112) .child(IKey.lang("cover.generic.ender.known_channels") - .color(UI_TITLE_COLOR).asWidget() + .color(UI_TITLE_COLOR) + .asWidget() .top(6) .left(4)) - .child(ListWidget.builder(names, name -> createRow(name, this.mainPanel, syncManager)) + .child(ListWidget.builder(names, name -> createRow(name, syncManager, type)) .background(GTGuiTextures.DISPLAY.asIcon() .width(168 - 8) .height(112 - 20)) @@ -337,177 +300,122 @@ public ModularPanel createUI(PanelSyncManager syncManager) { .size(168 - 12, 112 - 24) .left(4) .bottom(6)); - } + }; + } - protected IWidget createRow(String name, ModularPanel mainPanel, PanelSyncManager syncManager) { - T entry = VirtualEnderRegistry.getEntry(getPlayerUUID(), this.type, name); - String key = String.format("entry#%s_description", entry.getColorStr()); - var entryDescriptionSH = new EntryDescriptionSH(mainPanel, key, entry); - syncManager.syncValue(key, isPrivate ? 1 : 0, entryDescriptionSH); - - return new Row() - .left(4) - .marginBottom(2) - .height(18) - .widthRel(0.98f) - .setEnabledIf(row -> VirtualEnderRegistry.hasEntry(getOwner(), this.type, name)) - .child(new Rectangle() - .setColor(entry.getColor()) + protected PanelSyncHandler.IPanelBuilder entryDescription(String key, T entry) { + return (syncManager, syncHandler) -> { + var sync = new StringSyncValue(entry::getDescription, entry::setDescription); + return GTGuis.createPopupPanel(key, 168, 36 + 6) + .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) + .color(UI_TITLE_COLOR) .asWidget() - .marginRight(4) - .size(16) - .background(GTGuiTextures.SLOT.asIcon().size(18)) - .top(1)) - .child(new InteractableText<>(entry, CoverAbstractEnderLink.this::updateColor) - .tooltip(tooltip -> tooltip.setAutoUpdate(true)) - .tooltipBuilder(tooltip -> { - String desc = entry.getDescription(); - if (!desc.isEmpty()) - tooltip.addLine(desc); - }) - .width(64) - .height(16) - .top(1) - .marginRight(4)) - .child(new ButtonWidget<>() - .overlay(GuiTextures.GEAR) - .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) - .onMousePressed(i -> { - // open entry settings - if (entryDescriptionSH.isPanelOpen()) { - entryDescriptionSH.closePanel(); - } else { - entryDescriptionSH.openPanel(); + .left(4) + .top(6)) + .child(new TextFieldWidget() { + + // todo move this to new class? + @Override + public @NotNull Result onKeyPressed(char character, int keyCode) { + var result = super.onKeyPressed(character, keyCode); + if (result == Result.SUCCESS && keyCode == Keyboard.KEY_RETURN) { + sync.setStringValue(getText()); + if (syncHandler.isPanelOpen()) { + syncHandler.closePanel(); } - Interactable.playButtonClickSound(); - return true; - })) - .child(createSlotWidget(entry)) - .child(new ButtonWidget<>() - .overlay(GTGuiTextures.BUTTON_CROSS) - .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) - .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) - .onMousePressed(i -> { - // todo option to force delete, maybe as a popup? - deleteEntry(getPlayerUUID(), name); - syncToServer(1, buffer -> { - NetworkUtils.writeStringSafe(buffer, getPlayerUUID().toString()); - NetworkUtils.writeStringSafe(buffer, name); - }); - Interactable.playButtonClickSound(); - return true; - })); - } + } + return result; + } + }.setTextColor(Color.WHITE.darker(1)) + .value(sync) + .widthRel(0.95f) + .height(18) + .alignX(0.5f) + .bottom(6)); + }; + } - @Override - public void closePanel() { - var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); - for (var key : opened) { - if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { - psh.closePanel(); - } - } - super.closePanel(); - } + protected IWidget createRow(final String name, final PanelSyncManager syncManager, final EntryTypes type) { + final T entry = VirtualEnderRegistry.getEntry(getOwner(), type, name); + var key = String.format("entry#%s_description", entry.getColorStr()); + var syncKey = PanelSyncManager.makeSyncKey(key, isPrivate ? 1 : 0); + final var panelHandler = (PanelSyncHandler) syncManager.panel(syncKey, + entryDescription(key, entry), true); + final var syncHandler = new EnderCoverSyncHandler(); + syncManager.syncValue(key + "_handler", syncHandler); + + return Flow.row() + .left(4) + .marginBottom(2) + .height(18) + .widthRel(0.98f) + .setEnabledIf(row -> VirtualEnderRegistry.hasEntry(getOwner(), type, name)) + .child(new Rectangle() + .setColor(entry.getColor()) + .asWidget() + .marginRight(4) + .size(16) + .background(GTGuiTextures.SLOT.asIcon().size(18)) + .top(1)) + .child(new InteractableText<>(entry, this::updateColor) + .tooltip(tooltip -> tooltip.setAutoUpdate(true)) + .tooltipBuilder(tooltip -> { + String desc = entry.getDescription(); + if (!desc.isEmpty()) tooltip.add(desc); + }) + .width(64) + .height(16) + .top(1) + .marginRight(4)) + .child(new ButtonWidget<>() + .overlay(GuiTextures.GEAR) + .addTooltipLine(IKey.lang("cover.generic.ender.set_description.tooltip")) + .onMousePressed(i -> { + // open entry settings + if (panelHandler.isPanelOpen()) { + panelHandler.closePanel(); + } else { + panelHandler.openPanel(); + } + return true; + })) + .child(createSlotWidget(entry)) + .child(new ButtonWidget<>() + .overlay(GTGuiTextures.BUTTON_CROSS) + .setEnabledIf(w -> !Objects.equals(entry.getColor(), activeEntry.getColor())) + .addTooltipLine(IKey.lang("cover.generic.ender.delete_entry")) + .onMousePressed(i -> { + // todo option to force delete, maybe as a popup? + deleteEntry(getOwner(), name); + syncHandler.syncToServer(1, buffer -> { + NetworkUtils.writeStringSafe(buffer, + getOwner() == null ? "null" : getOwner().toString()); + NetworkUtils.writeStringSafe(buffer, name); + }); + Interactable.playButtonClickSound(); + return true; + })); + } - @Override - @SuppressWarnings("UnstableApiUsage") - public void closePanelInternal() { - var manager = getSyncManager().getModularSyncManager().getPanelSyncManager(PANEL_NAME); - for (var key : opened) { - if (manager.getSyncHandler(key) instanceof PanelSyncHandler psh) { - psh.closePanel(); - } - } - super.closePanelInternal(); - } + protected abstract IWidget createSlotWidget(T entry); + + protected abstract void deleteEntry(UUID player, String name); + + private final class EnderCoverSyncHandler extends SyncHandler { + + private static final int DELETE_ENTRY = 1; @Override - public void readOnClient(int i, PacketBuffer packetBuffer) throws IOException { - if (i == TRACK_SUBPANELS) { - handleTracking(packetBuffer); - } - super.readOnClient(i, packetBuffer); - } + public void readOnClient(int i, PacketBuffer packetBuffer) {} @Override - public void readOnServer(int i, PacketBuffer packetBuffer) throws IOException { - if (i == TRACK_SUBPANELS) { - handleTracking(packetBuffer); - } - super.readOnServer(i, packetBuffer); + public void readOnServer(int i, PacketBuffer packetBuffer) { if (i == DELETE_ENTRY) { - UUID uuid = UUID.fromString(NetworkUtils.readStringSafe(packetBuffer)); + var s = NetworkUtils.readStringSafe(packetBuffer); + UUID uuid = "null".equals(s) ? null : UUID.fromString(s); String name = NetworkUtils.readStringSafe(packetBuffer); deleteEntry(uuid, name); } } - - private void handleTracking(PacketBuffer buffer) { - boolean add = buffer.readBoolean(); - String key = NetworkUtils.readStringSafe(buffer); - if (key != null) { - if (add) opened.add(key); - else opened.remove(key); - } - } - - private class EntryDescriptionSH extends PanelSyncHandler { - - /** - * Creates a PanelSyncHandler - * - * @param mainPanel the main panel of the current GUI - */ - public EntryDescriptionSH(ModularPanel mainPanel, String key, VirtualEntry entry) { - super(mainPanel, (syncManager, syncHandler) -> defaultPanel(syncHandler, key, entry)); - } - - private static ModularPanel defaultPanel(@NotNull PanelSyncHandler syncHandler, String key, - VirtualEntry entry) { - return GTGuis.createPopupPanel(key, 168, 36 + 6) - .child(IKey.lang("cover.generic.ender.set_description.title", entry.getColorStr()) - .color(UI_TITLE_COLOR) - .asWidget() - .left(4) - .top(6)) - .child(new TextFieldWidget() - .setTextColor(Color.WHITE.darker(1)) - .widthRel(0.95f) - .height(18) - .value(new StringSyncValue(entry::getDescription, string -> { - entry.setDescription(string); - if (syncHandler.isPanelOpen()) { - syncHandler.closePanel(); - } - })) - .alignX(0.5f) - .bottom(6)); - } - - @Override - public void openPanel() { - opened.add(getKey()); - EntrySelectorSH.this.sync(3, buffer -> { - buffer.writeBoolean(true); - NetworkUtils.writeStringSafe(buffer, getKey()); - }); - super.openPanel(); - } - - @Override - public void closePanel() { - opened.remove(getKey()); - EntrySelectorSH.this.sync(3, buffer -> { - buffer.writeBoolean(false); - NetworkUtils.writeStringSafe(buffer, getKey()); - }); - super.closePanel(); - } - } - - protected abstract IWidget createSlotWidget(T entry); - - protected abstract void deleteEntry(UUID player, String name); } } diff --git a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java index 27c338154b1..4c373dfd41c 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java @@ -29,11 +29,10 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.value.sync.EnumSyncValue; -import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -119,27 +118,20 @@ public CoverPump.PumpMode getPumpMode() { } @Override - protected PanelSyncHandler createEntrySelector(ModularPanel panel) { - return new EntrySelectorSH(panel, EntryTypes.ENDER_FLUID) { + protected IWidget createSlotWidget(VirtualTank entry) { + var fluidTank = GTFluidSlot.sync(entry) + .accessibility(false, false); - @Override - protected IWidget createSlotWidget(VirtualTank entry) { - var fluidTank = GTFluidSlot.sync(entry) - .canFillSlot(false) - .canDrainSlot(false); - - return new GTFluidSlot() - .size(18) - .background(GTGuiTextures.FLUID_SLOT) - .syncHandler(fluidTank) - .marginRight(2); - } + return new GTFluidSlot() + .size(18) + .background(GTGuiTextures.FLUID_SLOT) + .syncHandler(fluidTank) + .marginRight(2); + } - @Override - protected void deleteEntry(UUID uuid, String name) { - VirtualEnderRegistry.deleteEntry(uuid, getType(), name, tank -> tank.getFluidAmount() == 0); - } - }; + @Override + protected void deleteEntry(UUID uuid, String name) { + VirtualEnderRegistry.deleteEntry(uuid, getType(), name, tank -> tank.getFluidAmount() == 0); } @Override @@ -151,15 +143,15 @@ protected IWidget createEntrySlot() { .marginRight(2); } - protected Column createWidgets(ModularPanel panel, PanelSyncManager syncManager) { + protected Flow createWidgets(GuiData data, PanelSyncManager syncManager) { getFluidFilterContainer().setMaxTransferSize(1); var pumpMode = new EnumSyncValue<>(CoverPump.PumpMode.class, this::getPumpMode, this::setPumpMode); syncManager.syncValue("pump_mode", pumpMode); pumpMode.updateCacheFromSource(true); - return super.createWidgets(panel, syncManager) - .child(getFluidFilterContainer().initUI(panel, syncManager)) + return super.createWidgets(data, syncManager) + .child(getFluidFilterContainer().initUI(data, syncManager)) .child(new EnumRowBuilder<>(CoverPump.PumpMode.class) .value(pumpMode) .overlay(GTGuiTextures.CONVEYOR_MODE_OVERLAY) diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilter.java b/src/main/java/gregtech/common/covers/filter/BaseFilter.java index 27f6a56bccb..b0a312b6e1e 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilter.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilter.java @@ -144,7 +144,8 @@ public IWidget createBlacklistUI() { .value(new BooleanSyncValue( this::isBlacklistFilter, this::setBlacklistFilter)) - .textureGetter(state -> GTGuiTextures.BUTTON_BLACKLIST[state]) + .stateBackground(0, GTGuiTextures.BUTTON_BLACKLIST[0]) + .stateBackground(1, GTGuiTextures.BUTTON_BLACKLIST[1]) .addTooltip(0, IKey.lang("cover.filter.blacklist.disabled")) .addTooltip(1, IKey.lang("cover.filter.blacklist.enabled"))); } diff --git a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java index 38867b542bf..7bb6c7473e3 100644 --- a/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java +++ b/src/main/java/gregtech/common/covers/filter/BaseFilterContainer.java @@ -1,5 +1,6 @@ package gregtech.common.covers.filter; +import gregtech.api.cover.CoverWithUI; import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.IDirtyNotifiable; @@ -11,16 +12,15 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; -import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiTextures; -import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.factory.GuiData; import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.value.sync.PanelSyncHandler; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.value.sync.SyncHandlers; import com.cleanroommc.modularui.widgets.ButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -212,17 +212,14 @@ public void handleLegacyNBT(NBTTagCompound nbt) { } /** Uses Cleanroom MUI */ - public IWidget initUI(ModularPanel main, PanelSyncManager manager) { - PanelSyncHandler panel = manager.panel("filter_panel", main, (syncManager, syncHandler) -> { + public IWidget initUI(GuiData data, PanelSyncManager manager) { + PanelSyncHandler panel = (PanelSyncHandler) manager.panel("filter_panel", (syncManager, syncHandler) -> { var filter = hasFilter() ? getFilter() : BaseFilter.ERROR_FILTER; filter.setMaxTransferSize(getMaxTransferSize()); return filter.createPopupPanel(syncManager); - }); + }, true); - var filterButton = new ButtonWidget<>(); - filterButton.setEnabled(hasFilter()); - - return new Row().coverChildrenHeight() + return Flow.row().coverChildrenHeight() .marginBottom(2).widthRel(1f) .child(new ItemSlot() .slot(SyncHandlers.itemSlot(this, 0) @@ -235,7 +232,7 @@ public IWidget initUI(ModularPanel main, PanelSyncManager manager) { })) .size(18).marginRight(2) .background(GTGuiTextures.SLOT, GTGuiTextures.FILTER_SLOT_OVERLAY.asIcon().size(16))) - .child(filterButton + .child(new ButtonWidget<>() .background(GTGuiTextures.MC_BUTTON, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) .hoverBackground(GuiTextures.MC_BUTTON_HOVERED, GTGuiTextures.FILTER_SETTINGS_OVERLAY.asIcon().size(16)) @@ -246,10 +243,11 @@ public IWidget initUI(ModularPanel main, PanelSyncManager manager) { } else { panel.closePanel(); } - Interactable.playButtonClickSound(); return true; })) .child(IKey.dynamic(this::getFilterName) + .color(CoverWithUI.UI_TEXT_COLOR) + .shadow(false) .alignment(Alignment.CenterRight).asWidget() .left(36).right(0).height(18)); } diff --git a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java index 0eec589f555..0d91fd97cf8 100644 --- a/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/OreDictionaryItemFilter.java @@ -20,7 +20,7 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.drawable.UITexture; import com.cleanroommc.modularui.screen.ModularPanel; -import com.cleanroommc.modularui.screen.Tooltip; +import com.cleanroommc.modularui.screen.RichTooltip; import com.cleanroommc.modularui.utils.BooleanConsumer; import com.cleanroommc.modularui.utils.Color; import com.cleanroommc.modularui.value.sync.BooleanSyncValue; @@ -29,8 +29,7 @@ import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.CycleButtonWidget; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -112,7 +111,7 @@ public void initUI(Consumer widgetGroup) {} var caseSensitive = new BooleanSyncValue(this.filterReader::isCaseSensitive, setCaseSensitive); var matchAll = new BooleanSyncValue(this.filterReader::shouldMatchAll, setMatchAll); - return new Column().widthRel(1f).coverChildrenHeight() + return Flow.column().widthRel(1f).coverChildrenHeight() .child(new HighlightedTextField() .setHighlightRule(this::highlightRule) .onUnfocus(() -> { @@ -123,9 +122,9 @@ public void initUI(Consumer widgetGroup) {} .setTextColor(Color.WHITE.darker(1)) .value(expression).marginBottom(4) .height(18).widthRel(1f)) - .child(new Row().coverChildrenHeight() + .child(Flow.row().coverChildrenHeight() .widthRel(1f) - .child(new Column().height(18) + .child(Flow.column().height(18) .coverChildrenWidth().marginRight(2) .child(GTGuiTextures.OREDICT_INFO.asWidget() .size(8).top(0) @@ -148,7 +147,8 @@ public void initUI(Consumer widgetGroup) {} .child(new CycleButtonWidget() .size(18).value(caseSensitive) .marginRight(2) - .textureGetter(state -> GTGuiTextures.BUTTON_CASE_SENSITIVE[state]) + .stateBackground(0, GTGuiTextures.BUTTON_CASE_SENSITIVE[0]) + .stateBackground(1, GTGuiTextures.BUTTON_CASE_SENSITIVE[1]) .addTooltip(0, IKey.lang("cover.ore_dictionary_filter.button.case_sensitive.disabled")) .addTooltip(1, @@ -156,7 +156,8 @@ public void initUI(Consumer widgetGroup) {} .child(new CycleButtonWidget() .size(18).value(matchAll) .marginRight(2) - .textureGetter(state -> GTGuiTextures.BUTTON_MATCH_ALL[state]) + .stateBackground(0, GTGuiTextures.BUTTON_MATCH_ALL[0]) + .stateBackground(1, GTGuiTextures.BUTTON_MATCH_ALL[1]) .addTooltip(0, IKey.lang("cover.ore_dictionary_filter.button.match_all.disabled")) .addTooltip(1, @@ -180,7 +181,7 @@ protected void getStatusIcon(Widget widget) { widget.background(texture); } - protected void createStatusTooltip(Tooltip tooltip) { + protected void createStatusTooltip(RichTooltip tooltip) { var result = this.filterReader.getResult(); if (result == null) return; List list = new ArrayList<>(); diff --git a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java index ed2b3a40eaf..b36acc61283 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleFluidFilter.java @@ -2,8 +2,8 @@ import gregtech.api.cover.CoverWithUI; import gregtech.api.mui.GTGuis; -import gregtech.api.mui.sync.FixedFluidSlotSH; import gregtech.common.covers.filter.readers.SimpleFluidFilterReader; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; @@ -11,9 +11,8 @@ import com.cleanroommc.modularui.screen.ModularPanel; import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; -import com.cleanroommc.modularui.widgets.FluidSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -53,13 +52,15 @@ public void configureFilterTanks(int amount) { @Override public @NotNull Widget createWidgets(PanelSyncManager syncManager) { - return new Row().coverChildrenHeight().widthRel(1f) + return Flow.row().coverChildrenHeight().widthRel(1f) .child(SlotGroupWidget.builder() .matrix("FFF", "FFF", "FFF") - .key('F', i -> new FluidSlot() - .syncHandler(new FixedFluidSlotSH(filterReader.getFluidTank(i)).phantom(true))) + .key('F', i -> new GTFluidSlot() + .syncHandler(GTFluidSlot.sync(filterReader.getFluidTank(i)) + .phantom(true) + .showAmount(getFilterReader()::shouldShowAmount))) .build().marginRight(4)) .child(createBlacklistUI()); } diff --git a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java index 4eaf4ffc865..d69e6de7649 100644 --- a/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SimpleItemFilter.java @@ -26,8 +26,7 @@ import com.cleanroommc.modularui.widgets.CycleButtonWidget; import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.slot.SlotGroup; import org.jetbrains.annotations.NotNull; @@ -114,7 +113,7 @@ public void initUI(Consumer widgetGroup) { syncManager.registerSlotGroup(filterInventory); - return new Row().coverChildren() + return Flow.row().coverChildren() .child(SlotGroupWidget.builder() .matrix("XXX", "XXX", @@ -134,7 +133,7 @@ public void initUI(Consumer widgetGroup) { .getInteger(SimpleItemFilterReader.COUNT); if (count > 0) tooltip.addLine( - IKey.format("Count: %s", TextFormattingUtil.formatNumbers(count))); + IKey.str("Count: %s", TextFormattingUtil.formatNumbers(count))); } }) .slot(SyncHandlers.phantomItemSlot(this.filterReader, index) @@ -146,16 +145,18 @@ public void initUI(Consumer widgetGroup) { } }))) .build().marginRight(4)) - .child(new Column().width(18).coverChildren() + .child(Flow.column().width(18).coverChildren() .child(createBlacklistUI()) .child(new CycleButtonWidget() .value(ignoreDamage) - .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_DAMAGE[state]) + .stateBackground(0, GTGuiTextures.BUTTON_IGNORE_DAMAGE[0]) + .stateBackground(1, GTGuiTextures.BUTTON_IGNORE_DAMAGE[1]) .addTooltip(0, IKey.lang("cover.item_filter.ignore_damage.disabled")) .addTooltip(1, IKey.lang("cover.item_filter.ignore_damage.enabled"))) .child(new CycleButtonWidget() .value(ignoreNBT) - .textureGetter(state -> GTGuiTextures.BUTTON_IGNORE_NBT[state]) + .stateBackground(0, GTGuiTextures.BUTTON_IGNORE_NBT[0]) + .stateBackground(1, GTGuiTextures.BUTTON_IGNORE_NBT[1]) .addTooltip(0, IKey.lang("cover.item_filter.ignore_nbt.disabled")) .addTooltip(1, IKey.lang("cover.item_filter.ignore_nbt.enabled")))); } diff --git a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java index 425189b7de2..d7cbf29c463 100644 --- a/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java +++ b/src/main/java/gregtech/common/covers/filter/SmartItemFilter.java @@ -22,8 +22,7 @@ import com.cleanroommc.modularui.value.sync.PanelSyncManager; import com.cleanroommc.modularui.widget.Widget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; -import com.cleanroommc.modularui.widgets.layout.Row; +import com.cleanroommc.modularui.widgets.layout.Flow; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -115,8 +114,8 @@ public void initUI(Consumer widgetGroup) { filterReader::setFilteringMode); syncManager.syncValue("filter_mode", filterMode); - return new Row().coverChildren() - .child(new Column().coverChildren().marginRight(4) + return Flow.row().coverChildren() + .child(Flow.column().coverChildren().marginRight(4) .child(createFilterModeButton(filterMode, SmartFilteringMode.ELECTROLYZER)) .child(createFilterModeButton(filterMode, SmartFilteringMode.CENTRIFUGE)) .child(createFilterModeButton(filterMode, SmartFilteringMode.SIFTER))) diff --git a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java index 5a7091e838e..f7523d976d1 100644 --- a/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java +++ b/src/main/java/gregtech/common/items/behaviors/IntCircuitBehaviour.java @@ -21,6 +21,7 @@ import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.IWidget; +import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.ItemDrawable; import com.cleanroommc.modularui.factory.HandGuiData; import com.cleanroommc.modularui.screen.ModularPanel; @@ -65,6 +66,7 @@ public ActionResult onItemRightClick(World world, EntityPlayer player @Override public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager) { + var panel = GTGuis.createPanel(guiData.getUsedItemStack(), 176, 120); ItemDrawable circuitPreview = new ItemDrawable(guiData.getUsedItemStack()); for (int i = 0; i <= 32; i++) { int finalI = i; @@ -73,6 +75,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager ItemStack item = IntCircuitIngredient.getIntegratedCircuit(finalI); item.setCount(guiData.getUsedItemStack().getCount()); circuitPreview.setItem(item); + if (Interactable.hasShiftDown()) panel.animateClose(); guiData.getPlayer().setHeldItem(guiData.getHand(), item); })); } @@ -91,8 +94,7 @@ public ModularPanel buildUI(HandGuiData guiData, PanelSyncManager guiSyncManager .syncHandler("config", index)); } } - return GTGuis.createPanel(guiData.getUsedItemStack(), 176, 120) - .child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) + return panel.child(IKey.lang("metaitem.circuit.integrated.gui").asWidget().pos(5, 5)) .child(circuitPreview.asIcon().size(16).asWidget() .size(18) .top(19).alignX(0.5f) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java index 8cf7c4f2e6a..935d40d451f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityFluidHatch.java @@ -4,33 +4,28 @@ import gregtech.api.capability.impl.FilteredItemHandler; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.NotifiableFluidTank; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.ModularUI.Builder; -import gregtech.api.gui.widgets.*; import gregtech.api.items.itemhandlers.GTItemStackHandler; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; -import gregtech.api.util.GTUtility; +import gregtech.api.mui.GTGuiTextures; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.metatileentities.storage.MetaTileEntityQuantumTank; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; -import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidUtil; import net.minecraftforge.fluids.IFluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -38,16 +33,28 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.value.sync.BooleanSyncValue; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.ItemSlot; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; -import java.util.function.Consumer; public class MetaTileEntityFluidHatch extends MetaTileEntityMultiblockNotifiablePart implements IMultiblockAbilityPart, IControllable { public static final int INITIAL_INVENTORY_SIZE = 8000; + public static final int LOCK_FILL = GregtechDataCodes.assignId(); // only holding this for convenience protected final HatchFluidTank fluidTank; @@ -161,6 +168,8 @@ public void receiveCustomData(int dataId, PacketBuffer buf) { super.receiveCustomData(dataId, buf); if (dataId == GregtechDataCodes.WORKING_ENABLED) { this.workingEnabled = buf.readBoolean(); + } else if (dataId == LOCK_FILL) { + this.lockedFluid = NetworkUtils.readFluidStack(buf); } } @@ -212,93 +221,85 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { - return createTankUI(fluidTank, getMetaFullName(), entityPlayer).build(getHolder(), entityPlayer); + public boolean usesMui2() { + return true; } - public ModularUI.Builder createTankUI(IFluidTank fluidTank, String title, EntityPlayer entityPlayer) { - // Create base builder/widget references - Builder builder = ModularUI.defaultBuilder(); - TankWidget tankWidget; - - // Add input/output-specific widgets - if (isExportHatch) { - tankWidget = new PhantomTankWidget(fluidTank, 69, 43, 18, 18, - () -> this.lockedFluid, - f -> { - if (this.fluidTank.getFluidAmount() != 0) { - return; - } - if (f == null) { - this.setLocked(false); - this.lockedFluid = null; - } else { - this.setLocked(true); - this.lockedFluid = f.copy(); - this.lockedFluid.amount = 1; - } - }) - .setAlwaysShowFull(true).setDrawHoveringText(false); - - builder.image(7, 16, 81, 46, GuiTextures.DISPLAY) - .widget(new SlotWidget(exportItems, 0, 90, 44, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)) - .widget(new ToggleButtonWidget(7, 64, 18, 18, - GuiTextures.BUTTON_LOCK, this::isLocked, this::setLocked) - .setTooltipText("gregtech.gui.fluid_lock.tooltip") - .shouldUseBaseBackground()); - } else { - tankWidget = new TankWidget(fluidTank, 69, 52, 18, 18) - .setAlwaysShowFull(true).setDrawHoveringText(false); - - builder.image(7, 16, 81, 55, GuiTextures.DISPLAY) - .widget(new ImageWidget(91, 36, 14, 15, GuiTextures.TANK_ICON)) - .widget(new SlotWidget(exportItems, 0, 90, 53, true, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.OUT_SLOT_OVERLAY)); - } - - // Add general widgets - return builder.label(6, 6, title) - .label(11, 20, "gregtech.gui.fluid_amount", 0xFFFFFF) - .widget(new AdvancedTextWidget(11, 30, getFluidAmountText(tankWidget), 0xFFFFFF)) - .widget(new AdvancedTextWidget(11, 40, getFluidNameText(tankWidget), 0xFFFFFF)) - .widget(tankWidget) - .widget(new FluidContainerSlotWidget(importItems, 0, 90, 16, false) - .setBackgroundTexture(GuiTextures.SLOT, GuiTextures.IN_SLOT_OVERLAY)) - .bindPlayerInventory(entityPlayer.inventory); - } - - protected Consumer> getFluidNameText(TankWidget tankWidget) { - return (list) -> { - TextComponentTranslation translation = tankWidget.getFluidTextComponent(); - // If there is no fluid in the tank, but there is a locked fluid - if (translation == null) { - translation = GTUtility.getFluidTranslation(this.lockedFluid); - } - - if (translation != null) { - list.add(translation); - } - }; - } - - protected Consumer> getFluidAmountText(TankWidget tankWidget) { - return (list) -> { - String fluidAmount = ""; - - // Nothing in the tank - if (tankWidget.getFormattedFluidAmount().equals("0")) { - // Display Zero to show information about the locked fluid - if (this.lockedFluid != null) { - fluidAmount = "0"; - } - } else { - fluidAmount = tankWidget.getFormattedFluidAmount(); - } - if (!fluidAmount.isEmpty()) { - list.add(new TextComponentString(fluidAmount)); - } - }; + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { + var fluidSyncHandler = GTFluidSlot.sync(fluidTank) + .showAmount(false) + .accessibility(true, !isExportHatch) + .handleLocking(() -> this.lockedFluid, fluidStack -> { + setLocked(fluidStack != null); + this.lockedFluid = fluidStack; + this.fluidTank.onContentsChanged(); + }, this::setLocked); + + return GTGuis.createPanel(this, 176, 166) + .child(IKey.lang(getMetaFullName()).asWidget().pos(6, 6)) + + // export specific + .childIf(isExportHatch, new ItemSlot() + .pos(90, 44) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .slot(new ModularSlot(exportItems, 0) + .accessibility(false, true))) + .childIf(isExportHatch, new ToggleButton() + .pos(7, 63) + .overlay(GTGuiTextures.BUTTON_LOCK) + // todo doing things this way causes flickering if it fails + // due to sync value cache + .value(new BooleanSyncValue(this::isLocked, b -> fluidSyncHandler.lockFluid(b, false))) + .addTooltip(true, IKey.lang("gregtech.gui.fluid_lock.tooltip.enabled")) + .addTooltip(false, IKey.lang("gregtech.gui.fluid_lock.tooltip.disabled"))) + + // import specific + .childIf(!isExportHatch, GTGuiTextures.TANK_ICON.asWidget() + .pos(91, 36) + .size(14, 15)) + .childIf(!isExportHatch, new ItemSlot() + .pos(90, 53) + .background(GTGuiTextures.SLOT, GTGuiTextures.OUT_SLOT_OVERLAY) + .slot(new ModularSlot(exportItems, 0) + .accessibility(false, true))) + + // common ui + .child(new RichTextWidget() + .size(81 - 6, (isExportHatch ? 46 : 55) - 8) + // .padding(3, 4) + .background(GTGuiTextures.DISPLAY.asIcon().size(81, isExportHatch ? 46 : 55)) + .pos(7 + 3, 16 + 4) + .textColor(Color.WHITE.main) + .alignment(Alignment.TopLeft) + .autoUpdate(true) + .textBuilder(richText -> { + richText.addLine(IKey.lang("gregtech.gui.fluid_amount")); + String name = fluidSyncHandler.getFluidLocalizedName(); + if (name == null) return; + if (name.length() > 25) name = name.substring(0, 25) + "..."; + + richText.addLine(IKey.str(name)); + richText.addLine(IKey.str(fluidSyncHandler.getFormattedFluidAmount())); + })) + .child(new GTFluidSlot() + .disableBackground() + .pos(69, isExportHatch ? 43 : 52) + .size(18) + .syncHandler(fluidSyncHandler)) + .child(new ItemSlot() + .pos(90, 16) + .background(GTGuiTextures.SLOT, GTGuiTextures.IN_SLOT_OVERLAY) + .slot(new ModularSlot(importItems, 0) + .singletonSlotGroup() + .filter(stack -> { + if (!isExportHatch) return true; + var h = FluidUtil.getFluidHandler(stack); + if (h == null) return false; + return h.getTankProperties()[0].getContents() == null; + }) + .accessibility(true, true))) + .bindPlayerInventory(); } @Override @@ -324,11 +325,10 @@ private boolean isLocked() { } private void setLocked(boolean locked) { - if (this.locked == locked) return; + if (!isExportHatch || this.locked == locked) return; this.locked = locked; - if (!getWorld().isRemote) { - markDirty(); - } + + if (!getWorld().isRemote) markDirty(); if (locked && fluidTank.getFluid() != null) { this.lockedFluid = fluidTank.getFluid().copy(); this.lockedFluid.amount = 1; @@ -352,6 +352,7 @@ public int fillInternal(FluidStack resource, boolean doFill) { if (doFill && locked && lockedFluid == null) { lockedFluid = resource.copy(); lockedFluid.amount = 1; + writeCustomData(LOCK_FILL, buffer -> NetworkUtils.writeFluidStack(buffer, lockedFluid)); } return accepted; } diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java index 50435231a3b..a549ccbf81f 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityItemBus.java @@ -47,7 +47,7 @@ import com.cleanroommc.modularui.widgets.ItemSlot; import com.cleanroommc.modularui.widgets.SlotGroupWidget; import com.cleanroommc.modularui.widgets.ToggleButton; -import com.cleanroommc.modularui.widgets.layout.Column; +import com.cleanroommc.modularui.widgets.layout.Flow; import com.cleanroommc.modularui.widgets.layout.Grid; import it.unimi.dsi.fastutil.objects.Object2IntMap; import org.jetbrains.annotations.NotNull; @@ -310,7 +310,7 @@ public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) .minColWidth(18).minRowHeight(18) .alignX(0.5f) .matrix(widgets)) - .child(new Column() + .child(Flow.column() .pos(backgroundWidth - 7 - 18, backgroundHeight - 18 * 4 - 7 - 5) .width(18).height(18 * 4 + 5) .child(GTGuiTextures.getLogo(getUITheme()).asWidget().size(17).top(18 * 3 + 5)) diff --git a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java index cf053eb8500..6ac0ad4ee05 100644 --- a/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java +++ b/src/main/java/gregtech/common/metatileentities/multi/multiblockpart/MetaTileEntityMultiFluidHatch.java @@ -6,18 +6,16 @@ import gregtech.api.capability.IControllable; import gregtech.api.capability.impl.FluidTankList; import gregtech.api.capability.impl.NotifiableFluidTank; -import gregtech.api.gui.GuiTextures; -import gregtech.api.gui.ModularUI; -import gregtech.api.gui.widgets.TankWidget; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.interfaces.IGregTechTileEntity; import gregtech.api.metatileentity.multiblock.IMultiblockAbilityPart; import gregtech.api.metatileentity.multiblock.MultiblockAbility; +import gregtech.api.mui.GTGuis; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.common.mui.widget.GTFluidSlot; import net.minecraft.client.resources.I18n; -import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; @@ -31,8 +29,15 @@ import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; import codechicken.lib.vec.Matrix4; +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.factory.PosGuiData; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widgets.layout.Grid; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; public class MetaTileEntityMultiFluidHatch extends MetaTileEntityMultiblockNotifiablePart @@ -114,12 +119,19 @@ public T getCapability(Capability capability, EnumFacing side) { public void writeInitialSyncData(PacketBuffer buf) { super.writeInitialSyncData(buf); buf.writeBoolean(workingEnabled); + for (var tank : fluidTankList.getFluidTanks()) { + NetworkUtils.writeFluidStack(buf, tank.getFluid()); + } } @Override public void receiveInitialSyncData(PacketBuffer buf) { super.receiveInitialSyncData(buf); this.workingEnabled = buf.readBoolean(); + for (var tank : fluidTankList.getFluidTanks()) { + var fluid = NetworkUtils.readFluidStack(buf); + tank.fill(fluid, true); + } } @Override @@ -190,23 +202,29 @@ public void registerAbilities(List abilityList) { } @Override - protected ModularUI createUI(EntityPlayer entityPlayer) { + public boolean usesMui2() { + return true; + } + + @Override + public ModularPanel buildUI(PosGuiData guiData, PanelSyncManager guiSyncManager) { int rowSize = (int) Math.sqrt(numSlots); - ModularUI.Builder builder = ModularUI.builder(GuiTextures.BACKGROUND, 176, - 18 + 18 * rowSize + 94) - .label(10, 5, getMetaFullName()); - - for (int y = 0; y < rowSize; y++) { - for (int x = 0; x < rowSize; x++) { - int index = y * rowSize + x; - builder.widget( - new TankWidget(fluidTankList.getTankAt(index), 89 - rowSize * 9 + x * 18, 18 + y * 18, 18, 18) - .setBackgroundTexture(GuiTextures.FLUID_SLOT) - .setContainerClicking(true, !isExportHatch) - .setAlwaysShowFull(true)); - } + + List fluidSlots = new ArrayList<>(); + for (int i = 0; i < numSlots; i++) { + fluidSlots.add(new GTFluidSlot()); } - builder.bindPlayerInventory(entityPlayer.inventory, GuiTextures.SLOT, 7, 18 + 18 * rowSize + 12); - return builder.build(getHolder(), entityPlayer); + + return GTGuis.createPanel(this, 176, 18 + 18 * rowSize + 94) + .child(IKey.lang(getMetaFullName()).asWidget().pos(5, 5)) + .child(new Grid() + .margin(0) + .leftRel(0.5f) + .top(17) + .mapTo(rowSize, fluidSlots, + (i, slot) -> slot.syncHandler(GTFluidSlot.sync(fluidTankList.getTankAt(i)) + .accessibility(true, !isExportHatch))) + .coverChildren()) + .bindPlayerInventory(); } } diff --git a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java index 1b0ccff4ebe..2530e38a587 100644 --- a/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java +++ b/src/main/java/gregtech/common/mui/widget/GTFluidSlot.java @@ -3,58 +3,73 @@ import gregtech.api.GTValues; import gregtech.api.mui.sync.GTFluidSyncHandler; import gregtech.api.util.FluidTooltipUtil; +import gregtech.api.util.GTUtility; import gregtech.api.util.LocalizationUtils; import gregtech.client.utils.TooltipHelper; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.item.ItemStack; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.IFluidTank; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import com.cleanroommc.modularui.api.ITheme; import com.cleanroommc.modularui.api.drawable.IKey; import com.cleanroommc.modularui.api.widget.Interactable; import com.cleanroommc.modularui.drawable.GuiDraw; -import com.cleanroommc.modularui.drawable.TextRenderer; +import com.cleanroommc.modularui.drawable.text.TextRenderer; +import com.cleanroommc.modularui.integration.jei.JeiGhostIngredientSlot; import com.cleanroommc.modularui.integration.jei.JeiIngredientProvider; -import com.cleanroommc.modularui.screen.Tooltip; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularScreen; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetSlotTheme; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.utils.Alignment; import com.cleanroommc.modularui.utils.Color; +import com.cleanroommc.modularui.utils.MouseData; import com.cleanroommc.modularui.utils.NumberFormat; +import com.cleanroommc.modularui.value.sync.SyncHandler; import com.cleanroommc.modularui.widget.Widget; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; - -public class GTFluidSlot extends Widget implements Interactable, JeiIngredientProvider { +public final class GTFluidSlot extends Widget implements Interactable, JeiIngredientProvider, + JeiGhostIngredientSlot { private final TextRenderer textRenderer = new TextRenderer(); private GTFluidSyncHandler syncHandler; + private boolean disableBackground = false; public GTFluidSlot() { - tooltip().setAutoUpdate(true).setHasTitleMargin(true); + tooltip().setAutoUpdate(true); + // .setHasTitleMargin(true); tooltipBuilder(tooltip -> { if (!isSynced()) return; var fluid = this.syncHandler.getFluid(); + + if (fluid == null) + fluid = this.syncHandler.getLockedFluid(); + if (fluid == null) return; - tooltip.addLine(fluid.getLocalizedName()); - tooltip.addLine(IKey.lang("gregtech.fluid.amount", fluid.amount, this.syncHandler.getCapacity())); + tooltip.addLine(IKey.str(fluid.getLocalizedName())); + if (this.syncHandler.showAmount()) + tooltip.addLine(IKey.lang("gregtech.fluid.amount", fluid.amount, this.syncHandler.getCapacity())); + + if (this.syncHandler.isPhantom() && this.syncHandler.showAmount()) + tooltip.addLine(IKey.lang("modularui.fluid.phantom.control")); // Add various tooltips from the material - List formula = FluidTooltipUtil.getFluidTooltip(fluid); - if (formula != null) { - for (String s : formula) { - if (s.isEmpty()) continue; - tooltip.addLine(s); - } + for (String s : FluidTooltipUtil.getFluidTooltip(fluid)) { + if (s.isEmpty()) continue; + tooltip.addLine(IKey.str(s)); } - addIngotMolFluidTooltip(fluid, tooltip); + if (this.syncHandler.showAmount()) + addIngotMolFluidTooltip(fluid, tooltip); }); } @@ -67,10 +82,11 @@ public void onInit() { this.textRenderer.setShadow(true); this.textRenderer.setScale(0.5f); this.textRenderer.setColor(Color.WHITE.main); + getContext().getJeiSettings().addJeiGhostIngredientSlot(this); } public GTFluidSlot syncHandler(IFluidTank fluidTank) { - return syncHandler(new GTFluidSyncHandler(fluidTank)); + return syncHandler(sync(fluidTank)); } public GTFluidSlot syncHandler(GTFluidSyncHandler syncHandler) { @@ -79,55 +95,82 @@ public GTFluidSlot syncHandler(GTFluidSyncHandler syncHandler) { return this; } + public GTFluidSlot disableBackground() { + this.disableBackground = true; + return this; + } + + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof GTFluidSyncHandler; + } + @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { + public void drawBackground(ModularGuiContext context, WidgetTheme widgetTheme) { + if (disableBackground) return; + super.drawBackground(context, widgetTheme); + } + + @Override + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + if (widgetTheme instanceof WidgetSlotTheme slotTheme) { + draw(context, slotTheme); + } + } + + public void draw(ModularGuiContext context, WidgetSlotTheme widgetTheme) { FluidStack content = this.syncHandler.getFluid(); - if (content != null) { - GuiDraw.drawFluidTexture(content, 1, 1, getArea().w() - 2, getArea().h() - 2, 0); + if (content == null) + content = this.syncHandler.getLockedFluid(); - String s = NumberFormat.formatWithMaxDigits(getBaseUnitAmount(content.amount)) + getBaseUnit(); + GuiDraw.drawFluidTexture(content, 1, 1, getArea().w() - 2, getArea().h() - 2, 0); + + if (content != null && this.syncHandler.showAmount()) { + String amount = NumberFormat.formatWithMaxDigits(content.amount, 3) + "L"; this.textRenderer.setAlignment(Alignment.CenterRight, getArea().width - 1f); this.textRenderer.setPos(0, 12); - this.textRenderer.draw(s); + this.textRenderer.draw(amount); } + if (isHovering()) { GlStateManager.colorMask(true, true, true, false); - GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, - getWidgetTheme(context.getTheme()).getSlotHoverColor()); + GuiDraw.drawRect(1, 1, getArea().w() - 2, getArea().h() - 2, widgetTheme.getSlotHoverColor()); GlStateManager.colorMask(true, true, true, true); } } - protected double getBaseUnitAmount(double amount) { - return amount / 1000; - } - - protected String getBaseUnit() { - return "L"; - } - - @NotNull @Override - public Result onMouseTapped(int mouseButton) { + public @NotNull Result onMousePressed(int mouseButton) { + var data = MouseData.create(mouseButton); if (this.syncHandler.canFillSlot() || this.syncHandler.canDrainSlot()) { - this.syncHandler.syncToServer(1, buffer -> buffer.writeBoolean(mouseButton == 0)); - Interactable.playButtonClickSound(); + this.syncHandler.handleClick(data); + + if (this.syncHandler.canLockFluid()) + this.syncHandler.toggleLockFluid(); + return Result.SUCCESS; } return Result.IGNORE; } @Override - public WidgetSlotTheme getWidgetTheme(ITheme theme) { - return theme.getFluidSlotTheme(); + public boolean onMouseScroll(ModularScreen.UpOrDown scrollDirection, int amount) { + if (!this.syncHandler.isPhantom()) return false; + if ((scrollDirection.isUp() && !this.syncHandler.canFillSlot()) || + (scrollDirection.isDown() && !this.syncHandler.canDrainSlot())) { + return false; + } + MouseData mouseData = MouseData.create(scrollDirection.modifier); + this.syncHandler.handlePhantomScroll(mouseData); + return true; } @Override - public @Nullable Object getIngredient() { - return this.syncHandler.getFluid(); + protected WidgetTheme getWidgetThemeInternal(ITheme theme) { + return theme.getFluidSlotTheme(); } - public static void addIngotMolFluidTooltip(FluidStack fluidStack, Tooltip tooltip) { + public static void addIngotMolFluidTooltip(FluidStack fluidStack, RichTooltip tooltip) { // Add tooltip showing how many "ingot moles" (increments of 144) this fluid is if shift is held if (TooltipHelper.isShiftDown() && fluidStack.amount > GTValues.L) { int numIngots = fluidStack.amount / GTValues.L; @@ -136,7 +179,37 @@ public static void addIngotMolFluidTooltip(FluidStack fluidStack, Tooltip toolti if (extra != 0) { fluidAmount += String.format(" + %d L", extra); } - tooltip.addLine(TextFormatting.GRAY + LocalizationUtils.format("gregtech.gui.amount_raw") + fluidAmount); + tooltip.add(TextFormatting.GRAY + LocalizationUtils.format("gregtech.gui.amount_raw") + fluidAmount); } } + + @Override + public void setGhostIngredient(@NotNull FluidStack ingredient) { + if (this.syncHandler.isPhantom()) { + this.syncHandler.setFluid(ingredient); + this.syncHandler.syncToServer(GTFluidSyncHandler.UPDATE_TANK, + buffer -> NetworkUtils.writeFluidStack(buffer, ingredient)); + } else { + this.syncHandler.lockFluid(ingredient, true); + } + } + + @Override + public @Nullable FluidStack castGhostIngredientIfValid(@NotNull Object ingredient) { + if (ingredient instanceof FluidStack stack) { + return stack; + } else if (ingredient instanceof ItemStack stack && + stack.hasCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null)) { + if (stack.getCount() > 1) stack = GTUtility.copy(1, stack); + + var handler = stack.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY, null); + return handler == null ? null : handler.drain(Integer.MAX_VALUE, true); + } + return null; + } + + @Override + public @Nullable Object getIngredient() { + return this.syncHandler.getFluid(); + } } diff --git a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java index 3bb6a3e652b..c7f339db275 100644 --- a/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java +++ b/src/main/java/gregtech/common/mui/widget/HighlightedTextField.java @@ -1,7 +1,7 @@ package gregtech.common.mui.widget; import com.cleanroommc.modularui.api.value.IStringValue; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.value.sync.StringSyncValue; import com.cleanroommc.modularui.widgets.textfield.TextFieldHandler; import com.cleanroommc.modularui.widgets.textfield.TextFieldRenderer; @@ -53,7 +53,7 @@ public HighlightedTextField getThis() { } @Override - public void onRemoveFocus(GuiContext context) { + public void onRemoveFocus(ModularGuiContext context) { super.onRemoveFocus(context); highlighter.runHighlighter(getText()); if (isSynced()) @@ -70,7 +70,7 @@ public static final class TextHighlighter extends TextFieldRenderer { private Function highlightRule = string -> string; - private Map cacheMap = new Object2ObjectOpenHashMap<>(); + private final Map cacheMap = new Object2ObjectOpenHashMap<>(); public TextHighlighter(TextFieldHandler handler) { super(handler); @@ -81,15 +81,15 @@ public void setHighlightRule(Function highlightRule) { } @Override - protected float draw(String text, float x, float y) { - return super.draw(this.cacheMap.getOrDefault(text, text), x, y); + protected void draw(String text, float x, float y) { + super.draw(this.cacheMap.getOrDefault(text, text), x, y); } public void runHighlighter(String text) { if (this.highlightRule == null) { return; } - this.cacheMap.computeIfAbsent(text, string -> this.highlightRule.apply(string)); + this.cacheMap.computeIfAbsent(text, this.highlightRule); } } } diff --git a/src/main/java/gregtech/common/mui/widget/InteractableText.java b/src/main/java/gregtech/common/mui/widget/InteractableText.java index eac6936059a..bcafa15208d 100644 --- a/src/main/java/gregtech/common/mui/widget/InteractableText.java +++ b/src/main/java/gregtech/common/mui/widget/InteractableText.java @@ -38,6 +38,11 @@ public Result onMousePressed(int mouseButton) { return Result.SUCCESS; } + @Override + public boolean isValidSyncHandler(SyncHandler syncHandler) { + return syncHandler instanceof EntryColorSH; + } + private static class EntryColorSH extends SyncHandler { private final Consumer setter; diff --git a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java index 1948364bbec..e4d0ea8648c 100644 --- a/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java +++ b/src/main/java/gregtech/common/mui/widget/orefilter/OreFilterTestSlot.java @@ -7,7 +7,7 @@ import gregtech.common.covers.filter.oreglob.impl.ImpossibleOreGlob; import com.cleanroommc.modularui.api.drawable.IKey; -import com.cleanroommc.modularui.screen.viewport.GuiContext; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; import com.cleanroommc.modularui.theme.WidgetTheme; import com.cleanroommc.modularui.widgets.ItemSlot; import it.unimi.dsi.fastutil.objects.Object2BooleanAVLTreeMap; @@ -106,7 +106,7 @@ public void updatePreview() { } @Override - public void draw(GuiContext context, WidgetTheme widgetTheme) { + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { super.draw(context, widgetTheme); if (this.matchSuccess) { GTGuiTextures.OREDICT_MATCH diff --git a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java index f429a9d749e..f26eacee77a 100644 --- a/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java +++ b/src/main/java/gregtech/mixins/GregTechLateMixinLoadingPlugin.java @@ -19,6 +19,7 @@ public List getMixinConfigs() { configs.add("mixins.gregtech.ccl.json"); configs.add("mixins.gregtech.littletiles.json"); configs.add("mixins.gregtech.vintagium.json"); + configs.add("mixins.gregtech.mui2.json"); configs.add("mixins.gregtech.nothirium.json"); return configs; diff --git a/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java b/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java new file mode 100644 index 00000000000..2b876ca38b8 --- /dev/null +++ b/src/main/java/gregtech/mixins/jei/IngredientGridMixin.java @@ -0,0 +1,30 @@ +package gregtech.mixins.jei; + +import net.minecraft.client.Minecraft; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import mezz.jei.gui.GuiScreenHelper; +import mezz.jei.gui.overlay.IngredientGrid; +import mezz.jei.gui.overlay.IngredientGridWithNavigation; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(value = IngredientGridWithNavigation.class, remap = false) +public class IngredientGridMixin { + + @Shadow + @Final + private GuiScreenHelper guiScreenHelper; + + @WrapOperation(method = "drawTooltips", + at = @At(value = "INVOKE", + target = "Lmezz/jei/gui/overlay/IngredientGrid;drawTooltips(Lnet/minecraft/client/Minecraft;II)V")) + private void considerExclusions(IngredientGrid instance, Minecraft minecraft, int mouseX, int mouseY, + Operation original) { + if (!guiScreenHelper.isInGuiExclusionArea(mouseX, mouseY)) + original.call(instance, minecraft, mouseX, mouseY); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java new file mode 100644 index 00000000000..678de031802 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ClientEventHandlerMixin.java @@ -0,0 +1,79 @@ +package gregtech.mixins.mui2; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.client.event.GuiScreenEvent; + +import com.cleanroommc.modularui.ClientEventHandler; +import com.cleanroommc.modularui.api.IMuiScreen; +import com.cleanroommc.modularui.core.mixin.GuiScreenAccessor; +import com.cleanroommc.modularui.screen.ClientScreenHandler; +import com.cleanroommc.modularui.screen.ModularScreen; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.IOException; + +@Mixin(value = ClientEventHandler.class, remap = false) +@SuppressWarnings("UnstableApiUsage") +public abstract class ClientEventHandlerMixin { + + @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleMouseInput()V")) + private static void fixMouseInput(GuiScreen instance) { + int button = Mouse.getEventButton(); + if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { + ModularScreen ms = screen.getScreen(); + if (Mouse.getEventButtonState()) { + acc.setEventButton(button); + acc.setLastMouseEvent(Minecraft.getSystemTime()); + ms.onMousePressed(button); + + } else if (button != -1) { + acc.setEventButton(-1); + ms.onMouseRelease(button); + + } else if (acc.getEventButton() != -1 && acc.getLastMouseEvent() > 0L) { + long l = Minecraft.getSystemTime() - acc.getLastMouseEvent(); + ms.onMouseDrag(button, l); + } + } + } + + @Inject(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$MouseInputEvent$Pre;)V", + at = @At("TAIL")) + private static void fixScrollJei(GuiScreenEvent.MouseInputEvent.Pre event, CallbackInfo ci) throws IOException { + if (!event.isCanceled()) + ClientScreenHandler.onGuiInputLow(event); + } + + @Unique + private static Character gregTech$lastChar = null; + + @Redirect(method = "onGuiInput(Lnet/minecraftforge/client/event/GuiScreenEvent$KeyboardInputEvent$Pre;)V", + at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/GuiScreen;handleKeyboardInput()V")) + private static void fixKeyInput(GuiScreen instance) { + if (instance instanceof IMuiScreen screen && instance instanceof GuiScreenAccessor acc) { + char c0 = Keyboard.getEventCharacter(); + int key = Keyboard.getEventKey(); + boolean state = Keyboard.getEventKeyState(); + if (state) { + gregTech$lastChar = c0; + screen.getScreen().onKeyPressed(c0, key); + } else { + // releasing a key + // for some reason when you press E after joining a world the button will not trigger the press event, + // but only the release event, causing this to be null + if (gregTech$lastChar == null) return; + // when the key is released, the event char is empty + screen.getScreen().onKeyRelease(gregTech$lastChar, key); + } + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java b/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java new file mode 100644 index 00000000000..5d53a35d3d0 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ItemSlotSHMixin.java @@ -0,0 +1,141 @@ +package gregtech.mixins.mui2; + +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.items.ItemHandlerHelper; + +import com.cleanroommc.modularui.network.NetworkUtils; +import com.cleanroommc.modularui.screen.ModularContainer; +import com.cleanroommc.modularui.utils.MouseData; +import com.cleanroommc.modularui.value.sync.ItemSlotSH; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import com.cleanroommc.modularui.widgets.slot.ModularSlot; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.io.IOException; + +@Mixin(value = ItemSlotSH.class, remap = false) +public abstract class ItemSlotSHMixin extends SyncHandler { + + @Unique + private boolean gregTech$registered; + + @Shadow + protected abstract void phantomScroll(MouseData mouseData); + + @Shadow + public abstract void setEnabled(boolean enabled, boolean sync); + + @Shadow + public abstract boolean isPhantom(); + + @Shadow + private ItemStack lastStoredPhantomItem; + + @Shadow + public abstract ModularSlot getSlot(); + + @Shadow + public abstract void incrementStackCount(int amount); + + @WrapOperation(method = "init", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/screen/ModularContainer;registerSlot(Ljava/lang/String;Lcom/cleanroommc/modularui/widgets/slot/ModularSlot;)V")) + protected void wrapRegister(ModularContainer instance, String slotGroup, ModularSlot modularSlot, + Operation original) { + if (!gregTech$registered) { + original.call(instance, slotGroup, modularSlot); + gregTech$registered = true; + } + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#90 + */ + @Overwrite + public void readOnServer(int id, PacketBuffer buf) throws IOException { + if (id == 2) { + phantomClick(MouseData.readPacket(buf)); + } else if (id == 3) { + phantomScroll(MouseData.readPacket(buf)); + } else if (id == 4) { + setEnabled(buf.readBoolean(), false); + } else if (id == 5) { + if (!isPhantom()) return; + gregTech$phantomClick(MouseData.create(0), buf.readItemStack()); + } + } + + @Inject(method = "readOnClient", at = @At("HEAD")) + protected void handlePhantomScroll(int id, PacketBuffer buf, CallbackInfo ci) { + if (id == 3) { + this.lastStoredPhantomItem = NetworkUtils.readItemStack(buf); + getSlot().putStack(this.lastStoredPhantomItem.copy()); + } + } + + @Inject(method = "phantomScroll", at = @At("TAIL")) + protected void syncPhantomScroll(MouseData mouseData, CallbackInfo ci) { + syncToClient(3, buffer -> NetworkUtils.writeItemStack(buffer, this.lastStoredPhantomItem)); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#90 + */ + @Overwrite + protected void phantomClick(MouseData mouseData) { + gregTech$phantomClick(mouseData, getSyncManager().getCursorItem()); + } + + @Unique + protected void gregTech$phantomClick(MouseData mouseData, ItemStack cursorStack) { + ItemStack slotStack = getSlot().getStack(); + ItemStack stackToPut; + if (!cursorStack.isEmpty() && !slotStack.isEmpty() && + !ItemHandlerHelper.canItemStacksStack(cursorStack, slotStack)) { + stackToPut = cursorStack.copy(); + if (mouseData.mouseButton == 1) { + stackToPut.setCount(1); + } + stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); + getSlot().putStack(stackToPut); + this.lastStoredPhantomItem = stackToPut.copy(); + } else if (slotStack.isEmpty()) { + if (cursorStack.isEmpty()) { + if (mouseData.mouseButton == 1 && !this.lastStoredPhantomItem.isEmpty()) { + stackToPut = this.lastStoredPhantomItem.copy(); + } else { + return; + } + } else { + stackToPut = cursorStack.copy(); + } + if (mouseData.mouseButton == 1) { + stackToPut.setCount(1); + } + stackToPut.setCount(Math.min(stackToPut.getCount(), getSlot().getItemStackLimit(stackToPut))); + getSlot().putStack(stackToPut); + this.lastStoredPhantomItem = stackToPut.copy(); + } else { + if (mouseData.mouseButton == 0) { + if (mouseData.shift) { + getSlot().putStack(ItemStack.EMPTY); + } else { + incrementStackCount(-1); + } + } else if (mouseData.mouseButton == 1) { + incrementStackCount(1); + } + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java new file mode 100644 index 00000000000..99a850b1c10 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/PanelSyncHandlerMixin.java @@ -0,0 +1,47 @@ +package gregtech.mixins.mui2; + +import com.cleanroommc.modularui.api.widget.ISynced; +import com.cleanroommc.modularui.screen.ModularPanel; +import com.cleanroommc.modularui.value.sync.ModularSyncManager; +import com.cleanroommc.modularui.value.sync.PanelSyncHandler; +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.widget.WidgetTree; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.concurrent.atomic.AtomicInteger; + +@Mixin(value = PanelSyncHandler.class, remap = false) +public abstract class PanelSyncHandlerMixin { + + @Shadow + private PanelSyncManager syncManager; + + @Shadow + public abstract boolean isPanelOpen(); + + @Redirect(method = "openPanel(Z)V", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/widget/WidgetTree;collectSyncValues(Lcom/cleanroommc/modularui/value/sync/PanelSyncManager;Lcom/cleanroommc/modularui/screen/ModularPanel;)V")) + protected void redirectCollectValues(PanelSyncManager syncManager, ModularPanel panel) { + AtomicInteger id = new AtomicInteger(0); + String syncKey = ModularSyncManager.AUTO_SYNC_PREFIX + panel.getName(); + WidgetTree.foreachChildBFS(panel, widget -> { + if (widget instanceof ISyncedsynced) { + if (synced.isSynced() && !this.syncManager.hasSyncHandler(synced.getSyncHandler())) { + this.syncManager.syncValue(syncKey, id.getAndIncrement(), synced.getSyncHandler()); + } + } + return true; + }, false); + } + + @Inject(method = "openPanel(Z)V", at = @At("HEAD"), cancellable = true) + protected void openCheck(boolean syncToServer, CallbackInfo ci) { + if (isPanelOpen()) ci.cancel(); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java b/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java new file mode 100644 index 00000000000..9bea0ab1af2 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/PanelSyncManagerMixin.java @@ -0,0 +1,36 @@ +package gregtech.mixins.mui2; + +import gregtech.api.util.GTLog; + +import net.minecraft.network.PacketBuffer; + +import com.cleanroommc.modularui.value.sync.PanelSyncManager; +import com.cleanroommc.modularui.value.sync.SyncHandler; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Map; + +@Mixin(value = PanelSyncManager.class, remap = false) +public abstract class PanelSyncManagerMixin { + + @Shadow + @Final + private Map syncHandlers; + + @Shadow + private String panelName; + + @Inject(method = "receiveWidgetUpdate", at = @At("HEAD"), cancellable = true) + public void injectCheck(String mapKey, int id, PacketBuffer buf, CallbackInfo ci) { + if (!this.syncHandlers.containsKey(mapKey)) { + GTLog.logger.warn("[ModularUI] SyncHandler \"{}\" does not exist for panel \"{}\"! ID was {}.", mapKey, + panelName, id); + ci.cancel(); + } + } +} diff --git a/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java b/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java new file mode 100644 index 00000000000..41c269111ab --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/StyledTextMixin.java @@ -0,0 +1,119 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.UnboxFix; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import com.cleanroommc.modularui.api.drawable.IKey; +import com.cleanroommc.modularui.drawable.text.AnimatedText; +import com.cleanroommc.modularui.drawable.text.StyledText; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.utils.Alignment; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(value = StyledText.class, remap = false) +public abstract class StyledTextMixin implements UnboxFix { + + @Shadow + @Final + private IKey key; + + @Shadow + private Alignment alignment; + + @Shadow + private Integer color; + + @Shadow + private float scale; + + @Shadow + private Boolean shadow; + + @Unique + private boolean gregTech$defaultTextColor = true; + + @Unique + private boolean gregTech$defaultShadow = true; + + @Override + public void gregTech$useDefaultTextColor(boolean b) { + gregTech$defaultTextColor = b; + } + + @Override + public void gregTech$useDefaultShadow(boolean b) { + gregTech$defaultShadow = b; + } + + @Inject(method = "color", at = @At("HEAD")) + private void setDefault(int color, CallbackInfoReturnable cir) { + gregTech$useDefaultTextColor(false); + } + + @Inject(method = "shadow", at = @At("HEAD")) + private void setDefault(boolean shadow, CallbackInfoReturnable cir) { + gregTech$useDefaultShadow(false); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#86 + */ + @Overwrite + public TextWidget asWidget() { + var text = new TextWidget(this.key) + .alignment(this.alignment) + .scale(this.scale); + + ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); + ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); + + return text.color(color == null ? 0 : color) + .shadow(shadow != null && shadow); + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#86 + */ + @Overwrite + public AnimatedText withAnimation() { + var text = new AnimatedText(this.key) + .alignment(this.alignment) + .scale(this.scale); + + ((UnboxFix) text).gregTech$useDefaultTextColor(this.gregTech$defaultTextColor); + ((UnboxFix) text).gregTech$useDefaultShadow(this.gregTech$defaultShadow); + + return text.color(color == null ? 0 : color) + .shadow(shadow != null && shadow); + } + + @SideOnly(Side.CLIENT) + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) + public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultTextColor ? theme.getTextColor() : color; + } + + @SideOnly(Side.CLIENT) + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) + public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultShadow ? theme.getTextShadow() : shadow; + } +} diff --git a/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java b/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java new file mode 100644 index 00000000000..40320a51020 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/TextWidgetMixin.java @@ -0,0 +1,57 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.UnboxFix; + +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.TextWidget; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; + +@Mixin(value = TextWidget.class, remap = false) +public abstract class TextWidgetMixin extends Widget implements UnboxFix { + + @Unique + private boolean gregTech$defaultTextColor = true; + + @Unique + private boolean gregTech$defaultShadow = true; + + @Override + public void gregTech$useDefaultTextColor(boolean b) { + gregTech$defaultTextColor = b; + } + + @Override + public void gregTech$useDefaultShadow(boolean b) { + gregTech$defaultShadow = b; + } + + @Override + public boolean canHover() { + return hasTooltip(); + } + + @ModifyReturnValue(method = { "getDefaultHeight", "getDefaultWidth" }, at = @At("TAIL")) + public int clamp(int r) { + return Math.max(1, r); + } + + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setColor(I)V")) + public int fixColor(int color, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultTextColor ? theme.getTextColor() : color; + } + + @ModifyArg(method = "draw", + at = @At(value = "INVOKE", + target = "Lcom/cleanroommc/modularui/drawable/text/TextRenderer;setShadow(Z)V")) + public boolean fixShadow(boolean shadow, @Local(argsOnly = true) WidgetTheme theme) { + return gregTech$defaultShadow ? theme.getTextShadow() : shadow; + } +} diff --git a/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java b/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java new file mode 100644 index 00000000000..3838ecf5805 --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/ToggleButtonMixin.java @@ -0,0 +1,22 @@ +package gregtech.mixins.mui2; + +import gregtech.api.mui.StateOverlay; + +import com.cleanroommc.modularui.api.drawable.IDrawable; +import com.cleanroommc.modularui.widgets.AbstractCycleButtonWidget; +import com.cleanroommc.modularui.widgets.ToggleButton; +import org.spongepowered.asm.mixin.Mixin; + +@Mixin(value = ToggleButton.class, remap = false) +public class ToggleButtonMixin extends AbstractCycleButtonWidget implements StateOverlay { + + public StateOverlay overlay(boolean selected, IDrawable... overlay) { + this.overlay = addToArray(this.overlay, overlay, selected ? 1 : 0); + return (StateOverlay) getThis(); + } + + public StateOverlay hoverOverlay(boolean selected, IDrawable... overlay) { + this.hoverOverlay = addToArray(this.hoverOverlay, overlay, selected ? 1 : 0); + return (StateOverlay) getThis(); + } +} diff --git a/src/main/java/gregtech/mixins/mui2/TooltipMixin.java b/src/main/java/gregtech/mixins/mui2/TooltipMixin.java new file mode 100644 index 00000000000..7883e8b12de --- /dev/null +++ b/src/main/java/gregtech/mixins/mui2/TooltipMixin.java @@ -0,0 +1,100 @@ +package gregtech.mixins.mui2; + +import com.cleanroommc.modularui.drawable.text.RichText; +import com.cleanroommc.modularui.screen.RichTooltip; +import com.cleanroommc.modularui.screen.viewport.ModularGuiContext; +import com.cleanroommc.modularui.theme.WidgetTheme; +import com.cleanroommc.modularui.widget.Widget; +import com.cleanroommc.modularui.widgets.RichTextWidget; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.function.Consumer; + +@Mixin(value = RichTooltip.class, remap = false) +public abstract class TooltipMixin { + + @Shadow + private boolean dirty; + + @Shadow + @Final + private RichText text; + + @Shadow + private Consumer tooltipBuilder; + + @Shadow + public abstract RichTooltip getThis(); + + @Shadow + public abstract void markDirty(); + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public void buildTooltip() { + this.dirty = false; + if (this.tooltipBuilder != null) { + this.text.clearText(); + this.tooltipBuilder.accept(getThis()); + } + } + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public RichTooltip tooltipBuilder(Consumer tooltipBuilder) { + Consumer existingBuilder = this.tooltipBuilder; + if (existingBuilder != null) { + this.tooltipBuilder = tooltip -> { + existingBuilder.accept(getThis()); + tooltipBuilder.accept(getThis()); + }; + } else { + this.tooltipBuilder = tooltipBuilder; + } + markDirty(); + return getThis(); + } + + @Mixin(value = RichTextWidget.class, remap = false) + private static abstract class RichTextWidgetMixin extends Widget { + + @Shadow + private boolean autoUpdate; + + @Shadow + private boolean dirty; + + @Shadow + @Final + private RichText text; + + @Shadow + private Consumer builder; + + /** + * @author GTCEu - Ghzdude + * @reason Implement MUI2 PR#83 + */ + @Overwrite + public void draw(ModularGuiContext context, WidgetTheme widgetTheme) { + super.draw(context, widgetTheme); + if (this.autoUpdate || this.dirty) { + if (this.builder != null) { + this.text.clearText(); + this.builder.accept(this.text); + } + this.dirty = false; + } + this.text.drawAtZero(context, getArea(), widgetTheme); + } + } +} diff --git a/src/main/resources/mixins.gregtech.jei.json b/src/main/resources/mixins.gregtech.jei.json index 2520843c7d6..47158a7ea6c 100644 --- a/src/main/resources/mixins.gregtech.jei.json +++ b/src/main/resources/mixins.gregtech.jei.json @@ -1,12 +1,13 @@ { - "package" : "gregtech.mixins.jei", - "refmap" : "mixins.gregtech.refmap.json", - "target" : "@env(DEFAULT)", - "minVersion" : "0.8", - "compatibilityLevel" : "JAVA_8", - "mixins" : [ + "package": "gregtech.mixins.jei", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "mixins": [ + "IngredientGridMixin", "JEITooltipMixin" ], - "client" : [], - "server" : [] + "client": [], + "server": [] } diff --git a/src/main/resources/mixins.gregtech.mui2.json b/src/main/resources/mixins.gregtech.mui2.json new file mode 100644 index 00000000000..cb97f2be00c --- /dev/null +++ b/src/main/resources/mixins.gregtech.mui2.json @@ -0,0 +1,24 @@ +{ + "package": "gregtech.mixins.mui2", + "refmap": "mixins.gregtech.refmap.json", + "target": "@env(DEFAULT)", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_8", + "injectors": { + "maxShiftBy": 10 + }, + "mixins": [ + "ItemSlotSHMixin", + "PanelSyncHandlerMixin", + "PanelSyncManagerMixin", + "StyledTextMixin", + "TextWidgetMixin", + "ToggleButtonMixin", + "TooltipMixin", + "TooltipMixin$RichTextWidgetMixin" + ], + "client": [ + "ClientEventHandlerMixin" + ], + "server": [] +} From 778dec677aaaa6e76b938877786941a9f402f505 Mon Sep 17 00:00:00 2001 From: Zorbatron <46525467+Zorbatron@users.noreply.github.com> Date: Sun, 5 Jan 2025 22:52:26 -0500 Subject: [PATCH 7/7] Add an easier way for MTEs to be added or removed from creative tabs (#2675) --- .../api/metatileentity/MetaTileEntity.java | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java index 0ba5fd53e73..723df6f6808 100644 --- a/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java +++ b/src/main/java/gregtech/api/metatileentity/MetaTileEntity.java @@ -100,6 +100,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArraySet; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.ApiStatus; @@ -107,6 +108,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.Collections; import java.util.EnumMap; import java.util.List; import java.util.Map; @@ -166,6 +168,13 @@ public abstract class MetaTileEntity implements ISyncedTileEntity, CoverHolder, @Nullable private UUID owner = null; + private final Set creativeTabs = new ObjectArraySet<>(); + + { + creativeTabs.add(CreativeTabs.SEARCH); + creativeTabs.add(GTCreativeTabs.TAB_GREGTECH_MACHINES); + } + protected MetaTileEntity(@NotNull ResourceLocation metaTileEntityId) { this.metaTileEntityId = metaTileEntityId; this.registry = GregTechAPI.mteManager.getRegistry(metaTileEntityId.getNamespace()); @@ -365,7 +374,7 @@ public void getSubItems(CreativeTabs creativeTab, NonNullList subItem * MachineItemBlock#addCreativeTab(CreativeTabs) */ public boolean isInCreativeTab(CreativeTabs creativeTab) { - return creativeTab == CreativeTabs.SEARCH || creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES; + return creativeTabs.contains(creativeTab); } public String getItemSubTypeId(ItemStack itemStack) { @@ -1664,4 +1673,45 @@ public AENetworkProxy getProxy() { @Method(modid = Mods.Names.APPLIED_ENERGISTICS2) public void gridChanged() {} + + /** + * Add MTE to a creative tab. Ensure that the creative tab has been registered via + * {@link gregtech.api.block.machines.MachineItemBlock#addCreativeTab(CreativeTabs) + * MachineItemBlock#addCreativeTab(CreativeTabs)} beforehand. + */ + public void addAdditionalCreativeTabs(CreativeTabs creativeTab) { + Preconditions.checkNotNull(creativeTab, "creativeTab"); + if (creativeTabs.contains(creativeTab)) { + GTLog.logger.error("{} is already in the creative tab {}.", this, creativeTab.tabLabel, + new IllegalArgumentException()); + return; + } + + creativeTabs.add(creativeTab); + } + + public void removeFromCreativeTab(CreativeTabs creativeTab) { + Preconditions.checkNotNull(creativeTab, "creativeTab"); + if (creativeTab == CreativeTabs.SEARCH) { + GTLog.logger.error("Cannot remove MTEs from the creative search tab.", + new IllegalArgumentException()); + return; + } + if (creativeTab == GTCreativeTabs.TAB_GREGTECH_MACHINES && + metaTileEntityId.getNamespace().equals(GTValues.MODID)) { + GTLog.logger.error("Cannot remove GT MTEs from the GT machines tab.", new IllegalArgumentException()); + return; + } + if (!creativeTabs.contains(creativeTab)) { + GTLog.logger.error("{} is not in the creative tab {}.", this, creativeTab.tabLabel, + new IllegalArgumentException()); + return; + } + + creativeTabs.remove(creativeTab); + } + + public Set getCreativeTabs() { + return Collections.unmodifiableSet(creativeTabs); + } }