2020-04-14 01:38:48 +02:00
|
|
|
package de.ellpeck.prettypipes;
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
import net.minecraft.ChatFormatting;
|
|
|
|
import net.minecraft.client.gui.screens.Screen;
|
|
|
|
import net.minecraft.client.resources.language.I18n;
|
|
|
|
import net.minecraft.core.BlockPos;
|
|
|
|
import net.minecraft.core.Direction;
|
2021-12-02 14:44:26 +01:00
|
|
|
import net.minecraft.nbt.CompoundTag;
|
|
|
|
import net.minecraft.nbt.ListTag;
|
2021-12-02 15:25:46 +01:00
|
|
|
import net.minecraft.network.chat.*;
|
2021-12-02 12:31:04 +01:00
|
|
|
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
|
|
|
|
import net.minecraft.server.level.ServerLevel;
|
|
|
|
import net.minecraft.world.Containers;
|
|
|
|
import net.minecraft.world.WorldlyContainerHolder;
|
|
|
|
import net.minecraft.world.entity.player.Player;
|
|
|
|
import net.minecraft.world.inventory.AbstractContainerMenu;
|
|
|
|
import net.minecraft.world.item.ItemStack;
|
2021-12-02 14:44:26 +01:00
|
|
|
import net.minecraft.world.level.BlockGetter;
|
2021-12-02 12:31:04 +01:00
|
|
|
import net.minecraft.world.level.ChunkPos;
|
|
|
|
import net.minecraft.world.level.Level;
|
|
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
2020-05-09 12:57:25 +02:00
|
|
|
import net.minecraftforge.common.util.INBTSerializable;
|
2020-04-14 01:38:48 +02:00
|
|
|
import net.minecraftforge.items.IItemHandler;
|
2020-10-24 15:00:11 +02:00
|
|
|
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
2020-05-07 18:30:40 +02:00
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
2020-04-14 01:38:48 +02:00
|
|
|
|
2020-05-09 12:57:25 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collection;
|
2020-04-20 13:12:26 +02:00
|
|
|
import java.util.List;
|
2020-05-07 18:30:40 +02:00
|
|
|
import java.util.function.Function;
|
2020-04-20 13:12:26 +02:00
|
|
|
|
2020-04-14 01:38:48 +02:00
|
|
|
public final class Utility {
|
|
|
|
|
2021-12-02 14:44:26 +01:00
|
|
|
public static <T extends BlockEntity> T getBlockEntity(Class<T> type, BlockGetter world, BlockPos pos) {
|
2021-12-02 12:31:04 +01:00
|
|
|
var tile = world.getBlockEntity(pos);
|
2020-04-14 01:38:48 +02:00
|
|
|
return type.isInstance(tile) ? (T) tile : null;
|
|
|
|
}
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static void dropInventory(BlockEntity tile, IItemHandler inventory) {
|
|
|
|
var pos = tile.getBlockPos();
|
|
|
|
for (var i = 0; i < inventory.getSlots(); i++) {
|
|
|
|
var stack = inventory.getStackInSlot(i);
|
2020-04-14 01:38:48 +02:00
|
|
|
if (!stack.isEmpty())
|
2021-12-02 12:31:04 +01:00
|
|
|
Containers.dropItemStack(tile.getLevel(), pos.getX(), pos.getY(), pos.getZ(), stack);
|
2020-04-14 01:38:48 +02:00
|
|
|
}
|
|
|
|
}
|
2020-04-14 18:51:43 +02:00
|
|
|
|
|
|
|
public static Direction getDirectionFromOffset(BlockPos pos, BlockPos other) {
|
2021-12-02 12:31:04 +01:00
|
|
|
var diff = pos.subtract(other);
|
|
|
|
return Direction.fromNormal(diff.getX(), diff.getY(), diff.getZ());
|
2020-04-14 18:51:43 +02:00
|
|
|
}
|
2020-04-20 13:12:26 +02:00
|
|
|
|
2021-12-02 15:25:46 +01:00
|
|
|
public static void addTooltip(String name, List<Component> tooltip) {
|
2020-04-20 13:12:26 +02:00
|
|
|
if (Screen.hasShiftDown()) {
|
2021-12-02 12:31:04 +01:00
|
|
|
var content = I18n.get("info." + PrettyPipes.ID + "." + name).split("\n");
|
|
|
|
for (var s : content)
|
|
|
|
tooltip.add(new TextComponent(s).setStyle(Style.EMPTY.applyFormat(ChatFormatting.GRAY)));
|
2020-04-20 13:12:26 +02:00
|
|
|
} else {
|
2021-12-02 12:31:04 +01:00
|
|
|
tooltip.add(new TranslatableComponent("info." + PrettyPipes.ID + ".shift").setStyle(Style.EMPTY.applyFormat(ChatFormatting.DARK_GRAY)));
|
2020-04-20 13:12:26 +02:00
|
|
|
}
|
|
|
|
}
|
2020-05-07 18:30:40 +02:00
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static ItemStack transferStackInSlot(AbstractContainerMenu container, IMergeItemStack merge, Player player, int slotIndex, Function<ItemStack, Pair<Integer, Integer>> predicate) {
|
|
|
|
var inventoryStart = (int) container.slots.stream().filter(slot -> slot.container != player.getInventory()).count();
|
|
|
|
var inventoryEnd = inventoryStart + 26;
|
|
|
|
var hotbarStart = inventoryEnd + 1;
|
|
|
|
var hotbarEnd = hotbarStart + 8;
|
2020-05-07 18:30:40 +02:00
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
var slot = container.slots.get(slotIndex);
|
|
|
|
if (slot != null && slot.hasItem()) {
|
|
|
|
var newStack = slot.getItem();
|
|
|
|
var currentStack = newStack.copy();
|
2020-05-07 18:30:40 +02:00
|
|
|
|
|
|
|
if (slotIndex >= inventoryStart) {
|
|
|
|
// shift into this container here
|
|
|
|
// mergeItemStack with the slots that newStack should go into
|
|
|
|
// return an empty stack if mergeItemStack fails
|
2021-12-02 12:31:04 +01:00
|
|
|
var slots = predicate.apply(newStack);
|
2020-05-07 18:30:40 +02:00
|
|
|
if (slots != null) {
|
|
|
|
if (!merge.mergeItemStack(newStack, slots.getLeft(), slots.getRight(), false))
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
}
|
|
|
|
// end custom code
|
|
|
|
else if (slotIndex >= inventoryStart && slotIndex <= inventoryEnd) {
|
|
|
|
if (!merge.mergeItemStack(newStack, hotbarStart, hotbarEnd + 1, false))
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
} else if (slotIndex >= inventoryEnd + 1 && slotIndex < hotbarEnd + 1 && !merge.mergeItemStack(newStack, inventoryStart, inventoryEnd + 1, false)) {
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
}
|
|
|
|
} else if (!merge.mergeItemStack(newStack, inventoryStart, hotbarEnd + 1, false)) {
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
}
|
|
|
|
if (newStack.isEmpty()) {
|
2021-12-02 12:31:04 +01:00
|
|
|
slot.set(ItemStack.EMPTY);
|
2020-05-07 18:30:40 +02:00
|
|
|
} else {
|
2021-12-02 12:31:04 +01:00
|
|
|
slot.setChanged();
|
2020-05-07 18:30:40 +02:00
|
|
|
}
|
|
|
|
if (newStack.getCount() == currentStack.getCount())
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
slot.onTake(player, newStack);
|
|
|
|
return currentStack;
|
|
|
|
}
|
|
|
|
return ItemStack.EMPTY;
|
|
|
|
}
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static ListTag serializeAll(Collection<? extends INBTSerializable<CompoundTag>> items) {
|
|
|
|
var list = new ListTag();
|
|
|
|
for (INBTSerializable<CompoundTag> item : items)
|
2020-05-09 12:57:25 +02:00
|
|
|
list.add(item.serializeNBT());
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static void sendBlockEntityToClients(BlockEntity tile) {
|
|
|
|
var world = (ServerLevel) tile.getLevel();
|
|
|
|
var entities = world.getChunkSource().chunkMap.getPlayers(new ChunkPos(tile.getBlockPos()), false);
|
2021-12-04 13:07:18 +01:00
|
|
|
var packet = ClientboundBlockEntityDataPacket.create(tile, BlockEntity::saveWithoutMetadata);
|
2021-12-02 12:31:04 +01:00
|
|
|
for (var e : entities)
|
|
|
|
e.connection.send(packet);
|
2020-10-13 18:11:40 +02:00
|
|
|
}
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static <T extends INBTSerializable<CompoundTag>> List<T> deserializeAll(ListTag list, Function<CompoundTag, T> supplier) {
|
2020-05-09 12:57:25 +02:00
|
|
|
List<T> items = new ArrayList<>();
|
2021-12-02 12:31:04 +01:00
|
|
|
for (var i = 0; i < list.size(); i++) {
|
|
|
|
var item = supplier.apply(list.getCompound(i));
|
2020-10-16 22:36:44 +02:00
|
|
|
if (item != null)
|
|
|
|
items.add(item);
|
|
|
|
}
|
2020-05-09 12:57:25 +02:00
|
|
|
return items;
|
|
|
|
}
|
|
|
|
|
2021-12-02 12:31:04 +01:00
|
|
|
public static IItemHandler getBlockItemHandler(Level world, BlockPos pos, Direction direction) {
|
|
|
|
var state = world.getBlockState(pos);
|
|
|
|
var block = state.getBlock();
|
|
|
|
if (!(block instanceof WorldlyContainerHolder holder))
|
2020-10-24 15:00:11 +02:00
|
|
|
return null;
|
2021-12-02 12:31:04 +01:00
|
|
|
var inventory = holder.getContainer(state, world, pos);
|
2020-10-24 15:00:11 +02:00
|
|
|
if (inventory == null)
|
|
|
|
return null;
|
|
|
|
return new SidedInvWrapper(inventory, direction);
|
|
|
|
}
|
|
|
|
|
2020-05-07 18:30:40 +02:00
|
|
|
public interface IMergeItemStack {
|
2021-12-02 12:31:04 +01:00
|
|
|
|
2020-05-07 18:30:40 +02:00
|
|
|
boolean mergeItemStack(ItemStack stack, int startIndex, int endIndex, boolean reverseDirection);
|
|
|
|
}
|
2020-04-14 01:38:48 +02:00
|
|
|
}
|