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

CyclopsMC / IntegratedDynamics / 19266698686

11 Nov 2025 01:11PM UTC coverage: 44.848% (-0.006%) from 44.854%
19266698686

push

github

rubensworks
Bump mod version

2582 of 8548 branches covered (30.21%)

Branch coverage included in aggregate %.

11789 of 23496 relevant lines covered (50.17%)

2.38 hits per line

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

0.0
/src/main/java/org/cyclops/integrateddynamics/core/logicprogrammer/ValueTypeIngredientsLPElement.java
1
package org.cyclops.integrateddynamics.core.logicprogrammer;
2

3
import com.google.common.collect.Lists;
4
import com.google.common.collect.Maps;
5
import net.minecraft.client.Minecraft;
6
import net.minecraft.client.gui.Font;
7
import net.minecraft.client.gui.GuiGraphics;
8
import net.minecraft.client.gui.components.Button;
9
import net.minecraft.client.renderer.texture.TextureManager;
10
import net.minecraft.network.chat.Component;
11
import net.minecraft.resources.ResourceLocation;
12
import net.minecraft.world.item.ItemStack;
13
import net.neoforged.api.distmarker.Dist;
14
import net.neoforged.api.distmarker.OnlyIn;
15
import org.cyclops.commoncapabilities.api.ingredient.IMixedIngredients;
16
import org.cyclops.commoncapabilities.api.ingredient.IngredientComponent;
17
import org.cyclops.commoncapabilities.api.ingredient.MixedIngredients;
18
import org.cyclops.cyclopscore.client.gui.component.button.ButtonArrow;
19
import org.cyclops.cyclopscore.client.gui.component.button.ButtonText;
20
import org.cyclops.cyclopscore.client.gui.component.input.IInputListener;
21
import org.cyclops.cyclopscore.client.gui.component.input.WidgetArrowedListField;
22
import org.cyclops.cyclopscore.helper.Helpers;
23
import org.cyclops.cyclopscore.helper.L10NHelpers;
24
import org.cyclops.cyclopscore.helper.MinecraftHelpers;
25
import org.cyclops.cyclopscore.helper.RenderHelpers;
26
import org.cyclops.integrateddynamics.IntegratedDynamics;
27
import org.cyclops.integrateddynamics.api.client.gui.subgui.ISubGuiBox;
28
import org.cyclops.integrateddynamics.api.evaluate.variable.IValue;
29
import org.cyclops.integrateddynamics.api.evaluate.variable.IValueType;
30
import org.cyclops.integrateddynamics.api.evaluate.variable.ValueDeseralizationContext;
31
import org.cyclops.integrateddynamics.api.ingredient.IIngredientComponentHandler;
32
import org.cyclops.integrateddynamics.api.logicprogrammer.IConfigRenderPattern;
33
import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElementType;
34
import org.cyclops.integrateddynamics.api.logicprogrammer.IValueTypeLogicProgrammerElement;
35
import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammerBase;
36
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueObjectTypeIngredients;
37
import org.cyclops.integrateddynamics.core.evaluate.variable.ValueTypes;
38
import org.cyclops.integrateddynamics.core.helper.L10NValues;
39
import org.cyclops.integrateddynamics.core.ingredient.IngredientComponentHandlers;
40
import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase;
41
import org.cyclops.integrateddynamics.network.packet.LogicProgrammerSetElementInventory;
42
import org.cyclops.integrateddynamics.network.packet.LogicProgrammerValueTypeIngredientsValueChangedPacket;
43

44
import java.util.Comparator;
45
import java.util.List;
46
import java.util.Map;
47

48
/**
49
 * Element for the ingredients value type.
50
 *
51
 * @author rubensworks
52
 */
53
public class ValueTypeIngredientsLPElement extends ValueTypeLPElementBase {
54

55
    protected static final int OFFSET_X = 20;
56
    protected static final int OFFSET_Y = 21;
57

58
    private IngredientComponent currentType = IngredientComponent.ITEMSTACK;
×
59
    private Map<IngredientComponent, Integer> lengths = Maps.newHashMap();
×
60
    private Map<IngredientComponent, Map<Integer, IValueTypeLogicProgrammerElement>> subElements = Maps.newHashMap();
×
61
    private Map<IngredientComponent, Map<Integer, RenderPattern>> subElementGuis = Maps.newHashMap();
×
62
    private int activeElement = -1;
×
63
    @OnlyIn(Dist.CLIENT)
64
    private MasterSubGuiRenderPattern masterGui;
65

66
    private ValueObjectTypeIngredients.ValueIngredients serverValue = null;
×
67

68
    public ValueTypeIngredientsLPElement() {
69
        super(ValueTypes.OBJECT_INGREDIENTS);
×
70
    }
×
71

72
    public void setServerValue(ValueObjectTypeIngredients.ValueIngredients serverValue) {
73
        this.serverValue = serverValue;
×
74
    }
×
75

76
    @Override
77
    public ILogicProgrammerElementType getType() {
78
        return LogicProgrammerElementTypes.VALUETYPE;
×
79
    }
80

81
    @Override
82
    public IConfigRenderPattern getRenderPattern() {
83
        return IConfigRenderPattern.NONE_CANVAS_WIDE;
×
84
    }
85

86
    @Override
87
    public boolean canWriteElementPre() {
88
        return true;
×
89
    }
90

91
    protected IMixedIngredients constructValues() {
92
        Map<IngredientComponent<?, ?>, List<?>> lists = Maps.newIdentityHashMap();
×
93
        for (IngredientComponent<?, ?> component : IngredientComponentHandlers.REGISTRY.getComponents()) {
×
94
            List values = Lists.newArrayListWithExpectedSize(lengths.get(component));
×
95
            subElements.get(component).entrySet().forEach(entry -> {
×
96
                IIngredientComponentHandler componentHandler = IngredientComponentHandlers.REGISTRY.getComponentHandler(component);
×
97
                try {
98
                    values.add(componentHandler.toInstance(entry.getValue().getValue()));
×
99
                } catch (Exception e) {
×
100
                    values.add(component.getMatcher().getEmptyInstance());
×
101
                }
×
102
            });
×
103
            if (!values.isEmpty()) {
×
104
                lists.put(component, values);
×
105
            }
106
        }
×
107
        return new MixedIngredients(lists);
×
108
    }
109

110
    @Override
111
    public IValue getValue() {
112
        return MinecraftHelpers.isClientSideThread()
×
113
                ? ValueObjectTypeIngredients.ValueIngredients.of(constructValues()) : serverValue;
×
114
    }
115

116
    @Override
117
    public void setValue(IValue value) {
118
        ValueObjectTypeIngredients.ValueIngredients valueIngredients = (ValueObjectTypeIngredients.ValueIngredients) value;
×
119
        if (!MinecraftHelpers.isClientSideThread()) {
×
120
            setServerValue(valueIngredients);
×
121
        }
122

123
        valueIngredients.getRawValue().ifPresent(ingredients -> {
×
124
            // Select itemstack by default if it has instances
125
            if (ingredients.getComponents().contains(IngredientComponent.ITEMSTACK)) {
×
126
                currentType = IngredientComponent.ITEMSTACK;
×
127
            } else {
128
                currentType = null;
×
129
            }
130

131
            for (IngredientComponent<?, ?> ingredientComponent : ingredients.getComponents()) {
×
132
                IIngredientComponentHandler handler = IngredientComponentHandlers.REGISTRY.getComponentHandler(ingredientComponent);
×
133

134
                // If no itemstacks in ingredient, select any other
135
                if (currentType == null) {
×
136
                    currentType = ingredientComponent;
×
137
                }
138

139
                // Save length per ingredient component
140
                lengths.put(ingredientComponent, ingredients.getInstances(ingredientComponent).size());
×
141

142
                // Initialize LP elements for all instances of this ingredient component
143
                Map<Integer, IValueTypeLogicProgrammerElement> entries = Maps.newHashMap();
×
144
                List<?> instances = ingredients.getInstances(ingredientComponent);
×
145
                for (int i = 0; i < instances.size(); i++) {
×
146
                    initializeElementFromInstanceValue(entries, handler, instances.get(i), i);
×
147
                }
148
                subElements.put(ingredientComponent, entries);
×
149
            }
×
150
        });
×
151
    }
×
152

153
    protected <VT extends IValueType<V>, V extends IValue, T, M> void initializeElementFromInstanceValue(Map<Integer, IValueTypeLogicProgrammerElement> entries, IIngredientComponentHandler<VT, V, T, M> handler, T instance, int instanceIndex) {
154
        IValue instanceValue = handler.toValue(instance);
×
155
        IValueTypeLogicProgrammerElement lpElement = instanceValue.getType().createLogicProgrammerElement();
×
156
        lpElement.setValue(instanceValue);
×
157
        entries.put(instanceIndex, lpElement);
×
158
    }
×
159

160
    @Override
161
    @OnlyIn(Dist.CLIENT)
162
    public void setValueInGui(ISubGuiBox subGui) {
163
        if (!subElements.get(currentType).isEmpty()) {
×
164
            setActiveElement(0);
×
165
        }
166
    }
×
167

168
    @Override
169
    public void setValueInContainer(ContainerLogicProgrammerBase container) {
170
        if (!subElements.get(currentType).isEmpty()) {
×
171
            IValueTypeLogicProgrammerElement subElement = setActiveElement(0);
×
172
            int x = RenderPatternCommon.calculateX(ContainerLogicProgrammerBase.BASE_X, ContainerLogicProgrammerBase.MAX_WIDTH, subElement.getRenderPattern()) + ContainerLogicProgrammerBase.BASE_X - OFFSET_X;
×
173
            int y = RenderPatternCommon.calculateY(ContainerLogicProgrammerBase.BASE_Y, ContainerLogicProgrammerBase.MAX_HEIGHT, subElement.getRenderPattern()) + ContainerLogicProgrammerBase.BASE_Y - OFFSET_Y;
×
174
            container.setElementInventory(subElement, x, y);
×
175
            subElement.setValueInContainer(container);
×
176
        }
177
    }
×
178

179
    public int getLength() {
180
        return lengths.get(currentType);
×
181
    }
182

183
    public void setLength(int length) {
184
        lengths.put(currentType, length);
×
185
        setActiveElement(getLength() - 1);
×
186
    }
×
187

188
    public void setCurrentType(IngredientComponent currentType) {
189
        this.currentType = currentType;
×
190
        setActiveElement(subElements.get(currentType).size() - 1);
×
191
    }
×
192

193
    public IValueTypeLogicProgrammerElement setActiveElement(int index) {
194
        activeElement = index;
×
195
        IValueTypeLogicProgrammerElement subElement = null;
×
196
        if (index >= 0) {
×
197
            if (!subElements.get(currentType).containsKey(index)) {
×
198
                subElements.get(currentType).put(index, subElement = IngredientComponentHandlers.REGISTRY.getComponentHandler(currentType)
×
199
                        .getValueType().createLogicProgrammerElement());
×
200
            } else {
201
                subElement = subElements.get(currentType).get(index);
×
202
            }
203
        }
204
        if (MinecraftHelpers.isClientSideThread() && masterGui != null) {
×
205
            masterGui.setActiveElement(activeElement);
×
206
            masterGui.container.onDirty();
×
207
        }
208
        return subElement;
×
209
    }
210

211
    public void removeElement(int index) {
212
        Map<Integer, IValueTypeLogicProgrammerElement> oldSubElements = subElements.get(currentType);
×
213
        Map<Integer, RenderPattern> oldSubElementGuis = subElementGuis.get(currentType);
×
214
        subElements.put(currentType, Maps.newHashMap());
×
215
        subElementGuis.put(currentType, Maps.newHashMap());
×
216
        for (Map.Entry<Integer, IValueTypeLogicProgrammerElement> entry : oldSubElements.entrySet()) {
×
217
            int i = entry.getKey();
×
218
            if (i < index) {
×
219
                subElements.get(currentType).put(i, entry.getValue());
×
220
                subElementGuis.get(currentType).put(i, oldSubElementGuis.get(i));
×
221
            } else if (i > index) {
×
222
                subElements.get(currentType).put(i - 1, entry.getValue());
×
223
                subElementGuis.get(currentType).put(i - 1, oldSubElementGuis.get(i));
×
224
            }
225
        }
×
226
        setLength(getLength() - 1);
×
227
    }
×
228

229
    @Override
230
    public void activate() {
231
        for (IngredientComponent recipeComponent : IngredientComponentHandlers.REGISTRY.getComponents()) {
×
232
            subElements.put(recipeComponent, Maps.newHashMap());
×
233
            subElementGuis.put(recipeComponent, Maps.newHashMap());
×
234
            lengths.put(recipeComponent, 0);
×
235
        }
×
236
    }
×
237

238
    @Override
239
    public void deactivate() {
240

241
    }
×
242

243
    @Override
244
    public Component validate() {
245
        if (!MinecraftHelpers.isClientSideThread()) {
×
246
            return serverValue == null ? Component.literal("") : null;
×
247
        }
248
        if (MinecraftHelpers.isClientSideThread()) {
×
249
            IntegratedDynamics._instance.getPacketHandler().sendToServer(
×
250
                    new LogicProgrammerValueTypeIngredientsValueChangedPacket(ValueDeseralizationContext.ofClient(),
×
251
                            ValueObjectTypeIngredients.ValueIngredients.of(constructValues())));
×
252
        }
253
        for (Map<Integer, IValueTypeLogicProgrammerElement> componentValues : subElements.values()) {
×
254
            for (Map.Entry<Integer, IValueTypeLogicProgrammerElement> entry : componentValues.entrySet()) {
×
255
                Component error = entry.getValue().validate();
×
256
                if (error != null) {
×
257
                    return Component.translatable(L10NValues.VALUETYPE_ERROR_INVALIDLISTELEMENT, entry.getKey(), error);
×
258
                }
259
            }
×
260
        }
×
261
        return null;
×
262
    }
263

264
    @Override
265
    public boolean isItemValidForSlot(int slotId, ItemStack itemStack) {
266
        return (slotId == 0 && super.isItemValidForSlot(slotId, itemStack)) ||
×
267
                (activeElement >= 0 && subElements.get(currentType).containsKey(activeElement)
×
268
                        && subElements.get(currentType).get(activeElement).isItemValidForSlot(slotId, itemStack));
×
269
    }
270

271
    @Override
272
    @OnlyIn(Dist.CLIENT)
273
    public ISubGuiBox createSubGui(int baseX, int baseY, int maxWidth, int maxHeight,
274
                                   ContainerScreenLogicProgrammerBase gui, ContainerLogicProgrammerBase container) {
275
        return masterGui = new MasterSubGuiRenderPattern(this, baseX, baseY, maxWidth, maxHeight, gui, container);
×
276
    }
277

278
    /**
279
     * Sub gui that holds the list element value type panel and the panel for browsing through the elements.
280
     */
281
    @OnlyIn(Dist.CLIENT)
282
    protected static class MasterSubGuiRenderPattern extends RenderPattern<ValueTypeIngredientsLPElement, ContainerScreenLogicProgrammerBase, ContainerLogicProgrammerBase>
283
            implements IRenderPatternValueTypeTooltip {
284

285
        private final int baseX;
286
        private final int baseY;
287
        private final int maxWidth;
288
        private final int maxHeight;
289
        private final ContainerScreenLogicProgrammerBase gui;
290
        private final ContainerLogicProgrammerBase container;
291

292
        protected ListElementSubGui elementSubGui = null;
×
293
        protected int lastGuiLeft;
294
        protected int lastGuiTop;
295
        private boolean renderTooltip = true;
×
296

297
        public MasterSubGuiRenderPattern(ValueTypeIngredientsLPElement element, int baseX, int baseY, int maxWidth, int maxHeight,
298
                                         ContainerScreenLogicProgrammerBase gui, ContainerLogicProgrammerBase container) {
299
            super(element, baseX, baseY, maxWidth, maxHeight, gui, container);
×
300
            subGuiHolder.addSubGui(new SelectionSubGui(element, baseX, baseY, maxWidth, maxHeight, gui, container));
×
301
            this.baseX = baseX;
×
302
            this.baseY = baseY;
×
303
            this.maxWidth = maxWidth;
×
304
            this.maxHeight = maxHeight;
×
305
            this.gui = gui;
×
306
            this.container = container;
×
307
        }
×
308

309
        public void setActiveElement(int index) {
310
            if (elementSubGui != null) {
×
311
                subGuiHolder.removeSubGui(elementSubGui);
×
312
                ((ContainerLogicProgrammerBase) gui.getMenu()).setElementInventory(null, 0, 0);
×
313
            }
314
            if (index >= 0) {
×
315
                subGuiHolder.addSubGui(elementSubGui = new ListElementSubGui(element, baseX, baseY + (getHeight() / 4),
×
316
                        maxWidth, maxHeight, gui, container));
317
                elementSubGui.init(lastGuiLeft, lastGuiTop);
×
318
            }
319
        }
×
320

321
        @Override
322
        public void init(int guiLeft, int guiTop) {
323
            super.init(guiLeft, guiTop);
×
324
            lastGuiLeft = guiLeft;
×
325
            lastGuiTop = guiTop;
×
326
        }
×
327

328
        @Override
329
        public void drawGuiContainerForegroundLayer(GuiGraphics guiGraphics, int guiLeft, int guiTop, TextureManager textureManager, Font fontRenderer, int mouseX, int mouseY) {
330
            super.drawGuiContainerForegroundLayer(guiGraphics, guiLeft, guiTop, textureManager, fontRenderer, mouseX, mouseY);
×
331

332
            // Output type tooltip
333
            this.drawTooltipForeground(gui, guiGraphics, container, guiLeft, guiTop, mouseX, mouseY, element.getValueType());
×
334
        }
×
335

336
        @Override
337
        public boolean isRenderTooltip() {
338
            return this.renderTooltip;
×
339
        }
340

341
        @Override
342
        public void setRenderTooltip(boolean renderTooltip) {
343
            this.renderTooltip = renderTooltip;
×
344
        }
×
345
    }
346

347
    /**
348
     * Selection panel for the type.
349
     */
350
    @OnlyIn(Dist.CLIENT)
351
    protected static class SelectionSubGui extends RenderPattern<ValueTypeIngredientsLPElement, ContainerScreenLogicProgrammerBase, ContainerLogicProgrammerBase> implements IInputListener {
352

353
        private WidgetArrowedListField<IngredientComponent<?, ?>> valueTypeSelector = null;
×
354
        private Button arrowAdd;
355

356
        public SelectionSubGui(ValueTypeIngredientsLPElement element, int baseX, int baseY, int maxWidth, int maxHeight,
357
                               ContainerScreenLogicProgrammerBase gui, ContainerLogicProgrammerBase container) {
358
            super(element, baseX, baseY, maxWidth, maxHeight, gui, container);
×
359
        }
×
360

361
        @Override
362
        public int getHeight() {
363
            return super.getHeight() / 4;
×
364
        }
365

366
        protected static List<IngredientComponent<?, ?>> getValueTypes() {
367
            // By coincidence, sorting by name (in reverse) is sufficient to achieve the order we want,
368
            // for the following known ingredient components:
369
            // - minecraft:itemstack
370
            // - minecraft:fluidstack
371
            // - minecraft:energy
372
            // - mekanism:chemicalstack
373
            return IngredientComponentHandlers.REGISTRY.getComponents().stream()
×
374
                    .sorted(Comparator.<IngredientComponent<?, ?>, ResourceLocation>comparing(IngredientComponent::getName).reversed())
×
375
                    .toList();
×
376
        }
377

378
        @Override
379
        public void init(int guiLeft, int guiTop) {
380
            super.init(guiLeft, guiTop);
×
381
            valueTypeSelector = new WidgetArrowedListField<>(Minecraft.getInstance().font,
×
382
                    getX() + guiLeft + getWidth() / 2 - 50, getY() + guiTop + 2, 100, 15, true, Component.translatable("valuetype.integrateddynamics.value_type"), true, getValueTypes()) {
×
383
                @Override
384
                protected String activeElementToString(IngredientComponent element) {
385
                    return L10NHelpers.localize(element.getTranslationKey());
×
386
                }
387
            };
388
            valueTypeSelector.setListener(this);
×
389
            //onChanged();
390
            int x = guiLeft + getX();
×
391
            int y = guiTop + getY();
×
392
            buttonList.add(arrowAdd = new ButtonText(x + getWidth() - 13, y + getHeight() - 13, 12, 12, Component.translatable("gui.integrateddynamics.button.add"), Component.literal("+"), (b) -> {
×
393
            }, true));
×
394
        }
×
395

396
        @Override
397
        public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
398
            return super.mouseClicked(mouseX, mouseY, mouseButton) || valueTypeSelector.mouseClicked(mouseX, mouseY, mouseButton);
×
399
        }
400

401
        @Override
402
        protected void actionPerformed(Button guibutton) {
403
            super.actionPerformed(guibutton);
×
404
            if (guibutton == arrowAdd) {
×
405
                element.setLength(element.getLength() + 1);
×
406
            }
407
        }
×
408

409
        @Override
410
        public void renderBg(GuiGraphics guiGraphics, int guiLeft, int guiTop, TextureManager textureManager, Font fontRenderer, float partialTicks, int mouseX, int mouseY) {
411
            super.renderBg(guiGraphics, guiLeft, guiTop, textureManager, fontRenderer, partialTicks, mouseX, mouseY);
×
412
            valueTypeSelector.renderWidget(guiGraphics, mouseX, mouseY, partialTicks);
×
413
        }
×
414

415
        @Override
416
        public void onChanged() {
417
            element.setCurrentType(valueTypeSelector.getActiveElement());
×
418
        }
×
419
    }
420

421
    /**
422
     * Panel for browsing through the list elements and updating them.
423
     */
424
    @OnlyIn(Dist.CLIENT)
425
    protected static class ListElementSubGui extends RenderPattern<ValueTypeIngredientsLPElement, ContainerScreenLogicProgrammerBase<?>, ContainerLogicProgrammerBase> {
426

427
        private ButtonArrow arrowLeft;
428
        private ButtonArrow arrowRight;
429
        private Button arrowRemove;
430

431
        private RenderPattern subGui;
432
        private IValueTypeLogicProgrammerElement subElement;
433

434
        public ListElementSubGui(ValueTypeIngredientsLPElement element, int baseX, int baseY, int maxWidth, int maxHeight,
435
                                 ContainerScreenLogicProgrammerBase<?> gui, ContainerLogicProgrammerBase container) {
436
            super(element, baseX, baseY, maxWidth, maxHeight, gui, container);
×
437
            this.subGui = element.subElementGuis.get(element.currentType).get(element.activeElement);
×
438
            this.subElement = element.subElements.get(element.currentType).get(element.activeElement);
×
439
            if(subGui == null) {
×
440
                subGui = (RenderPattern) subElement.createSubGui(baseX, baseY, maxWidth,
×
441
                        maxHeight / 3 * 2, gui, container);
442
                element.subElementGuis.get(element.currentType).put(
×
443
                        element.activeElement,
×
444
                        subGui);
445
            }
446
            int x = getX() + baseX - OFFSET_X;
×
447
            int y = getY() + baseY - OFFSET_Y;
×
448
            gui.getMenu().setElementInventory(subElement, x, y);
×
449
            subGuiHolder.addSubGui(subGui);
×
450

451
            // Do the same thing server-side
452
            IntegratedDynamics._instance.getPacketHandler().sendToServer(
×
453
                    new LogicProgrammerSetElementInventory(
454
                            IngredientComponentHandlers.REGISTRY.getComponentHandler(element.currentType).getValueType(), x, y));
×
455
        }
×
456

457
        @Override
458
        public int getHeight() {
459
            return (super.getHeight() / 4) * 3;
×
460
        }
461

462
        @Override
463
        public void init(int guiLeft, int guiTop) {
464
            super.init(guiLeft, guiTop);
×
465
            int x = guiLeft + getX();
×
466
            int y = guiTop + getY();
×
467
            buttonList.add(arrowLeft = new ButtonArrow(x, y, Component.translatable("gui.cyclopscore.left"),
×
468
                    b -> element.setActiveElement(element.activeElement - 1), ButtonArrow.Direction.WEST));
×
469
            buttonList.add(arrowRight = new ButtonArrow(x + getWidth() - arrowLeft.getWidth() - 1, y, Component.translatable("gui.cyclopscore.right"),
×
470
                    b -> element.setActiveElement(element.activeElement + 1), ButtonArrow.Direction.EAST));
×
471
            buttonList.add(arrowRemove = new ButtonText(x + (getWidth() / 2) - (arrowLeft.getWidth() / 2), y + getHeight() - 13, 12, 12, Component.translatable("gui.integrateddynamics.button.remove"), Component.literal("-"),
×
472
                    b -> element.removeElement(element.activeElement), true));
×
473
            arrowLeft.active = element.activeElement > 0;
×
474
            arrowRight.active = element.activeElement < element.getLength() - 1;
×
475
            arrowRemove.active = element.getLength() > 0;
×
476
            subElement.setValueInGui(subGui);
×
477
            subElement.setValueInContainer(subGui.container);
×
478
        }
×
479

480
        @Override
481
        public void renderBg(GuiGraphics guiGraphics, int guiLeft, int guiTop, TextureManager textureManager, Font fontRenderer, float partialTicks, int mouseX, int mouseY) {
482
            super.renderBg(guiGraphics, guiLeft, guiTop, textureManager, fontRenderer, partialTicks, mouseX, mouseY);
×
483
            int x = guiLeft + getX() + (getWidth() / 2);
×
484
            int y = guiTop + getY() + 4;
×
485
            RenderHelpers.drawScaledCenteredString(guiGraphics.pose(), guiGraphics.bufferSource(), fontRenderer, String.valueOf(element.activeElement), x - 4, y + 2, 10, Helpers.RGBToInt(20, 20, 20), false, Font.DisplayMode.NORMAL);
×
486
        }
×
487
    }
488

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

© 2026 Coveralls, Inc