package me.km.effects; import java.util.Collection; import java.util.HashMap; import java.util.stream.Collectors; import me.km.KajetansMod; import me.km.api.Module; import me.km.api.Utils; import me.km.entities.EntityItemProjectile; import me.km.jobsystem.JobAPI; import me.km.plots.ProtectionBank; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityEnderPearl; import net.minecraft.entity.item.EntityExpBottle; import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.projectile.*; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.potion.Potion; import net.minecraft.potion.PotionEffect; import net.minecraft.potion.PotionType; import net.minecraft.potion.PotionUtils; import net.minecraft.util.EnumParticleTypes; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraft.world.WorldServer; public class EffectUtils extends Module { private final HashMap entityData; public EffectUtils(String mname, String prefix, TextFormatting color) { super(mname, prefix, color); entityData = new HashMap<>(); } // ----------------------------------------------------------------------------------- // Entity-Data // ----------------------------------------------------------------------------------- private class EntityData { private final String s; private final Object data; public EntityData(String s, Object data) { this.s = s; this.data = data; } } public void addEntityData(Entity ent, String key, Object data) { entityData.put(ent.getEntityId(), new EntityData(key, data)); removeInvalidData(ent); } public void addEntityData(Entity ent, String key) { addEntityData(ent, key, true); } private void removeInvalidData(Entity ent) { if(ent.isDead) { entityData.remove(ent.getEntityId()); return; } KajetansMod.scheduler.scheduleTask(() -> removeInvalidData(ent), 100); } public Object getEntityData(Entity ent, String key) { EntityData data = entityData.get(ent.getEntityId()); if(data == null) { return null; } if(data.s.equals(key)) { return data.data; } return null; } // ----------------------------------------------------------------------------------- // Entity-Level // ----------------------------------------------------------------------------------- /** Returns the level of a players effect, this is used for passive effects * * @param p a player * @param eff an effect * @return the level of the effect, 0 on non existance for the player */ public static int getEffectLevel(EntityPlayer p, Effect eff) { JobAPI job = KajetansMod.jobs; return eff.getSkills().stream().mapToInt(s -> job.getSkillLevel(p, s)).max().orElse(0); } // ----------------------------------------------------------------------------------- // Entity-Collections // ----------------------------------------------------------------------------------- public static Collection getPlayersOfGuild(EntityPlayer p, World w, double x, double y, double z, double radius) { Collection col = Utils.getPlayers(w, x, y, z, radius); if(col.isEmpty()) { return col; } int id = KajetansMod.playerbank.getGuildId(p); col.removeIf(pl -> KajetansMod.playerbank.getGuildId(pl) != id); return col; } public static Collection getPlayersOfGuild(EntityPlayer p, double radius) { return getPlayersOfGuild(p, p.world, p.posX, p.posY, p.posZ, radius); } public static Collection getEntsOfNotGuild(EntityPlayer p, World w, double x, double y, double z, double radius) { boolean animals = KajetansMod.plots.getDataBank(ProtectionBank.class).canBuild(w, new BlockPos(x, y, z), p); boolean pvp = !KajetansMod.worldManager.getWorldPreferences(w).pvpProtection; boolean ppvp = KajetansMod.playerbank.getPvpStatus(p); int id = KajetansMod.playerbank.getGuildId(p); return Utils.getEntities(w, x, y, z, radius, EntityLivingBase.class).stream() .filter(ent -> animals || !(ent instanceof EntityAnimal)) .filter(ent -> pvp || !(ent instanceof EntityPlayer) || (ppvp && KajetansMod.playerbank.getPvpStatus((EntityPlayer) ent))) .filter(ent -> !(ent instanceof EntityPlayer) || (id != KajetansMod.playerbank.getGuildId((EntityPlayer) ent))) .filter(ent -> ent != p) .collect(Collectors.toList()); } public static Collection getEntsOfNotGuild(EntityPlayer p, double radius) { return getEntsOfNotGuild(p, p.world, p.posX, p.posY, p.posZ, radius); } // ----------------------------------------------------------------------------------- // Particles // ----------------------------------------------------------------------------------- public static void spawnParticle(WorldServer w, EnumParticleTypes particle, double x, double y, double z, double offX, double offY, double offZ, int count, int... data) { w.spawnParticle(particle, false, x, y, z, count, offX, offY, offZ, 1, data); } public static void spawnParticle(WorldServer w, EnumParticleTypes particle, double x, double y, double z, double offX, double offY, double offZ, int count) { spawnParticle(w, particle, x, y, z, offX, offY, offZ, count, new int[0]); } public static void spawnParticle(WorldServer w, EnumParticleTypes particle, double x, double y, double z, int count) { spawnParticle(w, particle, x, y, z, 0, 0, 0, count); } public static void spawnParticle(WorldServer w, EnumParticleTypes particle, Entity ent, int count) { spawnParticle(w, particle, ent.posX, ent.posY, ent.posZ, count); } public static void spawnSpell(EntityPlayerMP p, int level) { spawnParticle(p.getServerWorld(), EnumParticleTypes.SPELL, p.posX, p.posY + 1, p.posZ, 0.5f, 0.5f, 0.5f, 10 + level); } public static void spawnParticleCircle(WorldServer w, double x, double y, double z, EnumParticleTypes particle, double radius, int counter, int... data) { double angle = 2 * Math.PI / counter; for(int i = 0; i < counter; i++) { spawnParticle(w, particle, x + Math.cos(i * angle) * radius, y, z + Math.sin(i * angle) * radius, 0, 0, 0, 1, data); } } public static void spawnParticleCircle(WorldServer w, Entity ent, EnumParticleTypes particle, double radius, int counter, int... data) { spawnParticleCircle(w, ent.posX, ent.posY, ent.posZ, particle, radius, counter, data); } public static void spawnParticleCircle(WorldServer w, double x, double y, double z, EnumParticleTypes particle, double radius, int counter) { spawnParticleCircle(w, x, y, z, particle, radius, counter, new int[0]); } public static void spawnParticleCircle(WorldServer w, Entity ent, EnumParticleTypes particle, double radius, int counter) { spawnParticleCircle(w, ent.posX, ent.posY, ent.posZ, particle, radius, counter, new int[0]); } // ----------------------------------------------------------------------------------- // Sounds // ----------------------------------------------------------------------------------- public static void playSound(World w, SoundEvent se, SoundCategory sc, double x, double y, double z) { w.playSound(null, x, y, z, se, sc, 1, w.rand.nextFloat() * 0.1f + 0.9f); } public static void playSound(EntityPlayer p, SoundEvent se, SoundCategory sc) { playSound(p.world, se, sc, p.posX, p.posY, p.posZ); } public static void playSound(EntityPlayer p, SoundEvent se) { playSound(p.world, se, SoundCategory.PLAYERS, p.posX, p.posY, p.posZ); } // ----------------------------------------------------------------------------------- // Potions // ----------------------------------------------------------------------------------- public static void addPotionTo(EntityLivingBase ent, Potion potion, int duration, int amplifier) { if(ent.isPotionActive(potion)) { ent.removePotionEffect(potion); } ent.addPotionEffect(new PotionEffect(potion, duration, amplifier)); } // ----------------------------------------------------------------------------------- // Projectiles // ----------------------------------------------------------------------------------- public static T launchProjectile(EntityPlayer p, Class projectile, double scale, Object data) { World w = p.world; Entity launch = null; if(EntityItemProjectile.class == projectile) { if(data == null) { throw new NullPointerException("Data musn't be null for EntityItemProjectile"); } ItemStack stack = (ItemStack) data; if(stack.isEmpty()) { throw new IllegalArgumentException("Empty ItemStack not allowed here"); } launch = new EntityItemProjectile(p, stack.copy()); ((EntityItemProjectile) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, 0.0f, 1.5f, 1.0f); } else if(EntitySnowball.class == projectile) { launch = new EntitySnowball(w, p); ((EntitySnowball) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, 0.0f, 1.5f, 1.0f); } else if(EntityEgg.class == projectile) { launch = new EntityEgg(w, p); ((EntityEgg) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, 0.0f, 1.5f, 1.0f); } else if(EntityEnderPearl.class == projectile) { launch = new EntityEnderPearl(w, p); ((EntityEnderPearl) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, 0.0f, 1.5f, 1.0f); } else if(EntityPotion.class == projectile) { launch = new EntityPotion(w, p, (ItemStack) data); ((EntityPotion) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, -20.0f, 0.5f, 1.0f); } else if(EntityExpBottle.class == projectile) { launch = new EntityExpBottle(w, p); ((EntityExpBottle) launch).setHeadingFromThrower(p, p.rotationPitch, p.rotationYaw, -20.0f, 0.7f, 1.0f); } else if(EntityArrow.class.isAssignableFrom(projectile)) { if(EntityTippedArrow.class == projectile) { launch = new EntityTippedArrow(w, p); ((EntityTippedArrow) launch).setPotionEffect((ItemStack) data); } else if(EntitySpectralArrow.class == projectile) { launch = new EntitySpectralArrow(w, p); } else { launch = new EntityTippedArrow(w, p); } ((EntityArrow) launch).setAim(p, p.rotationPitch, p.rotationYaw, 0.0F, 3.0F, 1.0F); } else if(EntityFireball.class.isAssignableFrom(projectile)) { Vec3d v = p.getLookVec().scale(10); if (EntitySmallFireball.class == projectile) { launch = new EntitySmallFireball(w, p, v.x, v.y, v.z); } else if (EntityWitherSkull.class == projectile) { launch = new EntityWitherSkull(w, p, v.x, v.y, v.z); } else if (EntityDragonFireball.class == projectile) { launch = new EntityDragonFireball(w, p, v.x, v.y, v.z); } else { launch = new EntityLargeFireball(w, p, v.x, v.y, v.z); } } Utils.scaleVelocity(launch, scale); w.spawnEntity(launch); return (T) launch; } public static EntityTippedArrow launchTippedArrow(EntityPlayer p, double scale, Potion potion, int duration, int amplifier) { ItemStack stack = new ItemStack(Items.TIPPED_ARROW); PotionUtils.addPotionToItemStack(stack, new PotionType(new PotionEffect(potion, duration, amplifier))); EntityTippedArrow arrow = launchProjectile(p, EntityTippedArrow.class, scale, stack); return arrow; } public static void jumpTo(EntityLivingBase j, EntityLivingBase g) { Utils.setVelocity(j, (g.posX - g.posX) * 0.2, (g.posY - g.posY) * 0.2 + 0.9, (g.posZ - g.posZ) * 0.2); KajetansMod.scheduler.scheduleTask(() -> { Utils.setVelocity(j, (g.posX - j.posX) * 0.2, (g.posY - j.posY) * 0.2, (g.posZ - j.posZ) * 0.2); }, 12); } }