diff options
| author | shedaniel <daniel@shedaniel.me> | 2023-09-01 20:00:22 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2023-09-01 20:01:10 +0800 |
| commit | 21d144a7b605169578ba8e1dc1663d1ab042660d (patch) | |
| tree | c1be3b449d2f36290281a27b8bcdddf86e351d91 /api/src/main/java | |
| parent | 1833c18d5f3615d0a4a17689467b32df75dd92f1 (diff) | |
| parent | 8c03832d5ae716beba4047166505181cadd76e75 (diff) | |
| download | RoughlyEnoughItems-21d144a7b605169578ba8e1dc1663d1ab042660d.tar.gz RoughlyEnoughItems-21d144a7b605169578ba8e1dc1663d1ab042660d.tar.bz2 RoughlyEnoughItems-21d144a7b605169578ba8e1dc1663d1ab042660d.zip | |
Merge remote-tracking branch 'shedaniel/11.x-1.19.4' into 12.x-1.20
Diffstat (limited to 'api/src/main/java')
24 files changed, 560 insertions, 70 deletions
diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java index 994bb1aae..d639d340e 100644 --- a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/TransferHandler.java @@ -27,6 +27,7 @@ import me.shedaniel.math.Point; import me.shedaniel.rei.api.client.gui.widgets.Tooltip; import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.transfer.info.MenuTransferException; import me.shedaniel.rei.impl.ClientInternals; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -40,6 +41,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.function.BiConsumer; import java.util.function.Supplier; @@ -50,7 +52,7 @@ import java.util.function.Supplier; * as a lightweight and simple way to implement recipe transfers. * * @see TransferHandlerRegistry - * @see me.shedaniel.rei.api.common.transfer.info.MenuInfo + * @see me.shedaniel.rei.api.client.registry.transfer.simple.SimpleTransferHandler */ @Environment(EnvType.CLIENT) public interface TransferHandler extends Comparable<TransferHandler> { @@ -62,6 +64,16 @@ public interface TransferHandler extends Comparable<TransferHandler> { } /** + * Returns whether the transfer handler is applicable to the current context. + * + * @param context the context of the transfer + * @return whether the transfer handler is applicable to the current context. + */ + default ApplicabilityResult checkApplicable(Context context) { + return ApplicabilityResult.createApplicable(); + } + + /** * Handles the transfer of the specified display. * <p> * If {@link Context#isActuallyCrafting()} returns {@code false}, @@ -257,6 +269,33 @@ public interface TransferHandler extends Comparable<TransferHandler> { } } + interface ApplicabilityResult { + static ApplicabilityResult createNotApplicable() { + return new ApplicabilityResultImpl(false, null); + } + + static ApplicabilityResult createApplicableWithError(Component error) { + return createApplicableWithError(Result.createFailed(error)); + } + + static ApplicabilityResult createApplicableWithError(TransferHandler.Result result) { + if (result == null) throw new NullPointerException("result"); + if (!result.isApplicable()) throw new IllegalArgumentException("result is not applicable"); + return new ApplicabilityResultImpl(true, result); + } + + static ApplicabilityResult createApplicable() { + return new ApplicabilityResultImpl(true, null); + } + + boolean isApplicable(); + + boolean isSuccessful(); + + @Nullable + TransferHandler.Result getError(); + } + @ApiStatus.Internal final class ResultImpl implements Result { private boolean successful, applicable, returningToScreen, blocking; @@ -413,4 +452,32 @@ public interface TransferHandler extends Comparable<TransferHandler> { return recipeDisplaySupplier.get(); } } + + @ApiStatus.Internal + final class ApplicabilityResultImpl implements ApplicabilityResult { + private boolean applicable; + @Nullable + private Result error; + + public ApplicabilityResultImpl(boolean applicable, @Nullable Result error) { + this.applicable = applicable; + this.error = error; + } + + @Override + public boolean isApplicable() { + return this.applicable; + } + + @Override + public boolean isSuccessful() { + return this.isApplicable() && this.error == null; + } + + @Nullable + @Override + public TransferHandler.Result getError() { + return this.error; + } + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/simple/SimpleTransferHandler.java b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/simple/SimpleTransferHandler.java new file mode 100644 index 000000000..659cc933b --- /dev/null +++ b/api/src/main/java/me/shedaniel/rei/api/client/registry/transfer/simple/SimpleTransferHandler.java @@ -0,0 +1,200 @@ +/* + * This file is licensed under the MIT License, part of Roughly Enough Items. + * Copyright (c) 2018, 2019, 2020, 2021, 2022, 2023 shedaniel + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package me.shedaniel.rei.api.client.registry.transfer.simple; + +import it.unimi.dsi.fastutil.ints.IntSet; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.widgets.Slot; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.registry.transfer.TransferHandler; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.InputIngredient; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessor; +import me.shedaniel.rei.api.common.util.CollectionUtils; +import me.shedaniel.rei.impl.ClientInternals; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@ApiStatus.Experimental +public interface SimpleTransferHandler extends TransferHandler { + static <C extends AbstractContainerMenu, D extends Display> SimpleTransferHandler create(Class<? extends C> containerClass, + CategoryIdentifier<D> categoryIdentifier, + IntRange inputSlots) { + return new SimpleTransferHandler() { + @Override + public ApplicabilityResult checkApplicable(Context context) { + if (!containerClass.isInstance(context.getMenu()) + || !categoryIdentifier.equals(context.getDisplay().getCategoryIdentifier()) + || context.getContainerScreen() == null) { + return ApplicabilityResult.createNotApplicable(); + } else { + return ApplicabilityResult.createApplicable(); + } + } + + @Override + public Iterable<SlotAccessor> getInputSlots(Context context) { + return IntStream.range(inputSlots.min, inputSlots.maxExclusive) + .mapToObj(id -> SlotAccessor.fromSlot(context.getMenu().getSlot(id))) + .toList(); + } + + @Override + public Iterable<SlotAccessor> getInventorySlots(Context context) { + LocalPlayer player = context.getMinecraft().player; + Inventory inventory = player.getInventory(); + return IntStream.range(0, inventory.items.size()) + .mapToObj(index -> SlotAccessor.fromPlayerInventory(player, index)) + .collect(Collectors.toList()); + } + }; + } + + static <C extends Container, D extends Display> SimpleTransferHandler create(Class<? extends C> containerClass, + CategoryIdentifier<D> categoryIdentifier, + IntRange inputSlots, + IntRange inventorySlots) { + return new SimpleTransferHandler() { + @Override + public ApplicabilityResult checkApplicable(Context context) { + if (!containerClass.isInstance(context.getMenu()) + || !categoryIdentifier.equals(context.getDisplay().getCategoryIdentifier()) + || context.getContainerScreen() == null) { + return ApplicabilityResult.createNotApplicable(); + } else { + return ApplicabilityResult.createApplicable(); + } + } + + @Override + public Iterable<SlotAccessor> getInputSlots(Context context) { + return IntStream.range(inputSlots.min, inputSlots.maxExclusive) + .mapToObj(id -> SlotAccessor.fromSlot(context.getMenu().getSlot(id))) + .toList(); + } + + @Override + public Iterable<SlotAccessor> getInventorySlots(Context context) { + return IntStream.range(inventorySlots.min, inventorySlots.maxExclusive) + .mapToObj(id -> SlotAccessor.fromSlot(context.getMenu().getSlot(id))) + .toList(); + } + }; + } + + record IntRange(int min, int maxExclusive) { + } + + /** + * Returns an {@link Iterable} of {@link SlotAccessor}, of the slots that houses the inputs of the transfer. + * + * @param context the context of the transfer + * @return an {@link Iterable} of the input slots. + */ + Iterable<SlotAccessor> getInputSlots(Context context); + + /** + * Returns an {@link Iterable} of {@link SlotAccessor}, of the slots that provides ingredients. + * + * @param context the context of the transfer + * @return an {@link Iterable} of the inventory slots. + */ + Iterable<SlotAccessor> getInventorySlots(Context context); + + /** + * Returns the inputs of the {@link Display}. The nested lists are possible stacks for that specific slot. + * + * @param context the context of the transfer + * @return the list of lists of items + */ + default List<InputIngredient<ItemStack>> getInputsIndexed(Context context) { + if (context.getDisplay() == null) return Collections.emptyList(); + return CollectionUtils.map(context.getDisplay().getInputIngredients(context.getMenu(), context.getMinecraft().player), (entry) -> + InputIngredient.withType(entry, VanillaEntryTypes.ITEM)); + } + + /** + * Renders the missing ingredients of the transfer. + * + * @param context the context of the transfer + * @param inputs the list of inputs + * @param missing the list of missing stacks + * @param missingIndices the indices of the missing stacks + * @param graphics the rendering transforming context + * @param mouseX the mouse x position + * @param mouseY the mouse y position + * @param delta the delta frame time + * @param widgets the widgets set-up by the category + * @param bounds the bounds of the display + */ + default void renderMissingInput(Context context, List<InputIngredient<ItemStack>> inputs, List<InputIngredient<ItemStack>> missing, + IntSet missingIndices, GuiGraphics graphics, int mouseX, int mouseY, + float delta, List<Widget> widgets, Rectangle bounds) { + int i = 0; + for (Widget widget : widgets) { + if (widget instanceof Slot && ((Slot) widget).getNoticeMark() == Slot.INPUT) { + if (missingIndices.contains(i++)) { + graphics.pose().pushPose(); + graphics.pose().translate(0, 0, 50); + Rectangle innerBounds = ((Slot) widget).getInnerBounds(); + graphics.fill(innerBounds.x, innerBounds.y, innerBounds.getMaxX(), innerBounds.getMaxY(), 0x40ff0000); + graphics.pose().popPose(); + } + } + } + } + + default MissingInputRenderer getMissingInputRenderer() { + return this::renderMissingInput; + } + + @Override + default Result handle(Context context) { + return handleSimpleTransfer(context, getMissingInputRenderer(), getInputsIndexed(context), getInputSlots(context), getInventorySlots(context)); + } + + default Result handleSimpleTransfer(TransferHandler.Context context, MissingInputRenderer missingInputRenderer, + List<InputIngredient<ItemStack>> inputs, Iterable<SlotAccessor> inputSlots, + Iterable<SlotAccessor> inventorySlots) { + return ClientInternals.getSimpleTransferHandler().handle(context, missingInputRenderer, inputs, inputSlots, inventorySlots); + } + + interface MissingInputRenderer { + void renderMissingInput(Context context, List<InputIngredient<ItemStack>> inputs, List<InputIngredient<ItemStack>> missing, + IntSet missingIndices, GuiGraphics graphics, int mouseX, int mouseY, + float delta, List<Widget> widgets, Rectangle bounds); + } +} diff --git a/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java b/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java index 9fdda7940..4e436efcb 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/display/Display.java @@ -32,7 +32,10 @@ import me.shedaniel.rei.api.common.transfer.info.MenuSerializationContext; import me.shedaniel.rei.api.common.util.CollectionUtils; import me.shedaniel.rei.impl.display.DisplaySpec; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.Collections; @@ -68,11 +71,24 @@ public interface Display extends DisplaySpec { * * @return a list of inputs */ + @Deprecated(forRemoval = true) default List<InputIngredient<EntryStack<?>>> getInputIngredients(MenuSerializationContext<?, ?, ?> context, MenuInfo<?, ?> info, boolean fill) { return CollectionUtils.mapIndexed(getInputEntries(context, info, fill), InputIngredient::of); } /** + * Returns the list of inputs for this display, aligned for the menu. This only affects the stacks resolving for the display, + * and not necessarily the stacks that are displayed. + * <p> + * Each ingredient is also provided with the corresponding index slot-wise. The order of the list does not matter. + * + * @return a list of inputs + */ + default List<InputIngredient<EntryStack<?>>> getInputIngredients(@Nullable AbstractContainerMenu menu, @Nullable Player player) { + return CollectionUtils.mapIndexed(getInputEntries(), InputIngredient::of); + } + + /** * Returns the list of outputs for this display. This only affects the stacks resolving for the display, * and not necessarily the stacks that are displayed. * diff --git a/api/src/main/java/me/shedaniel/rei/api/common/entry/InputIngredient.java b/api/src/main/java/me/shedaniel/rei/api/common/entry/InputIngredient.java index 0189d3f87..d29a798d6 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/entry/InputIngredient.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/entry/InputIngredient.java @@ -71,6 +71,34 @@ public interface InputIngredient<T> { } /** + * Creates an input ingredient at the given index. + * + * @param index the index + * @param displayIndex the display index + * @param ingredient the ingredient + * @param <T> the type of entry + * @return the input ingredient + */ + static <T> InputIngredient<T> of(int index, int displayIndex, List<T> ingredient) { + return new InputIngredient<>() { + @Override + public List<T> get() { + return ingredient; + } + + @Override + public int getIndex() { + return index; + } + + @Override + public int getDisplayIndex() { + return displayIndex; + } + }; + } + + /** * Returns an input ingredient with only the stacks matching given entry type. * * @param ingredient the original ingredient @@ -93,6 +121,11 @@ public interface InputIngredient<T> { public int getIndex() { return ingredient.getIndex(); } + + @Override + public int getDisplayIndex() { + return ingredient.getDisplayIndex(); + } }; } @@ -111,4 +144,8 @@ public interface InputIngredient<T> { * @return the index */ int getIndex(); + + default int getDisplayIndex() { + return getIndex(); + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java index 6a1a320d0..ca265b611 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/plugins/REIPlugin.java @@ -32,6 +32,7 @@ import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry; import me.shedaniel.rei.api.common.fluid.FluidSupportProvider; import me.shedaniel.rei.api.common.registry.ReloadStage; import me.shedaniel.rei.api.common.registry.Reloadable; +import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessorRegistry; import org.jetbrains.annotations.ApiStatus; import java.util.Collection; @@ -108,6 +109,16 @@ public interface REIPlugin<P extends REIPlugin<?>> extends Comparable<REIPlugin< default void registerDisplaySerializer(DisplaySerializerRegistry registry) { } + /** + * Registers new slot accessor serializers + * + * @param registry the registry + */ + @ApiStatus.OverrideOnly + @ApiStatus.Experimental + default void registerSlotAccessors(SlotAccessorRegistry registry) { + } + @ApiStatus.OverrideOnly default void preStage(PluginManager<P> manager, ReloadStage stage) { } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java index 3c5faf553..dee0825db 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/RecipeFinder.java @@ -26,8 +26,7 @@ package me.shedaniel.rei.api.common.transfer; import com.google.common.collect.Lists; import it.unimi.dsi.fastutil.ints.*; import net.minecraft.core.NonNullList; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.world.item.Item; +import net.minecraft.world.entity.player.StackedContents; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import org.jetbrains.annotations.Nullable; @@ -40,11 +39,11 @@ public class RecipeFinder { public final Int2IntMap idToAmountMap = new Int2IntOpenHashMap(); public static int getItemId(ItemStack stack) { - return BuiltInRegistries.ITEM.getId(stack.getItem()); + return StackedContents.getStackingIndex(stack); } public static ItemStack getStackFromId(int itemId) { - return itemId == 0 ? ItemStack.EMPTY : new ItemStack(Item.byId(itemId)); + return StackedContents.fromStackingIndex(itemId); } public void addNormalItem(ItemStack stack) { @@ -63,7 +62,6 @@ public class RecipeFinder { int itemCount = Math.min(count, stack.getCount()); this.addItem(itemId, itemCount); } - } public boolean contains(int itemId) { @@ -93,16 +91,16 @@ public class RecipeFinder { return this.findRecipe(ingredients, intList_1, 1); } - public boolean findRecipe(NonNullList<Ingredient> ingredients, @Nullable IntList intList_1, int int_1) { - return (new RecipeFinder.Filter(ingredients)).find(int_1, intList_1); + public boolean findRecipe(NonNullList<Ingredient> ingredients, @Nullable IntList intList_1, int maxCrafts) { + return (new RecipeFinder.Filter(ingredients)).find(maxCrafts, intList_1); } public int countRecipeCrafts(NonNullList<Ingredient> ingredients, @Nullable IntList intList_1) { return this.countRecipeCrafts(ingredients, Integer.MAX_VALUE, intList_1); } - public int countRecipeCrafts(NonNullList<Ingredient> ingredients, int int_1, @Nullable IntList intList_1) { - return (new RecipeFinder.Filter(ingredients)).countCrafts(int_1, intList_1); + public int countRecipeCrafts(NonNullList<Ingredient> ingredients, int maxCrafts, @Nullable IntList intList_1) { + return (new RecipeFinder.Filter(ingredients)).countCrafts(maxCrafts, intList_1); } public void clear() { @@ -115,7 +113,7 @@ public class RecipeFinder { private final int[] usableIngredientItemIds; private final int usableIngredientSize; private final BitSet bitSet; - private final IntList field_7557 = new IntArrayList(); + private final IntList path = new IntArrayList(); private final NonNullList<Ingredient> ingredientsInput; public Filter(NonNullList<Ingredient> ingredientsInput) { @@ -133,7 +131,7 @@ public class RecipeFinder { // Loops over usable ingredients for (int usableIngredientIndex = 0; usableIngredientIndex < this.usableIngredientSize; ++usableIngredientIndex) { if (possibleStacks.contains(this.usableIngredientItemIds[usableIngredientIndex])) { - this.bitSet.set(this.method_7420(true, usableIngredientIndex, ingredientIndex)); + this.bitSet.set(this.getIndex(true, usableIngredientIndex, ingredientIndex)); } } } @@ -141,21 +139,21 @@ public class RecipeFinder { } @SuppressWarnings("deprecation") - public boolean find(int int_1, @Nullable IntList intList_1) { - if (int_1 <= 0) { + public boolean find(int maxCrafts, @Nullable IntList intList_1) { + if (maxCrafts <= 0) { return true; } else { int int_2; - for (int_2 = 0; this.method_7423(int_1); ++int_2) { - RecipeFinder.this.take(this.usableIngredientItemIds[this.field_7557.getInt(0)], int_1); - int int_3 = this.field_7557.size() - 1; - this.method_7421(this.field_7557.getInt(int_3)); + for (int_2 = 0; this.dfs(maxCrafts); ++int_2) { + RecipeFinder.this.take(this.usableIngredientItemIds[this.path.getInt(0)], maxCrafts); + int int_3 = this.path.size() - 1; + this.setSatisfied(this.path.getInt(int_3)); for (int int_4 = 0; int_4 < int_3; ++int_4) { - this.method_7414((int_4 & 1) == 0, this.field_7557.get(int_4), this.field_7557.get(int_4 + 1)); + this.toggleResidual((int_4 & 1) == 0, this.path.get(int_4), this.path.get(int_4 + 1)); } - this.field_7557.clear(); + this.path.clear(); this.bitSet.clear(0, this.ingredientCount + this.usableIngredientSize); } @@ -174,9 +172,9 @@ public class RecipeFinder { intList_1.add(0); } else { for (int int_7 = 0; int_7 < this.usableIngredientSize; ++int_7) { - if (this.method_7425(false, int_5, int_7)) { - this.method_7414(true, int_7, int_5); - RecipeFinder.this.addItem(this.usableIngredientItemIds[int_7], int_1); + if (this.hasResidual(false, int_5, int_7)) { + this.toggleResidual(true, int_7, int_5); + RecipeFinder.this.addItem(this.usableIngredientItemIds[int_7], maxCrafts); if (boolean_2) { intList_1.add(this.usableIngredientItemIds[int_7]); } @@ -209,18 +207,18 @@ public class RecipeFinder { return intCollection_1.toIntArray(); } - private boolean method_7423(int int_1) { + private boolean dfs(int amount) { int usableIngredientSize = this.usableIngredientSize; for (int int_3 = 0; int_3 < usableIngredientSize; ++int_3) { - if (RecipeFinder.this.idToAmountMap.get(this.usableIngredientItemIds[int_3]) >= int_1) { - this.method_7413(false, int_3); + if (RecipeFinder.this.idToAmountMap.get(this.usableIngredientItemIds[int_3]) >= amount) { + this.visit(false, int_3); - while (!this.field_7557.isEmpty()) { - int int_4 = this.field_7557.size(); + |
