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

CyclopsMC / IntegratedDynamics / 39312498789

19 Oct 2026 07:36PM UTC coverage: 48.454% (-0.2%) from 48.683%
39312498789

Pull #1766

github

claude
Color the types in the list of methods and types

The types in the list, such as Integer next to integer and the inputs
and output of methods, are shown in the colors of their types, as in
tooltips and in the footer. The selected entry gets a gray background
instead of a blue one, on which the blue of Boolean was hard to read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHtucHo4Qy2pTfBMgeE54y
Pull Request #1766: Expression cards in the Logic Programmer, editable as text

4812 of 12674 branches covered (37.97%)

Branch coverage included in aggregate %.

15726 of 29713 relevant lines covered (52.93%)

2.59 hits per line

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

66.27
/src/main/java/org/cyclops/integrateddynamics/core/evaluate/variable/ValueObjectTypeItemStack.java
1
package org.cyclops.integrateddynamics.core.evaluate.variable;
2

3
import lombok.ToString;
4
import net.minecraft.advancements.critereon.ItemPredicate;
5
import net.minecraft.core.registries.BuiltInRegistries;
6
import net.minecraft.nbt.CompoundTag;
7
import net.minecraft.nbt.Tag;
8
import net.minecraft.network.chat.Component;
9
import net.minecraft.network.chat.MutableComponent;
10
import net.minecraft.world.item.ItemStack;
11
import org.cyclops.commoncapabilities.api.capability.itemhandler.ItemMatch;
12
import org.cyclops.cyclopscore.helper.ItemStackHelpers;
13
import org.cyclops.integrateddynamics.api.advancement.criterion.ValuePredicate;
14
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
15
import org.cyclops.integrateddynamics.api.evaluate.variable.*;
16
import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeItemStackLPElement;
17
import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeLPElementBase;
18

19
import java.util.Objects;
20
import java.util.Optional;
21

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

31
    public ValueObjectTypeItemStack() {
32
        // TODO: in next major, prefix the global interact names of operators on items with item instead of itemstack,
33
        //  as expressions call this type item. This keeps the saved unique name, but changes names that scripts use.
34
        super("itemstack", ValueObjectTypeItemStack.ValueItemStack.class);
4 ✔
35
    }
1 ✔
36

37
    public static MutableComponent getItemStackDisplayNameUsSafe(ItemStack itemStack) throws NoSuchMethodException {
38
        return !itemStack.isEmpty()
×
39
                ? (itemStack.getHoverName().copy().append((itemStack.getCount() > 1 ? " (" + itemStack.getCount() + ")" : "")))
×
40
                : Component.literal("");
×
41
    }
42

43
    public static MutableComponent getItemStackDisplayNameSafe(ItemStack itemStack) {
44
        // Certain mods may call client-side only methods,
45
        // so call a server-side-safe fallback method if that fails.
46
        try {
47
            return getItemStackDisplayNameUsSafe(itemStack);
×
48
        } catch (NoSuchMethodException e) {
×
49
            return Component.translatable(itemStack.getDescriptionId());
×
50
        }
51
    }
52

53
    @Override
54
    public ValueItemStack getDefault() {
55
        return ValueItemStack.of(ItemStack.EMPTY);
×
56
    }
57

58
    @Override
59
    public MutableComponent toCompactString(ValueItemStack value) {
60
        return ValueObjectTypeItemStack.getItemStackDisplayNameSafe(value.getRawValue());
×
61
    }
62

63
    @Override
64
    public Tag serialize(ValueDeseralizationContext valueDeseralizationContext, ValueItemStack value) {
65
        CompoundTag tag = new CompoundTag();
4 ✔
66
        ItemStack itemStack = value.getRawValue();
3 ✔
67
        if(!itemStack.isEmpty()) {
3 ✔
68
            tag.putInt("count", itemStack.getCount());
5 ✔
69
            int count = itemStack.getCount();
3 ✔
70
            if (itemStack.getCount() > 99) {
4 ✔
71
                tag.putInt("ExtendedCount", count);
4 ✔
72
                itemStack = itemStack.copy();
3 ✔
73
                itemStack.setCount(99);
3 ✔
74
            }
75
            return itemStack.save(valueDeseralizationContext.holderLookupProvider(), tag);
6 ✔
76
        }
77
        return tag;
2 ✔
78
    }
79

80
    @Override
81
    public ValueItemStack deserialize(ValueDeseralizationContext valueDeseralizationContext, Tag value) {
82
        if (value instanceof CompoundTag tag && !tag.isEmpty()) {
9 !
83
            // Forge returns air for tags with negative count,
84
            // so we set it to 1 for deserialization and fix it afterwards.
85
            int realCount = tag.getInt("count");
4 ✔
86
            // Consider the tag immutable, to avoid changes elsewhere
87
            tag = tag.copy();
3 ✔
88
            tag.putInt("count", 1);
4 ✔
89
            ItemStack itemStack = ItemStack.parseOptional(valueDeseralizationContext.holderLookupProvider(), tag);
5 ✔
90
            if (!itemStack.isEmpty()) {
3 ✔
91
                itemStack.setCount(realCount);
3 ✔
92
            }
93
            if (tag.contains("ExtendedCount", Tag.TAG_INT)) {
5 ✔
94
                itemStack.setCount(tag.getInt("ExtendedCount"));
5 ✔
95
            }
96
            return ValueItemStack.of(itemStack);
3 ✔
97
        } else {
98
            return ValueItemStack.of(ItemStack.EMPTY);
3 ✔
99
        }
100
    }
101

102
    @Override
103
    public String getName(ValueItemStack a) {
104
        return toCompactString(a).getString();
×
105
    }
106

107
    @Override
108
    public boolean isNull(ValueItemStack a) {
109
        return a.getRawValue().isEmpty();
×
110
    }
111

112
    @Override
113
    public ValueTypeLPElementBase createLogicProgrammerElement() {
114
        return new ValueTypeItemStackLPElement<>(this, new ValueTypeItemStackLPElement.IItemStackToValue<ValueObjectTypeItemStack.ValueItemStack>() {
12 ✔
115
            @Override
116
            public boolean isNullable() {
117
                return true;
×
118
            }
119

120
            @Override
121
            public Component validate(ItemStack itemStack) {
122
                return null;
×
123
            }
124

125
            @Override
126
            public ValueObjectTypeItemStack.ValueItemStack getValue(ItemStack itemStack) {
127
                return ValueObjectTypeItemStack.ValueItemStack.of(itemStack);
×
128
            }
129

130
            @Override
131
            public ItemStack getValueAsItemStack(ValueItemStack value) {
132
                return value.getRawValue();
×
133
            }
134
        });
135
    }
136

137
    @Override
138
    public ValueItemStack materialize(ValueItemStack value) throws EvaluationException {
139
        return ValueItemStack.of(value.getRawValue().copy());
5 ✔
140
    }
141

142
    @Override
143
    public String getUniqueName(ValueItemStack value) {
144
        ItemStack itemStack = value.getRawValue();
×
145
        return !itemStack.isEmpty() ? BuiltInRegistries.ITEM.getKey(itemStack.getItem()).toString() : "";
×
146
    }
147

148
    @ToString
5 ✔
149
    public static class ValueItemStack extends ValueBase {
150

151
        private final ItemStack itemStack;
152

153
        private ValueItemStack(ItemStack itemStack) {
154
            super(ValueTypes.OBJECT_ITEMSTACK);
3 ✔
155
            this.itemStack = Objects.requireNonNull(itemStack, "Attempted to create a ValueItemStack for a null ItemStack.");
6 ✔
156
        }
1 ✔
157

158
        public static ValueItemStack of(ItemStack itemStack) {
159
            return new ValueItemStack(itemStack);
5 ✔
160
        }
161

162
        public ItemStack getRawValue() {
163
            return itemStack;
3 ✔
164
        }
165

166
        @Override
167
        public boolean equals(Object o) {
168
            return o instanceof ValueItemStack && ItemMatch.areItemStacksEqual(((ValueItemStack) o).itemStack, this.itemStack, ItemMatch.EXACT);
15 !
169
        }
170

171
        @Override
172
        public int hashCode() {
173
            return 37 + ItemStackHelpers.getItemStackHashCode(itemStack);
×
174
        }
175
    }
176

177
    public static class ValueItemStackPredicate extends ValuePredicate<ValueItemStack> {
178

179
        private final Optional<ItemPredicate> itemPredicate;
180

181
        public ValueItemStackPredicate(Optional<ItemPredicate> itemPredicate) {
182
            super(Optional.of(ValueTypes.OBJECT_ITEMSTACK), Optional.empty(), Optional.empty());
6 ✔
183
            this.itemPredicate = itemPredicate;
3 ✔
184
        }
1 ✔
185

186
        public Optional<ItemPredicate> getItemPredicate() {
187
            return itemPredicate;
×
188
        }
189

190
        @Override
191
        protected boolean testTyped(ValueItemStack value) {
192
            return super.testTyped(value) && (itemPredicate.isEmpty() || itemPredicate.get().test(value.getRawValue()));
20 !
193
        }
194
    }
195

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