diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java index 5298ed226..ca068eb00 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java @@ -59,6 +59,7 @@ import com.intellectualcrafters.plot.events.PlotDeleteEvent; import com.intellectualcrafters.plot.generator.DefaultPlotManager; import com.intellectualcrafters.plot.generator.DefaultPlotWorld; import com.intellectualcrafters.plot.generator.WorldGenerator; +import com.intellectualcrafters.plot.listeners.EntityListener; import com.intellectualcrafters.plot.listeners.ForceFieldListener; import com.intellectualcrafters.plot.listeners.PlayerEvents; import com.intellectualcrafters.plot.listeners.PlotListener; @@ -611,7 +612,7 @@ public class PlotMain extends JavaPlugin { if (Settings.KILL_ROAD_MOBS) { killAllEntities(); } - + // Enabled<3 if (C.ENABLED.s().length() > 0) { Broadcast(C.ENABLED); @@ -723,6 +724,9 @@ public class PlotMain extends JavaPlugin { } }); // getCommand("plots").setTabCompleter(command); + if (Settings.MOB_CAP_ENABLED) { + getServer().getPluginManager().registerEvents(new EntityListener(), this); + } getServer().getPluginManager().registerEvents(new PlayerEvents(), this); PlotPlusListener.startRunnable(this); getServer().getPluginManager().registerEvents(new PlotPlusListener(), this); @@ -1124,6 +1128,9 @@ public class PlotMain extends JavaPlugin { options.put("api.location", Settings.API_URL); options.put("api.custom", Settings.CUSTOM_API); options.put("titles", Settings.TITLES); + + options.put("perm-based-mob-cap.enabled", Settings.MOB_CAP_ENABLED); + options.put("perm-based-mob-cap.max", Settings.MOB_CAP); for (final Entry node : options.entrySet()) { if (!config.contains(node.getKey())) { @@ -1141,6 +1148,8 @@ public class PlotMain extends JavaPlugin { Settings.AUTO_CLEAR_DAYS = config.getInt("clear.auto.days"); Settings.AUTO_CLEAR = config.getBoolean("clear.auto.enabled"); Settings.TITLES = config.getBoolean("titles"); + Settings.MOB_CAP_ENABLED = config.getBoolean("perm-based-mob-cap.enabled"); + Settings.MOB_CAP = config.getInt("perm-based-mob-cap.max"); Settings.MAX_PLOTS = config.getInt("max_plots"); Settings.SCHEMATIC_SAVE_PATH = config.getString("schematics.save_path"); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/Settings.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/Settings.java index e9bd3c4fc..4dce14c24 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/Settings.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/Settings.java @@ -15,6 +15,10 @@ package com.intellectualcrafters.plot; * @author Empire92 */ public class Settings { + + public static boolean MOB_CAP_ENABLED = false; + public static int MOB_CAP = 20; + public static boolean TITLES = true; /** * Schematic Save Path diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java index 7ef109d0a..6fddf7652 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/PlotMeConverter.java @@ -249,7 +249,6 @@ public class PlotMeConverter { Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "mw create " + worldname + " plugin:PlotSquared"); } else { - System.out.print("LOADED WORLD"); Bukkit.getServer().unloadWorld(world, true); final World myworld = WorldCreator.name(worldname).generator(new WorldGenerator(worldname)).createWorld(); myworld.save(); diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/EntityListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/EntityListener.java new file mode 100644 index 000000000..a80341a23 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/EntityListener.java @@ -0,0 +1,216 @@ +package com.intellectualcrafters.plot.listeners; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +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.block.Action; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.world.ChunkLoadEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.scheduler.BukkitScheduler; + +import com.intellectualcrafters.plot.C; +import com.intellectualcrafters.plot.PlayerFunctions; +import com.intellectualcrafters.plot.Plot; +import com.intellectualcrafters.plot.PlotHelper; +import com.intellectualcrafters.plot.PlotMain; +import com.intellectualcrafters.plot.Settings; + +public class EntityListener implements Listener { + + public static HashMap>> entityMap = new HashMap>>(); + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public static void onPlayerInteract(final PlayerInteractEvent e) { + if (e.getAction() == Action.RIGHT_CLICK_BLOCK) { + final Player p = e.getPlayer(); + World w = p.getWorld(); + String n = w.getName(); + if (e.getMaterial() == Material.MONSTER_EGG || e.getMaterial() == Material.MONSTER_EGGS) { + if (entityMap.containsKey(n)) { + Location l = e.getClickedBlock().getLocation(); + Plot plot = PlotHelper.getCurrentPlot(l); + if (plot!=null && plot.hasRights(p)) { + int mobs; + if (entityMap.get(n).containsKey(plot)) { + mobs = entityMap.get(n).get(plot).size(); + } + else { + mobs = 0; + } + if (!(PlotMain.hasPermissionRange(p, "plots.mobcap", Settings.MOB_CAP)>mobs)) { + PlayerFunctions.sendMessage(p, C.NO_PLOTS, "plots.mobcap."+(mobs+1)); + } + } + } + } + } + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public static void onCreatureSpawn(CreatureSpawnEvent e) { + Location l = e.getLocation(); + String w = l.getWorld().getName(); + if (PlotMain.isPlotWorld(w)) { + Plot plot = PlotHelper.getCurrentPlot(l); + if (plot!=null && plot.hasOwner()) { + addEntity(e.getEntity(), plot); + } + } + } + + public EntityListener() { + BukkitScheduler scheduler = Bukkit.getServer().getScheduler(); + scheduler.scheduleSyncRepeatingTask(PlotMain.getMain(), new Runnable() { + @Override + public void run() { + Iterator>>> worldIt = entityMap.entrySet().iterator(); + + Set plots = PlotMain.getPlots(); + + while (worldIt.hasNext()) { + Entry>> entry = worldIt.next(); + String worldname = entry.getKey(); + if (!PlotMain.isPlotWorld(worldname)) { + worldIt.remove(); + continue; + } + World world = Bukkit.getWorld(worldname); + if (world == null || entry.getValue().size() == 0) { + worldIt.remove(); + continue; + } + Iterator>> it = entry.getValue().entrySet().iterator(); + while (it.hasNext()) { + Entry> plotEntry = it.next(); + Plot plot = plotEntry.getKey(); + if (!plots.contains(plot)) { + it.remove(); + continue; + } + + boolean loaded = false; + + final Location pos1 = PlotHelper.getPlotBottomLoc(world, plot.id).add(1, 0, 1); + final Location pos2 = PlotHelper.getPlotTopLoc(world, plot.id); + try { + loops: + for (int i = (pos1.getBlockX() / 16) * 16; i < (16 + ((pos2.getBlockX() / 16) * 16)); i += 16) { + for (int j = (pos1.getBlockZ() / 16) * 16; j < (16 + ((pos2.getBlockZ() / 16) * 16)); j += 16) { + final Chunk chunk = world.getChunkAt(i, j); + if (chunk.isLoaded()) { + loaded = true; + break loops; + } + } + } + } + catch (Exception e) { + it.remove(); + continue; + } + if (!loaded) { + it.remove(); + } + } + } + } + }, 24000L, 48000L); + } + + @EventHandler + public static void onChunkLoad(final ChunkLoadEvent e) { + if (PlotMain.isPlotWorld(e.getWorld())) { + for (Entity entity : e.getChunk().getEntities()) { + if (entity instanceof LivingEntity) { + if (!(entity instanceof Player)) { + Plot plot = PlotHelper.getCurrentPlot(entity.getLocation()); + if (plot!=null) { + if (plot.hasOwner()) { + addEntity(entity, plot); + } + } + } + } + } + } + } + + public static void addEntity(Entity entity, Plot plot) { + if (!entityMap.containsKey(plot.world)) { + entityMap.put(plot.world, new HashMap>()); + } + HashMap> section = entityMap.get(plot.world); + if (section.containsKey(plot)) { + section.put(plot, new HashSet()); + } + section.get(plot).add(entity.getEntityId()); + } + + @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) + public static void onEntityDeath(EntityDeathEvent e) { + Entity entity = e.getEntity(); + Location l = entity.getLocation(); + String w = l.getWorld().getName(); + if (entityMap.containsKey(w)) { + int id = entity.getEntityId(); + Plot plot = PlotHelper.getCurrentPlot(entity.getLocation()); + if (plot!=null) { + if (entityMap.get(w).containsKey(plot)) { + entityMap.get(w).get(plot).remove(id); + } + } + else { + Iterator>> it = entityMap.get(w).entrySet().iterator(); + while (it.hasNext()) { + Entry> n = it.next(); + n.getValue().remove(id); + } + } + } + } + + @EventHandler + public static void onChunkDespawn(final ChunkUnloadEvent e) { + String w = e.getWorld().getName(); + if (entityMap.containsKey(w)) { + for (Entity entity : e.getChunk().getEntities()) { + if (entity instanceof LivingEntity) { + if (!(entity instanceof Player)) { + Plot plot = PlotHelper.getCurrentPlot(entity.getLocation()); + if (plot!=null) { + if (plot.hasOwner()) { + if (entityMap.get(w).containsKey(plot)) { + if (entityMap.get(w).get(plot).size()==1) { + entityMap.get(w).remove(plot); + } + else { + entityMap.get(w).get(plot).remove(entity.getEntityId()); + } + } + } + } + } + } + } + } + } +}