NaturesAura/src/main/java/de/ellpeck/naturesaura/Helper.java

318 lines
14 KiB
Java
Raw Normal View History

2018-10-14 14:27:18 +02:00
package de.ellpeck.naturesaura;
2020-01-21 21:04:44 +01:00
import com.mojang.blaze3d.platform.GlStateManager;
2018-11-12 22:04:40 +01:00
import de.ellpeck.naturesaura.api.NaturesAuraAPI;
2018-11-11 13:26:19 +01:00
import de.ellpeck.naturesaura.api.aura.item.IAuraRecharge;
2018-10-18 13:34:37 +02:00
import de.ellpeck.naturesaura.blocks.tiles.TileEntityImpl;
import de.ellpeck.naturesaura.chunk.AuraChunk;
import net.minecraft.block.Block;
2019-10-20 22:30:49 +02:00
import net.minecraft.block.BlockState;
2018-10-16 11:49:30 +02:00
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderHelper;
2019-10-20 22:30:49 +02:00
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.item.ItemFrameEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
2019-01-27 13:57:34 +01:00
import net.minecraft.item.Item;
2018-10-16 01:36:30 +02:00
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
2020-01-21 21:04:44 +01:00
import net.minecraft.nbt.INBT;
import net.minecraft.state.IProperty;
2018-10-14 14:27:18 +02:00
import net.minecraft.tileentity.TileEntity;
2020-01-21 21:04:44 +01:00
import net.minecraft.util.*;
2018-11-05 16:36:10 +01:00
import net.minecraft.util.math.AxisAlignedBB;
2018-10-14 14:27:18 +02:00
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
2020-01-21 21:04:44 +01:00
import net.minecraft.world.IWorld;
2018-10-14 14:27:18 +02:00
import net.minecraft.world.World;
2019-10-20 22:30:49 +02:00
import net.minecraft.world.chunk.AbstractChunkProvider;
2020-01-21 21:04:44 +01:00
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
2018-10-20 21:19:08 +02:00
import net.minecraftforge.common.capabilities.Capability;
2018-11-12 22:04:40 +01:00
import net.minecraftforge.common.capabilities.CapabilityManager;
2018-10-20 21:19:08 +02:00
import net.minecraftforge.common.capabilities.ICapabilityProvider;
2020-01-21 21:04:44 +01:00
import net.minecraftforge.common.util.LazyOptional;
2019-02-17 22:51:05 +01:00
import net.minecraftforge.items.IItemHandler;
2018-10-18 13:34:37 +02:00
import net.minecraftforge.items.IItemHandlerModifiable;
2020-01-21 21:04:44 +01:00
import net.minecraftforge.registries.ForgeRegistries;
2018-10-18 18:00:21 +02:00
import org.lwjgl.opengl.GL11;
2018-10-14 14:27:18 +02:00
2018-10-20 21:19:08 +02:00
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
2018-10-14 14:27:18 +02:00
import java.util.List;
import java.util.function.Consumer;
2018-11-14 19:14:03 +01:00
import java.util.function.Function;
2018-10-14 14:27:18 +02:00
public final class Helper {
2020-01-21 21:04:44 +01:00
public static boolean getTileEntitiesInArea(IWorld world, BlockPos pos, int radius, Function<TileEntity, Boolean> consumer) {
2018-10-14 14:27:18 +02:00
for (int x = (pos.getX() - radius) >> 4; x <= (pos.getX() + radius) >> 4; x++) {
for (int z = (pos.getZ() - radius) >> 4; z <= (pos.getZ() + radius) >> 4; z++) {
2018-10-30 18:18:56 +01:00
if (isChunkLoaded(world, x, z)) {
2020-01-21 21:04:44 +01:00
for (BlockPos tilePos : world.getChunk(x, z).getTileEntitiesPos()) {
if (tilePos.distanceSq(pos) <= radius * radius)
if (consumer.apply(world.getTileEntity(tilePos)))
2018-11-14 19:14:03 +01:00
return true;
2018-10-14 14:27:18 +02:00
}
}
}
}
2018-11-14 19:14:03 +01:00
return false;
2018-10-14 14:27:18 +02:00
}
public static void getAuraChunksInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
for (int x = (pos.getX() - radius) >> 4; x <= (pos.getX() + radius) >> 4; x++) {
for (int z = (pos.getZ() - radius) >> 4; z <= (pos.getZ() + radius) >> 4; z++) {
2020-01-21 21:04:44 +01:00
if (isChunkLoaded(world, x, z)) {
Chunk chunk = world.getChunk(x, z);
2020-01-21 21:04:44 +01:00
AuraChunk auraChunk = (AuraChunk) chunk.getCapability(NaturesAuraAPI.capAuraChunk, null).orElse(null);
if (auraChunk != null)
consumer.accept(auraChunk);
}
}
}
}
2019-10-20 22:30:49 +02:00
public static List<ItemFrameEntity> getAttachedItemFrames(World world, BlockPos pos) {
List<ItemFrameEntity> frames = world.getEntitiesWithinAABB(ItemFrameEntity.class, new AxisAlignedBB(pos).grow(0.25));
2018-11-05 16:36:10 +01:00
for (int i = frames.size() - 1; i >= 0; i--) {
2019-10-20 22:30:49 +02:00
ItemFrameEntity frame = frames.get(i);
2020-01-21 21:04:44 +01:00
BlockPos framePos = frame.getHangingPosition().offset(frame.getHorizontalFacing());
2018-11-05 16:36:10 +01:00
if (!pos.equals(framePos))
frames.remove(i);
}
return frames;
}
2018-10-30 18:18:56 +01:00
// For some reason this method isn't public in World, but I also don't want to have to make a new BlockPos
// or use the messy MutableBlockPos system just to see if a chunk is loaded, so this will have to do I guess
2020-01-21 21:04:44 +01:00
public static boolean isChunkLoaded(IWorld world, int x, int z) {
2019-10-20 22:30:49 +02:00
AbstractChunkProvider provider = world.getChunkProvider();
2020-01-21 21:04:44 +01:00
if (!world.isRemote()) {
return provider.chunkExists(x, z);
} else {
return !provider.getChunk(x, z, false).isEmpty();
}
2018-10-30 18:18:56 +01:00
}
2018-10-15 18:36:46 +02:00
public static int blendColors(int c1, int c2, float ratio) {
int a = (int) ((c1 >> 24 & 0xFF) * ratio + (c2 >> 24 & 0xFF) * (1 - ratio));
int r = (int) ((c1 >> 16 & 0xFF) * ratio + (c2 >> 16 & 0xFF) * (1 - ratio));
int g = (int) ((c1 >> 8 & 0xFF) * ratio + (c2 >> 8 & 0xFF) * (1 - ratio));
int b = (int) ((c1 & 0xFF) * ratio + (c2 & 0xFF) * (1 - ratio));
return ((a & 255) << 24) | ((r & 255) << 16) | ((g & 255) << 8) | (b & 255);
}
2018-10-16 01:36:30 +02:00
public static boolean areItemsEqual(ItemStack first, ItemStack second, boolean nbt) {
if (!ItemStack.areItemsEqual(first, second))
return false;
2020-01-21 21:04:44 +01:00
return !nbt || ItemStack.areItemStackTagsEqual(first, second);
}
2019-10-20 22:30:49 +02:00
@OnlyIn(Dist.CLIENT)
2018-10-16 11:49:30 +02:00
public static void renderItemInWorld(ItemStack stack) {
if (!stack.isEmpty()) {
GlStateManager.pushMatrix();
GlStateManager.disableLighting();
2020-01-21 21:04:44 +01:00
GlStateManager.pushTextureAttributes();
GlStateManager.pushLightingAttributes();
2018-10-16 11:49:30 +02:00
RenderHelper.enableStandardItemLighting();
2020-01-21 21:04:44 +01:00
Minecraft.getInstance().getItemRenderer().renderItem(stack, ItemCameraTransforms.TransformType.FIXED);
2018-10-16 11:49:30 +02:00
RenderHelper.disableStandardItemLighting();
2020-01-21 21:04:44 +01:00
GlStateManager.popAttributes();
GlStateManager.popAttributes();
2018-10-16 11:49:30 +02:00
GlStateManager.enableLighting();
GlStateManager.popMatrix();
2018-10-16 01:36:30 +02:00
}
}
2018-10-18 13:34:37 +02:00
2019-10-20 22:30:49 +02:00
@OnlyIn(Dist.CLIENT)
2018-10-18 18:00:21 +02:00
public static void renderItemInGui(ItemStack stack, int x, int y, float scale) {
GlStateManager.pushMatrix();
GlStateManager.enableBlend();
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
RenderHelper.enableGUIStandardItemLighting();
2020-01-21 21:04:44 +01:00
GlStateManager.enableDepthTest();
2018-10-18 18:00:21 +02:00
GlStateManager.enableRescaleNormal();
2020-01-21 21:04:44 +01:00
GlStateManager.translatef(x, y, 0);
GlStateManager.scalef(scale, scale, scale);
Minecraft.getInstance().getItemRenderer().renderItemAndEffectIntoGUI(stack, 0, 0);
Minecraft.getInstance().getItemRenderer().renderItemOverlayIntoGUI(Minecraft.getInstance().fontRenderer, stack, 0, 0, null);
2018-10-18 18:00:21 +02:00
RenderHelper.disableStandardItemLighting();
GlStateManager.popMatrix();
}
2019-10-20 22:30:49 +02:00
public static boolean putStackOnTile(PlayerEntity player, Hand hand, BlockPos pos, int slot, boolean sound) {
2018-10-18 13:34:37 +02:00
TileEntity tile = player.world.getTileEntity(pos);
if (tile instanceof TileEntityImpl) {
IItemHandlerModifiable handler = ((TileEntityImpl) tile).getItemHandler(null);
if (handler != null) {
ItemStack handStack = player.getHeldItem(hand);
if (!handStack.isEmpty()) {
ItemStack remain = handler.insertItem(slot, handStack, player.world.isRemote);
if (!ItemStack.areItemStacksEqual(remain, handStack)) {
if (sound)
player.world.playSound(player, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
2020-01-21 21:04:44 +01:00
SoundEvents.ENTITY_ITEM_FRAME_ADD_ITEM, SoundCategory.PLAYERS, 0.75F, 1F);
if (!player.world.isRemote)
2018-10-18 13:34:37 +02:00
player.setHeldItem(hand, remain);
return true;
}
}
if (!handler.getStackInSlot(slot).isEmpty()) {
if (sound)
player.world.playSound(player, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
2020-01-21 21:04:44 +01:00
SoundEvents.ENTITY_ITEM_FRAME_REMOVE_ITEM, SoundCategory.PLAYERS, 0.75F, 1F);
2018-10-18 13:34:37 +02:00
if (!player.world.isRemote) {
ItemStack stack = handler.getStackInSlot(slot);
if (!player.addItemStackToInventory(stack)) {
2019-10-20 22:30:49 +02:00
ItemEntity item = new ItemEntity(player.world, player.posX, player.posY, player.posZ, stack);
2020-01-21 21:04:44 +01:00
player.world.addEntity(item);
}
2018-10-18 13:34:37 +02:00
handler.setStackInSlot(slot, ItemStack.EMPTY);
}
return true;
}
}
}
return false;
}
2018-10-20 21:19:08 +02:00
2018-12-01 18:56:05 +01:00
public static ICapabilityProvider makeRechargeProvider(ItemStack stack, boolean needsSelected) {
2018-10-20 21:19:08 +02:00
return new ICapabilityProvider() {
2018-12-01 18:56:05 +01:00
private final IAuraRecharge recharge = (container, containerSlot, itemSlot, isSelected) -> {
if (isSelected || !needsSelected) {
int toDrain = 300;
2020-01-21 21:04:44 +01:00
if (stack.getDamage() > 0 && container.drainAura(toDrain, true) >= toDrain) {
stack.setDamage(stack.getDamage() - 1);
2018-12-01 18:56:05 +01:00
container.drainAura(toDrain, false);
return true;
}
2018-10-20 21:19:08 +02:00
}
2018-12-01 18:56:05 +01:00
return false;
2018-10-20 21:19:08 +02:00
};
@Nullable
@Override
2020-01-21 21:04:44 +01:00
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction facing) {
if (capability == NaturesAuraAPI.capAuraRecharge)
return LazyOptional.of(() -> (T) this.recharge);
return LazyOptional.empty();
2018-10-20 21:19:08 +02:00
}
};
}
2019-10-20 22:30:49 +02:00
public static BlockState getStateFromString(String raw) {
String[] split = raw.split("\\[");
2020-01-21 21:04:44 +01:00
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(split[0]));
if (block != null) {
2019-10-20 22:30:49 +02:00
BlockState state = block.getDefaultState();
if (split.length > 1) {
for (String part : split[1].replace("]", "").split(",")) {
String[] keyValue = part.split("=");
2020-01-21 21:04:44 +01:00
for (IProperty<?> prop : state.getProperties()) {
2019-10-20 22:30:49 +02:00
BlockState changed = findProperty(state, prop, keyValue[0], keyValue[1]);
if (changed != null) {
state = changed;
break;
}
}
}
}
return state;
} else
return null;
}
2019-10-20 22:30:49 +02:00
private static <T extends Comparable<T>> BlockState findProperty(BlockState state, IProperty<T> prop, String key, String newValue) {
if (key.equals(prop.getName()))
for (T value : prop.getAllowedValues())
if (prop.getName(value).equals(newValue))
2020-01-21 21:04:44 +01:00
return state.with(prop, value);
return null;
}
2018-11-12 22:04:40 +01:00
public static <T> void registerCap(Class<T> type) {
CapabilityManager.INSTANCE.register(type, new Capability.IStorage<T>() {
@Override
2020-01-21 21:04:44 +01:00
public void readNBT(Capability<T> capability, T instance, Direction side, INBT nbt) {
2018-11-12 22:04:40 +01:00
}
2020-01-21 21:04:44 +01:00
@Nullable
2018-11-12 22:04:40 +01:00
@Override
2020-01-21 21:04:44 +01:00
public INBT writeNBT(Capability capability, Object instance, Direction side) {
return null;
2018-11-12 22:04:40 +01:00
}
}, () -> null);
}
2019-10-20 22:30:49 +02:00
public static void addAdvancement(PlayerEntity player, ResourceLocation advancement, String criterion) {
if (!(player instanceof ServerPlayerEntity))
2020-01-21 21:04:44 +01:00
return;/* TODO add advancements
2019-10-20 22:30:49 +02:00
ServerPlayerEntity playerMp = (ServerPlayerEntity) player;
Advancement adv = playerMp.getServerWorld().getAdvancementManager().getAdvancement(advancement);
if (adv != null)
2020-01-21 21:04:44 +01:00
playerMp.getAdvancements().grantCriterion(adv, criterion);*/
}
2018-12-30 20:37:00 +01:00
public static int getIngredientAmount(Ingredient ingredient) {
int highestAmount = 0;
for (ItemStack stack : ingredient.getMatchingStacks())
if (stack.getCount() > highestAmount)
highestAmount = stack.getCount();
return highestAmount;
}
2019-01-27 13:57:34 +01:00
2019-10-20 22:30:49 +02:00
@OnlyIn(Dist.CLIENT)
2019-01-27 13:57:34 +01:00
public static void renderWeirdBox(double x, double y, double z, double width, double height, double depth) {
GL11.glVertex3d(x, y + height, z);
GL11.glVertex3d(x + width, y + height, z);
GL11.glVertex3d(x + width, y, z);
GL11.glVertex3d(x, y, z);
GL11.glVertex3d(x + width, y, z + depth);
GL11.glVertex3d(x + width, y, z);
GL11.glVertex3d(x + width, y + height, z);
GL11.glVertex3d(x + width, y + height, z + depth);
GL11.glVertex3d(x + width, y + height, z + depth);
GL11.glVertex3d(x, y + height, z + depth);
GL11.glVertex3d(x, y, z + depth);
GL11.glVertex3d(x + width, y, z + depth);
GL11.glVertex3d(x, y + height, z + depth);
GL11.glVertex3d(x, y + height, z);
GL11.glVertex3d(x, y, z);
GL11.glVertex3d(x, y, z + depth);
GL11.glVertex3d(x, y + height, z);
GL11.glVertex3d(x, y + height, z + depth);
GL11.glVertex3d(x + width, y + height, z + depth);
GL11.glVertex3d(x + width, y + height, z);
GL11.glVertex3d(x + width, y, z);
GL11.glVertex3d(x + width, y, z + depth);
GL11.glVertex3d(x, y, z + depth);
GL11.glVertex3d(x, y, z);
}
2019-10-20 22:30:49 +02:00
public static boolean isHoldingItem(PlayerEntity player, Item item) {
for (Hand hand : Hand.values()) {
2019-01-27 13:57:34 +01:00
ItemStack stack = player.getHeldItem(hand);
if (!stack.isEmpty() && stack.getItem() == item)
return true;
}
return false;
}
2019-02-17 22:51:05 +01:00
public static boolean isEmpty(IItemHandler handler) {
for (int i = 0; i < handler.getSlots(); i++)
if (!handler.getStackInSlot(i).isEmpty())
return false;
return true;
}
public static AxisAlignedBB aabb(Vec3d pos) {
return new AxisAlignedBB(pos.x, pos.y, pos.z, pos.x, pos.y, pos.z);
}
2018-10-14 14:27:18 +02:00
}