giants/src/main/java/pl/minecon724/giants/Main.java

211 lines
6.9 KiB
Java

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<LivingEntity> giants = new ArrayList<LivingEntity>();
boolean ai;
boolean headRotations;
boolean attack;
double chance;
double attackDamage;
double attackReach;
double expandUp;
long refreshDelay;
Map<PotionEffectType, Integer> effects = new HashMap<PotionEffectType, Integer>();
Map<Material, List<Integer>> drops = new HashMap<Material, List<Integer>>();
@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<Object>())) {
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<Object>())) {
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<Integer> data = new ArrayList<Integer>();
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<Entity> 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<Entity> 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<Material, List<Integer>> 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<PotionEffectType, Integer> t : effects.entrySet()) {
PotionEffect effect = new PotionEffect(t.getKey(), Integer.MAX_VALUE, t.getValue());
effect.apply(entity);
}
giants.add(entity);
return entity;
}
}