commit 03730b6a9ed9760daa07ab2a871580892e32c81a Author: Jacek Date: Fri Mar 9 01:41:08 2012 +0000 Initial commit diff --git a/plugin.yml b/plugin.yml new file mode 100755 index 0000000..3fb25d4 --- /dev/null +++ b/plugin.yml @@ -0,0 +1,15 @@ +name: BloodMoon +version: 0.13.1 +main: uk.co.jacekk.bukkit.bloodmoon.BloodMoon +load: startup +commands: + bloodmoon: + description: Toggles the bloodmoon for the current world. + usage: /bloodmoon +permissions: + bloodmoon.command.bloodmoon: + description: Allows use of the /bloodmoon command. + default: op + bloodmoon.feature.ignore-world-lock: + description: Allows the player to leave the world even if the bloodmoon is active the lock-in-world feature is enabled. + default: op \ No newline at end of file diff --git a/uk/co/jacekk/bukkit/bloodmoon/BloodMoon.java b/uk/co/jacekk/bukkit/bloodmoon/BloodMoon.java new file mode 100755 index 0000000..65f38d2 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/BloodMoon.java @@ -0,0 +1,158 @@ +package uk.co.jacekk.bukkit.bloodmoon; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Random; + +import org.bukkit.Server; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitScheduler; + +import uk.co.jacekk.bukkit.bloodmoon.commands.BloodMoonExecuter; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityCreeper; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityEnderman; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySkeleton; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySpider; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityZombie; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.BreakBlocksListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.DoubleHealthListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.FireArrowsListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.LockInWorldListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.MoreExpListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.MoreSpawningListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.SpawnOnKillListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.SpawnOnSleepListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.SuperCreepersListener; +import uk.co.jacekk.bukkit.bloodmoon.featurelisteners.SwordDamageListener; +import uk.co.jacekk.bukkit.bloodmoon.listeners.EntityListener; +import uk.co.jacekk.bukkit.bloodmoon.listeners.PlayerListener; +import uk.co.jacekk.bukkit.bloodmoon.listeners.WorldListener; + +public class BloodMoon extends JavaPlugin { + + protected Server server; + protected PluginManager manager; + protected BukkitScheduler scheduler; + + protected String pluignDirPath; + protected File configFile; + + protected BloodMoonLogger log; + + public Random rand; + + public static BloodMoonConfig config; + public static ArrayList bloodMoonWorlds; + + protected BloodMoonTimeMonitor timeMonitor; + + public void onEnable(){ + this.server = this.getServer(); + this.manager = this.server.getPluginManager(); + this.scheduler = this.server.getScheduler(); + + this.log = new BloodMoonLogger(this); + + this.rand = new Random(); + + this.pluignDirPath = this.getDataFolder().getAbsolutePath(); + this.configFile = new File(this.pluignDirPath + File.separator + "config.yml"); + + BloodMoon.config = new BloodMoonConfig(this.configFile, this); + BloodMoon.bloodMoonWorlds = new ArrayList(); + + this.timeMonitor = new BloodMoonTimeMonitor(this); + + try{ + @SuppressWarnings({"rawtypes"}) + Class[] args = new Class[3]; + args[0] = Class.class; + args[1] = String.class; + args[2] = int.class; + + Method a = net.minecraft.server.EntityTypes.class.getDeclaredMethod("a", args); + + a.setAccessible(true); + + a.invoke(a, BloodMoonEntityCreeper.class, "Creeper", 50); + a.invoke(a, BloodMoonEntitySkeleton.class, "Skeleton", 51); + a.invoke(a, BloodMoonEntitySpider.class, "Spider", 52); + a.invoke(a, BloodMoonEntityZombie.class, "Zombie", 54); + a.invoke(a, BloodMoonEntityEnderman.class, "Enderman", 58); + }catch (Exception e){ + e.printStackTrace(); + + this.setEnabled(false); + return; + } + + if (BloodMoon.config.getBoolean("always-on")){ + this.manager.registerEvents(new WorldListener(), this); + }else{ + this.scheduler.scheduleAsyncRepeatingTask(this, this.timeMonitor, 100, 100); + } + + this.getCommand("bloodmoon").setExecutor(new BloodMoonExecuter()); + + // These events are always needed. + this.manager.registerEvents(new PlayerListener(), this); + this.manager.registerEvents(new EntityListener(), this); + + // These events are only needed by the certain features. + if (BloodMoon.config.getBoolean("features.break-blocks.enabled")){ + this.manager.registerEvents(new BreakBlocksListener(this), this); + } + + if (BloodMoon.config.getBoolean("features.fire-arrows.enabled") && BloodMoon.config.getBoolean("features.fire-arrows.ignight-target")){ + this.manager.registerEvents(new FireArrowsListener(), this); + } + + // spider-jump is handled in BloodMoonEntitySpider + + if (BloodMoon.config.getBoolean("features.double-health.enabled")){ + this.manager.registerEvents(new DoubleHealthListener(), this); + } + + if (BloodMoon.config.getBoolean("features.more-spawning.enabled")){ + this.manager.registerEvents(new MoreSpawningListener(), this); + } + + if (BloodMoon.config.getBoolean("features.more-exp.enabled")){ + this.manager.registerEvents(new MoreExpListener(), this); + } + + if (BloodMoon.config.getBoolean("features.super-creepers.enabled")){ + this.manager.registerEvents(new SuperCreepersListener(), this); + } + + if (BloodMoon.config.getBoolean("features.spawn-on-kill.enabled")){ + this.manager.registerEvents(new SpawnOnKillListener(this), this); + } + + // arrow-rate is handled in BloodMoonEntitySkeleton + + if (BloodMoon.config.getBoolean("features.sword-damage.enabled")){ + this.manager.registerEvents(new SwordDamageListener(this), this); + } + + if (BloodMoon.config.getBoolean("features.lock-in-world.enabled") && BloodMoon.config.getBoolean("always-on") == false){ + this.manager.registerEvents(new LockInWorldListener(), this); + } + + if (BloodMoon.config.getBoolean("features.spawn-on-sleep.enabled")){ + this.manager.registerEvents(new SpawnOnSleepListener(), this); + } + + this.log.info("Enabled."); + } + + public void onDisable(){ + this.log.info("Disabled"); + + BloodMoon.config = null; + BloodMoon.bloodMoonWorlds = null; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/BloodMoonConfig.java b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonConfig.java new file mode 100755 index 0000000..b6efb13 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonConfig.java @@ -0,0 +1,148 @@ +package uk.co.jacekk.bukkit.bloodmoon; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; + +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Creature; + +public class BloodMoonConfig { + + private YamlConfiguration config; + private LinkedHashMap configDefaults; + + public BloodMoonConfig(File configFile, BloodMoon plugin){ + this.configDefaults = new LinkedHashMap(); + this.config = new YamlConfiguration(); + + this.configDefaults.put("affected-worlds", Arrays.asList()); + + this.configDefaults.put("always-on", false); + this.configDefaults.put("bloodmoon-chance", 14); + + this.configDefaults.put("features.arrow-rate.enabled", true); + this.configDefaults.put("features.arrow-rate.multiplier", 2); + + this.configDefaults.put("features.fire-arrows.enabled", true); + this.configDefaults.put("features.fire-arrows.ignight-target", true); + + this.configDefaults.put("features.spider-jump.enabled", true); + this.configDefaults.put("features.spider-jump.multiplier", 2.0D); + + this.configDefaults.put("features.break-blocks.enabled", true); + this.configDefaults.put("features.break-blocks.realistic-drop", false); + this.configDefaults.put("features.break-blocks.mobs", Arrays.asList("ZOMBIE", "SKELETON", "SPIDER", "CREEPER", "ENDERMAN")); + this.configDefaults.put("features.break-blocks.blocks", Arrays.asList("WOOD")); + + this.configDefaults.put("features.double-health.enabled", true); + this.configDefaults.put("features.double-health.mobs", Arrays.asList("ZOMBIE", "SKELETON", "SPIDER", "CREEPER", "ENDERMAN")); + + this.configDefaults.put("features.more-spawning.enabled", true); + this.configDefaults.put("features.more-spawning.multiplier", 2); + + this.configDefaults.put("features.more-exp.enabled", true); + this.configDefaults.put("features.more-exp.multiplier", 2); + + this.configDefaults.put("features.sword-damage.enabled", true); + this.configDefaults.put("features.sword-damage.mobs", Arrays.asList("ZOMBIE", "SKELETON", "SPIDER", "CREEPER", "ENDERMAN")); + this.configDefaults.put("features.sword-damage.chance", 10); + this.configDefaults.put("features.sword-damage.damage.diamond", 100); + this.configDefaults.put("features.sword-damage.damage.iron", 20); + this.configDefaults.put("features.sword-damage.damage.gold", 10); + this.configDefaults.put("features.sword-damage.damage.stone", 20); + this.configDefaults.put("features.sword-damage.damage.wood", 10); + + this.configDefaults.put("features.super-creepers.enabled", true); + this.configDefaults.put("features.super-creepers.power", 4.0D); + + this.configDefaults.put("features.spawn-on-kill.enabled", true); + this.configDefaults.put("features.spawn-on-kill.mobs", Arrays.asList("ZOMBIE", "SKELETON", "SPIDER", "CREEPER", "ENDERMAN")); + this.configDefaults.put("features.spawn-on-kill.chance", 10); + this.configDefaults.put("features.spawn-on-kill.spawn", Arrays.asList("ZOMBIE", "SKELETON", "SPIDER", "CREEPER", "ENDERMAN")); + + this.configDefaults.put("features.spawn-on-sleep.enabled", true); + this.configDefaults.put("features.spawn-on-sleep.spawn", Arrays.asList("ZOMBIE")); + + this.configDefaults.put("features.lock-in-world.enabled", true); + + if (configFile.exists()){ + try { + this.config.load(configFile); + } catch (Exception e){ + e.printStackTrace(); + } + } + + boolean updateNeeded = false; + + for (String key : this.configDefaults.keySet()){ + if (this.config.contains(key) == false){ + this.config.set(key, this.configDefaults.get(key)); + + updateNeeded = true; + } + } + + if (updateNeeded){ + try { + this.config.save(configFile); + plugin.log.info("The config.yml file has been updated."); + } catch (IOException e){ + e.printStackTrace(); + } + } + } + + public boolean getBoolean(String key){ + if (this.configDefaults.containsKey(key) == false){ + return false; + } + + return this.config.getBoolean(key, (Boolean) this.configDefaults.get(key)); + } + + public int getInt(String key){ + if (this.configDefaults.containsKey(key) == false){ + return 0; + } + + return this.config.getInt(key, (Integer) this.configDefaults.get(key)); + } + + public double getDouble(String key){ + if (this.configDefaults.containsKey(key) == false){ + return 0.0; + } + + return this.config.getDouble(key, (Double) this.configDefaults.get(key)); + } + + public List getStringList(String key){ + if (this.configDefaults.containsKey(key) == false){ + return new ArrayList(); + } + + return this.config.getStringList(key); + } + + public String getRandomStringFromList(String key){ + List list = this.getStringList(key); + + return list.get((int) (Math.random() * (list.size() - 1))); + } + + public boolean isCreatureOnMobList(String key, Creature entity){ + String mobName = entity.toString().toUpperCase(); + + if (mobName.startsWith("CRAFT")){ + mobName = mobName.substring(5); + } + + return this.getStringList(key).contains(mobName); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/BloodMoonLogger.java b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonLogger.java new file mode 100755 index 0000000..30e2011 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonLogger.java @@ -0,0 +1,57 @@ +package uk.co.jacekk.bukkit.bloodmoon; + +import java.util.logging.Filter; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +import org.bukkit.plugin.PluginDescriptionFile; + +public class BloodMoonLogger { + + private BloodMoon plugin; + private Logger logger; + + public BloodMoonLogger(BloodMoon instance){ + this.plugin = instance; + this.logger = Logger.getLogger("Minecraft"); + + final Filter currentFilter = this.logger.getFilter(); + + this.logger.setFilter(new Filter(){ + + @Override + public boolean isLoggable(LogRecord record){ + if (currentFilter != null && currentFilter.isLoggable(record) == false){ + return false; + } + + if (record.getMessage().contains("Fetching addPacket for removed entity")){ + return false; + } + + return true; + } + + }); + + } + + private String buildString(String msg){ + PluginDescriptionFile pdFile = plugin.getDescription(); + + return pdFile.getName() + " " + pdFile.getVersion() + ": " + msg; + } + + public void info(String msg){ + this.logger.info(this.buildString(msg)); + } + + public void warn(String msg){ + this.logger.warning(this.buildString(msg)); + } + + public void fatal(String msg){ + this.logger.severe(this.buildString(msg)); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/BloodMoonTimeMonitor.java b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonTimeMonitor.java new file mode 100755 index 0000000..69b0057 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/BloodMoonTimeMonitor.java @@ -0,0 +1,35 @@ +package uk.co.jacekk.bukkit.bloodmoon; + +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.entity.Player; + +public class BloodMoonTimeMonitor implements Runnable { + + private BloodMoon plugin; + + public BloodMoonTimeMonitor(BloodMoon instance){ + this.plugin = instance; + } + + public void run(){ + for (String worldName : BloodMoon.config.getStringList("affected-worlds")){ + World world = plugin.server.getWorld(worldName); + + if (world != null){ + int worldTime = Math.round(world.getTime() / 100); + + if (worldTime == 123 && Math.random() < (((double) BloodMoon.config.getInt("bloodmoon-chance")) / 100) && BloodMoon.bloodMoonWorlds.contains(worldName) == false){ + for (Player player : world.getPlayers()){ + player.sendMessage(ChatColor.RED + "The blood moon is rising !"); + } + + BloodMoon.bloodMoonWorlds.add(worldName); + }else if (worldTime < 1 && BloodMoon.bloodMoonWorlds.contains(worldName)){ + BloodMoon.bloodMoonWorlds.remove(worldName); + } + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/commands/BloodMoonExecuter.java b/uk/co/jacekk/bukkit/bloodmoon/commands/BloodMoonExecuter.java new file mode 100755 index 0000000..3ae7862 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/commands/BloodMoonExecuter.java @@ -0,0 +1,51 @@ +package uk.co.jacekk.bukkit.bloodmoon.commands; + +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class BloodMoonExecuter implements CommandExecutor { + + public boolean onCommand(CommandSender sender, Command command, String label, String[] args){ + if (sender instanceof Player == false){ + sender.sendMessage("Sorry the /bloodmoon command can only be used in game."); + return true; + } + + Player player = (Player) sender; + World world = player.getWorld(); + String worldName = world.getName(); + + if (player.hasPermission("bloodmoon.command.bloodmoon") == false){ + player.sendMessage(ChatColor.RED + "You do not have permission to use this command !"); + return true; + } + + if (BloodMoon.config.getStringList("affected-worlds").contains(worldName) == false){ + player.sendMessage(ChatColor.RED + "The blood moon is not enabled for this world !"); + return true; + } + + if (BloodMoon.bloodMoonWorlds.contains(worldName)){ + BloodMoon.bloodMoonWorlds.remove(worldName); + + for (Player worldPlayer : world.getPlayers()){ + worldPlayer.sendMessage(ChatColor.RED + "[" + player.getName() + "] The blood moon has been stopped !"); + } + }else{ + BloodMoon.bloodMoonWorlds.add(worldName); + + for (Player worldPlayer : world.getPlayers()){ + worldPlayer.sendMessage(ChatColor.RED + "[" + player.getName() + "] The blood moon is rising !"); + } + } + + return true; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityCreeper.java b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityCreeper.java new file mode 100755 index 0000000..d825883 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityCreeper.java @@ -0,0 +1,34 @@ +package uk.co.jacekk.bukkit.bloodmoon.entities; + +import org.bukkit.Location; +import org.bukkit.entity.Creeper; + +import uk.co.jacekk.bukkit.bloodmoon.events.CreeperMoveEvent; + +import net.minecraft.server.World; + +public class BloodMoonEntityCreeper extends net.minecraft.server.EntityCreeper { + + public BloodMoonEntityCreeper(World world) { + super(world); + } + + @Override + public void d_(){ + Creeper creeper = (Creeper) this.getBukkitEntity(); + + Location from = new Location(creeper.getWorld(), this.lastX, this.lastY, this.lastZ, this.lastYaw, this.lastPitch); + Location to = new Location(creeper.getWorld(), this.locX, this.locY, this.locZ, this.yaw, this.pitch); + + CreeperMoveEvent event = new CreeperMoveEvent(creeper, from, to); + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() && creeper.isDead() == false){ + return; + } + + super.d_(); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityEnderman.java b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityEnderman.java new file mode 100755 index 0000000..62d6ace --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityEnderman.java @@ -0,0 +1,34 @@ +package uk.co.jacekk.bukkit.bloodmoon.entities; + +import org.bukkit.Location; +import org.bukkit.entity.Enderman; + +import uk.co.jacekk.bukkit.bloodmoon.events.EndermanMoveEvent; + +import net.minecraft.server.World; + +public class BloodMoonEntityEnderman extends net.minecraft.server.EntityEnderman { + + public BloodMoonEntityEnderman(World world) { + super(world); + } + + @Override + public void d_(){ + Enderman enderman = (Enderman) this.getBukkitEntity(); + + Location from = new Location(enderman.getWorld(), this.lastX, this.lastY, this.lastZ, this.lastYaw, this.lastPitch); + Location to = new Location(enderman.getWorld(), this.locX, this.locY, this.locZ, this.yaw, this.pitch); + + EndermanMoveEvent event = new EndermanMoveEvent(enderman, from, to); + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() && enderman.isDead() == false){ + return; + } + + super.d_(); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySkeleton.java b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySkeleton.java new file mode 100755 index 0000000..357e3a5 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySkeleton.java @@ -0,0 +1,66 @@ +package uk.co.jacekk.bukkit.bloodmoon.entities; + +import java.lang.reflect.Field; +import java.util.ArrayList; + +import org.bukkit.Location; +import org.bukkit.entity.Skeleton; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; +import uk.co.jacekk.bukkit.bloodmoon.events.SkeletonMoveEvent; +import uk.co.jacekk.bukkit.bloodmoon.pathfinders.BloodMoonPathfinderGoalArrowAttack; + +import net.minecraft.server.PathfinderGoal; +import net.minecraft.server.PathfinderGoalArrowAttack; +import net.minecraft.server.World; + +public class BloodMoonEntitySkeleton extends net.minecraft.server.EntitySkeleton { + + public boolean bloodMoonState; + + public BloodMoonEntitySkeleton(World world){ + super(world); + + this.bloodMoonState = BloodMoon.bloodMoonWorlds.contains(world.worldData.name); + + try{ + Field a = this.goalSelector.getClass().getDeclaredField("a"); + a.setAccessible(true); + + @SuppressWarnings("unchecked") + ArrayList goals = (ArrayList) a.get(this.goalSelector); + + for (Object item : goals){ + Field goal = item.getClass().getDeclaredField("a"); + goal.setAccessible(true); + + if (goal.get(item) instanceof PathfinderGoalArrowAttack){ + goal.set(item, new BloodMoonPathfinderGoalArrowAttack(this, this.bb, 1, 60)); + } + } + + a.set(this.goalSelector, goals); + }catch (Exception e){ + e.printStackTrace(); + } + } + + @Override + public void d_(){ + Skeleton skeleton = (Skeleton) this.getBukkitEntity(); + + Location from = new Location(skeleton.getWorld(), this.lastX, this.lastY, this.lastZ, this.lastYaw, this.lastPitch); + Location to = new Location(skeleton.getWorld(), this.locX, this.locY, this.locZ, this.yaw, this.pitch); + + SkeletonMoveEvent event = new SkeletonMoveEvent(skeleton, from, to); + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() && skeleton.isDead() == false){ + return; + } + + super.d_(); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySpider.java b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySpider.java new file mode 100755 index 0000000..5e6d3b8 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntitySpider.java @@ -0,0 +1,71 @@ +package uk.co.jacekk.bukkit.bloodmoon.entities; + +import org.bukkit.Location; +import org.bukkit.entity.Spider; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; +import uk.co.jacekk.bukkit.bloodmoon.events.SpiderMoveEvent; + +import net.minecraft.server.Entity; +import net.minecraft.server.MathHelper; +import net.minecraft.server.World; + +public class BloodMoonEntitySpider extends net.minecraft.server.EntitySpider { + + private boolean bloodMoonState; + + public BloodMoonEntitySpider(World world){ + super(world); + + this.bloodMoonState = BloodMoon.bloodMoonWorlds.contains(world.worldData.name); + } +/* + protected void a(Entity entity, float f){ + float f1 = this.a(1.0F); + + if (f1 > 0.5F && this.random.nextInt(100) == 0){ + this.target = null; + }else{ + double multiplier = BloodMoon.config.getDouble("features.spider-jump.multiplier"); + + if (f > 2.0F * multiplier && f < 6.0D * multiplier && this.random.nextInt(10) == 0){ + if (this.onGround){ + double d0 = entity.locX - this.locX; + double d1 = entity.locZ - this.locZ; + float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1); + + if (this.bloodMoonState && BloodMoon.config.getBoolean("features.spider-jump.enabled")){ + this.motX = multiplier * (d0 / (double) f2 * 0.5D * 0.800000011920929D + this.motX * 0.20000000298023224D); + this.motZ = multiplier * (d1 / (double) f2 * 0.5D * 0.800000011920929D + this.motZ * 0.20000000298023224D); + this.motY = multiplier * 0.5 * 0.4000000059604645D; + }else{ + this.motX = d0 / (double) f2 * 0.5D * 0.800000011920929D + this.motX * 0.20000000298023224D; + this.motZ = d1 / (double) f2 * 0.5D * 0.800000011920929D + this.motZ * 0.20000000298023224D; + this.motY = 0.4000000059604645D; + } + } + }else{ + super.a(entity, f); + } + } + } +*/ + @Override + public void d_(){ + Spider spider = (Spider) this.getBukkitEntity(); + + Location from = new Location(spider.getWorld(), this.lastX, this.lastY, this.lastZ, this.lastYaw, this.lastPitch); + Location to = new Location(spider.getWorld(), this.locX, this.locY, this.locZ, this.yaw, this.pitch); + + SpiderMoveEvent event = new SpiderMoveEvent(spider, from, to); + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() && spider.isDead() == false){ + return; + } + + super.d_(); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityZombie.java b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityZombie.java new file mode 100755 index 0000000..feb9346 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/entities/BloodMoonEntityZombie.java @@ -0,0 +1,34 @@ +package uk.co.jacekk.bukkit.bloodmoon.entities; + +import org.bukkit.Location; +import org.bukkit.entity.Zombie; + +import uk.co.jacekk.bukkit.bloodmoon.events.ZombieMoveEvent; + +import net.minecraft.server.World; + +public class BloodMoonEntityZombie extends net.minecraft.server.EntityZombie { + + public BloodMoonEntityZombie(World world){ + super(world); + } + + @Override + public void d_(){ + Zombie zombie = (Zombie) this.getBukkitEntity(); + + Location from = new Location(zombie.getWorld(), this.lastX, this.lastY, this.lastZ, this.lastYaw, this.lastPitch); + Location to = new Location(zombie.getWorld(), this.locX, this.locY, this.locZ, this.yaw, this.pitch); + + ZombieMoveEvent event = new ZombieMoveEvent(zombie, from, to); + + this.world.getServer().getPluginManager().callEvent(event); + + if (event.isCancelled() && zombie.isDead() == false){ + return; + } + + super.d_(); + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/events/CreeperMoveEvent.java b/uk/co/jacekk/bukkit/bloodmoon/events/CreeperMoveEvent.java new file mode 100755 index 0000000..8922948 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/events/CreeperMoveEvent.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.events; + +import org.bukkit.Location; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class CreeperMoveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private boolean isCancelled = false; + + private Creeper creeper; + private Location from; + private Location to; + + public CreeperMoveEvent(Creeper creeper, Location from, Location to){ + this.creeper = creeper; + this.from = from; + this.to = to; + } + + public HandlerList getHandlers(){ + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Creeper getCreeper(){ + return this.creeper; + } + + public Location getTo(){ + return this.to; + } + + public Location getFrom(){ + return this.from; + } + + public LivingEntity getTarget(){ + return creeper.getTarget(); + } + + public boolean isCancelled(){ + return this.isCancelled; + } + + public void setCancelled(boolean cancelled){ + this.isCancelled = cancelled; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/events/EndermanMoveEvent.java b/uk/co/jacekk/bukkit/bloodmoon/events/EndermanMoveEvent.java new file mode 100755 index 0000000..1857495 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/events/EndermanMoveEvent.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.events; + +import org.bukkit.Location; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class EndermanMoveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private boolean isCancelled = false; + + private Enderman enderman; + private Location from; + private Location to; + + public EndermanMoveEvent(Enderman enderman, Location from, Location to){ + this.enderman = enderman; + this.from = from; + this.to = to; + } + + public HandlerList getHandlers(){ + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Enderman getEnderman(){ + return this.enderman; + } + + public Location getTo(){ + return this.to; + } + + public Location getFrom(){ + return this.from; + } + + public LivingEntity getTarget(){ + return enderman.getTarget(); + } + + public boolean isCancelled(){ + return this.isCancelled; + } + + public void setCancelled(boolean cancelled){ + this.isCancelled = cancelled; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/events/SkeletonMoveEvent.java b/uk/co/jacekk/bukkit/bloodmoon/events/SkeletonMoveEvent.java new file mode 100755 index 0000000..de4aec2 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/events/SkeletonMoveEvent.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.events; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Skeleton; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class SkeletonMoveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private boolean isCancelled = false; + + private Skeleton skeleton; + private Location from; + private Location to; + + public SkeletonMoveEvent(Skeleton skeleton, Location from, Location to){ + this.skeleton = skeleton; + this.from = from; + this.to = to; + } + + public HandlerList getHandlers(){ + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Skeleton getSkeleton(){ + return this.skeleton; + } + + public Location getTo(){ + return this.to; + } + + public Location getFrom(){ + return this.from; + } + + public LivingEntity getTarget(){ + return skeleton.getTarget(); + } + + public boolean isCancelled(){ + return this.isCancelled; + } + + public void setCancelled(boolean cancelled){ + this.isCancelled = cancelled; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/events/SpiderMoveEvent.java b/uk/co/jacekk/bukkit/bloodmoon/events/SpiderMoveEvent.java new file mode 100755 index 0000000..9b9a6db --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/events/SpiderMoveEvent.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.events; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Spider; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class SpiderMoveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private boolean isCancelled = false; + + private Spider spider; + private Location from; + private Location to; + + public SpiderMoveEvent(Spider spider, Location from, Location to){ + this.spider = spider; + this.from = from; + this.to = to; + } + + public HandlerList getHandlers(){ + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Spider getSpider(){ + return this.spider; + } + + public Location getTo(){ + return this.to; + } + + public Location getFrom(){ + return this.from; + } + + public LivingEntity getTarget(){ + return spider.getTarget(); + } + + public boolean isCancelled(){ + return this.isCancelled; + } + + public void setCancelled(boolean cancelled){ + this.isCancelled = cancelled; + } + +} \ No newline at end of file diff --git a/uk/co/jacekk/bukkit/bloodmoon/events/ZombieMoveEvent.java b/uk/co/jacekk/bukkit/bloodmoon/events/ZombieMoveEvent.java new file mode 100755 index 0000000..59230a5 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/events/ZombieMoveEvent.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.events; + +import org.bukkit.Location; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Zombie; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ZombieMoveEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private boolean isCancelled = false; + + private Zombie zombie; + private Location from; + private Location to; + + public ZombieMoveEvent(Zombie zombie, Location from, Location to){ + this.zombie = zombie; + this.from = from; + this.to = to; + } + + public HandlerList getHandlers(){ + return handlers; + } + + public static HandlerList getHandlerList(){ + return handlers; + } + + public Zombie getZombie(){ + return this.zombie; + } + + public Location getTo(){ + return this.to; + } + + public Location getFrom(){ + return this.from; + } + + public LivingEntity getTarget(){ + return zombie.getTarget(); + } + + public boolean isCancelled(){ + return this.isCancelled; + } + + public void setCancelled(boolean cancelled){ + this.isCancelled = cancelled; + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/BreakBlocksListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/BreakBlocksListener.java new file mode 100755 index 0000000..4954246 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/BreakBlocksListener.java @@ -0,0 +1,168 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import java.util.List; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Zombie; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; +import uk.co.jacekk.bukkit.bloodmoon.events.CreeperMoveEvent; +import uk.co.jacekk.bukkit.bloodmoon.events.EndermanMoveEvent; +import uk.co.jacekk.bukkit.bloodmoon.events.SkeletonMoveEvent; +import uk.co.jacekk.bukkit.bloodmoon.events.SpiderMoveEvent; +import uk.co.jacekk.bukkit.bloodmoon.events.ZombieMoveEvent; + +public class BreakBlocksListener implements Listener { + + private BloodMoon plugin; + private List mobList; + + public BreakBlocksListener(BloodMoon instance){ + this.plugin = instance; + + if (BloodMoon.config != null){ + this.mobList = BloodMoon.config.getStringList("features.break-blocks.mobs"); + } + } + + private void mobAttemptBreakBlock(Block block){ + if (block.getWorld().getTime() % 10 == 0 && plugin.rand.nextInt(100) < 50) return; + + List blockList = BloodMoon.config.getStringList("features.break-blocks.blocks"); + Material type = block.getType(); + + if (type != Material.AIR && blockList.contains(type.toString())){ + block.setType(Material.AIR); + block.getWorld().dropItemNaturally(block.getLocation(), new ItemStack(type, 1)); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onCreeperMoveEvent(CreeperMoveEvent event){ + if (event.isCancelled() || this.mobList == null || mobList.contains("CREEPER") == false) return; + + LivingEntity target = event.getTarget(); + Creeper creeper = event.getCreeper(); + + if (target instanceof Player && BloodMoon.bloodMoonWorlds.contains(creeper.getWorld().getName())){ + Block[] blocks = new Block[2]; + + try{ + blocks[0] = creeper.getTargetBlock(null, 1); + blocks[1] = blocks[0].getRelative(BlockFace.DOWN); + }catch (Exception e){ + return; + } + + for (Block block : blocks){ + this.mobAttemptBreakBlock(block); + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onSkeletonMoveEvent(SkeletonMoveEvent event){ + if (event.isCancelled() || this.mobList == null || mobList.contains("SKELETON") == false) return; + + LivingEntity target = event.getTarget(); + Skeleton skeleton = event.getSkeleton(); + + if (target instanceof Player && BloodMoon.bloodMoonWorlds.contains(skeleton.getWorld().getName())){ + Block[] blocks = new Block[2]; + + try{ + blocks[0] = skeleton.getTargetBlock(null, 1); + blocks[1] = blocks[0].getRelative(BlockFace.DOWN); + }catch (Exception e){ + return; + } + + for (Block block : blocks){ + this.mobAttemptBreakBlock(block); + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onSpiderMoveEvent(SpiderMoveEvent event){ + if (event.isCancelled() || this.mobList == null || mobList.contains("SPIDER") == false) return; + + LivingEntity target = event.getTarget(); + Spider spider = event.getSpider(); + + if (target instanceof Player && BloodMoon.bloodMoonWorlds.contains(spider.getWorld().getName())){ + Block[] blocks = new Block[2]; + + try{ + blocks[0] = spider.getTargetBlock(null, 1); + blocks[1] = blocks[0].getRelative(BlockFace.DOWN); + }catch (Exception e){ + return; + } + + for (Block block : blocks){ + this.mobAttemptBreakBlock(block); + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onZombieMoveEvent(ZombieMoveEvent event){ + if (event.isCancelled() || this.mobList == null || mobList.contains("ZOMBIE") == false) return; + + LivingEntity target = event.getTarget(); + Zombie zombie = event.getZombie(); + + if (target instanceof Player && BloodMoon.bloodMoonWorlds.contains(zombie.getWorld().getName())){ + Block[] blocks = new Block[2]; + + try{ + blocks[0] = zombie.getTargetBlock(null, 1); + blocks[1] = blocks[0].getRelative(BlockFace.DOWN); + }catch (Exception e){ + return; + } + + for (Block block : blocks){ + this.mobAttemptBreakBlock(block); + } + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEndermanMoveEvent(EndermanMoveEvent event){ + if (event.isCancelled() || this.mobList == null || mobList.contains("ENDERMAN") == false) return; + + LivingEntity target = event.getTarget(); + Enderman enderman = event.getEnderman(); + + if (target instanceof Player && BloodMoon.bloodMoonWorlds.contains(enderman.getWorld().getName())){ + Block[] blocks = new Block[3]; + + try{ + blocks[0] = enderman.getTargetBlock(null, 1); + blocks[1] = blocks[0].getRelative(BlockFace.DOWN); + blocks[2] = blocks[1].getRelative(BlockFace.DOWN); + }catch (Exception e){ + return; + } + + for (Block block : blocks){ + this.mobAttemptBreakBlock(block); + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/DoubleHealthListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/DoubleHealthListener.java new file mode 100755 index 0000000..4b421c4 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/DoubleHealthListener.java @@ -0,0 +1,45 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class DoubleHealthListener implements Listener { + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDamage(EntityDamageEvent event){ + if (event.isCancelled()) return; + + Entity entity = event.getEntity(); + List causes = Arrays.asList( + DamageCause.ENTITY_ATTACK, + DamageCause.MAGIC, + DamageCause.POISON, + DamageCause.FIRE_TICK, + DamageCause.PROJECTILE + ); + + if (entity instanceof Creature && causes.contains(event.getCause()) && BloodMoon.bloodMoonWorlds.contains(entity.getWorld().getName())){ + Creature creature = (Creature) entity; + + if (creature.getTarget() instanceof Player){ + event.setDamage((int) Math.floor(event.getDamage() / 2F)); + + if (creature.getHealth() < 0){ + creature.setHealth(0); + } + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/FireArrowsListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/FireArrowsListener.java new file mode 100755 index 0000000..61fa993 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/FireArrowsListener.java @@ -0,0 +1,40 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.ProjectileHitEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySkeleton; + +public class FireArrowsListener implements Listener { + + @EventHandler(priority = EventPriority.HIGH) + public void onProjectileHit(ProjectileHitEvent event){ + Entity entity = event.getEntity(); + + if (entity instanceof Projectile && BloodMoon.bloodMoonWorlds.contains(entity.getWorld().getName())){ + Projectile projectile = (Projectile) entity; + + LivingEntity shooter = projectile.getShooter(); + + if (shooter != null){ + if (((CraftEntity) shooter).getHandle() instanceof BloodMoonEntitySkeleton){ + Block block = projectile.getWorld().getBlockAt(projectile.getLocation()); + + if (block.getType() != Material.AIR){ + block.setType(Material.FIRE); + } + } + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/LockInWorldListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/LockInWorldListener.java new file mode 100755 index 0000000..05dba25 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/LockInWorldListener.java @@ -0,0 +1,48 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerPortalEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class LockInWorldListener implements Listener { + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerTeleport(PlayerTeleportEvent event){ + if (event.isCancelled()) return; + + Player player = event.getPlayer(); + World toWorld = event.getTo().getWorld(); + World fromWorld = event.getFrom().getWorld(); + + if (player.hasPermission("bloodmoon.feature.ignore-world-lock") == false && fromWorld != toWorld && BloodMoon.bloodMoonWorlds.contains(fromWorld.getName())){ + event.setCancelled(true); + player.sendMessage(ChatColor.RED + "You cannot leave the world until the bloodmoon has ended."); + } + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerPortal(PlayerPortalEvent event){ + this.onPlayerTeleport(event); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onPlayerRespawn(PlayerRespawnEvent event){ + Player player = event.getPlayer(); + World toWorld = event.getRespawnLocation().getWorld(); + World fromWorld = player.getWorld(); + + if (player.hasPermission("bloodmoon.feature.ignore-world-lock") == false && fromWorld != toWorld && BloodMoon.bloodMoonWorlds.contains(fromWorld.getName())){ + event.setRespawnLocation(fromWorld.getSpawnLocation()); + player.sendMessage(ChatColor.RED + "You cannot leave the world until the bloodmoon has ended."); + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreExpListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreExpListener.java new file mode 100755 index 0000000..292bd12 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreExpListener.java @@ -0,0 +1,33 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class MoreExpListener implements Listener { + +private int multiplier; + + public MoreExpListener(){ + this.multiplier = BloodMoon.config.getInt("features.more-exp.multiplier"); + + if (this.multiplier == 0 || this.multiplier > 100){ + this.multiplier = 1; + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEntityDeath(EntityDeathEvent event){ + Entity entity = event.getEntity(); + + if (entity instanceof Creature && BloodMoon.bloodMoonWorlds.contains(entity.getWorld().getName())){ + event.setDroppedExp(event.getDroppedExp() * multiplier); + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreSpawningListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreSpawningListener.java new file mode 100755 index 0000000..bf58c44 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/MoreSpawningListener.java @@ -0,0 +1,46 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.CreatureType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class MoreSpawningListener implements Listener { + + private int multiplier; + + public MoreSpawningListener(){ + this.multiplier = BloodMoon.config.getInt("features.more-spawning.multiplier"); + + if (this.multiplier == 0 || this.multiplier > 100){ + this.multiplier = 1; + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onCreatureSpawn(CreatureSpawnEvent event){ + if (event.isCancelled() || event.getSpawnReason() != SpawnReason.NATURAL) return; + + CreatureType type = event.getCreatureType(); + Location location = event.getLocation(); + World world = location.getWorld(); + + List types = Arrays.asList(CreatureType.CREEPER, CreatureType.ENDERMAN, CreatureType.SKELETON, CreatureType.ZOMBIE, CreatureType.SPIDER); + + if (BloodMoon.bloodMoonWorlds.contains(world.getName()) && types.contains(type)){ + for (int i = 0; i < this.multiplier; ++i){ + world.spawnCreature(location, type); + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnKillListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnKillListener.java new file mode 100755 index 0000000..6e6de04 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnKillListener.java @@ -0,0 +1,58 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import java.util.Arrays; +import java.util.List; + +import org.bukkit.World; +import org.bukkit.entity.Creature; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class SpawnOnKillListener implements Listener { + + private BloodMoon plugin; + + public SpawnOnKillListener(BloodMoon instance){ + this.plugin = instance; + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDeath(EntityDeathEvent event){ + Entity entity = event.getEntity(); + World world = entity.getWorld(); + + if (entity instanceof Creature && BloodMoon.bloodMoonWorlds.contains(world.getName())){ + Creature creature = (Creature) entity; + LivingEntity target = creature.getTarget(); + + List causes = Arrays.asList( + DamageCause.ENTITY_ATTACK, + DamageCause.MAGIC, + DamageCause.POISON, + DamageCause.FIRE_TICK, + DamageCause.PROJECTILE + ); + + if (target instanceof Player && causes.contains(entity.getLastDamageCause().getCause()) && BloodMoon.config.isCreatureOnMobList("features.spawn-on-kill.mobs", creature)){ + if (plugin.rand.nextInt(100) <= BloodMoon.config.getInt("features.spawn-on-kill.chance")){ + String mobName = BloodMoon.config.getRandomStringFromList("features.spawn-on-kill.spawn"); + CreatureType creatureType = CreatureType.fromName(Character.toUpperCase(mobName.charAt(0)) + mobName.toLowerCase().substring(1)); + + if (creatureType != null){ + world.spawnCreature(creature.getLocation(), creatureType); + } + } + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnSleepListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnSleepListener.java new file mode 100755 index 0000000..2ea7704 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SpawnOnSleepListener.java @@ -0,0 +1,34 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerBedEnterEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class SpawnOnSleepListener implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST) + public void onPlayerBedEnter(PlayerBedEnterEvent event){ + if (event.isCancelled()) return; + + Player player = event.getPlayer(); + Location location = player.getLocation(); + World world = location.getWorld(); + + if (BloodMoon.bloodMoonWorlds.contains(world.getName())){ + String mobName = BloodMoon.config.getRandomStringFromList("features.spawn-on-sleep.spawn"); + CreatureType creatureType = CreatureType.fromName(Character.toUpperCase(mobName.charAt(0)) + mobName.toLowerCase().substring(1)); + + if (creatureType != null){ + world.spawnCreature(location, creatureType); + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SuperCreepersListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SuperCreepersListener.java new file mode 100755 index 0000000..aef4d1a --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SuperCreepersListener.java @@ -0,0 +1,32 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Creeper; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityExplodeEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class SuperCreepersListener implements Listener { + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEntityExplode(EntityExplodeEvent event){ + if (event.isCancelled()) return; + + if (event.getEntity() instanceof Creeper){ + Location location = event.getLocation(); + World world = location.getWorld(); + String worldName = world.getName(); + + if (BloodMoon.bloodMoonWorlds.contains(worldName)){ + event.setCancelled(true); + + world.createExplosion(location, (float) BloodMoon.config.getDouble("features.super-creepers.power"), true); + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SwordDamageListener.java b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SwordDamageListener.java new file mode 100755 index 0000000..2f37df1 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/featurelisteners/SwordDamageListener.java @@ -0,0 +1,73 @@ +package uk.co.jacekk.bukkit.bloodmoon.featurelisteners; + +import org.bukkit.entity.Creature; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.inventory.ItemStack; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class SwordDamageListener implements Listener { + + private BloodMoon plugin; + + public SwordDamageListener(BloodMoon instance){ + this.plugin = instance; + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEntityDamage(EntityDamageEvent event){ + if (event.isCancelled()) return; + + Entity entity = event.getEntity(); + + if (event.getCause() == DamageCause.ENTITY_ATTACK && BloodMoon.bloodMoonWorlds.contains(entity.getWorld().getName())){ + if (entity instanceof Creature){ + Creature creature = (Creature) entity; + + LivingEntity target = creature.getTarget(); + + if (target instanceof Player){ + Player player = (Player) target; + + ItemStack item = player.getItemInHand(); + + // 190 character line :D + if (BloodMoon.config.isCreatureOnMobList("features.sword-damage.mobs", creature) && plugin.rand.nextInt(100) <= BloodMoon.config.getInt("features.sword-damage.chance")){ + short damage = item.getDurability(); + + switch (item.getType()){ + case DIAMOND_SWORD: + if (damage > BloodMoon.config.getInt("features.sword-damage.damage.diamond")){ + item.setDurability((short) (item.getDurability() - BloodMoon.config.getInt("features.sword-damage.damage.diamond"))); + } + case IRON_SWORD: + if (damage > BloodMoon.config.getInt("features.sword-damage.damage.iron")){ + item.setDurability((short) (item.getDurability() - BloodMoon.config.getInt("features.sword-damage.damage.iron"))); + } + case GOLD_SWORD: + if (damage > BloodMoon.config.getInt("features.sword-damage.damage.gold")){ + item.setDurability((short) (item.getDurability() - BloodMoon.config.getInt("features.sword-damage.damage.gold"))); + } + case STONE_SWORD: + if (damage > BloodMoon.config.getInt("features.sword-damage.damage.stone")){ + item.setDurability((short) (item.getDurability() - BloodMoon.config.getInt("features.sword-damage.damage.stone"))); + } + case WOOD_SWORD: + if (damage > BloodMoon.config.getInt("features.sword-damage.damage.wood")){ + item.setDurability((short) (item.getDurability() - BloodMoon.config.getInt("features.sword-damage.damage.wood"))); + } + } + } + } + } + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/listeners/EntityListener.java b/uk/co/jacekk/bukkit/bloodmoon/listeners/EntityListener.java new file mode 100755 index 0000000..b600cf9 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/listeners/EntityListener.java @@ -0,0 +1,91 @@ +package uk.co.jacekk.bukkit.bloodmoon.listeners; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityCreeper; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityEnderman; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySkeleton; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySpider; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntityZombie; + +public class EntityListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onCreatureSpawn(CreatureSpawnEvent event){ + if (event.isCancelled()) return; + + Location location = event.getLocation(); + Entity entity = event.getEntity(); + CreatureType creatureType = event.getCreatureType(); + World world = location.getWorld(); + + net.minecraft.server.World mcWorld = ((CraftWorld) world).getHandle(); + net.minecraft.server.Entity mcEntity = (((CraftEntity) entity).getHandle()); + + if (creatureType == CreatureType.CREEPER && mcEntity instanceof BloodMoonEntityCreeper == false){ + BloodMoonEntityCreeper bloodMoonEntityCreeper = new BloodMoonEntityCreeper(mcWorld); + + bloodMoonEntityCreeper.setPosition(location.getX(), location.getY(), location.getZ()); + + mcWorld.removeEntity((net.minecraft.server.EntityCreeper) mcEntity); + mcWorld.addEntity(bloodMoonEntityCreeper, SpawnReason.CUSTOM); + + return; + } + + if (creatureType == CreatureType.SKELETON && mcEntity instanceof BloodMoonEntitySkeleton == false){ + BloodMoonEntitySkeleton bloodMoonEntitySkeleton = new BloodMoonEntitySkeleton(mcWorld); + + bloodMoonEntitySkeleton.setPosition(location.getX(), location.getY(), location.getZ()); + + mcWorld.removeEntity((net.minecraft.server.EntitySkeleton) mcEntity); + mcWorld.addEntity(bloodMoonEntitySkeleton, SpawnReason.CUSTOM); + + return; + } + + if (creatureType == CreatureType.SPIDER && mcEntity instanceof BloodMoonEntitySpider == false){ + BloodMoonEntitySpider bloodMoonEntitySpider = new BloodMoonEntitySpider(mcWorld); + + bloodMoonEntitySpider.setPosition(location.getX(), location.getY(), location.getZ()); + + mcWorld.removeEntity((net.minecraft.server.EntitySpider) mcEntity); + mcWorld.addEntity(bloodMoonEntitySpider, SpawnReason.CUSTOM); + + return; + } + + if (creatureType == CreatureType.ZOMBIE && mcEntity instanceof BloodMoonEntityZombie == false){ + BloodMoonEntityZombie bloodMoonEntityZombie = new BloodMoonEntityZombie(mcWorld); + + bloodMoonEntityZombie.setPosition(location.getX(), location.getY(), location.getZ()); + + mcWorld.removeEntity((net.minecraft.server.EntityZombie) mcEntity); + mcWorld.addEntity(bloodMoonEntityZombie, SpawnReason.CUSTOM); + + return; + } + + if (creatureType == CreatureType.ENDERMAN && mcEntity instanceof BloodMoonEntityEnderman == false){ + BloodMoonEntityEnderman bloodMoonEntityEnderman = new BloodMoonEntityEnderman(mcWorld); + + bloodMoonEntityEnderman.setPosition(location.getX(), location.getY(), location.getZ()); + + mcWorld.removeEntity((net.minecraft.server.EntityEnderman) mcEntity); + mcWorld.addEntity(bloodMoonEntityEnderman, SpawnReason.CUSTOM); + + return; + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/listeners/PlayerListener.java b/uk/co/jacekk/bukkit/bloodmoon/listeners/PlayerListener.java new file mode 100755 index 0000000..386a3e1 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/listeners/PlayerListener.java @@ -0,0 +1,49 @@ +package uk.co.jacekk.bukkit.bloodmoon.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerChangedWorldEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerJoinEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class PlayerListener implements Listener { + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerJoin(PlayerJoinEvent event){ + Player player = event.getPlayer(); + World toWorld = player.getWorld(); + + if (BloodMoon.bloodMoonWorlds.contains(toWorld.getName())){ + player.sendMessage(ChatColor.RED + "The blood moon is rising !"); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerChangedWorld(PlayerChangedWorldEvent event){ + Player player = event.getPlayer(); + + if (BloodMoon.bloodMoonWorlds.contains(player.getWorld().getName())){ + player.sendMessage(ChatColor.RED + "The blood moon is rising !"); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event){ + if (event.isCancelled()) return; + + if (event.getMessage().equalsIgnoreCase("/reload")){ + event.getPlayer().sendMessage(ChatColor.RED + "Due to the way BloodMoon works, /reload can cause a crash."); + event.getPlayer().sendMessage(ChatColor.RED + "A fix is being worked on, but for now you will have to restart."); + event.getPlayer().sendMessage(ChatColor.RED + "To ignore this and crash the server use /reload force."); + + event.setCancelled(true); + } + } + +} \ No newline at end of file diff --git a/uk/co/jacekk/bukkit/bloodmoon/listeners/WorldListener.java b/uk/co/jacekk/bukkit/bloodmoon/listeners/WorldListener.java new file mode 100755 index 0000000..edec873 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/listeners/WorldListener.java @@ -0,0 +1,21 @@ +package uk.co.jacekk.bukkit.bloodmoon.listeners; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldInitEvent; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; + +public class WorldListener implements Listener { + + @EventHandler(priority = EventPriority.NORMAL) + public void onWorldInit(WorldInitEvent event){ + String worldName = event.getWorld().getName(); + + if (BloodMoon.config.getStringList("affected-worlds").contains(worldName)){ + BloodMoon.bloodMoonWorlds.add(worldName); + } + } + +} diff --git a/uk/co/jacekk/bukkit/bloodmoon/pathfinders/BloodMoonPathfinderGoalArrowAttack.java b/uk/co/jacekk/bukkit/bloodmoon/pathfinders/BloodMoonPathfinderGoalArrowAttack.java new file mode 100755 index 0000000..ae77cc1 --- /dev/null +++ b/uk/co/jacekk/bukkit/bloodmoon/pathfinders/BloodMoonPathfinderGoalArrowAttack.java @@ -0,0 +1,88 @@ +package uk.co.jacekk.bukkit.bloodmoon.pathfinders; + +import uk.co.jacekk.bukkit.bloodmoon.BloodMoon; +import uk.co.jacekk.bukkit.bloodmoon.entities.BloodMoonEntitySkeleton; +import net.minecraft.server.EntityArrow; +import net.minecraft.server.EntityLiving; +import net.minecraft.server.PathfinderGoal; +import net.minecraft.server.World; + +public class BloodMoonPathfinderGoalArrowAttack extends PathfinderGoal { + + World world; + BloodMoonEntitySkeleton skeleton; + EntityLiving c; + int d = 0; + float e; + int f = 0; + int g; + int h; + + public BloodMoonPathfinderGoalArrowAttack(BloodMoonEntitySkeleton skeleton, float f, int i, int j){ + this.skeleton = skeleton; + this.world = skeleton.world; + + this.e = f; + this.g = i; + this.h = j; + + this.a(3); + } + + public boolean a(){ + EntityLiving entityliving = this.skeleton.as(); + + if (entityliving == null){ + return false; + }else{ + this.c = entityliving; + return true; + } + } + + public boolean b(){ + return this.a() || !this.skeleton.ak().e(); + } + + public void d(){ + this.c = null; + } + + public void e(){ + double d0 = 100.0D; + double d1 = this.skeleton.e(this.c.locX, this.c.boundingBox.b, this.c.locZ); + boolean flag = this.skeleton.al().canSee(this.c); + + if (flag){ + ++this.f; + }else{ + this.f = 0; + } + + if (d1 <= d0 && this.f >= 20){ + this.skeleton.ak().f(); + }else{ + this.skeleton.ak().a(this.c, this.e); + } + + this.skeleton.getControllerLook().a(this.c, 30.0F, 30.0F); + this.d = Math.max(this.d - ((this.skeleton.bloodMoonState) ? BloodMoon.config.getInt("features.arrow-rate.multiplier") : 1), 0); + + if (this.d <= 0 && d1 <= d0 && flag){ + this.f(); + this.d = this.h; + } + } + + private void f(){ + EntityArrow entityarrow = new EntityArrow(this.world, this.skeleton, this.c, 1.6F, 12.0F); + + this.world.makeSound(this.skeleton, "random.bow", 1.0F, 1.0F / (this.skeleton.am().nextFloat() * 0.4F + 0.8F)); + this.world.addEntity(entityarrow); + + if (this.skeleton.bloodMoonState && BloodMoon.config.getBoolean("features.fire-arrows.enabled")){ + entityarrow.fireTicks = 1200; + } + } + +}