package pl.minecon724.giants; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Random; import org.apache.commons.lang.StringUtils; import org.bstats.bukkit.Metrics; import org.bstats.charts.SimplePie; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.EntityDeathEvent; import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.scheduler.BukkitRunnable; public class Main extends JavaPlugin implements Listener, CommandExecutor { File configFile = new File(getDataFolder(), "config.yml"); FileConfiguration config; Metrics metrics = new Metrics(this, 14131); Random rnd = new Random(); List giants = new ArrayList(); boolean ai; boolean headRotations; boolean attack; double chance; double attackDamage; double attackReach; double expandUp; long refreshDelay; Map effects = new HashMap(); Map> drops = new HashMap>(); @Override public void onEnable() { metrics.addCustomChart(new SimplePie("ram_allocation", () -> { return Long.toString(Runtime.getRuntime().maxMemory()); })); if (!(configFile.exists())) { saveResource("config.yml", false); } config = YamlConfiguration.loadConfiguration(configFile); ai = config.getBoolean("ai", true); chance = config.getDouble("chance", 0.02D); attackDamage = config.getDouble("attackDamage", 1.0D); attackReach = config.getDouble("attackReach", 2D); expandUp = config.getDouble("expandUp", 0D); for (Object s : config.getList("effects", new ArrayList())) { try { String[] parts = ((String) s).split(":"); if (!(StringUtils.isNumeric(parts[1]))) { throw new IllegalArgumentException(parts[1] + " is not a number"); } PotionEffectType effectType = PotionEffectType.getByName(parts[0]); if (effectType == null) { throw new IllegalArgumentException(parts[0] + " is not a PotionEffectType"); } Integer duration = Integer.valueOf(parts[1]); effects.put(effectType, duration); } catch (Exception e) { Bukkit.getLogger().severe("Exception while parsing " + s); e.printStackTrace(); continue; } } for (Object s : config.getList("drops", new ArrayList())) { try { String[] parts = ((String) s).split(":"); /* TODO find a better way to do this if (!(StringUtils.isNumeric(parts[1]))) { throw new IllegalArgumentException(parts[1] + " is not a number"); } */ Material material = Material.getMaterial(parts[0]); if (material == null) { throw new IllegalArgumentException(parts[0] + " is not a Material"); } List data = new ArrayList(); data.add(Integer.parseInt(parts[1])); data.add(Integer.parseInt(parts[2])); data.add(Integer.parseInt(parts[3])); drops.put(material, data); } catch (Exception e) { Bukkit.getLogger().severe("Exception while parsing " + s); e.printStackTrace(); continue; } } getServer().getPluginManager().registerEvents(this, this); getCommand("spawngiant").setExecutor(this); new BukkitRunnable() { @Override public void run() { for (Entity e : giants) { if (!(e.isValid())) continue; Collection nearby = e.getWorld().getNearbyEntities(e.getBoundingBox().expand( attackReach, expandUp, attackReach), n -> (n instanceof Player)); for (Entity p : nearby) { ((LivingEntity) p).damage(attackDamage, e); } } } }.runTaskTimer(this, config.getLong("hitDelay", 20L), 0L); if (headRotations) { new BukkitRunnable() { @Override public void run() { for (Entity e : giants) { List passengers = e.getPassengers(); if (passengers.size() > 0) { passengers.removeIf(n -> (n.getType() != EntityType.HUSK)); Location loc = passengers.get(0).getLocation(); e.setRotation(loc.getYaw(), loc.getPitch()); } } } }.runTaskTimerAsynchronously(this, refreshDelay, 0L); } } public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if (!(sender instanceof Player)) return true; spawnGiant(true, ((Player) sender).getLocation()); return true; } @EventHandler public void entitySpawn(EntitySpawnEvent e) { if (e.getEntityType() == EntityType.ZOMBIE) { if (rnd.nextDouble() <= chance) { e.setCancelled(true); spawnGiant(ai, e.getLocation()); } } } @EventHandler public void entityDamage(EntityDamageByEntityEvent e) { LivingEntity entity = (LivingEntity) e.getDamager(); if (entity.hasMetadata("giant")) { entity.setInvulnerable(false); entity.setHealth(0); } } @EventHandler public void entityDeath(EntityDeathEvent e) { LivingEntity entity = e.getEntity(); if (entity.getType() == EntityType.GIANT) { giants.remove(entity); for (Entry> d : drops.entrySet()) { int max = d.getValue().get(0); int min = d.getValue().get(1); ItemStack is = new ItemStack(d.getKey(), rnd.nextInt((max - min) + 1) + min); if (rnd.nextInt(100) < d.getValue().get(2)) { entity.getWorld().dropItemNaturally(entity.getLocation(), is); } } for (Entity p : entity.getPassengers()) ((LivingEntity) p).setHealth(0); } } LivingEntity spawnGiant(boolean ai, Location pos) { LivingEntity entity = (LivingEntity) pos.getWorld().spawnEntity(pos, EntityType.GIANT); if (ai) { LivingEntity passenger = (LivingEntity) pos.getWorld().spawnEntity(pos, EntityType.HUSK); new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 1) .apply((LivingEntity) passenger); passenger.setCustomName("Giant"); passenger.setCustomNameVisible(false); passenger.setInvulnerable(true); passenger.setPersistent(true); passenger.setMetadata("giant", new FixedMetadataValue(this, "y")); entity.addPassenger(passenger); } for (Entry t : effects.entrySet()) { PotionEffect effect = new PotionEffect(t.getKey(), Integer.MAX_VALUE, t.getValue()); effect.apply(entity); } giants.add(entity); return entity; } }