diff --git a/src/main/java/ca/gibstick/discosheep/DiscoCommands.java b/src/main/java/ca/gibstick/discosheep/DiscoCommands.java index 2e35987..faff3df 100644 --- a/src/main/java/ca/gibstick/discosheep/DiscoCommands.java +++ b/src/main/java/ca/gibstick/discosheep/DiscoCommands.java @@ -1,14 +1,10 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package ca.gibstick.discosheep; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.NestedCommand; +import java.util.Arrays; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandException; @@ -35,23 +31,64 @@ public class DiscoCommands { static final String PERMISSION_TOGGLEPARTYONJOIN = "discosheep.admin.toggleonjoin"; static final String PERMISSION_LIGHTNING = "discosheep.party.lightning"; - static final String FLAGS = "n:t:p:r:lf"; + static final String FLAGS = "n:t:p:r:lfg"; private static final DiscoSheep plugin = DiscoSheep.getInstance(); public static class ParentCommand { - @Command(aliases = {"discosheep", "ds"}, desc = "Main Discosheep Command", min = 0, max = -1) + @Command(aliases = {"ds", "discosheep"}, desc = "Main Discosheep Command (see /ds help)", min = 0, max = -1) @NestedCommand(DiscoCommands.class) public static void DiscoCommand(final CommandContext args, CommandSender sender) throws CommandException { } } + private static boolean getNextArg(String[] args, int i, String compare) { + if (i < args.length - 1) { + return args[i + 1].equalsIgnoreCase(compare); + } + return false; + } + + private static String getNextArg(String[] args, int i) { + if (i < args.length - 1) { + return args[i + 1]; + } else { + return null; + } + } + + // return portion of the array that contains space-separated args, + // stopping at the end of the array or the next -switch + private static String[] getNextArgs(String[] args, int i) { + int j = i; + while (j < args.length && !args[j].startsWith("-")) { + j++; + } + return Arrays.copyOfRange(args, i, j); + } + + private static int getNextIntArg(String[] args, int i) { + if (i < args.length - 1) { + try { + return Integer.parseInt(args[i + 1]); + } catch (NumberFormatException e) { + return -1; // so that it fails limit checks elsewhere + } + } + return -1; // ibid + } + private static void parsePartyFlags(DiscoParty party, final CommandContext args, CommandSender sender) throws IllegalArgumentException { - party.setDuration(args.getFlagInteger('t', DiscoParty.defaultDuration)); party.setPeriod(args.getFlagInteger('p', DiscoParty.defaultPeriod)); party.setSheep(args.getFlagInteger('n', DiscoParty.defaultSheep)); + // handle special case of duration conversion ugh + if (args.hasFlag('t')) { + int duration = args.getFlagInteger('t'); + party.setDuration(plugin.toTicks(duration)); + } + // handle the special case of radius flag arg "dense" String radiusArg = args.getFlag('r', Integer.toString(DiscoParty.defaultRadius)); if ("dense".equals(radiusArg)) { @@ -60,6 +97,7 @@ public class DiscoCommands { party.setRadius(Integer.parseInt(radiusArg)); } + // party will still start if player doesn't have permission for extras if (sender.hasPermission(PERMISSION_FIREWORKS)) { party.setDoFireworks(args.hasFlag('f')); } else { @@ -71,11 +109,58 @@ public class DiscoCommands { } else { plugin.noPermsMessage(sender, PERMISSION_LIGHTNING); } + + // handle guests + if (args.hasFlag('g')) { + // stop if no permission for spawning guests + if (!sender.hasPermission(PERMISSION_SPAWNGUESTS)) { + plugin.noPermsMessage(sender, PERMISSION_SPAWNGUESTS); + return; + } + + String dirtyArgs[] = args.getParsedSlice(0); + //sender.sendMessage(dirtyArgs); + for (int i = 0; i < dirtyArgs.length; i++) { + if ("none".equals(dirtyArgs[0])) { + plugin.clearGuests(party); + return; + } + + String[] guests = dirtyArgs; + int j = 0; + while (j < guests.length - 1) { + try { + party.setGuestNumber(guests[j].toUpperCase(), getNextIntArg(guests, j)); + } catch (IllegalArgumentException e) { + sender.sendMessage(ChatColor.RED + "Invalid arguments: " + ChatColor.WHITE + guests[j] + ", " + guests[j + 1] + + ".\nEither a name typo or a number that is not within limits."); + } + j += 2; // skip over two arguments, since they come in pairs of entity-number + } + } + + } + } - @Command(aliases = {"test"}, desc = "Test command", usage = "No arguments", min = 0, max = 0) - public static void test(final CommandContext args, CommandSender sender) throws CommandException { - sender.sendMessage("TESTING"); + /*-- Actual commands begin here --*/ + @Command(aliases = "help", desc = "DiscoSheep help", usage = "No arguments", min = 0, max = -1) + public static void helpCommand(CommandContext args, CommandSender sender) { + sender.sendMessage(ChatColor.YELLOW + + "DiscoSheep Help\n" + + ChatColor.GRAY + + " Subcommands\n" + + ChatColor.WHITE + "me, stop, all, stopall, save, reload, togglejoin\n" + + "other : start a party for the space-delimited list of players\n" + + "defaults: Change the default settings for parties (takes normal arguments)\n" + + ChatColor.GRAY + " Arguments\n" + + ChatColor.WHITE + "-n : set the number of sheep per player that spawn\n" + + "-t : set the party duration in seconds\n" + + "-p : set the number of ticks between each disco beat\n" + + "-r : set radius of the area in which sheep can spawn\n" + + "-g : set spawns for other mobs" + + "-l: enables lightning" + + "-f: enables fireworks"); } @Command(aliases = {"stop", "stoppls", "wtf"}, desc = "Stop your own disco party", usage = "No arguments", min = 0, max = 0) @@ -90,7 +175,8 @@ public class DiscoCommands { } @Command(aliases = {"reload"}, desc = "Reload DiscoSheep configuration from file", usage = "No arguments", min = 0, max = 0) - public static void reloadCommand(final CommandContext args, CommandSender sender) { + public static void reloadCommand(final CommandContext args, CommandSender sender + ) { plugin.reloadConfigFromDisk(); sender.sendMessage(ChatColor.GREEN + "DiscoSheep config reloaded from file."); } @@ -104,7 +190,8 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_PARTY) - public static void partyCommand(final CommandContext args, CommandSender sender) { + public static void partyCommand(final CommandContext args, CommandSender sender + ) { if (!(sender instanceof Player)) { sender.sendMessage("You must be a player to have a party"); return; @@ -131,13 +218,13 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_OTHER) - public static void partyOtherCommand(CommandContext args, CommandSender sender) { + public static void partyOtherCommand(CommandContext args, CommandSender sender + ) { DiscoParty party = new DiscoParty(); - Player p; - String players[] = args.getSlice(1); - parsePartyFlags(party, args, sender); + String players[] = args.getParsedSlice(0); + Player p; for (String playerName : players) { p = Bukkit.getServer().getPlayer(playerName); if (p != null) { @@ -160,7 +247,8 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_ALL) - public static void partyAllCommand(final CommandContext args, CommandSender sender) { + public static void partyAllCommand(final CommandContext args, CommandSender sender + ) { DiscoParty party = new DiscoParty(); parsePartyFlags(party, args, sender); for (Player p : Bukkit.getServer().getOnlinePlayers()) { @@ -181,7 +269,8 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_TOGGLEPARTYONJOIN) - public static void togglePartyOnJoinCommand(final CommandContext args, CommandSender sender) { + public static void togglePartyOnJoinCommand(final CommandContext args, CommandSender sender + ) { boolean result = plugin.toggleOnJoin(); if (result) { sender.sendMessage(ChatColor.GREEN + "DiscoSheep party on join functionality enabled."); @@ -199,7 +288,8 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_CHANGEDEFAULTS) - public static void setDefaultsCommand(final CommandContext args, CommandSender sender) { + public static void setDefaultsCommand(final CommandContext args, CommandSender sender + ) { DiscoParty party = new DiscoParty(); parsePartyFlags(party, args, sender); party.setDefaultsFromCurrent(); @@ -215,7 +305,8 @@ public class DiscoCommands { flags = FLAGS ) @CommandPermissions(value = PERMISSION_SAVECONFIG) - public static void saveConfigCommand(final CommandContext args, CommandSender sender) { + public static void saveConfigCommand(final CommandContext args, CommandSender sender + ) { plugin.saveConfigToDisk(); sender.sendMessage(ChatColor.GREEN + "DiscoSheep config saved to disk"); } diff --git a/src/main/java/ca/gibstick/discosheep/DiscoParty.java b/src/main/java/ca/gibstick/discosheep/DiscoParty.java index 46991a3..42c4ce2 100644 --- a/src/main/java/ca/gibstick/discosheep/DiscoParty.java +++ b/src/main/java/ca/gibstick/discosheep/DiscoParty.java @@ -273,7 +273,7 @@ public class DiscoParty { } } - loc = player.getLocation(); + //loc = player.getLocation(); //this.spawnFloor(world, new Location(world, loc.getBlockX(), loc.getBlockY() - 1, loc.getBlockZ())); } @@ -498,7 +498,7 @@ public class DiscoParty { this.scheduleUpdate(); parent.getPartyMap().put(this.player.getName(), this); // start listening - this.partyEvents = new PartyEvents(this.parent, this); + this.partyEvents = new PartyEvents(this); parent.getServer().getPluginManager().registerEvents(this.partyEvents, this.parent); } diff --git a/src/main/java/ca/gibstick/discosheep/DiscoSheep.java b/src/main/java/ca/gibstick/discosheep/DiscoSheep.java index 0ac1b5b..c3f8b53 100644 --- a/src/main/java/ca/gibstick/discosheep/DiscoSheep.java +++ b/src/main/java/ca/gibstick/discosheep/DiscoSheep.java @@ -16,6 +16,7 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandException; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; @@ -96,21 +97,15 @@ public final class DiscoSheep extends JavaPlugin { * Iterate through all live entities and create default configuration values for them * excludes bosses and other mobs that throw NPE */ - /* for (EntityType ent : EntityType.values()) { - if (ent.isAlive() - && !ent.equals(EntityType.ENDER_DRAGON) - && !ent.equals(EntityType.WITHER) - && !ent.equals(EntityType.PIG_ZOMBIE) - && !ent.equals(EntityType.OCELOT) - && !ent.equals(EntityType.CAVE_SPIDER) - && !ent.equals(EntityType.MAGMA_CUBE) - && !ent.equals(EntityType.MUSHROOM_COW) - && !ent.equals(EntityType.IRON_GOLEM) - && !ent.equals(EntityType.PLAYER)) { - getConfig().addDefault("default.guests." + ent.toString(), 0); - getConfig().addDefault("max.guests." + ent.toString(), 0); - } - }*/ + for (EntityType ent : EntityType.values()) { + if (ent.isAlive() + && !ent.equals(EntityType.ENDER_DRAGON) + && !ent.equals(EntityType.WITHER) + && !ent.equals(EntityType.PLAYER)) { + getConfig().addDefault("default.guests." + ent.toString(), 0); + getConfig().addDefault("max.guests." + ent.toString(), 5); + } + } loadConfigFromDisk(); } @@ -129,13 +124,13 @@ public final class DiscoSheep extends JavaPlugin { DiscoParty.defaultDuration = toTicks(getConfig().getInt("default.duration")); DiscoParty.defaultPeriod = getConfig().getInt("default.period-ticks"); - /* for (String key : getConfig().getConfigurationSection("default.guests").getKeys(false)) { - DiscoParty.getDefaultGuestNumbers().put(key, getConfig().getInt("default.guests." + key)); - } - - for (String key : getConfig().getConfigurationSection("max.guests").getKeys(false)) { - DiscoParty.getMaxGuestNumbers().put(key, getConfig().getInt("max.guests." + key)); - }*/ + for (String key : getConfig().getConfigurationSection("default.guests").getKeys(false)) { + DiscoParty.getDefaultGuestNumbers().put(key, getConfig().getInt("default.guests." + key)); + } + + for (String key : getConfig().getConfigurationSection("max.guests").getKeys(false)) { + DiscoParty.getMaxGuestNumbers().put(key, getConfig().getInt("max.guests." + key)); + } } void reloadConfigFromDisk() { @@ -150,9 +145,9 @@ public final class DiscoSheep extends JavaPlugin { getConfig().set("default.duration", toSeconds_i(DiscoParty.defaultDuration)); getConfig().set("default.period-ticks", DiscoParty.defaultPeriod); - /* for (Map.Entry entry : DiscoParty.getDefaultGuestNumbers().entrySet()) { - getConfig().set("default.guests." + entry.getKey(), entry.getValue()); - }*/ + for (Map.Entry entry : DiscoParty.getDefaultGuestNumbers().entrySet()) { + getConfig().set("default.guests." + entry.getKey(), entry.getValue()); + } saveConfig(); } @@ -163,15 +158,15 @@ public final class DiscoSheep extends JavaPlugin { commands = null; } - static int toTicks(double seconds) { + int toTicks(double seconds) { return (int) Math.round(seconds * 20.0); } - static double toSeconds(int ticks) { + double toSeconds(int ticks) { return (double) Math.round(ticks / 20.0); } - static int toSeconds_i(int ticks) { + int toSeconds_i(int ticks) { return (int) Math.round(ticks / 20.0); } diff --git a/src/main/java/ca/gibstick/discosheep/PartyEvents.java b/src/main/java/ca/gibstick/discosheep/PartyEvents.java index 2848410..c66f724 100644 --- a/src/main/java/ca/gibstick/discosheep/PartyEvents.java +++ b/src/main/java/ca/gibstick/discosheep/PartyEvents.java @@ -5,7 +5,9 @@ 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.EntityPortalEnterEvent; import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.player.PlayerInteractEntityEvent; import org.bukkit.event.player.PlayerShearEntityEvent; /** @@ -14,7 +16,7 @@ import org.bukkit.event.player.PlayerShearEntityEvent; */ public class PartyEvents implements Listener { - DiscoSheep parent; + DiscoSheep plugin = DiscoSheep.getInstance(); DiscoParty party; /* * There will be multiple instances of PartyEvents, @@ -24,8 +26,7 @@ public class PartyEvents implements Listener { * unregister the listeners when no parties are running. */ - public PartyEvents(DiscoSheep parent, DiscoParty party) { - this.parent = parent; + public PartyEvents(DiscoParty party) { this.party = party; } @@ -33,11 +34,9 @@ public class PartyEvents implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPlayerShear(PlayerShearEntityEvent e) { if (e.getEntity() instanceof Sheep) { - if (party.getSheepList().contains((Sheep) e.getEntity())) { e.setCancelled(true); } - } } @@ -46,12 +45,9 @@ public class PartyEvents implements Listener { public void onLivingEntityDamageEvent(EntityDamageEvent e) { if (e.getEntity() instanceof Sheep) { if (party.getSheepList().contains((Sheep) e.getEntity())) { - { - party.jump(e.getEntity()); // for kicks - e.setCancelled(true); - } + party.jump(e.getEntity()); // for kicks + e.setCancelled(true); } - } if (party.getGuestList().contains(e.getEntity())) { party.jump(e.getEntity()); @@ -62,10 +58,17 @@ public class PartyEvents implements Listener { // prevent uninvited guests from targetting players @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onEntityTargetLivingEntityEvent(EntityTargetEvent e) { - if (party.getGuestList().contains(e.getEntity())) { e.setCancelled(true); } - } + + // prevent egg breeding + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPlayerInteractEntityEvent(PlayerInteractEntityEvent e) { + if (party.getSheepList().contains(e.getRightClicked()) || party.getGuestList().contains(e.getRightClicked())) { + e.setCancelled(true); + } + } + }