• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

CyclopsMC / IntegratedDynamics / 42508761336

08 Nov 2026 06:11PM UTC coverage: 58.584% (+0.3%) from 58.308%
42508761336

Pull #1781

github

claude
Merge remote-tracking branch 'origin/master-1.21-lts' into master-26-lts

Ports the expressions of the Logic Programmer (#1766) to Minecraft 26.1:
- Client-only classes of the expression panel move to core.logicprogrammer.client,
  the typed text is kept by the screen instead of the container, and the card
  facades get client classes for their model overlays.
- Expression trees are written with ValueOutput and ValueInput, so values and
  operators in them are serialized as everywhere else in 26.1.
- Values written with their type in the text leave out the "v" field of the
  serialized value, and items are written as their stack, so the text form is
  the same as in 1.21, such as @Item{id: "minecraft:diamond"}.
- Rendering uses GuiGraphicsExtractor, with strata instead of depth for the
  popups and dragged parameters, and input uses the new event types.
- Tests use JUnit 5 and the game test API of 26.1. Unknown items, invalid entity
  ids and non-compound lists can no longer be read at all, so their error is
  bad_value instead of value_changed, and an empty entity is written as @Entity{}.
- The icons of the expression advancements are converted to the 26.1 format, and
  an unreadable operator makes an expression card invalid instead of throwing,
  which crashed the book on the Expressions tutorial.
- The expression action packet no longer uses @OnlyIn, which NeoForge 26.1 warns
  about on every start.

Also fixes the invisible operator symbol in the Logic Programmer, which was drawn
with color 0, fully transparent since 26.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHtucHo4Qy2pTfBMgeE54y
Pull Request #1781: Upmerge expressions in the Logic Programmer to 26.1

5828 of 13562 branches covered (42.97%)

Branch coverage included in aggregate %.

26150 of 41023 relevant lines covered (63.74%)

3.34 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

61.9
/src/main/java/org/cyclops/integrateddynamics/core/evaluate/variable/ValueObjectTypeFluidStack.java
1
package org.cyclops.integrateddynamics.core.evaluate.variable;
2

3
import net.minecraft.core.registries.BuiltInRegistries;
4
import net.minecraft.network.chat.Component;
5
import net.minecraft.network.chat.MutableComponent;
6
import net.minecraft.world.item.ItemStack;
7
import net.minecraft.world.level.storage.ValueInput;
8
import net.minecraft.world.level.storage.ValueOutput;
9
import net.neoforged.neoforge.capabilities.Capabilities;
10
import net.neoforged.neoforge.fluids.FluidStack;
11
import net.neoforged.neoforge.transfer.access.ItemAccess;
12
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueTypeNamed;
13
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueTypeNullable;
14
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueTypeUniquelyNamed;
15
import org.cyclops.integrateddynamics.core.helper.Helpers;
16
import org.cyclops.integrateddynamics.core.helper.L10NValues;
17
import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeItemStackLPElement;
18
import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeLPElementBase;
19

20
import java.util.Objects;
21

22
/**
23
 * Value type with values that are fluidstacks.
24
 * @author rubensworks
25
 */
26
public class ValueObjectTypeFluidStack extends ValueObjectTypeBase<ValueObjectTypeFluidStack.ValueFluidStack> implements
27
        IValueTypeNamed<ValueObjectTypeFluidStack.ValueFluidStack>,
28
        IValueTypeUniquelyNamed<ValueObjectTypeFluidStack.ValueFluidStack>,
29
        IValueTypeNullable<ValueObjectTypeFluidStack.ValueFluidStack> {
30

31
    public ValueObjectTypeFluidStack() {
32
        // TODO: in next major, prefix the global interact names of operators on fluids with fluid instead of fluidstack.
33
        super("fluidstack", ValueObjectTypeFluidStack.ValueFluidStack.class);
4 ✔
34
    }
1 ✔
35

36
    @Override
37
    public String getExpressionName() {
38
        return "Fluid";
2 ✔
39
    }
40

41
    @Override
42
    public ValueFluidStack getDefault() {
43
        return ValueFluidStack.of(FluidStack.EMPTY);
×
44
    }
45

46
    @Override
47
    public MutableComponent toCompactString(ValueFluidStack value) {
48
        FluidStack fluidStack = value.getRawValue();
×
49
        return !fluidStack.isEmpty() ? fluidStack.getHoverName().copy().append(String.format(" (%s mB)", fluidStack.getAmount())) : Component.literal("");
×
50
    }
51

52
    @Override
53
    public void serialize(ValueOutput valueOutput, ValueFluidStack value) {
54
        valueOutput.store("v", FluidStack.OPTIONAL_CODEC, value.getRawValue());
6 ✔
55
    }
1 ✔
56

57
    @Override
58
    public ValueFluidStack deserialize(ValueInput valueInput) {
59
        return ValueFluidStack.of(valueInput.read("v", FluidStack.OPTIONAL_CODEC).orElse(FluidStack.EMPTY));
9 ✔
60
    }
61

62
    @Override
63
    public String getName(ValueFluidStack a) {
64
        return toCompactString(a).getString();
×
65
    }
66

67
    @Override
68
    public boolean isNull(ValueFluidStack a) {
69
        return a.getRawValue().isEmpty();
×
70
    }
71

72
    @Override
73
    public ValueTypeLPElementBase createLogicProgrammerElement() {
74
        return new ValueTypeItemStackLPElement<>(this, new ValueTypeItemStackLPElement.IItemStackToValue<ValueObjectTypeFluidStack.ValueFluidStack>() {
17 ✔
75
            @Override
76
            public boolean isNullable() {
77
                return true;
×
78
            }
79

80
            @Override
81
            public Component validate(ItemStack itemStack) {
82
                return itemStack.isEmpty() ||
5 !
83
                        ItemAccess.forStack(itemStack).getCapability(Capabilities.Fluid.ITEM) != null ?
4 ✔
84
                        null :
2 ✔
85
                        Component.translatable(L10NValues.VALUETYPE_OBJECT_FLUID_ERROR_NOFLUID);
2 ✔
86
            }
87

88
            @Override
89
            public ValueObjectTypeFluidStack.ValueFluidStack getValue(ItemStack itemStack) {
90
                return ValueObjectTypeFluidStack.ValueFluidStack.of(Helpers.getFluidStack(itemStack));
4 ✔
91
            }
92

93
            @Override
94
            public ItemStack getValueAsItemStack(ValueFluidStack value) {
95
                return value.getRawValue().getFluid().getFluidType().getBucket(value.getRawValue());
8 ✔
96
            }
97
        });
98
    }
99

100
    @Override
101
    public String getUniqueName(ValueFluidStack value) {
102
        FluidStack fluidStack = value.getRawValue();
×
103
        return !fluidStack.isEmpty() ?
×
104
                String.format("%s %s", BuiltInRegistries.FLUID.getKey(fluidStack.getFluid()), fluidStack.getAmount()) : "";
×
105
    }
106

107
    public static class ValueFluidStack extends ValueBase {
108

109
        private final FluidStack fluidStack;
110

111
        private ValueFluidStack(FluidStack itemStack) {
112
            super(ValueTypes.OBJECT_FLUIDSTACK);
3 ✔
113
            this.fluidStack = Objects.requireNonNull(itemStack, "Attempted to create a ValueFluidStack for a null FluidStack.");
6 ✔
114
        }
1 ✔
115

116
        public static ValueFluidStack of(FluidStack itemStack) {
117
            return new ValueFluidStack(itemStack);
5 ✔
118
        }
119

120
        public FluidStack getRawValue() {
121
            return fluidStack;
3 ✔
122
        }
123

124
        @Override
125
        public boolean equals(Object o) {
126
            return o instanceof ValueFluidStack && FluidStack.matches(this.getRawValue(), ((ValueFluidStack) o).getRawValue());
14 !
127
        }
128

129
        @Override
130
        public int hashCode() {
131
            return fluidStack.hashCode();
×
132
        }
133

134
        @Override
135
        public String toString() {
136
            return "ValueFluidStack(fluidStack=" + this.fluidStack + ")";
5 ✔
137
        }
138

139
    }
140

141
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc