Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
07db970
Update v8 machine migration docs (#5112)
gustovafing Jul 14, 2026
8fe56e7
Wiki information on .handleNonMaterialFluids() in Java (#5101)
Jambon123 Jul 15, 2026
fe988f5
Fix CM forming after multi refactor (#5091)
TarLaboratories Jul 15, 2026
8fe2b63
major rewrite to pattern buffers (#4910)
GilbertzRivi Jul 15, 2026
3bb345a
Fix tooltips and allow tank locking (#5116)
jurrejelle Jul 15, 2026
0e00bc5
Fix flickering of items in filters (#5125)
jurrejelle Jul 17, 2026
ddc9131
Fix filters in covers not working (#5130)
jurrejelle Jul 17, 2026
54e25a3
Add slot group priority to battery slot (#5134)
jurrejelle Jul 18, 2026
781be14
ender link allowc2s (#5137)
jurrejelle Jul 18, 2026
cb08d84
Better visibility on oxygen/liquid oxygen boosting tooltips for LCE a…
lolmat13 Jul 18, 2026
d72b620
RotorHolderPartMachine shouldn't allow IO on its inventory (#5146)
Reabstraction Jul 19, 2026
4cf6acc
Disable ui of the AutoMaintenanceHatch (#5148)
htmlcsjs Jul 19, 2026
d3e87ac
Fix drum interaction (#5145)
gustovafing Jul 19, 2026
22accb0
drop filter when item bus broken (#5147)
gustovafing Jul 19, 2026
8ba5054
Fix batch mode button (#5143)
gustovafing Jul 19, 2026
6ccc823
Add instanceof check to miner logic getCachedItemHandler (#5152)
htmlcsjs Jul 20, 2026
d2abda7
Add relativedirection binding to kjs (#5153)
jurrejelle Jul 20, 2026
2f5a836
Update forge.versions.toml
gustovafing Jul 23, 2026
6a601f3
Update forge.versions.toml
gustovafing Jul 23, 2026
818fc35
Update PlaceholderHandler.java
gustovafing Jul 23, 2026
da0f629
Update MEPatternBufferPartMachine.java
gustovafing Jul 23, 2026
cdef3c5
Update MEPatternBufferPartMachine.java
gustovafing Jul 23, 2026
d8400a6
some random renames which will be on 1.20
gustovafing Jul 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/content/Modpacks/Changes/v8.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ Many aspects of the machine classes have been refactored and changed in order to

- The `MetaMachineBlockEntity`(MMBE) class has been removed, and `MetaMachine`(MM) is now a BlockEntity.
- Most methods and properties of MMBE have been moved onto MM.
- The `IMachineBlockEntity` interface has been removed. Use `MetaMachineBlock` directly instead.
- The `IMachineBlock` interface has been removed. Use `MetaMachineBlock` directly instead.
- The `IMachineBlockEntity` interface has been removed. Use `MetaMachine` directly instead.
- Many methods common to all block entities have been moved to the `IGregtechBlockEntity` interface.
- Machine instance creation functions have signature `(BlockEntityCreationInfo) -> MetaMachine` instead of `(IMachineBlockEntity) -> MetaMachine`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,25 @@ GTCEuStartupEvents.materialModification(event => { // (1)

The `Material` for which you are adjusting the TagPrefix must be registered in GTCEu Modern's material registry; if this
material is custom, this is done using `GTCEuStartupEvents.registry()`, as depicted in these docs.


## What about fluids?

Fluids are treated differently to items, their inclusion in a material is a property rather than a TagPrefix or MaterialFlag.
This makes replacing the fluid of a material with a fluid that you or another mod have created require a different approach than setIgnored.
The way to do this is using `GTFluids.handleNonMaterialFluids()` which can be found in the [``GTFluids`` class](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/common/data/GTFluids.java)

`GTFluids.handleNonMaterialFluids()` takes in a `Material` and a `Fluid` or `Supplier<Fluid>` to replace the liquid of the material with the provided fluid.
Assure that the material is registered with a liquid before attempting to replace it with your new fluid. An example is below.

!!! note "This may differ!"
Depending on the way your fluid is registered you may need to change how you pass the `Fluid` argument, check how it is registered in the mod you are working with.

```java title="ExampleMaterials.java"
public static void register() {
GLUGG_BRINE = new Material.Builder(MyMod.id("glugg_brine"))
.liquid(new FluidBuilder()).buildAndRegister();

GTFluids.handleNonMaterialFluids(GLUGG_BRINE, () -> PVFluidRegistry.BRINE_FLUID_SOURCE.get());
}
```
4 changes: 2 additions & 2 deletions gradle/forge.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ registrate = "MC1.21-1.3.0+67"
configuration = "3.1.1-neoforge"
jei = "19.25.1.328"
rei = "16.0.799"
emi = "1.1.22+1.21.1"
emi = "1.1.24+1.21.1"
ae2 = "19.2.8"
mui = "3.3.0-SNAPSHOT"
mui = "3.3.1-SNAPSHOT"
kubejs = "2101.7.2-build.336"
rhino = "2101.2.7-build.81"
architectury = "13.0.8"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,9 @@ protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Lev

InteractionResult machineInteractResult = InteractionResult.PASS;

if (!itemStack.isEmpty())
if (!itemStack.isEmpty()) {
machineInteractResult = machine.onUseWithItem(new ExtendedUseOnContext(player, hand, hit));
}
if (machineInteractResult != InteractionResult.PASS) return getFromInteractionResult(machineInteractResult);
machineInteractResult = machine.onUse(new ExtendedUseOnContext(player, hand, hit));
if (machineInteractResult != InteractionResult.PASS) return getFromInteractionResult(machineInteractResult);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ public int getSlotLimit(int slot) {
};

this.filterSlot.setFilter(this::canInsertFilterItem);
this.filterSlot.setOnContentsChanged(this::updateFilter);
}

return this.filterSlot;
}

public void setFilterItem(ItemStack item) {
getFilterSlot().setStackInSlot(0, item);
updateFilter();
}

private void updateFilter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ public Flow getFilterUI(GuiData data, PanelSyncManager syncManager, UISettings s
.gridOfSizeWidth(9, 3, (x, y, i) -> new PhantomItemSlot()
.size(16)
.syncHandler(new PhantomItemSlotSyncHandler(new ModularSlot(handler, i)
.changeListener((stack, amount, client, init) -> {
handler.setStackInSlot(i, stack);
}).ignoreMaxStackSize(true).accessibility(true, false))));
.ignoreMaxStackSize(true).accessibility(true, false))));

BooleanSyncValue blacklist = new BooleanSyncValue(this::isBlackList, this::setBlackList).allowC2S();
syncManager.syncValue("blacklist", blacklist);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import com.gregtechceu.gtceu.api.machine.MetaMachine;
import com.gregtechceu.gtceu.api.machine.feature.IVoidable;
import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDistinctPart;
import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine;
import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine;
import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine;
import com.gregtechceu.gtceu.api.machine.trait.feature.IAttachConfiguratorsTrait;
import com.gregtechceu.gtceu.api.recipe.modifier.RecipeModifierList;
import com.gregtechceu.gtceu.common.data.GTRecipeModifiers;
import com.gregtechceu.gtceu.common.mui.GTGuiTextures;
import com.gregtechceu.gtceu.common.mui.GTMuiWidgets;
import com.gregtechceu.gtceu.common.mui.widgets.SteamDialWidget;
Expand All @@ -27,6 +30,7 @@
import lombok.Setter;
import lombok.experimental.Accessors;

import java.util.Arrays;
import java.util.function.Consumer;

@Accessors(fluent = true)
Expand Down Expand Up @@ -86,6 +90,11 @@ public MachineUIPanel build(PanelSyncManager syncManager, UISettings settings) {
attachRight.childIf(distinctPart.supportsDistinct(),
() -> GTMuiWidgets.createDistinctnessButton(distinctPart));
}
if (machine.getDefinition().getRecipeModifier() instanceof RecipeModifierList rml &&
Arrays.stream(rml.getModifiers()).anyMatch(m -> m == GTRecipeModifiers.BATCH_MODE) &&
machine instanceof WorkableElectricMultiblockMachine workableElectric) {
attachRight.child(GTMuiWidgets.createBatchModeButton(workableElectric));
}
}

leftConfigurators.accept(attachLeft);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public NotifiableFluidTank(int slots, int capacity, IO io, IO capabilityIO) {
this.storages[i] = new CustomFluidTank(capacity);
this.storages[i].setOnContentsChanged(this::onContentsChanged);
}
this.lockedFluid.setOnContentsChanged(this::onLockedFluidChanged);
}

public NotifiableFluidTank(List<CustomFluidTank> storages, IO io, IO capabilityIO) {
Expand All @@ -80,6 +81,7 @@ public NotifiableFluidTank(List<CustomFluidTank> storages, IO io, IO capabilityI
if (io == IO.IN) {
this.allowSameFluids = true;
}
this.lockedFluid.setOnContentsChanged(this::onLockedFluidChanged);
}

public NotifiableFluidTank(int slots, int capacity, IO io) {
Expand All @@ -96,6 +98,26 @@ public void onContentsChanged() {
notifyListeners();
}

protected void onLockedFluidChanged() {
syncDataHolder.markClientSyncFieldDirty("lockedFluid");
var newFluid = this.lockedFluid.getFluid();
if (newFluid.isEmpty()) {
this.setFilter(stack -> true);
this.onContentsChanged();
return;
}
for (int i = 0; i < this.getTanks(); i++) {
if (this.getFluidInTank(i).isEmpty()) continue;
if (!this.getFluidInTank(i).isFluidEqual(newFluid)) {
// Fluid in a tank that doesn't equal the new locked fluid
this.lockedFluid.setFluid(FluidStack.EMPTY);
return;
}
}
this.setFilter(stack -> stack.isFluidEqual(newFluid));
this.onContentsChanged();
}

@Override
public List<SizedFluidIngredient> handleRecipeInner(IO io, GTRecipe recipe,
List<SizedFluidIngredient> left,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.gregtechceu.gtceu.api.placeholder;

import net.minecraft.ChatFormatting;
import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.*;
import net.minecraft.network.chat.*;

import com.mojang.serialization.Codec;
Expand All @@ -10,7 +12,6 @@
import lombok.experimental.Accessors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.*;
import java.util.ArrayList;
Expand Down Expand Up @@ -177,6 +178,7 @@ public MultiLineComponent withStyle(UnaryOperator<Style> style) {
out.appendNewline();
}
if (!out.isEmpty()) out.removeLast();
out.addGraphics(this.getGraphics());
return out;
}

Expand All @@ -187,11 +189,44 @@ public MultiLineComponent withStyle(ChatFormatting... style) {
out.appendNewline();
}
if (!out.isEmpty()) out.removeLast();
out.addGraphics(this.getGraphics());
return out;
}

public @UnmodifiableView List<Component> toImmutable() {
return Collections.unmodifiableList(this);
public List<Component> toImmutable() {
return new ArrayList<>(this);
}

public Tag toTag(HolderLookup.Provider registries) {
CompoundTag compoundTag = new CompoundTag();
ListTag tag = new ListTag();
for (MutableComponent component : this) {
tag.add(StringTag.valueOf(Component.Serializer.toJson(component, registries)));
}
compoundTag.put("text", tag);
ListTag graphicsTag = new ListTag();
for (GraphicsComponent component : this.getGraphics()) {
graphicsTag.add(GraphicsComponent.CODEC.encodeStart(NbtOps.INSTANCE, component).result().orElseThrow());
}
compoundTag.put("graphics", graphicsTag);
return compoundTag;
}

public static MultiLineComponent fromTag(@Nullable Tag tag, HolderLookup.Provider registries) {
MultiLineComponent out = MultiLineComponent.empty();
out.clear();
if (tag == null) return out;
if (tag instanceof ListTag listTag) {
for (Tag i : listTag) {
out.add(Component.Serializer.fromJson(i.getAsString(), registries));
}
} else if (tag instanceof CompoundTag compoundTag) {
ListTag textTag = compoundTag.getList("text", Tag.TAG_STRING);
for (Tag i : textTag) out.add(Component.Serializer.fromJson(i.getAsString(), registries));
ListTag graphicsTag = compoundTag.getList("graphics", Tag.TAG_COMPOUND);
for (Tag i : graphicsTag) out.addGraphics(GraphicsComponent.CODEC.parse(NbtOps.INSTANCE, i).getOrThrow());
}
return out;
}

public long toLong() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ public abstract class Placeholder {
@Getter
private final ResourceLocation id;

@Getter
private final String name;

public abstract MultiLineComponent apply(PlaceholderContext ctx,
List<MultiLineComponent> args) throws PlaceholderException;

public Placeholder(String str) {
this(GTCEu.id(str));
this.id = GTCEu.id(str);
this.name = str;
}

public Placeholder(ResourceLocation id) {
this.id = id;
}

public String getName() {
return id.getPath();
this.name = id.getPath();
}

protected CompoundTag getData(PlaceholderContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import brachy.modularui.widgets.layout.Flow;
import brachy.modularui.widgets.slot.ItemSlot;
import brachy.modularui.widgets.textfield.TextFieldWidget;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import org.jetbrains.annotations.Nullable;

import java.util.*;
Expand Down Expand Up @@ -101,8 +100,7 @@ public static void addRenderer(String id, IPlaceholderRenderer renderer) {
}

public static MultiLineComponent processPlaceholder(List<MultiLineComponent> placeholder,
PlaceholderContext context,
Object2IntOpenHashMap<String> indices) throws PlaceholderException {
PlaceholderContext context) throws PlaceholderException {
var id = toId(placeholder.getFirst().toString());
if (id == null) throw new UnknownPlaceholderException(placeholder.getFirst().toString());
var holder = context.holderLookup().holder(id);
Expand All @@ -118,7 +116,6 @@ public static MultiLineComponent processPlaceholders(String s, PlaceholderContex
if (ctx.level().isClientSide)
GTCEu.LOGGER.warn("Placeholder processing is running on client instead of server!");
List<Exception> exceptions = new ArrayList<>();
Object2IntOpenHashMap<String> indices = new Object2IntOpenHashMap<>();
boolean escape = false;
boolean escapeNext = false;
boolean literalEscape = false;
Expand Down Expand Up @@ -180,7 +177,7 @@ public static MultiLineComponent processPlaceholders(String s, PlaceholderContex
List<MultiLineComponent> placeholder = stack.pop();
try {
if (stack.isEmpty()) throw new UnexpectedBracketException();
MultiLineComponent result = processPlaceholder(placeholder, ctx, indices);
MultiLineComponent result = processPlaceholder(placeholder, ctx);
if (result.isIgnoreSpaces() || stack.size() == 1) {
stack.peek().getLast().append(result);
} else {
Expand Down Expand Up @@ -347,8 +344,7 @@ public static ModularPanel<?> createPlaceholderEditorPanel(String name,
.center())
.tooltip(new RichTooltip()
.addDrawableLines(LangHandler
.getSingleOrMultiLang(
"gtceu.placeholder_info." + s)
.getSingleOrMultiLang("gtceu.placeholder_info." + s)
.stream()
.map(Text::of)
.map(key -> (IDrawable) key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,16 @@ public void createCoverUIRows(Flow column, SidedPosGuiData data, PanelSyncManage
(sm, sh) -> createChannelManagerPanel(data, sm, settings));

var colorSyncer = new IntSyncValue(this::getColor);
EnumSyncValue<IO> ioSync = new EnumSyncValue<>(IO.class, this::getIo, this::setIo);
EnumSyncValue<IO> ioSync = new EnumSyncValue<>(IO.class, this::getIo, this::setIo).allowC2S();

syncManager.syncValue("io", ioSync);
syncManager.syncValue("color", colorSyncer);

var currentEntry = GenericSyncValue.<RegistryFriendlyByteBuf, VirtualEntry>builder(VirtualEntry.class)
.adapter(new VirtualEntryAdapter())
.getter(this::getEntry)
.adapter(new VirtualEntryAdapter())
.allowC2S()
.build();
syncManager.syncValue("currentEntry", currentEntry);

Expand All @@ -277,9 +279,9 @@ public void createCoverUIRows(Flow column, SidedPosGuiData data, PanelSyncManage
.tooltip(1, t -> t.addLine(Text.lang(Permissions.PROTECTED.tooltip)))
.tooltip(2, t -> t.addLine(Text.lang(Permissions.PRIVATE.tooltip)))
.value(new EnumSyncValue<>(Permissions.class, this::getPermission,
this::setPermission)))
this::setPermission).allowC2S()))
.child(new TextFieldWidget()
.value(new StringSyncValue(this::getColorStr, this::setColorStr))
.value(new StringSyncValue(this::getColorStr, this::setColorStr).allowC2S())
.setMaxLength(8)
.setValidator(str -> COLOR_INPUT_PATTERN.matcher(str).replaceAll(""))
.addTooltipLine(Text.lang("cover.ender_link.tooltip.channel_name")))
Expand All @@ -294,7 +296,7 @@ public void createCoverUIRows(Flow column, SidedPosGuiData data, PanelSyncManage
.setMaxLength(32)
.widthRel(1f)
.addTooltipLine(Text.lang("cover.ender_link.tooltip.channel_description"))
.value(new StringSyncValue(this::getDescription, this::setDescription))));
.value(new StringSyncValue(this::getDescription, this::setDescription).allowC2S())));

Flow bottomRow = coverUIRow();
bottomRow.child(GTMuiWidgets.createPowerButton(this));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -873,11 +873,7 @@ public class GTMultiMachines {
.rotationState(RotationState.ALL)
.recipeType(DUMMY_RECIPES)
.appearanceBlock(CASING_ALUMINIUM_FROSTPROOF)
.pattern((definition) -> MultiblockPatternBuilder.start()
.slice("BCB", "BBB", "BBB", "BBB")
.where('C', Predicates.controller(Predicates.blocks(definition.get())))
.where('B', CentralMonitorMachine.getMultiPredicate())
.build())
.pattern(CentralMonitorMachine::getPattern)
.modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE)
.model(createWorkableCasingMachineModel(
GTCEu.id("block/casings/solid/machine_casing_frost_proof"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ private ParentWidget<?> createSimpleFilterPage(SimpleItemFilter filter) {
.gridOfSizeWidth(9, 3, (x, y, i) -> new PhantomItemSlot()
.size(16)
.syncHandler(new PhantomItemSlotSyncHandler(new ModularSlot(handler, i)
.changeListener((stack, amount, client, init) -> handler.setStackInSlot(i, stack))
.ignoreMaxStackSize(true).accessibility(true, false))));

BooleanSyncValue blacklist = new BooleanSyncValue(filter::isBlackList, filter::setBlackList).allowC2S();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.gregtechceu.gtceu.api.item.component.IAddInformation;
import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem;
import com.gregtechceu.gtceu.api.placeholder.GraphicsComponent;
import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent;
import com.gregtechceu.gtceu.api.placeholder.PlaceholderContext;
import com.gregtechceu.gtceu.api.placeholder.PlaceholderHandler;
Expand Down Expand Up @@ -137,6 +138,11 @@ public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext conte
.addAll(stack.getOrDefault(GTDataComponents.FORMAT_STRING_LIST, TextLineList.EMPTY).lines());
tooltipComponents.add(Component.literal("Processed text:").withStyle(ChatFormatting.GOLD));
tooltipComponents.addAll(getText(stack));
tooltipComponents.add(Component.literal("Graphics components:").withStyle(ChatFormatting.GOLD));
tooltipComponents.addAll(getText(stack).getGraphics().stream()
.map(GraphicsComponent::rendererId)
.map(Component::literal)
.toList());
}
}
}
Loading
Loading