2018-10-14 14:27:18 +02:00
|
|
|
package de.ellpeck.naturesaura;
|
|
|
|
|
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;
|
2019-02-09 21:55:40 +01:00
|
|
|
import de.ellpeck.naturesaura.chunk.AuraChunk;
|
2018-12-20 21:43:19 +01:00
|
|
|
import net.minecraft.advancements.Advancement;
|
2018-11-12 00:32:35 +01:00
|
|
|
import net.minecraft.block.Block;
|
|
|
|
import net.minecraft.block.properties.IProperty;
|
|
|
|
import net.minecraft.block.state.IBlockState;
|
2018-10-16 11:49:30 +02:00
|
|
|
import net.minecraft.client.Minecraft;
|
|
|
|
import net.minecraft.client.renderer.GlStateManager;
|
|
|
|
import net.minecraft.client.renderer.RenderHelper;
|
|
|
|
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
2019-01-18 12:29:18 +01:00
|
|
|
import net.minecraft.entity.item.EntityItem;
|
2018-11-05 16:36:10 +01:00
|
|
|
import net.minecraft.entity.item.EntityItemFrame;
|
2018-10-18 13:34:37 +02:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2018-12-20 21:43:19 +01:00
|
|
|
import net.minecraft.entity.player.EntityPlayerMP;
|
2018-10-24 12:42:04 +02:00
|
|
|
import net.minecraft.init.SoundEvents;
|
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;
|
2018-11-20 11:44:07 +01:00
|
|
|
import net.minecraft.item.crafting.Ingredient;
|
2018-11-12 22:04:40 +01:00
|
|
|
import net.minecraft.nbt.NBTBase;
|
2018-10-14 14:27:18 +02:00
|
|
|
import net.minecraft.tileentity.TileEntity;
|
2018-10-20 21:19:08 +02:00
|
|
|
import net.minecraft.util.EnumFacing;
|
2018-10-18 13:34:37 +02:00
|
|
|
import net.minecraft.util.EnumHand;
|
2018-11-12 00:32:35 +01:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
2018-10-24 12:42:04 +02:00
|
|
|
import net.minecraft.util.SoundCategory;
|
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.world.World;
|
2019-02-09 21:55:40 +01:00
|
|
|
import net.minecraft.world.chunk.Chunk;
|
2018-10-30 18:18:56 +01:00
|
|
|
import net.minecraft.world.chunk.IChunkProvider;
|
|
|
|
import net.minecraft.world.gen.ChunkProviderServer;
|
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;
|
2018-10-15 18:36:46 +02:00
|
|
|
import net.minecraftforge.fml.relauncher.Side;
|
|
|
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
2018-10-18 13:34:37 +02:00
|
|
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
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;
|
2019-02-09 21:55:40 +01:00
|
|
|
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 {
|
|
|
|
|
2018-11-14 19:14:03 +01:00
|
|
|
public static boolean getTileEntitiesInArea(World world, BlockPos pos, int radius, Function<TileEntity, Boolean> consumer) {
|
2019-02-09 21:55:40 +01:00
|
|
|
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getAuraChunksInArea");
|
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)) {
|
|
|
|
for (TileEntity tile : world.getChunk(x, z).getTileEntityMap().values()) {
|
|
|
|
if (tile.getPos().distanceSq(pos) <= radius * radius)
|
2019-02-09 21:55:40 +01:00
|
|
|
if (consumer.apply(tile)) {
|
|
|
|
world.profiler.endSection();
|
2018-11-14 19:14:03 +01:00
|
|
|
return true;
|
2019-02-09 21:55:40 +01:00
|
|
|
}
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-09 21:55:40 +01:00
|
|
|
world.profiler.endSection();
|
2018-11-14 19:14:03 +01:00
|
|
|
return false;
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|
|
|
|
|
2019-02-09 21:55:40 +01:00
|
|
|
public static void getAuraChunksInArea(World world, BlockPos pos, int radius, Consumer<AuraChunk> consumer) {
|
|
|
|
world.profiler.func_194340_a(() -> NaturesAura.MOD_ID + ":getAuraChunksInArea");
|
|
|
|
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++) {
|
|
|
|
if (Helper.isChunkLoaded(world, x, z)) {
|
|
|
|
Chunk chunk = world.getChunk(x, z);
|
|
|
|
if (chunk.hasCapability(NaturesAuraAPI.capAuraChunk, null)) {
|
|
|
|
AuraChunk auraChunk = (AuraChunk) chunk.getCapability(NaturesAuraAPI.capAuraChunk, null);
|
|
|
|
consumer.accept(auraChunk);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
world.profiler.endSection();
|
|
|
|
}
|
|
|
|
|
2018-11-05 16:36:10 +01:00
|
|
|
public static List<EntityItemFrame> getAttachedItemFrames(World world, BlockPos pos) {
|
|
|
|
List<EntityItemFrame> frames = world.getEntitiesWithinAABB(EntityItemFrame.class, new AxisAlignedBB(pos).grow(0.25));
|
|
|
|
for (int i = frames.size() - 1; i >= 0; i--) {
|
|
|
|
EntityItemFrame frame = frames.get(i);
|
|
|
|
BlockPos framePos = frame.getHangingPosition().offset(frame.facingDirection.getOpposite());
|
|
|
|
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
|
|
|
|
public static boolean isChunkLoaded(World world, int x, int z) {
|
|
|
|
IChunkProvider provider = world.getChunkProvider();
|
|
|
|
if (provider instanceof ChunkProviderServer)
|
|
|
|
return ((ChunkProviderServer) provider).chunkExists(x, z);
|
|
|
|
else
|
|
|
|
return !provider.provideChunk(x, z).isEmpty();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2018-11-08 18:03:58 +01:00
|
|
|
public static boolean areItemsEqual(ItemStack first, ItemStack second, boolean nbt) {
|
|
|
|
if (!ItemStack.areItemsEqual(first, second))
|
|
|
|
return false;
|
|
|
|
return !nbt || ItemStack.areItemStackShareTagsEqual(first, second);
|
|
|
|
}
|
|
|
|
|
2018-10-16 11:49:30 +02:00
|
|
|
@SideOnly(Side.CLIENT)
|
|
|
|
public static void renderItemInWorld(ItemStack stack) {
|
|
|
|
if (!stack.isEmpty()) {
|
|
|
|
GlStateManager.pushMatrix();
|
|
|
|
GlStateManager.disableLighting();
|
|
|
|
GlStateManager.pushAttrib();
|
|
|
|
RenderHelper.enableStandardItemLighting();
|
|
|
|
Minecraft.getMinecraft().getRenderItem().renderItem(stack, ItemCameraTransforms.TransformType.FIXED);
|
|
|
|
RenderHelper.disableStandardItemLighting();
|
|
|
|
GlStateManager.popAttrib();
|
|
|
|
GlStateManager.enableLighting();
|
|
|
|
GlStateManager.popMatrix();
|
2018-10-16 01:36:30 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-18 13:34:37 +02:00
|
|
|
|
2018-10-18 18:00:21 +02:00
|
|
|
@SideOnly(Side.CLIENT)
|
|
|
|
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();
|
|
|
|
GlStateManager.enableDepth();
|
|
|
|
GlStateManager.enableRescaleNormal();
|
|
|
|
GlStateManager.translate(x, y, 0);
|
|
|
|
GlStateManager.scale(scale, scale, scale);
|
|
|
|
Minecraft.getMinecraft().getRenderItem().renderItemAndEffectIntoGUI(stack, 0, 0);
|
|
|
|
Minecraft.getMinecraft().getRenderItem().renderItemOverlayIntoGUI(Minecraft.getMinecraft().fontRenderer, stack, 0, 0, null);
|
|
|
|
RenderHelper.disableStandardItemLighting();
|
|
|
|
GlStateManager.popMatrix();
|
|
|
|
}
|
|
|
|
|
2018-10-24 12:42:04 +02:00
|
|
|
public static boolean putStackOnTile(EntityPlayer player, EnumHand 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)) {
|
2018-10-24 12:42:04 +02:00
|
|
|
if (sound)
|
|
|
|
player.world.playSound(player, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
|
|
|
|
SoundEvents.ENTITY_ITEMFRAME_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()) {
|
2018-10-24 12:42:04 +02:00
|
|
|
if (sound)
|
|
|
|
player.world.playSound(player, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5,
|
|
|
|
SoundEvents.ENTITY_ITEMFRAME_REMOVE_ITEM, SoundCategory.PLAYERS, 0.75F, 1F);
|
2018-10-18 13:34:37 +02:00
|
|
|
if (!player.world.isRemote) {
|
2019-01-18 12:29:18 +01:00
|
|
|
ItemStack stack = handler.getStackInSlot(slot);
|
|
|
|
if (!player.addItemStackToInventory(stack)) {
|
|
|
|
EntityItem item = new EntityItem(player.world, player.posX, player.posY, player.posZ, stack);
|
|
|
|
player.world.spawnEntity(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) {
|
2019-02-06 23:51:33 +01:00
|
|
|
int toDrain = 300;
|
2018-12-01 18:56:05 +01:00
|
|
|
if (stack.getItemDamage() > 0 && container.drainAura(toDrain, true) >= toDrain) {
|
|
|
|
stack.setItemDamage(stack.getItemDamage() - 1);
|
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean hasCapability(@Nonnull Capability<?> capability, @Nullable EnumFacing facing) {
|
2018-11-12 22:04:40 +01:00
|
|
|
return capability == NaturesAuraAPI.capAuraRecharge;
|
2018-10-20 21:19:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public <T> T getCapability(@Nonnull Capability<T> capability, @Nullable EnumFacing facing) {
|
2018-11-12 22:04:40 +01:00
|
|
|
return capability == NaturesAuraAPI.capAuraRecharge ? (T) this.recharge : null;
|
2018-10-20 21:19:08 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2018-11-12 00:32:35 +01:00
|
|
|
|
|
|
|
public static IBlockState getStateFromString(String raw) {
|
|
|
|
String[] split = raw.split("\\[");
|
|
|
|
Block block = Block.REGISTRY.getObject(new ResourceLocation(split[0]));
|
|
|
|
if (block != null) {
|
|
|
|
IBlockState state = block.getDefaultState();
|
|
|
|
if (split.length > 1) {
|
|
|
|
for (String part : split[1].replace("]", "").split(",")) {
|
|
|
|
String[] keyValue = part.split("=");
|
|
|
|
for (IProperty<?> prop : state.getProperties().keySet()) {
|
|
|
|
IBlockState changed = findProperty(state, prop, keyValue[0], keyValue[1]);
|
|
|
|
if (changed != null) {
|
|
|
|
state = changed;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return state;
|
|
|
|
} else
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static <T extends Comparable<T>> IBlockState findProperty(IBlockState state, IProperty<T> prop, String key, String newValue) {
|
|
|
|
if (key.equals(prop.getName()))
|
|
|
|
for (T value : prop.getAllowedValues())
|
|
|
|
if (prop.getName(value).equals(newValue))
|
|
|
|
return state.withProperty(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>() {
|
|
|
|
@Nullable
|
|
|
|
@Override
|
|
|
|
public NBTBase writeNBT(Capability capability, Object instance, EnumFacing side) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void readNBT(Capability capability, Object instance, EnumFacing side, NBTBase nbt) {
|
|
|
|
|
|
|
|
}
|
|
|
|
}, () -> null);
|
|
|
|
}
|
2018-11-20 11:44:07 +01:00
|
|
|
|
|
|
|
public static Ingredient blockIng(Block block) {
|
|
|
|
return Ingredient.fromStacks(new ItemStack(block));
|
|
|
|
}
|
2018-12-20 21:43:19 +01:00
|
|
|
|
|
|
|
public static void addAdvancement(EntityPlayer player, ResourceLocation advancement, String criterion) {
|
|
|
|
if (!(player instanceof EntityPlayerMP))
|
|
|
|
return;
|
|
|
|
EntityPlayerMP playerMp = (EntityPlayerMP) player;
|
|
|
|
Advancement adv = playerMp.getServerWorld().getAdvancementManager().getAdvancement(advancement);
|
|
|
|
if (adv != null)
|
|
|
|
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
|
|
|
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean isHoldingItem(EntityPlayer player, Item item) {
|
|
|
|
for (EnumHand hand : EnumHand.values()) {
|
|
|
|
ItemStack stack = player.getHeldItem(hand);
|
|
|
|
if (!stack.isEmpty() && stack.getItem() == item)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-10-14 14:27:18 +02:00
|
|
|
}
|