diff --git a/gradle.properties b/gradle.properties index 11bbc782..83a702dd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,7 +13,7 @@ loader_version_range=[4,) mod_id=sophisticatedstorage mod_name=Sophisticated Storage mod_license=GNU General Public License v3.0 -mod_version=1.2.11 +mod_version=1.3.0 mod_group_id=sophisticatedstorage mod_authors=P3pp3rF1y, Ridanisaurus mod_description=Fancy and functional storage containers. @@ -35,7 +35,7 @@ jade_cf_file_id=5109393 chipped_cf_file_id=5506938 resourcefullib_cf_file_id=5483169 athena_cf_file_id=5431579 -sc_version=[1.21.1-1.1.6,1.22) +sc_version=[1.21.1-1.2.0,1.22) sb_version=[1.21,1.22) # publish diff --git a/src/generated/resources/data/sophisticatedstorage/tags/item/upgrade.json b/src/generated/resources/data/sophisticatedstorage/tags/item/upgrade.json index 73c346a0..9ed98cba 100644 --- a/src/generated/resources/data/sophisticatedstorage/tags/item/upgrade.json +++ b/src/generated/resources/data/sophisticatedstorage/tags/item/upgrade.json @@ -1,66 +1,67 @@ { "values": [ - "sophisticatedstorage:advanced_pickup_upgrade", - "sophisticatedstorage:advanced_pump_upgrade", + "sophisticatedstorage:blasting_upgrade", + "sophisticatedstorage:auto_smoking_upgrade", + "sophisticatedstorage:auto_smelting_upgrade", + "sophisticatedstorage:smoking_upgrade", "sophisticatedstorage:advanced_void_upgrade", - "sophisticatedstorage:stack_upgrade_tier_1_plus", - { - "id": "sophisticatedstorage:chipped/alchemy_bench_upgrade", - "required": false - }, + "sophisticatedstorage:pump_upgrade", + "sophisticatedstorage:stack_upgrade_tier_4", { - "id": "sophisticatedstorage:chipped/loom_table_upgrade", + "id": "sophisticatedstorage:chipped/carpenters_table_upgrade", "required": false }, + "sophisticatedstorage:filter_upgrade", + "sophisticatedstorage:jukebox_upgrade", + "sophisticatedstorage:advanced_filter_upgrade", + "sophisticatedstorage:void_upgrade", { - "id": "sophisticatedstorage:chipped/botanist_workbench_upgrade", + "id": "sophisticatedstorage:chipped/alchemy_bench_upgrade", "required": false }, + "sophisticatedstorage:hopper_upgrade", "sophisticatedstorage:stack_upgrade_tier_1", - "sophisticatedstorage:smelting_upgrade", - "sophisticatedstorage:auto_smoking_upgrade", + "sophisticatedstorage:magnet_upgrade", + "sophisticatedstorage:advanced_feeding_upgrade", + "sophisticatedstorage:feeding_upgrade", { "id": "sophisticatedstorage:chipped/mason_table_upgrade", "required": false }, - "sophisticatedstorage:advanced_jukebox_upgrade", - "sophisticatedstorage:feeding_upgrade", - "sophisticatedstorage:xp_pump_upgrade", - "sophisticatedstorage:advanced_feeding_upgrade", - "sophisticatedstorage:void_upgrade", - "sophisticatedstorage:blasting_upgrade", - "sophisticatedstorage:compacting_upgrade", - "sophisticatedstorage:auto_blasting_upgrade", - "sophisticatedstorage:smoking_upgrade", - "sophisticatedstorage:advanced_magnet_upgrade", - "sophisticatedstorage:filter_upgrade", - "sophisticatedstorage:pickup_upgrade", "sophisticatedstorage:stack_upgrade_tier_2", + "sophisticatedstorage:stack_upgrade_tier_3", + "sophisticatedstorage:stack_upgrade_tier_1_plus", + "sophisticatedstorage:advanced_pump_upgrade", + "sophisticatedstorage:pickup_upgrade", + { + "id": "sophisticatedstorage:chipped/loom_table_upgrade", + "required": false + }, + "sophisticatedstorage:compression_upgrade", { "id": "sophisticatedstorage:chipped/glassblower_upgrade", "required": false }, - "sophisticatedstorage:stonecutter_upgrade", - "sophisticatedstorage:advanced_hopper_upgrade", "sophisticatedstorage:crafting_upgrade", - "sophisticatedstorage:jukebox_upgrade", - "sophisticatedstorage:stack_upgrade_tier_5", - "sophisticatedstorage:hopper_upgrade", - "sophisticatedstorage:advanced_compacting_upgrade", - "sophisticatedstorage:magnet_upgrade", - "sophisticatedstorage:compression_upgrade", + "sophisticatedstorage:advanced_hopper_upgrade", { - "id": "sophisticatedstorage:chipped/tinkering_table_upgrade", + "id": "sophisticatedstorage:chipped/botanist_workbench_upgrade", "required": false }, - "sophisticatedstorage:stack_upgrade_tier_4", - "sophisticatedstorage:auto_smelting_upgrade", - "sophisticatedstorage:pump_upgrade", - "sophisticatedstorage:advanced_filter_upgrade", - "sophisticatedstorage:stack_upgrade_tier_3", + "sophisticatedstorage:infinity_upgrade", + "sophisticatedstorage:auto_blasting_upgrade", + "sophisticatedstorage:smelting_upgrade", { - "id": "sophisticatedstorage:chipped/carpenters_table_upgrade", + "id": "sophisticatedstorage:chipped/tinkering_table_upgrade", "required": false - } + }, + "sophisticatedstorage:compacting_upgrade", + "sophisticatedstorage:advanced_jukebox_upgrade", + "sophisticatedstorage:stonecutter_upgrade", + "sophisticatedstorage:advanced_magnet_upgrade", + "sophisticatedstorage:advanced_pickup_upgrade", + "sophisticatedstorage:advanced_compacting_upgrade", + "sophisticatedstorage:stack_upgrade_tier_5", + "sophisticatedstorage:xp_pump_upgrade" ] } \ No newline at end of file diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/LimitedBarrelBlockEntity.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/LimitedBarrelBlockEntity.java index 92602d57..0481b16d 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/LimitedBarrelBlockEntity.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/LimitedBarrelBlockEntity.java @@ -165,15 +165,30 @@ public boolean depositItem(Player player, InteractionHand hand, ItemStack stackI return depositFromAllOfPlayersInventory(player, slot, invHandler, stackInSlot, memorySettings); } - ItemStack result = invHandler.insertItemOnlyToSlot(slot, stackInHand, true); - if (result.getCount() != stackInHand.getCount()) { - result = invHandler.insertItemOnlyToSlot(slot, stackInHand, false); - if (isLocked()) { - memorySettings.selectSlot(slot); + if (stackInSlot.isEmpty()) { + if (invHandler.isItemValid(slot, stackInHand, player)) { + int stackLimit = invHandler.getStackLimit(slot, stackInHand); + invHandler.setStackInSlot(slot, stackInHand.split(stackLimit)); + if (isLocked()) { + memorySettings.selectSlot(slot); + } + if (stackInHand.isEmpty()) { + player.setItemInHand(hand, ItemStack.EMPTY); + } + return true; + } + } else { + ItemStack result = invHandler.insertItemOnlyToSlot(slot, stackInHand, true); + if (result.getCount() != stackInHand.getCount()) { + result = invHandler.insertItemOnlyToSlot(slot, stackInHand, false); + if (isLocked()) { + memorySettings.selectSlot(slot); + } + player.setItemInHand(hand, result); + return true; } - player.setItemInHand(hand, result); - return true; } + return false; } diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageBlockEntity.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageBlockEntity.java index bf70dc6c..44ff0145 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageBlockEntity.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageBlockEntity.java @@ -68,7 +68,7 @@ protected StorageBlockEntity(BlockPos pos, BlockState state, BlockEntityType this::setChanged, () -> WorldHelper.notifyBlockUpdate(this), () -> { setChanged(); WorldHelper.notifyBlockUpdate(this); - }, this instanceof BarrelBlockEntity ? 4 : 1) { + }, this instanceof BarrelBlockEntity ? 4 : 1, this instanceof ICountDisplay || this instanceof IFillLevelDisplay) { @Override public Optional getContentsUuid() { diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageWrapper.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageWrapper.java index c59ec5c1..692813ec 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageWrapper.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/block/StorageWrapper.java @@ -73,12 +73,12 @@ public abstract class StorageWrapper implements IStorageWrapper { private final Map, Consumer> upgradeDefaultsHandlers = new HashMap<>(); protected StorageWrapper(Supplier getSaveHandler, Runnable onSerializeRenderInfo, Runnable markContentsDirty) { - this(getSaveHandler, onSerializeRenderInfo, markContentsDirty, 1); + this(getSaveHandler, onSerializeRenderInfo, markContentsDirty, 1, false); } - protected StorageWrapper(Supplier getSaveHandler, Runnable onSerializeRenderInfo, Runnable markContentsDirty, int numberOfDisplayItems) { + protected StorageWrapper(Supplier getSaveHandler, Runnable onSerializeRenderInfo, Runnable markContentsDirty, int numberOfDisplayItems, boolean showsCountsAndFillRatios) { this.getSaveHandler = getSaveHandler; - renderInfo = new RenderInfo(getSaveHandler) { + renderInfo = new RenderInfo(getSaveHandler, showsCountsAndFillRatios) { @Override protected void serializeRenderInfo(CompoundTag renderInfo) { renderInfoNbt = renderInfo; diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/client/render/LimitedBarrelRenderer.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/client/render/LimitedBarrelRenderer.java index 790a7924..89d23591 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/client/render/LimitedBarrelRenderer.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/client/render/LimitedBarrelRenderer.java @@ -16,6 +16,7 @@ import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; +import net.p3pp3rf1y.sophisticatedcore.renderdata.RenderInfo; import net.p3pp3rf1y.sophisticatedcore.util.CountAbbreviator; import net.p3pp3rf1y.sophisticatedstorage.SophisticatedStorage; import net.p3pp3rf1y.sophisticatedstorage.block.*; @@ -30,7 +31,8 @@ public class LimitedBarrelRenderer extends BarrelRenderer slotCounts = blockEntity.getStorageWrapper().getRenderInfo().getItemDisplayRenderInfo().getSlotCounts(); + RenderInfo.ItemDisplayRenderInfo itemDisplayRenderInfo = blockEntity.getStorageWrapper().getRenderInfo().getItemDisplayRenderInfo(); + List slotCounts = itemDisplayRenderInfo.getSlotCounts(); + List infiniteSlots = itemDisplayRenderInfo.getInfiniteSlots(); if (slotCounts.isEmpty()) { slotCounts = blockEntity.getSlotCounts(); } @@ -166,13 +170,22 @@ private void renderItemCounts(LimitedBarrelBlockEntity blockEntity, PoseStack po Vector3f frontOffset = DisplayItemRenderer.getDisplayItemIndexFrontOffset(displayItemIndex, slotCounts.size()); double xTranslation = -frontOffset.x(); - float yTranslation = frontOffset.y() + countDisplayYOffset; + boolean isInfinite = infiniteSlots.contains(displayItemIndex); + float yTranslation = frontOffset.y() + (isInfinite ? countDisplayYOffset / 1.8f : countDisplayYOffset); double zTranslation = 0.001 - (flatTop ? 0 : 0.75 / 16D); poseStack.translate(xTranslation, yTranslation, zTranslation); float scale = slotCounts.size() == 1 ? SINGLE_ITEM_FONT_SCALE : MULTIPLE_ITEMS_FONT_SCALE; + if (isInfinite) { + scale *= 2; + } poseStack.scale(scale, -scale, scale); - MutableComponent countString = Component.literal(CountAbbreviator.abbreviate(count, slotCounts.size() == 1 ? 6 : 5)).withStyle(COUNT_DISPLAY_STYLE); + MutableComponent countString; + if (isInfinite) { + countString = Component.literal("∞").withStyle(INFINITE_COUNT_DISPLAY_STYLE); + } else { + countString = Component.literal(CountAbbreviator.abbreviate(count, slotCounts.size() == 1 ? 6 : 5)).withStyle(COUNT_DISPLAY_STYLE); + } Font font = Minecraft.getInstance().font; float countDisplayXOffset = -font.getSplitter().stringWidth(countString) / 2f; poseStack.translate(countDisplayXOffset, 0, 0); diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/common/CommonEventHandler.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/common/CommonEventHandler.java index ee80cf58..8551b996 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/common/CommonEventHandler.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/common/CommonEventHandler.java @@ -21,9 +21,13 @@ import net.neoforged.neoforge.event.level.BlockEvent; import net.neoforged.neoforge.event.tick.LevelTickEvent; import net.neoforged.neoforge.network.PacketDistributor; +import net.p3pp3rf1y.sophisticatedbackpacks.backpack.BackpackBlock; +import net.p3pp3rf1y.sophisticatedbackpacks.backpack.BackpackBlockEntity; +import net.p3pp3rf1y.sophisticatedbackpacks.client.gui.SBPTranslationHelper; import net.p3pp3rf1y.sophisticatedcore.inventory.InventoryHandler; import net.p3pp3rf1y.sophisticatedcore.network.SyncPlayerSettingsPayload; import net.p3pp3rf1y.sophisticatedcore.settings.SettingsManager; +import net.p3pp3rf1y.sophisticatedcore.upgrades.infinity.InfinityUpgradeItem; import net.p3pp3rf1y.sophisticatedcore.util.InventoryHelper; import net.p3pp3rf1y.sophisticatedcore.util.ItemBase; import net.p3pp3rf1y.sophisticatedcore.util.WorldHelper; @@ -46,7 +50,8 @@ public void registerHandlers() { IEventBus eventBus = NeoForge.EVENT_BUS; eventBus.addListener(this::onPlayerChangedDimension); eventBus.addListener(this::onPlayerRespawn); - eventBus.addListener(this::onBlockBreak); + eventBus.addListener(this::handleTooManyDropsBreak); + eventBus.addListener(this::handleBreakBackpackWithInfinityUpgrade); eventBus.addListener(this::onLimitedBarrelLeftClicked); eventBus.addListener(this::onSneakItemBlockInteraction); eventBus.addListener(this::onLevelTick); @@ -116,7 +121,22 @@ private void onLevelTick(LevelTickEvent.Post event) { } } - private void onBlockBreak(BlockEvent.BreakEvent event) { + private void handleBreakBackpackWithInfinityUpgrade(BlockEvent.BreakEvent event) { + Player player = event.getPlayer(); + + if (player.hasPermissions(2) || !(event.getState().getBlock() instanceof StorageBlockBase)) { + return; + } + + if (WorldHelper.getBlockEntity(event.getLevel(), event.getPos(), StorageBlockEntity.class) + .map(storageBlockEntity -> !storageBlockEntity.getStorageWrapper().getUpgradeHandler().getTypeWrappers(InfinityUpgradeItem.TYPE).isEmpty()) + .orElse(false)) { + event.setCanceled(true); + player.displayClientMessage(StorageTranslationHelper.INSTANCE.translStatusMessage("infinity_upgrade_only_admin_break").withStyle(ChatFormatting.RED), true); + } + } + + private void handleTooManyDropsBreak(BlockEvent.BreakEvent event) { Player player = event.getPlayer(); if (!(event.getState().getBlock() instanceof WoodStorageBlockBase) || player.isShiftKeyDown()) { return; @@ -146,7 +166,7 @@ private void onBlockBreak(BlockEvent.BreakEvent event) { return; } droppedItemEntityCount.addAndGet((int) Math.ceil(stack.getCount() / (double) Math.min(stack.getMaxStackSize(), AVERAGE_MAX_ITEM_ENTITY_DROP_COUNT))); - }); + }, () -> false, false); if (droppedItemEntityCount.get() > Config.SERVER.tooManyItemEntityDrops.get()) { event.setCanceled(true); diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/init/ModItems.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/init/ModItems.java index ca24590c..7f4a353c 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/init/ModItems.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/init/ModItems.java @@ -42,6 +42,7 @@ import net.p3pp3rf1y.sophisticatedcore.upgrades.feeding.FeedingUpgradeWrapper; import net.p3pp3rf1y.sophisticatedcore.upgrades.filter.FilterUpgradeContainer; import net.p3pp3rf1y.sophisticatedcore.upgrades.filter.FilterUpgradeItem; +import net.p3pp3rf1y.sophisticatedcore.upgrades.infinity.InfinityUpgradeItem; import net.p3pp3rf1y.sophisticatedcore.upgrades.jukebox.JukeboxUpgradeContainer; import net.p3pp3rf1y.sophisticatedcore.upgrades.jukebox.JukeboxUpgradeItem; import net.p3pp3rf1y.sophisticatedcore.upgrades.jukebox.JukeboxUpgradeWrapper; @@ -158,6 +159,8 @@ private ModItems() { new HopperUpgradeItem(Config.SERVER.hopperUpgrade.inputFilterSlots::get, Config.SERVER.hopperUpgrade.outputFilterSlots::get, Config.SERVER.hopperUpgrade.transferSpeedTicks::get, Config.SERVER.hopperUpgrade.maxTransferStackSize::get)); public static final DeferredHolder ADVANCED_HOPPER_UPGRADE = ITEMS.register("advanced_hopper_upgrade", () -> new HopperUpgradeItem(Config.SERVER.advancedHopperUpgrade.inputFilterSlots::get, Config.SERVER.advancedHopperUpgrade.outputFilterSlots::get, Config.SERVER.advancedHopperUpgrade.transferSpeedTicks::get, Config.SERVER.advancedHopperUpgrade.maxTransferStackSize::get)); + public static final DeferredHolder INFINITY_UPGRADE = ITEMS.register("infinity_upgrade", () -> new InfinityUpgradeItem(Config.SERVER.maxUpgradesPerStorage)); + public static final Supplier BASIC_TIER_UPGRADE = ITEMS.register("basic_tier_upgrade", () -> new StorageTierUpgradeItem(StorageTierUpgradeItem.TierUpgrade.BASIC, true)); public static final Supplier BASIC_TO_COPPER_TIER_UPGRADE = ITEMS.register("basic_to_copper_tier_upgrade", () -> new StorageTierUpgradeItem(StorageTierUpgradeItem.TierUpgrade.BASIC_TO_COPPER)); public static final Supplier BASIC_TO_IRON_TIER_UPGRADE = ITEMS.register("basic_to_iron_tier_upgrade", () -> new StorageTierUpgradeItem(StorageTierUpgradeItem.TierUpgrade.BASIC_TO_IRON)); diff --git a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/upgrades/compression/CompressionInventoryPart.java b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/upgrades/compression/CompressionInventoryPart.java index 9259d1d4..e215ea04 100644 --- a/src/main/java/net/p3pp3rf1y/sophisticatedstorage/upgrades/compression/CompressionInventoryPart.java +++ b/src/main/java/net/p3pp3rf1y/sophisticatedstorage/upgrades/compression/CompressionInventoryPart.java @@ -2,6 +2,7 @@ import com.mojang.datafixers.util.Pair; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -17,10 +18,7 @@ import javax.annotation.Nullable; import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.IntFunction; -import java.util.function.Supplier; -import java.util.function.ToIntFunction; +import java.util.function.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -618,7 +616,7 @@ public void setStackInSlot(int slot, ItemStack stack, BiConsumer isItemValidSuper) { if (!slotDefinitions.containsKey(slot)) { return true; } diff --git a/src/main/resources/assets/sophisticatedstorage/lang/en_us.json b/src/main/resources/assets/sophisticatedstorage/lang/en_us.json index d5d8662e..c26d274e 100644 --- a/src/main/resources/assets/sophisticatedstorage/lang/en_us.json +++ b/src/main/resources/assets/sophisticatedstorage/lang/en_us.json @@ -187,6 +187,8 @@ "item.sophisticatedstorage.hopper_upgrade.tooltip": "Pulls items from block on top and/or pushes them to block below", "item.sophisticatedstorage.advanced_hopper_upgrade": "Advanced Hopper Upgrade", "item.sophisticatedstorage.advanced_hopper_upgrade.tooltip": "Pulls items from block on top and/or pushes them to block below\nFaster and with input / ouput options", + "item.sophisticatedstorage.infinity_upgrade": "Infinity Upgrade", + "item.sophisticatedstorage.infinity_upgrade.tooltip": "Makes all items in storage infinite", "item.sophisticatedstorage.chipped.botanist_workbench_upgrade": "Chipped: Botanist's Workbench Upgrade", "item.sophisticatedstorage.chipped.botanist_workbench_upgrade.tooltip": "Chipped Botanist's Workbench in an upgrade tab", "item.sophisticatedstorage.chipped.glassblower_upgrade": "Chipped: Glassblower Upgrade", @@ -262,6 +264,7 @@ "gui.sophisticatedstorage.settings.buttons.context_storage.tooltip_detail": "Inherited from player or overriden for this storage", "keybind.sophisticatedstorage.category": "Sophisticated Storage", "keybind.sophisticatedstorage.sort": "Sort Storage", + "gui.sophisticatedstorage.status.infinity_upgrade_only_admin_break": "Only Admins can break storage with Infinity Upgrade", "gui.sophisticatedstorage.status.too_many_item_entity_drops": "Can't break the %s as it would cause too many (%s) item entities to drop from it\nConsider using %s or break it while sneaking to skip this check", "gui.sophisticatedstorage.status.too_low_tier_upgrade_count": "Upgrading requires %s %ss", "gui.sophisticatedstorage.status.packing_tape_disabled": "Config set to drop all storages as packed without the need for packing tape", diff --git a/src/main/resources/assets/sophisticatedstorage/models/item/infinity_upgrade.json b/src/main/resources/assets/sophisticatedstorage/models/item/infinity_upgrade.json new file mode 100644 index 00000000..cae8a31e --- /dev/null +++ b/src/main/resources/assets/sophisticatedstorage/models/item/infinity_upgrade.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "sophisticatedstorage:item/infinity_upgrade" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/sophisticatedstorage/textures/item/infinity_upgrade.png b/src/main/resources/assets/sophisticatedstorage/textures/item/infinity_upgrade.png new file mode 100644 index 00000000..51da22d0 Binary files /dev/null and b/src/main/resources/assets/sophisticatedstorage/textures/item/infinity_upgrade.png differ