package me.km.api; import com.mojang.authlib.GameProfile; import java.io.File; import me.km.utils.ItemStackBuilder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Random; import java.util.stream.Collectors; import me.km.KajetansMod; import me.km.dimensions.ModTeleporter; import me.km.entities.EntityItemProjectile; import me.km.exception.PlayerNotFoundException; import me.km.items.ItemDagger; import me.km.items.ItemHammer; import me.km.items.ItemStick; import me.km.items.ItemWand; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.block.Block; import net.minecraft.block.BlockButton; import net.minecraft.block.BlockContainer; import net.minecraft.block.BlockDoor; import net.minecraft.block.BlockPistonMoving; import net.minecraft.block.BlockTrapDoor; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.SharedMonsterAttributes; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.projectile.EntityArrow; import net.minecraft.entity.projectile.EntityFireball; import net.minecraft.entity.projectile.EntityThrowable; import net.minecraft.init.Blocks; import net.minecraft.init.Enchantments; import net.minecraft.init.Items; import net.minecraft.init.MobEffects; import net.minecraft.item.Item; import net.minecraft.item.ItemAxe; import net.minecraft.item.ItemHoe; import net.minecraft.item.ItemPickaxe; import net.minecraft.item.ItemSpade; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemSword; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTUtil; import net.minecraft.network.play.server.SPacketEntityVelocity; import net.minecraft.tileentity.TileEntitySkull; import net.minecraft.util.CombatRules; import net.minecraft.util.DamageSource; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.WorldServer; public class Utils { public static void breakBlock(World w, BlockPos pos, EntityPlayer p) { IBlockState state = w.getBlockState(pos); state.getBlock().dropBlockAsItem(w, pos, state, EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, p.getHeldItemMainhand())); w.setBlockToAir(pos); } private static ItemStack getPlayerHead(GameProfile gameprofile) { ItemStack stack = new ItemStack(Items.SKULL, 1, 3); NBTTagCompound com = stack.getTagCompound(); if(com == null) { return stack; } gameprofile = TileEntitySkull.updateGameprofile(gameprofile); com.setTag("SkullOwner", NBTUtil.writeGameProfile(new NBTTagCompound(), gameprofile)); return stack; } public static ItemStack getPlayerHead(String name) { return getPlayerHead(KajetansMod.playerbank.getDataBank().getOfflinePlayer(name)); } public static ItemStack getPlayerHead(EntityPlayer p) { return getPlayerHead(p.getGameProfile()); } public static void setVelocity(Entity ent, double x, double y, double z) { ent.motionX = x; ent.motionY = y; ent.motionZ = z; updateVelocity(ent); } public static void addVelocity(Entity ent, double x, double y, double z) { ent.motionX += x; ent.motionY += y; ent.motionZ += z; updateVelocity(ent); } private static void updateVelocity(Entity ent) { if(ent instanceof EntityPlayerMP) { EntityPlayerMP p = (EntityPlayerMP) ent; SPacketEntityVelocity packet = new SPacketEntityVelocity(p); p.connection.sendPacket(packet); } } public static void scaleVelocity(Entity ent, double scale) { ent.motionX *= scale; ent.motionY *= scale; ent.motionZ *= scale; } public static boolean hasPlayedBefore(EntityPlayer p) { return new File("./world/playerdata/" + p.getUniqueID() + ".dat").exists(); } public static > T getStateValue(IBlockState state, IProperty property) { try { return state.getValue(property); } catch(IllegalArgumentException ex) { return null; } } // ------------------------------------------------------------------------- // Befehle für Werkzeuge // ------------------------------------------------------------------------- public enum ToolTypes { PICKAXE, AXE, HOE, SHOVEL, SWORD, MUSKET, DAGGER, HAMMER, STICK, WAND, SPEAR // MUSKET, SPEAR } public static ToolTypes getToolType(ItemStack stack) { if(stack == null) { return null; } Item item = stack.getItem(); if(item instanceof ItemHoe) { return ToolTypes.HOE; } else if(item instanceof ItemPickaxe) { return ToolTypes.PICKAXE; } else if(item instanceof ItemAxe) { return ToolTypes.AXE; } else if(item instanceof ItemSpade) { return ToolTypes.SHOVEL; } else if(item instanceof ItemSword) { return ToolTypes.SWORD; } else if(item instanceof ItemDagger) { return ToolTypes.DAGGER; } else if(item instanceof ItemHammer) { return ToolTypes.HAMMER; } else if(item instanceof ItemStick) { return ToolTypes.STICK; } else if(item instanceof ItemWand) { return ToolTypes.WAND; } return null; } // ------------------------------------------------------------------------- // Zufallszahlen // ------------------------------------------------------------------------- public static int randomInt(int min, int max) { return new Random().nextInt((max - min) + 1) + min; } public static boolean randomBoolean() { return new Random().nextBoolean(); } // ------------------------------------------------------------------------- // String-Tools // ------------------------------------------------------------------------- public static String formatString(String original) { if(original.length() == 0) { return original; } else if(original.length() == 1) { return original.toUpperCase(); } String[] parts = original.split("_"); for(int i = 0; i < parts.length; i++) { parts[i] = parts[i].substring(0, 1).toUpperCase() + parts[i].substring(1).toLowerCase(); } return connectSpaces(parts, 0); } public static String formatToEnumString(String original) { StringBuilder sb = new StringBuilder(); for(char c : original.toCharArray()) { if(c == ' ') { sb.append("_"); } else if(Character.isUpperCase(c)) { sb.append("_"); sb.append(c); } else { sb.append(Character.toUpperCase(c)); } } if(sb.charAt(0) == '_') { sb.deleteCharAt(0); } return sb.toString(); } public static String connect(String[] array, int start, String c) { if(start >= array.length) { return ""; } return Arrays.stream(array, start, array.length).collect(Collectors.joining(c)); } public static String connectSpaces(String[] array, int start) { return connect(array, start, " "); } public static String connect(String[] array, int start) { if(start >= array.length) { return ""; } return Arrays.stream(array, start, array.length).collect(Collectors.joining()); } // ------------------------------------------------------------------------- // ItemStack-Tools // ------------------------------------------------------------------------- public static void dropRandomTreeItem(World w, BlockPos l, IBlockState b) { Block block = b.getBlock(); int identifier = block.getMetaFromState(b) % 4; if(b == Blocks.LEAVES2) { identifier += 4; } ArrayList list = new ArrayList<>(); list.add(Items.NAME_TAG); list.add(Items.LEAD); list.add(Blocks.WEB); if(identifier == 3) { list.add(Blocks.VINE); list.add(Items.DYE); list.add(Blocks.VINE); list.add(Items.DYE); list.add(Blocks.VINE); list.add(Items.DYE); } if(identifier == 0 || identifier == 5) { list.add(Items.APPLE); list.add(Items.APPLE); list.add(Items.APPLE); list.add(Items.APPLE); list.add(Items.GOLDEN_APPLE); } list.add(Items.STICK); list.add(Items.STICK); list.add(Items.STICK); list.add(Items.STICK); list.add(Items.STRING); list.add(Items.STRING); list.add(Items.FEATHER); list.add(Items.FEATHER); if(identifier == 4) { list.add(Items.BONE); list.add(Items.BONE); list.add(Items.BONE); } int rand = Utils.randomInt(0, 19); if(rand >= list.size()) { return; } if(list.get(rand) == Items.DYE) { new ItemStackBuilder(Items.DYE, 1, (short) 3).drop(w, l); return; } if(list.get(rand) instanceof Item) { new ItemStackBuilder((Item) list.get(rand), 1).drop(w, l); return; } new ItemStackBuilder((Block) list.get(rand), 1).drop(w, l); } // ------------------------------------------------------------------------- // Inventory-Tools // ------------------------------------------------------------------------- public static EntityPlayer getPlayerFromProjectile(Entity ent) { if(ent instanceof EntityArrow) { EntityArrow arrow = (EntityArrow) ent; if(arrow.shootingEntity instanceof EntityPlayer) { return (EntityPlayer) arrow.shootingEntity; } return null; } else if(ent instanceof EntityThrowable) { EntityThrowable thrown = (EntityThrowable) ent; if(thrown.getThrower() instanceof EntityPlayer) { return (EntityPlayer) thrown.getThrower(); } return null; } else if(ent instanceof EntityFireball) { EntityFireball fire = (EntityFireball) ent; if(fire.shootingEntity instanceof EntityPlayer) { return (EntityPlayer) fire.shootingEntity; } return null; } else if(ent instanceof EntityItemProjectile) { EntityItemProjectile item = (EntityItemProjectile) ent; if(item.getItemThrower() instanceof EntityPlayer) { return (EntityPlayer) item.getItemThrower(); } return null; } return null; } public static EntityPlayer getDamager(DamageSource ds) { Entity ent = ds.getTrueSource(); if(ent == null) { return null; } if(ent instanceof EntityPlayer) { return (EntityPlayer) ent; } return null;//getPlayerFromProjectile(ent); } // ------------------------------------------------------------------------- // Entities // ------------------------------------------------------------------------- public static Vec3d getEyeLocation(Entity ent) { return ent.getPositionVector().addVector(0, ent.getEyeHeight(), 0); } public static void teleportEntity(Entity ent, Location l) { int dim = l.getWorld().provider.getDimension(); if(ent instanceof EntityPlayerMP) { EntityPlayerMP p = (EntityPlayerMP) ent; KajetansMod.playerbank.saveLocation(p); if(ent.dimension != dim) { KajetansMod.server.getPlayerList().transferPlayerToDimension(p, dim, new ModTeleporter(KajetansMod.server.getWorld(dim))); } if(l.getYaw() != 0 || l.getPitch() != 0) { p.connection.setPlayerLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); } else { p.connection.setPlayerLocation(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch); } } else { if(ent.dimension != dim) { WorldServer n = KajetansMod.server.getWorld(dim); KajetansMod.server.getPlayerList().transferEntityToWorld(ent, ent.dimension, KajetansMod.server.getWorld(ent.dimension), n, new ModTeleporter(n)); } if(l.getYaw() != 0 && l.getPitch() != 0) { ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()); } else { ent.setLocationAndAngles(l.getX(), l.getY(), l.getZ(), ent.rotationYaw, ent.rotationPitch); } } } public static void teleportEntity(Entity ent, Entity ent2) { teleportEntity(ent, new Location(ent2)); } // ------------------------------------------------------------------------- // Entities aus Umgebung // ------------------------------------------------------------------------- @SuppressWarnings("unchecked") public static List getEntitiesExcluding(Entity ent, World w, BlockPos pos, BlockPos pos2) { return w.getEntitiesWithinAABBExcludingEntity(ent, new AxisAlignedBB(pos, pos2).grow(1)); } @SuppressWarnings("unchecked") public static List getEntities(World w, double x, double y, double z, double radius, Class type) { double sqareRadius = radius * radius; return w.getEntitiesWithinAABB(type, new AxisAlignedBB( x - radius, y - radius, z - radius, x + radius, y + radius, z + radius), ent -> ent.getDistanceSq(x, y, z) <= sqareRadius); } public static List getPlayers(World w, double x, double y, double z, double radius) { double sqareRadius = radius * radius; return w.playerEntities.stream().filter(p -> p.getDistanceSq(x, y, z) <= sqareRadius).collect(Collectors.toList()); } public static List getPlayers(Entity not, double radius) { double sqareRadius = radius * radius; double x = not.posX; double y = not.posY; double z = not.posZ; return not.world.playerEntities.stream().filter(p -> p != not && p.getDistanceSq(x, y, z) <= sqareRadius).collect(Collectors.toList()); } public static T getEntity(World w, double x, double y, double z, double radius, Class type) { return getEntities(w, x, y, z, radius, type).stream() .min((e1, e2) -> Double.compare(e1.getDistanceSq(x, y, z), e2.getDistanceSq(x, y, z))) .orElse(null); } private static boolean doesIntersect(AxisAlignedBB bound, Vec3d start, Vec3d unit) { double lowerX = Double.NEGATIVE_INFINITY; double upperX = Double.POSITIVE_INFINITY; if(unit.x != 0) { if(unit.x > 0) { lowerX = (bound.minX - start.x) / unit.x; upperX = (bound.maxX - start.x) / unit.x; } else { lowerX = (bound.maxX - start.x) / unit.x; upperX = (bound.minX - start.x) / unit.x; } } double lowerY = Double.NEGATIVE_INFINITY; double upperY = Double.POSITIVE_INFINITY; if(unit.y != 0) { if(unit.y > 0) { lowerY = (bound.minY - start.y) / unit.y; upperY = (bound.maxY - start.y) / unit.y; } else { lowerY = (bound.maxY - start.y) / unit.y; upperY = (bound.minY - start.y) / unit.y; } } double lowerZ = Double.NEGATIVE_INFINITY; double upperZ = Double.POSITIVE_INFINITY; if(unit.z != 0) { if(unit.z > 0) { lowerZ = (bound.minZ - start.z) / unit.z; upperZ = (bound.maxZ - start.z) / unit.z; } else { lowerZ = (bound.maxZ - start.z) / unit.z; upperZ = (bound.minZ - start.z) / unit.z; } } return Math.max(Math.max(lowerX, lowerY), lowerZ) < Math.min(Math.min(upperX, upperY), upperZ); } @SuppressWarnings("unchecked") public static T getTargetedEntity(EntityPlayer p, double radius, double mX, double mY, double mZ, Class type) { World w = p.getEntityWorld(); BlockPos l = getPlayerTarget(p, radius); Vec3d eye = getEyeLocation(p); if(mX != 0 || mY != 0 || mZ != 0) { Random r = p.getRNG(); mX *= r.nextDouble(); mY *= r.nextDouble(); mZ *= r.nextDouble(); } Vec3d unit = new Vec3d(l.getX() - eye.x + mX, l.getY() - eye.y + mY, l.getZ() - eye.z + mZ); List col = getEntitiesExcluding(p, w, new BlockPos(eye), l); col.removeIf(ent -> !type.isAssignableFrom(ent.getClass())); // Entfernt Entities, die sich nicht mit dem Blick-Vektor schneiden col.removeIf(ent -> !doesIntersect(ent.getEntityBoundingBox().grow(0.1), eye, unit)); return (T) col.stream().sorted((Entity e1, Entity e2) -> { return Double.compare(e1.getDistanceSq(eye.x, eye.y, eye.z), e2.getDistanceSq(eye.x, eye.y, eye.z)); }).findFirst().orElse(null); } @SuppressWarnings("unchecked") public static T getTargetedEntity(EntityPlayer p, double radius, Class type) { return getTargetedEntity(p, radius, 0, 0, 0, type); } // ------------------------------------------------------------------------- // Player-Tools // ------------------------------------------------------------------------- public static EntityPlayer getNearestPlayer(World w, Vec3d v) { return w.playerEntities.stream().min((p1, p2) -> Double.compare(p1.getDistanceSq(v.x, v.y, v.z), p2.getDistanceSq(v.x, v.y, v.z))).orElse(null); } public static BlockPos getPlayerTarget(EntityPlayer p, double range, boolean boundingBox) { if(range > 128) { range = 128; } World w = p.getEntityWorld(); Vec3d start = getEyeLocation(p); Vec3d end = start.add(p.getLookVec().scale(range)); RayTraceResult ray = w.rayTraceBlocks(start, end, true, !boundingBox, false); if(ray == null) { return new BlockPos(end); } return ray.getBlockPos(); } public static BlockPos getPlayerTarget(EntityPlayer p, double range) { return getPlayerTarget(p, range, false); } public static BlockPos getPlayerTarget(EntityPlayer p) { return getPlayerTarget(p, 20); } public static EntityPlayerMP getPlayerByName(String name) throws PlayerNotFoundException { String nameLower = name.toLowerCase(); return KajetansMod.server.getPlayerList().getPlayers().stream() .filter(pl -> pl.getName().toLowerCase().contains(nameLower)) .findFirst().orElseThrow(() -> new PlayerNotFoundException(name)); } // ------------------------------------------------------------------------- // Spawn // ------------------------------------------------------------------------- public static Location getSpawn() { // Player changeDimension, WorldServer, MinecraftServer return KajetansMod.conf.getLocation("spawn"); } public static void setSpawn(World w, Vec3d v, float yaw, float pitch) { SimpleConfig conf = KajetansMod.conf; conf.setLocation("spawn", new Location(w, v, yaw, pitch)); conf.save(); w.setSpawnPoint(new BlockPos(v.x, v.y, v.z)); } // ------------------------------------------------------------------------- // Warps // ------------------------------------------------------------------------- public static Location getWarp(Module m, String name) { SimpleConfig conf = new SimpleConfig(m, "warp", name, true); if(conf.exists()) { return conf.getLocation("warp"); } return null; } // ------------------------------------------------------------------------- // Blocks // ------------------------------------------------------------------------- public static BlockPos getSameNearbyBlock(World w, BlockPos pos, Block b) { Location l = new Location(w, pos); if(l.getRelativeBlockState(1, 0, 0).getBlock() == b) { return pos.add(1, 0, 0); } else if(l.getRelativeBlockState(-1, 0, 0).getBlock() == b) { return pos.add(-1, 0, 0); } else if(l.getRelativeBlockState(0, 0, 1).getBlock() == b) { return pos.add(0, 0, 1); } else if(l.getRelativeBlockState(0, 0, -1).getBlock() == b) { return pos.add(0, 0, -1); } return null; } public static boolean shouldBeProtected(Block b) { return (b instanceof BlockDoor || b instanceof BlockContainer || b == Blocks.LEVER || b instanceof BlockButton || b instanceof BlockTrapDoor) && !(b instanceof BlockPistonMoving); } // ------------------------------------------------------------------------- // Roman Numbers // ------------------------------------------------------------------------- public static String intToRoman(int i) { switch(i) { case 1: return "I"; case 2: return "II"; case 3: return "III"; case 4: return "IV"; case 5: return "V"; case 6: return "VI"; case 7: return "VII"; case 8: return "VIII"; case 9: return "IX"; case 10: return "X"; case 11: return "XI"; case 12: return "XII"; case 13: return "XIII"; case 14: return "XIV"; case 15: return "XV"; case 16: return "XVI"; case 17: return "XVII"; case 18: return "XVIII"; case 19: return "XIX"; case 20: return "XX"; } return "I"; } public static int romanToInt(String s) { switch(s) { case "I": return 1; case "II": return 2; case "III": return 3; case "IV": return 4; case "V": return 5; case "VI": return 6; case "VII": return 7; case "VIII": return 8; case "IX": return 9; case "X": return 10; case "XI": return 11; case "XII": return 12; case "XIII": return 13; case "XIV": return 14; case "XV": return 15; case "XVI": return 16; case "XVII": return 17; case "XVIII": return 18; case "XIX": return 19; case "XX": return 20; } return 1; } }