diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/C.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/C.java index f339f78cb..24de09989 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/C.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/C.java @@ -16,6 +16,12 @@ import org.bukkit.ChatColor; * @author Citymonstret */ public enum C { + /* + * Records + */ + RECORD_PLAY("&c%player &cstarted playing record &6%name"), + NOTIFY_ENTER("&c%player ¢ered your plot (&6%plot&c)"), + NOTIFY_LEAVE("&c%player &left your plot (&6%plot&c)"), /* * Swap */ diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java index f73f387de..4317c577f 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotMain.java @@ -16,9 +16,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.PlayerEvents; -import com.intellectualcrafters.plot.listeners.WorldEditListener; -import com.intellectualcrafters.plot.listeners.WorldGuardListener; +import com.intellectualcrafters.plot.listeners.*; import com.intellectualcrafters.plot.uuid.PlotUUIDSaver; import com.intellectualcrafters.plot.uuid.UUIDSaver; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -680,7 +678,9 @@ public class PlotMain extends JavaPlugin { }); getServer().getPluginManager().registerEvents(new PlayerEvents(), this); - + PlotPlusListener.startRunnable(this); + getServer().getPluginManager().registerEvents(new PlotPlusListener(), this); + getServer().getPluginManager().registerEvents(new ForceFieldListener(this), this); defaultFlags(); @@ -1282,7 +1282,98 @@ public class PlotMain extends JavaPlugin { booleanFlags.put(Material.DROPPER, "dropper"); } + private static void addPlusFlags() { + List booleanFlags = Arrays.asList( + "notify-enter", + "notify-leave", + "item-drop", + "invincible", + "instabreak", + "drop-protection", + "forcefield" + ); + List intervalFlags = Arrays.asList( + "feed", + "heal" + ); + List stringFlags = Arrays.asList( + "greeting", + "farewell" + ); + for(String flag : stringFlags) { + FlagManager.addFlag(new AbstractFlag(flag) { + @Override + public String parseValue(String value) { + return value; + } + + @Override + public String getValueDesc() { + return "Value must be a string, supports color codes (&)"; + } + }); + } + for(String flag : intervalFlags) { + FlagManager.addFlag(new AbstractFlag(flag) { + @Override + public String parseValue(String value) { + int seconds; + int amount; + String[] values = value.split(" "); + if (values.length < 2) { + seconds = 1; + try { + amount = Integer.parseInt(values[0]); + } catch (Exception e) { + return null; + } + } else { + try { + amount = Integer.parseInt(values[0]); + seconds = Integer.parseInt(values[1]); + } catch (Exception e) { + return null; + } + } + return amount + " " + seconds; + } + + @Override + public String getValueDesc() { + return "Value(s) must be numeric. /plot set flag {flag} {amount} [seconds]"; + } + }); + } + for(String flag : booleanFlags) { + FlagManager.addFlag(new AbstractFlag(flag) { + @Override + public String parseValue(String value) { + switch (value) { + case "on": + case "1": + case "true": + case "enabled": + return "true"; + case "off": + case "0": + case "false": + case "disabled": + return "false"; + default: + return null; + } + } + + @Override + public String getValueDesc() { + return "Value must be true/false, 1/0, on/off, enabled/disabled"; + } + }); + } + } + private static void defaultFlags() { + addPlusFlags(); FlagManager.addFlag(new AbstractFlag("fly") { @Override public String parseValue(String value) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java index 59ef54bc2..2011be25a 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MainCommand.java @@ -30,7 +30,7 @@ public class MainCommand implements CommandExecutor { private static SubCommand[] _subCommands = new SubCommand[] { new Claim(), new Paste(), new Copy(), new Clipboard(), new Auto(), new Home(), new Visit(), new TP(), new Set(), new Clear(), new Delete(), new SetOwner(), new Denied(), new Helpers(), new Trusted(), new Info(), new list(), new Help(), new Debug(), new Schematic(), new plugin(), new Inventory(), new Purge(), - new Reload(), new Merge(), new Unlink(), new Kick(), new Setup(), new DebugClaimTest(), new Inbox(), new Comment(), new Swap() }; + new Reload(), new Merge(), new Unlink(), new Kick(), new Setup(), new DebugClaimTest(), new Inbox(), new Comment(), new Swap(), new MusicSubcommand() }; public static ArrayList subCommands = new ArrayList() { { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java new file mode 100644 index 000000000..ddb7c4cc1 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/MusicSubcommand.java @@ -0,0 +1,41 @@ +package com.intellectualcrafters.plot.commands; + +import com.intellectualcrafters.plot.C; +import com.intellectualcrafters.plot.PlayerFunctions; +import com.intellectualcrafters.plot.Plot; +import com.intellectualcrafters.plot.listeners.PlotPlusListener; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Arrays; +public class MusicSubcommand extends SubCommand { + public MusicSubcommand() { + super("music", "plots.music", "Play music in plot", "music", "mus", CommandCategory.ACTIONS, true); + } + @Override + public boolean execute(Player player, String... args) { + if(!PlayerFunctions.isInPlot(player)) { + sendMessage(player, C.NOT_IN_PLOT); + return true; + } + Plot plot = PlayerFunctions.getCurrentPlot(player); + if(!plot.hasRights(player)) { + sendMessage(player, C.NO_PLOT_PERMS); + return true; + } + org.bukkit.inventory.Inventory inventory = Bukkit.createInventory(null, 9, ChatColor.RED + "Plot Jukebox"); + for(PlotPlusListener.RecordMeta meta : PlotPlusListener.RecordMeta.metaList) { + ItemStack stack = new ItemStack(meta.getMaterial()); + ItemMeta itemMeta = stack.getItemMeta(); + itemMeta.setDisplayName(ChatColor.GOLD + meta.toString()); + itemMeta.setLore(Arrays.asList(ChatColor.GRAY + "Click to play the record")); + stack.setItemMeta(itemMeta); + inventory.addItem(stack); + } + player.openInventory(inventory); + return true; + } +} \ No newline at end of file diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java new file mode 100644 index 000000000..04f091a40 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/ForceFieldListener.java @@ -0,0 +1,92 @@ +package com.intellectualcrafters.plot.listeners; + +import com.intellectualcrafters.plot.PlayerFunctions; +import com.intellectualcrafters.plot.Plot; +import org.bukkit.Location; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.util.Vector; + +import java.util.HashSet; +import java.util.Set; +/** + * Created by Citymonstret on 2014-10-24. + */ +public class ForceFieldListener implements Listener { + + private JavaPlugin plugin; + public ForceFieldListener(JavaPlugin plugin) { + this.plugin = plugin; + plugin.getServer().getPluginManager().registerEvents(this, plugin); + } + private Set getNearbyPlayers(Player player, Plot plot) { + Set players = new HashSet<>(); + Player oPlayer = null; + for(Entity entity : player.getNearbyEntities(5d, 5d, 5d)) { + if(!(entity instanceof Player) || (oPlayer = (Player) entity) == null || !PlayerFunctions.isInPlot(oPlayer) || !PlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) { + continue; + } + if(!plot.hasRights(oPlayer)) + players.add(oPlayer); + } + return players; + } + private Player hasNearbyPermitted(Player player, Plot plot) { + Player oPlayer = null; + for(Entity entity : player.getNearbyEntities(5d, 5d, 5d)) { + if(!(entity instanceof Player) || (oPlayer = (Player) entity) == null || !PlayerFunctions.isInPlot(oPlayer) || !PlayerFunctions.getCurrentPlot(oPlayer).equals(plot)) { + continue; + } + if(plot.hasRights(oPlayer)) + return oPlayer; + } + return null; + } + public Vector calculateVelocity(Player p, Player e) { + Location playerLocation = p.getLocation(); + Location oPlayerLocation = e.getLocation(); + double + playerX = playerLocation.getX(), + playerY = playerLocation.getY(), + playerZ = playerLocation.getZ(), + oPlayerX = oPlayerLocation.getX(), + oPlayerY = oPlayerLocation.getY(), + oPlayerZ = oPlayerLocation.getZ(), + x = 0d, y = 0d, z = 0d; + if(playerX < oPlayerX) + x = 1.0d; + else if(playerX > oPlayerX) + x = -1.0d; + if(playerY < oPlayerY) + y = 0.5d; + else if(playerY > oPlayerY) + y = -0.5d; + if(playerZ < oPlayerZ) + z = 1.0d; + else if(playerZ > oPlayerZ) + z = -1.0d; + return new Vector(x, y, z); + } + @EventHandler + public void onPlotEntry(PlayerMoveEvent event){ + Player player = event.getPlayer(); + if(!PlayerFunctions.isInPlot(player)) + return; + Plot plot = PlayerFunctions.getCurrentPlot(player); + if(!PlotListener.booleanFlag(plot, "forcefield")) + if(plot.hasRights(player)) { + Set players = getNearbyPlayers(player, plot); + for(Player oPlayer : players) { + oPlayer.setVelocity(calculateVelocity(player, oPlayer)); + } + } else { + Player oPlayer = hasNearbyPermitted(player, plot); + if(oPlayer == null) return; + player.setVelocity(calculateVelocity(oPlayer, player)); + } + } +} \ No newline at end of file diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java index 4733505da..14a1e310c 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotListener.java @@ -123,6 +123,27 @@ public class PlotListener { } } + public static boolean booleanFlag(Plot plot, String flag) { + return plot.settings.getFlag(flag) != null && getBooleanFlag(plot.settings.getFlag(flag).getValue()).equals("true"); + } + + private static String getBooleanFlag(String value) { + switch(value) { + case "on": + case "1": + case "true": + case "enabled": + return "true"; + case "off": + case "0": + case "false": + case "disabled": + return "false"; + default: + return null; + } + } + private static GameMode getGameMode(String str) { switch (str) { case "creative": diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java new file mode 100644 index 000000000..1b7afeca2 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/listeners/PlotPlusListener.java @@ -0,0 +1,226 @@ +package com.intellectualcrafters.plot.listeners; + +import com.intellectualcrafters.plot.C; +import com.intellectualcrafters.plot.PlayerFunctions; +import com.intellectualcrafters.plot.Plot; +import com.intellectualcrafters.plot.events.PlayerEnterPlotEvent; +import com.intellectualcrafters.plot.events.PlayerLeavePlotEvent; +import org.bukkit.*; +import org.bukkit.entity.EntityType; +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.BlockDamageEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.plugin.java.JavaPlugin; + +import java.util.*; + +/** + * Created by Citymonstret on 2014-10-30. + */ +public class PlotPlusListener extends PlotListener implements Listener { + + private static HashMap feedRunnable = new HashMap<>(); + private static HashMap healRunnable = new HashMap<>(); + + public static void startRunnable(JavaPlugin plugin) { + plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { + @Override + public void run() { + for(Map.Entry entry : feedRunnable.entrySet()) { + Interval value = entry.getValue(); + ++value.count; + if(value.count == value.interval) { + value.count = 0; + Player player = Bukkit.getPlayer(entry.getKey()); + int level = player.getFoodLevel(); + if(level != value.max) { + player.setFoodLevel(Math.min(level + value.amount, value.max)); + } + } + } + for(Map.Entry entry : healRunnable.entrySet()) { + Interval value = entry.getValue(); + ++value.count; + if(value.count == value.interval) { + value.count = 0; + Player player = Bukkit.getPlayer(entry.getKey()); + double level = player.getHealth(); + if(level != value.max) { + player.setHealth(Math.min(level + value.amount, value.max)); + } + } + } + } + }, 0l, 20l); + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + Player player = (Player) event.getWhoClicked(); + if(!event.getInventory().getName().equals(ChatColor.RED + "Plot Jukebox")) + return; + event.setCancelled(true); + if(!isInPlot(player)) { + PlayerFunctions.sendMessage(player, C.NOT_IN_PLOT); + return; + } + Plot plot = getPlot(player); + if(!plot.hasRights(player)) { + PlayerFunctions.sendMessage(player, C.NO_PLOT_PERMS); + return; + } + Set plotPlayers = new HashSet<>(); + for(Player p : player.getWorld().getPlayers()) { + if(isInPlot(p) && getPlot(p).equals(plot)) + plotPlayers.add(p); + } + RecordMeta meta = null; + for(RecordMeta m : RecordMeta.metaList) { + if(m.getMaterial() == event.getCurrentItem().getType()) { + meta = m; + break; + } + } + if(meta == null) + return; + for(Player p : plotPlayers) { + p.playEffect(p.getLocation(), Effect.RECORD_PLAY, meta.getMaterial()); + PlayerFunctions.sendMessage(p, C.RECORD_PLAY.s().replaceAll("%player", player.getName()).replaceAll("%name", meta.toString())); + } + + } + + @EventHandler(priority = EventPriority.HIGH) + public void onInteract(BlockDamageEvent event) { + Player player = event.getPlayer(); + if(player.getGameMode() != GameMode.SURVIVAL) return; + if(!isInPlot(player)) return; + Plot plot = getPlot(player); + if(booleanFlag(plot, "instabreak")) + event.getBlock().breakNaturally(); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onDamage(EntityDamageEvent event) { + if(event.getEntityType() != EntityType.PLAYER) + return; + Player player = (Player) event.getEntity(); + if(!isInPlot(player)) return; + if(booleanFlag(getPlot(player), "invincible")) + event.setCancelled(true); + } + + @EventHandler public void onItemPickup(PlayerPickupItemEvent event) { if(isInPlot(event.getPlayer()) && !getPlot(event.getPlayer()).hasRights(event.getPlayer()) && booleanFlag(getPlot(event.getPlayer()), "drop-protection")) event.setCancelled(true); } + + @EventHandler public void onItemDrop(PlayerDropItemEvent event) { if(isInPlot(event.getPlayer()) && !getPlot(event.getPlayer()).hasRights(event.getPlayer()) && booleanFlag(getPlot(event.getPlayer()), "item-drop")) event.setCancelled(true);} + + @EventHandler + public void onPlotEnter(PlayerEnterPlotEvent event) { + Plot plot = event.getPlot(); + if(plot.settings.getFlag("greeting") != null) { + event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', plot.settings.getFlag("greeting").getValue())); + } + if(booleanFlag(plot, "notify-enter")) { + if(plot.hasOwner()) { + Player player = Bukkit.getPlayer(plot.getOwner()); + if(player == null) return; + if(player.getUniqueId().equals(event.getPlayer().getUniqueId())) + return; + if(player.isOnline()) { + PlayerFunctions.sendMessage(player, + C.NOTIFY_ENTER + .s() + .replace("%player", event.getPlayer().getName()) + .replace("%plot", plot.getId().toString())); + } + } + } + } + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (feedRunnable.containsKey(event.getPlayer().getName()) ) { + feedRunnable.remove(event.getPlayer().getName()); + } + if (healRunnable.containsKey(event.getPlayer().getName()) ) { + healRunnable.remove(event.getPlayer().getName()); + } + } + @EventHandler + public void onPlotLeave(PlayerLeavePlotEvent event) { + event.getPlayer().playEffect(event.getPlayer().getLocation(), Effect.RECORD_PLAY, 0); + Plot plot = event.getPlot(); + if(plot.settings.getFlag("farewell") != null) { + event.getPlayer().sendMessage(ChatColor.translateAlternateColorCodes('&', plot.settings.getFlag("farewell").getValue())); + } + if (feedRunnable.containsKey(event.getPlayer().getName()) ) { + feedRunnable.remove(event.getPlayer().getName()); + } + if (healRunnable.containsKey(event.getPlayer().getName()) ) { + healRunnable.remove(event.getPlayer().getName()); + } + if(booleanFlag(plot, "notify-leave")) { + if(plot.hasOwner()) { + Player player = Bukkit.getPlayer(plot.getOwner()); + if(player == null) return; + if(player.getUniqueId().equals(event.getPlayer().getUniqueId())) + return; + if(player.isOnline()) { + PlayerFunctions.sendMessage(player, + C.NOTIFY_LEAVE + .s() + .replace("%player", event.getPlayer().getName()) + .replace("%plot", plot.getId().toString())); + } + } + } + } + + public static class Interval { + public int interval; + public int amount; + public int count = 0; + public int max; + public Interval(int interval, int amount, int max) { + this.interval = interval; + this.amount = amount; + this.max = max; + } + } + + /** + * Created by Citymonstret on 2014-10-22. + */ + public static class RecordMeta { + public static List metaList = new ArrayList<>(); + static { + for(int x = 3; x < 12; x++) { + metaList.add( + new RecordMeta( + x + "", + Material.valueOf("RECORD_" + x) + ) + ); + } + } + private String name; + private Material material; + public RecordMeta(String name, Material material) { + this.name = name; + this.material = material; + } + @Override + public String toString() { + return this.name; + } + public Material getMaterial() { + return this.material; + } + } +}