Bläddra i källkod

Merge branch 'master' of github.com:mcMMO-Dev/mcMMO

shatteredbeam 12 år sedan
förälder
incheckning
0528139c2c
34 ändrade filer med 844 tillägg och 644 borttagningar
  1. 4 0
      Changelog.txt
  2. 13 2
      src/main/java/com/gmail/nossr50/api/PartyAPI.java
  3. 13 2
      src/main/java/com/gmail/nossr50/commands/CommandRegistrationHelper.java
  4. 0 79
      src/main/java/com/gmail/nossr50/commands/player/MccCommand.java
  5. 71 2
      src/main/java/com/gmail/nossr50/commands/player/McmmoCommand.java
  6. 3 6
      src/main/java/com/gmail/nossr50/mcMMO.java
  7. 1 1
      src/main/java/com/gmail/nossr50/party/PartyManager.java
  8. 40 0
      src/main/java/com/gmail/nossr50/party/commands/PartyChangeOwnerCommand.java
  9. 55 0
      src/main/java/com/gmail/nossr50/party/commands/PartyChangePasswordCommand.java
  10. 75 324
      src/main/java/com/gmail/nossr50/party/commands/PartyCommand.java
  11. 43 0
      src/main/java/com/gmail/nossr50/party/commands/PartyDisbandCommand.java
  12. 7 8
      src/main/java/com/gmail/nossr50/party/commands/PartyExpShareCommand.java
  13. 30 0
      src/main/java/com/gmail/nossr50/party/commands/PartyHelpCommand.java
  14. 97 0
      src/main/java/com/gmail/nossr50/party/commands/PartyInfoCommand.java
  15. 7 2
      src/main/java/com/gmail/nossr50/party/commands/PartyInviteCommand.java
  16. 7 8
      src/main/java/com/gmail/nossr50/party/commands/PartyItemShareCommand.java
  17. 7 30
      src/main/java/com/gmail/nossr50/party/commands/PartyKickCommand.java
  18. 97 0
      src/main/java/com/gmail/nossr50/party/commands/PartyLockCommand.java
  19. 65 0
      src/main/java/com/gmail/nossr50/party/commands/PartyRenameCommand.java
  20. 45 0
      src/main/java/com/gmail/nossr50/party/commands/PartySubcommandType.java
  21. 92 94
      src/main/java/com/gmail/nossr50/party/commands/PtpCommand.java
  22. 1 1
      src/main/java/com/gmail/nossr50/party/runnables/PartiesLoader.java
  23. 1 1
      src/main/java/com/gmail/nossr50/party/runnables/PartyAutoKick.java
  24. 1 3
      src/main/java/com/gmail/nossr50/skills/SkillGuide.java
  25. 1 4
      src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java
  26. 23 31
      src/main/java/com/gmail/nossr50/skills/axes/ImpactEventHandler.java
  27. 2 2
      src/main/java/com/gmail/nossr50/skills/fishing/ShakeMob.java
  28. 3 3
      src/main/java/com/gmail/nossr50/skills/repair/Salvage.java
  29. 13 3
      src/main/java/com/gmail/nossr50/util/ItemChecks.java
  30. 0 16
      src/main/java/com/gmail/nossr50/util/Misc.java
  31. 1 1
      src/main/java/com/gmail/nossr50/util/Users.java
  32. 2 2
      src/main/resources/config.yml
  33. 16 11
      src/main/resources/locale/locale_en_US.properties
  34. 8 8
      src/main/resources/plugin.yml

+ 4 - 0
Changelog.txt

@@ -30,6 +30,8 @@ Version 1.4.00-dev
  + Added Shears, Buckets, Fishing Rods, Flint & Steel, Carrot Sticks, and Bows to the list of items that can be Salvaged
  + Added the "wait" music disc to the default fishing treasures
  + Added "Chinese (Taiwan)" localization files (zh_TW)
+ = Fixed /ptp telporting the target to the player, rather than the other way around.
+ = Fixed Impact reducing durability of non-armor equipped blocks
  = Fixed multiple commands not working properly on offline players
  = Fixed /mmoedit not giving feedback when modifying another players stats
  = Fixed the guide usage string showing up every time /skillname was called
@@ -51,6 +53,7 @@ Version 1.4.00-dev
  = Fixed Experience.Gains.Mobspawners.Enabled not being used correctly (the check was inverted)
  = Fixed bug where Iron Grip was using the attacker's skill values rather than the defender's.
  = Fixed a bug where /party kick would trigger the PartyChangeEvent for the wrong player
+ = Fixed /party kick not working on offline players
  = Fixed a bug where party join messages weren't displayed
  = Fixed a bug where Disarm and Deflect had wrong values
  = Fixed Magic Hunter (Fishing ability) favoring certain enchants
@@ -74,6 +77,7 @@ Version 1.4.00-dev
  - Removed unused "healthbar" files from the resources
  - Removed config options for disabling commands from the config.yml. This should instead be done through permissions.
  - Removed Chimaera Wing
+ - Removed /mcc command. Replaced with /mcmmo [?|help|commands]
 
 Version 1.3.14
  + Added new Hylian Luck skill to Herbalism.

+ 13 - 2
src/main/java/com/gmail/nossr50/api/PartyAPI.java

@@ -125,8 +125,7 @@ public final class PartyAPI {
      * @return all the players in the player's party
      * @deprecated
      */
-    // TODO: I naively tried to add another getAllMembers that returns a List<OffflinePlayer>, but that wasn't possible
-    // since the return type isn't part of the the method's signature. If anybody has an idea...
+    @Deprecated
     public static List<String> getAllMembers(Player player) {
         List<String> memberNames = new ArrayList<String>();
 
@@ -137,6 +136,18 @@ public final class PartyAPI {
         return memberNames;
     }
 
+    /**
+     * Get a list of all players in this player's party.
+     * </br>
+     * This function is designed for API usage.
+     *
+     * @param player The player to check
+     * @return all the players in the player's party
+     */
+    public static List<OfflinePlayer> getOnlineAndOfflineMembers(Player player) {
+        return PartyManager.getAllMembers(player);
+    }
+
     /**
      * Get a list of all online players in this party.
      * </br>

+ 13 - 2
src/main/java/com/gmail/nossr50/commands/CommandRegistrationHelper.java

@@ -27,6 +27,7 @@ import com.gmail.nossr50.database.commands.McremoveCommand;
 import com.gmail.nossr50.database.commands.MmoupdateCommand;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.commands.PartyCommand;
+import com.gmail.nossr50.party.commands.PtpCommand;
 import com.gmail.nossr50.skills.acrobatics.AcrobaticsCommand;
 import com.gmail.nossr50.skills.archery.ArcheryCommand;
 import com.gmail.nossr50.skills.axes.AxesCommand;
@@ -211,10 +212,10 @@ public final class CommandRegistrationHelper {
     public static void registerMcmmoCommand() {
         PluginCommand command = mcMMO.p.getCommand("mcmmo");
         command.setDescription(LocaleLoader.getString("Commands.Description.mcmmo"));
-        command.setPermission("mcmmo.commands.mcmmo");
+        command.setPermission("mcmmo.commands.mcmmo;mcmmo.commands.mcmmo.help");
         command.setPermissionMessage(permissionsMessage);
         command.setUsage(LocaleLoader.getString("Commands.Usage.0", "mcmmo"));
-        command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.1", "mcmmo", "?"));
+        command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.1", "mcmmo", "help"));
         command.setExecutor(new McmmoCommand());
     }
 
@@ -324,4 +325,14 @@ public final class CommandRegistrationHelper {
         command.setPermissionMessage(permissionsMessage);
         command.setExecutor(new PartyCommand());
     }
+
+    public static void registerPtpCommand() {
+        PluginCommand command = mcMMO.p.getCommand("ptp");
+        command.setDescription(LocaleLoader.getString("Commands.Description.ptp"));
+        command.setPermission("mcmmo.commands.ptp;mcmmo.commands.ptp.accept;mcmmo.commands.ptp.acceptall;mcmmo.commands.ptp.toggle");
+        command.setPermissionMessage(permissionsMessage);
+        command.setUsage(LocaleLoader.getString("Commands.Usage.1", "ptp", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">"));
+        command.setUsage(command.getUsage() + "\n" + LocaleLoader.getString("Commands.Usage.1", "ptp", "<toggle|accept|acceptall>"));
+        command.setExecutor(new PtpCommand());
+    }
 }

+ 0 - 79
src/main/java/com/gmail/nossr50/commands/player/MccCommand.java

@@ -1,79 +0,0 @@
-package com.gmail.nossr50.commands.player;
-
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-
-import com.gmail.nossr50.commands.CommandHelper;
-import com.gmail.nossr50.locale.LocaleLoader;
-import com.gmail.nossr50.util.Permissions;
-
-//TODO: Rework this whole thing. It's ugly. Also is missing all the admin & spout commands.
-public class MccCommand implements CommandExecutor {
-    @Override
-    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        if (CommandHelper.noConsoleUsage(sender)) {
-            return true;
-        }
-
-        if (!Permissions.hasPermission(sender, "mcmmo.commands.mcc")) {
-            return true;
-        }
-
-        Player player = (Player) sender;
-
-        player.sendMessage(LocaleLoader.getString("Commands.mcc.Header"));
-
-        if (Permissions.party(player)) {
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Commands"));
-            player.sendMessage("/party create <" + LocaleLoader.getString("Commands.Usage.PartyName") + "> " + LocaleLoader.getString("Commands.Party1"));
-            player.sendMessage("/party join <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party2"));
-            player.sendMessage("/party quit " + LocaleLoader.getString("Commands.Party.Quit"));
-
-            if (Permissions.partyChat(player)) {
-                player.sendMessage("/p " + LocaleLoader.getString("Commands.Party.Toggle"));
-            }
-
-            player.sendMessage("/party invite <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party.Invite"));
-            player.sendMessage("/party accept " + LocaleLoader.getString("Commands.Party.Accept"));
-
-            if (Permissions.partyTeleport(player)) {
-                player.sendMessage("/ptp " + LocaleLoader.getString("Commands.Party.Teleport"));
-            }
-        }
-
-        player.sendMessage(LocaleLoader.getString("Commands.Other"));
-        player.sendMessage("/mcstats " + LocaleLoader.getString("Commands.Stats"));
-        player.sendMessage("/mctop " + LocaleLoader.getString("Commands.Leaderboards"));
-
-        if (Permissions.skillReset(player)) {
-            player.sendMessage("/skillreset <skill|all> " + LocaleLoader.getString("Commands.Reset"));
-        }
-
-        if (Permissions.mcAbility(player)) {
-            player.sendMessage("/mcability " + LocaleLoader.getString("Commands.ToggleAbility"));
-        }
-
-        if (Permissions.adminChat(player)) {
-            player.sendMessage("/a " + LocaleLoader.getString("Commands.AdminToggle"));
-        }
-
-        if (Permissions.inspect(player)) {
-            player.sendMessage("/inspect " + LocaleLoader.getString("Commands.Inspect"));
-        }
-
-        if (Permissions.mmoedit(player)) {
-            player.sendMessage("/mmoedit " + LocaleLoader.getString("Commands.mmoedit"));
-        }
-
-        if (Permissions.mcgod(player)) {
-            player.sendMessage("/mcgod " + LocaleLoader.getString("Commands.mcgod"));
-        }
-
-        player.sendMessage(LocaleLoader.getString("Commands.SkillInfo"));
-        player.sendMessage("/mcmmo " + LocaleLoader.getString("Commands.ModDescription"));
-
-        return true;
-    }
-}

+ 71 - 2
src/main/java/com/gmail/nossr50/commands/player/McmmoCommand.java

@@ -10,12 +10,14 @@ import org.getspout.spoutapi.player.SpoutPlayer;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.Permissions;
 
 public class McmmoCommand implements CommandExecutor {
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 
-        if (args.length == 0 || (args.length == 1 && args[0].equals("?"))) {
+        switch (args.length) {
+        case 0:
             String description = LocaleLoader.getString("mcMMO.Description");
             String[] mcSplit = description.split(",");
             sender.sendMessage(mcSplit);
@@ -32,8 +34,75 @@ public class McmmoCommand implements CommandExecutor {
 
             sender.sendMessage(LocaleLoader.getString("MOTD.Version", mcMMO.p.getDescription().getVersion()));
             return true;
+
+        case 1:
+            if (args[0].equalsIgnoreCase("?") || args[0].equalsIgnoreCase("help") || args[0].equalsIgnoreCase("commands")) {
+                if (!Permissions.hasPermission(sender, "mcmmo.commands.mcmmo.help")) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
+                sender.sendMessage(LocaleLoader.getString("Commands.mcc.Header"));
+                displayPartyCommands(sender);
+                displayOtherCommands(sender);
+
+            }
+            return true;
+
+        default:
+            return false;
+        }
+    }
+
+    private void displayPartyCommands(CommandSender sender) {
+        if (sender.hasPermission("mcmmo.commands.party")) {
+            sender.sendMessage(LocaleLoader.getString("Commands.Party.Commands"));
+            sender.sendMessage("/party create <" + LocaleLoader.getString("Commands.Usage.PartyName") + "> " + LocaleLoader.getString("Commands.Party1"));
+            sender.sendMessage("/party join <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party2"));
+            sender.sendMessage("/party quit " + LocaleLoader.getString("Commands.Party.Quit"));
+
+            if (sender.hasPermission("mcmmo.chat.party")) {
+                sender.sendMessage("/party chat " + LocaleLoader.getString("Commands.Party.Toggle"));
+            }
+
+            sender.sendMessage("/party invite <" + LocaleLoader.getString("Commands.Usage.Player") + "> " + LocaleLoader.getString("Commands.Party.Invite"));
+            sender.sendMessage("/party accept " + LocaleLoader.getString("Commands.Party.Accept"));
+
+            if (sender.hasPermission("mcmmo.commands.ptp")) {
+                sender.sendMessage("/party teleport " + LocaleLoader.getString("Commands.Party.Teleport"));
+            }
+        }
+    }
+
+    private void displayOtherCommands(CommandSender sender) {
+        sender.sendMessage(LocaleLoader.getString("Commands.Other"));
+        sender.sendMessage("/mcstats " + LocaleLoader.getString("Commands.Stats"));
+        sender.sendMessage("/mctop " + LocaleLoader.getString("Commands.Leaderboards"));
+
+        if (sender.hasPermission("mcmmo.commands.skillreset")) {
+            sender.sendMessage("/skillreset <skill|all> " + LocaleLoader.getString("Commands.Reset"));
+        }
+
+        if (sender.hasPermission("mcmmo.commands.mcability")) {
+            sender.sendMessage("/mcability " + LocaleLoader.getString("Commands.ToggleAbility"));
+        }
+
+        if (sender.hasPermission("mcmmo.chat.admin")) {
+            sender.sendMessage("/adminchat " + LocaleLoader.getString("Commands.AdminToggle"));
+        }
+
+        if (sender.hasPermission("mcmmo.commands.inspect")) {
+            sender.sendMessage("/inspect " + LocaleLoader.getString("Commands.Inspect"));
+        }
+
+        if (sender.hasPermission("mcmmo.commands.mmoedit")) {
+            sender.sendMessage("/mmoedit " + LocaleLoader.getString("Commands.mmoedit"));
+        }
+
+        if (sender.hasPermission("mcmmo.commands.mcgod")) {
+            sender.sendMessage("/mcgod " + LocaleLoader.getString("Commands.mcgod"));
         }
 
-        return false;
+        sender.sendMessage(LocaleLoader.getString("Commands.SkillInfo"));
     }
 }

+ 3 - 6
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -23,7 +23,6 @@ import org.mcstats.Metrics.Graph;
 import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManager;
 import com.gmail.nossr50.util.blockmeta.chunkmeta.ChunkManagerFactory;
 import com.gmail.nossr50.commands.CommandRegistrationHelper;
-import com.gmail.nossr50.commands.player.MccCommand;
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.config.HiddenConfig;
@@ -44,7 +43,8 @@ import com.gmail.nossr50.mods.config.CustomBlocksConfig;
 import com.gmail.nossr50.mods.config.CustomEntityConfig;
 import com.gmail.nossr50.mods.config.CustomToolsConfig;
 import com.gmail.nossr50.party.PartyManager;
-import com.gmail.nossr50.party.commands.PtpCommand;
+import com.gmail.nossr50.party.runnables.PartiesLoader;
+import com.gmail.nossr50.party.runnables.PartyAutoKick;
 import com.gmail.nossr50.runnables.MobStoreCleaner;
 import com.gmail.nossr50.runnables.SaveTimer;
 import com.gmail.nossr50.skills.repair.RepairManager;
@@ -52,8 +52,6 @@ import com.gmail.nossr50.skills.repair.RepairManagerFactory;
 import com.gmail.nossr50.skills.repair.Repairable;
 import com.gmail.nossr50.skills.repair.config.RepairConfigManager;
 import com.gmail.nossr50.skills.runnables.BleedTimer;
-import com.gmail.nossr50.skills.runnables.PartiesLoader;
-import com.gmail.nossr50.skills.runnables.PartyAutoKick;
 import com.gmail.nossr50.skills.runnables.SkillMonitor;
 import com.gmail.nossr50.spout.SpoutConfig;
 import com.gmail.nossr50.spout.SpoutTools;
@@ -278,7 +276,6 @@ public class mcMMO extends JavaPlugin {
         CommandRegistrationHelper.registerMcpurgeCommand();
         CommandRegistrationHelper.registerMcremoveCommand();
         CommandRegistrationHelper.registerMcabilityCommand();
-        getCommand("mcc").setExecutor(new MccCommand());
         CommandRegistrationHelper.registerMcgodCommand();
         CommandRegistrationHelper.registerMcmmoCommand();
         CommandRegistrationHelper.registerMcrefreshCommand();
@@ -290,7 +287,7 @@ public class mcMMO extends JavaPlugin {
         CommandRegistrationHelper.registerAdminChatCommand();
         CommandRegistrationHelper.registerPartyCommand();
         CommandRegistrationHelper.registerPartyChatCommand();
-        getCommand("ptp").setExecutor(new PtpCommand(this));
+        CommandRegistrationHelper.registerPtpCommand();
 
         // Other commands
         CommandRegistrationHelper.registerAddxpCommand();

+ 1 - 1
src/main/java/com/gmail/nossr50/party/PartyManager.java

@@ -39,7 +39,7 @@ public final class PartyManager {
     }
 
     /**
-     * Check if two players are in the same party.
+     * Check if two online players are in the same party.
      *
      * @param firstPlayer The first player
      * @param secondPlayer The second player

+ 40 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyChangeOwnerCommand.java

@@ -0,0 +1,40 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class PartyChangeOwnerCommand implements CommandExecutor {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.owner")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        switch (args.length) {
+        case 2:
+            Party playerParty = Users.getPlayer((Player) sender).getParty();
+
+            if (!playerParty.getMembers().contains(mcMMO.p.getServer().getOfflinePlayer(args[1]))) {
+                sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));
+                return true;
+            }
+
+            PartyManager.setPartyLeader(args[1], playerParty);
+            return true;
+
+        default:
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "owner", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">"));
+            return true;
+        }
+    }
+}

+ 55 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyChangePasswordCommand.java

@@ -0,0 +1,55 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class PartyChangePasswordCommand implements CommandExecutor {
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.password")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        Party playerParty = Users.getPlayer((Player) sender).getParty();
+        switch (args.length) {
+        case 1:
+            unprotectParty(sender, playerParty);
+            return true;
+
+        case 2:
+            if (args[1].equalsIgnoreCase("clear") || args[1].equalsIgnoreCase("reset")) {
+                unprotectParty(sender, playerParty);
+                return true;
+            }
+
+            protectParty(sender, playerParty, args[1]);
+            return true;
+
+        default:
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "password", "[clear|reset]"));
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "password", "<" + LocaleLoader.getString("Commands.Usage.Password") + ">"));
+            return true;
+        }
+    }
+
+    private void unprotectParty(CommandSender sender, Party playerParty) {
+        playerParty.setLocked(true);
+        playerParty.setPassword(null);
+        sender.sendMessage(LocaleLoader.getString("Party.Password.Removed"));
+    }
+
+    private void protectParty(CommandSender sender, Party playerParty, String password) {
+        playerParty.setLocked(true);
+        playerParty.setPassword(password);
+        sender.sendMessage(LocaleLoader.getString("Party.Password.Set", password));
+    }
+}

+ 75 - 324
src/main/java/com/gmail/nossr50/party/commands/PartyCommand.java

@@ -1,21 +1,14 @@
 package com.gmail.nossr50.party.commands;
 
-import org.bukkit.ChatColor;
-import org.bukkit.OfflinePlayer;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
-import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.chat.commands.PartyChatCommand;
 import com.gmail.nossr50.commands.CommandHelper;
-import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.McMMOPlayer;
-import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
-import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
 import com.gmail.nossr50.locale.LocaleLoader;
-import com.gmail.nossr50.party.Party;
-import com.gmail.nossr50.party.PartyManager;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
@@ -31,6 +24,15 @@ public class PartyCommand implements CommandExecutor {
     private CommandExecutor partyItemShareCommand = new PartyItemShareCommand();
     private CommandExecutor partyInviteCommand = new PartyInviteCommand();
     private CommandExecutor partyKickCommand = new PartyKickCommand();
+    private CommandExecutor partyDisbandCommand = new PartyDisbandCommand();
+    private CommandExecutor partyChangeOwnerCommand = new PartyChangeOwnerCommand();
+    private CommandExecutor partyLockCommand = new PartyLockCommand();
+    private CommandExecutor partyChangePasswordCommand = new PartyChangePasswordCommand();
+    private CommandExecutor partyRenameCommand = new PartyRenameCommand();
+    private CommandExecutor partyInfoCommand = new PartyInfoCommand();
+    private CommandExecutor partyHelpCommand = new PartyHelpCommand();
+    private CommandExecutor partyTeleportCommand = new PtpCommand();
+    private CommandExecutor partyChatCommand = new PartyChatCommand();
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
@@ -46,351 +48,100 @@ public class PartyCommand implements CommandExecutor {
         player = (Player) sender;
         mcMMOPlayer = Users.getPlayer(player);
 
-        if (args.length < 1 || args[0].equalsIgnoreCase("info")) {
-            return party();
+        if (args.length < 1) {
+            if (!mcMMOPlayer.inParty()) {
+                sender.sendMessage(LocaleLoader.getString("Commands.Party.None"));
+                return printUsage();
+            }
+
+            return partyInfoCommand.onCommand(sender, command, label, args);
         }
 
-        if (args[0].equalsIgnoreCase("join")) {
-            return partyJoinCommand.onCommand(sender, command, label, args);
+        PartySubcommandType subcommand = PartySubcommandType.getSubcommand(args[0]);
+
+        if (subcommand == null) {
+            return printUsage();
         }
-        else if (args[0].equalsIgnoreCase("accept")) {
+
+        switch (subcommand) {
+        case JOIN:
+            return partyJoinCommand.onCommand(sender, command, label, args);
+        case ACCEPT:
             return partyAcceptCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("create")) {
+        case CREATE:
             return partyCreateCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("?") || args[0].equalsIgnoreCase("help")) {
-            return printHelp();
+        case HELP:
+            return partyHelpCommand.onCommand(sender, command, label, args);
+        default:
+            break;
         }
 
+        // Party member commands
         if (!mcMMOPlayer.inParty()) {
             sender.sendMessage(LocaleLoader.getString("Commands.Party.None"));
             return printUsage();
         }
 
-        if (args[0].equalsIgnoreCase("quit") || args[0].equalsIgnoreCase("q") || args[0].equalsIgnoreCase("leave")) {
+        switch (subcommand) {
+        case INFO:
+            return partyInfoCommand.onCommand(sender, command, label, args);
+        case QUIT:
             return partyQuitCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("expshare") || args[0].equalsIgnoreCase("xpshare") || args[0].equalsIgnoreCase("sharexp") || args[0].equalsIgnoreCase("shareexp")) {
-            return partyExpShareCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("itemshare") || args[0].equalsIgnoreCase("shareitem") || args[0].equalsIgnoreCase("shareitems")) {
-            return partyItemShareCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("invite")) {
+        case INVITE:
             return partyInviteCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("kick")) {
-            return partyKickCommand.onCommand(sender, command, label, args);
-        }
-        else if (args[0].equalsIgnoreCase("disband")) {
-            return disband();
-        }
-        else if (args[0].equalsIgnoreCase("owner")) {
-            return changeOwner(args);
-        }
-        else if (args[0].equalsIgnoreCase("lock")) {
-            return lock();
-        }
-        else if (args[0].equalsIgnoreCase("unlock")) {
-            return unlock();
-        }
-        else if (args[0].equalsIgnoreCase("password")) {
-            return changePassword(args);
-        }
-        else if (args[0].equalsIgnoreCase("rename")) {
-            return rename(args);
-        }
-        else {
-            return printUsage();
-        }
-    }
-
-    private boolean printUsage() {
-        player.sendMessage(LocaleLoader.getString("Party.Help.0"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.1"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.2"));
-        return true;
-    }
-
-    private boolean party() {
-        if (mcMMOPlayer.inParty()) {
-            Party party = mcMMOPlayer.getParty();
-            String leader = party.getLeader();
-            StringBuilder tempList = new StringBuilder();
-
-            int membersNear = PartyManager.getNearMembers(player, party, Config.getInstance().getPartyShareRange()).size();
-            int membersOnline = party.getOnlineMembers().size() - 1;
-
-            String ItemShare = "";
-            String ExpShare = "";
-            String Split = "";
-
-            for (OfflinePlayer otherMember : party.getMembers()) {
-                if (leader.equals(otherMember.getName())) {
-                    tempList.append(ChatColor.GOLD);
-                }
-                else if (otherMember.isOnline()) {
-                    tempList.append(ChatColor.WHITE);
-                }
-                else {
-                    tempList.append(ChatColor.GRAY);
-                }
-
-                tempList.append(otherMember.getName()).append(" ");
-            }
-
-            String status = LocaleLoader.getString("Party.Status.Locked");
-            if (!party.isLocked()) {
-                status = LocaleLoader.getString("Party.Status.Unlocked");
-            }
-
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Header"));
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Status", party.getName(), status));
-
-            boolean xpShareEnabled = Config.getInstance().getExpShareEnabled();
-            boolean itemShareEnabled = Config.getInstance().getItemShareEnabled();
-
-            if (xpShareEnabled) {
-                ExpShare = LocaleLoader.getString("Commands.Party.ExpShare", party.getXpShareMode().toString());
-            }
-
-            if (itemShareEnabled) {
-                ItemShare = LocaleLoader.getString("Commands.Party.ItemShare", party.getItemShareMode().toString());
-            }
-
-            if (xpShareEnabled && itemShareEnabled) {
-                Split = ChatColor.DARK_GRAY + " || ";
-            }
-
-            if (xpShareEnabled || itemShareEnabled) {
-                player.sendMessage(LocaleLoader.getString("Commands.Party.ShareMode") + ExpShare + Split + ItemShare);
-            }
-
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Members.Header"));
-            player.sendMessage(LocaleLoader.getString("Commands.Party.MembersNear", membersNear, membersOnline));
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Members", tempList));
-        }
-        else {
-            return printUsage();
-        }
-
-        return true;
-    }
-
-    private boolean printHelp() {
-        player.sendMessage(LocaleLoader.getString("Party.Help.3"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.1"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.4"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.5"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.6"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.7"));
-        player.sendMessage(LocaleLoader.getString("Party.Help.8"));
-        return true;
-    }
-
-    /**
-     * Disband the current party, kicks out all party members.
-     */
-    private boolean disband() {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.disband")) {
-            return true;
-        }
-
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-
-        if (party.getLeader().equals(playerName)) {
-            for (Player onlineMembers : party.getOnlineMembers()) {
-                McMMOPartyChangeEvent event = new McMMOPartyChangeEvent(onlineMembers, party.getName(), null, EventReason.KICKED_FROM_PARTY);
-                mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-                if (event.isCancelled()) {
-                    return true;
-                }
-
-                onlineMembers.sendMessage(LocaleLoader.getString("Party.Disband"));
-            }
-
-            PartyManager.disbandParty(party);
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-        }
-
-        return true;
-    }
-
-    /**
-     * Change the owner of the current party
-     */
-    private boolean changeOwner(String[] args) {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.owner")) {
-            return true;
-        }
-
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-
-        if (args.length < 2) {
-            player.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "owner", "[" + LocaleLoader.getString("Commands.Usage.Player") + "]"));
-            return true;
+        case TELEPORT:
+            return partyTeleportCommand.onCommand(sender, command, label, extractArgs(args));
+        case CHAT:
+            return partyChatCommand.onCommand(sender, command, label, extractArgs(args));
+        default:
+            break;
         }
 
-        if (party.getLeader().equals(playerName)) {
-            if (!party.getMembers().contains(mcMMO.p.getServer().getOfflinePlayer(args[1]))) {
-                player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));
-                return true;
-            }
-
-            PartyManager.setPartyLeader(args[1], party);
-        }
-
-        return true;
-    }
-
-    /**
-     * Lock the current party
-     */
-    private boolean lock() {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.lock")) {
+        // Party leader commands
+        if (!mcMMOPlayer.getParty().getLeader().equals(player.getName())) {
+            sender.sendMessage(LocaleLoader.getString("Party.NotOwner"));
             return true;
         }
 
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-
-        if (party == null) {
-            player.sendMessage("Commands.Party.None");
-            return true;
-        }
-
-        if (!party.getLeader().equals(playerName)) {
-            player.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-            return true;
-        }
-
-        if (party.isLocked()) {
-            player.sendMessage(LocaleLoader.getString("Party.IsLocked"));
-        }
-        else {
-            party.setLocked(true);
-            player.sendMessage(LocaleLoader.getString("Party.Locked"));
-        }
-
-        return true;
-    }
-
-    /**
-     * Unlock the current party
-     */
-    private boolean unlock() {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.unlock")) {
-            return true;
-        }
-
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-
-        if (party == null) {
-            player.sendMessage("Commands.Party.None");
-            return true;
-        }
-
-        if (!party.getLeader().equals(playerName)) {
-            player.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-            return true;
+        switch (subcommand) {
+        case EXPSHARE:
+            return partyExpShareCommand.onCommand(sender, command, label, args);
+        case ITEMSHARE:
+            return partyItemShareCommand.onCommand(sender, command, label, args);
+        case KICK:
+            return partyKickCommand.onCommand(sender, command, label, args);
+        case DISBAND:
+            return partyDisbandCommand.onCommand(sender, command, label, args);
+        case OWNER:
+            return partyChangeOwnerCommand.onCommand(sender, command, label, args);
+        case LOCK:
+        case UNLOCK:
+            return partyLockCommand.onCommand(sender, command, label, args);
+        case PASSWORD:
+            return partyChangePasswordCommand.onCommand(sender, command, label, args);
+        case RENAME:
+            return partyRenameCommand.onCommand(sender, command, label, args);
+        default:
+            break;
         }
 
-        if (!party.isLocked()) {
-            player.sendMessage(LocaleLoader.getString("Party.IsntLocked"));
-        }
-        else {
-            party.setLocked(false);
-            player.sendMessage(LocaleLoader.getString("Party.Unlocked"));
-        }
         return true;
     }
 
-    private boolean changePassword(String[] args) {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.password")) {
-            return true;
-        }
-
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-
-        if (!party.getLeader().equals(playerName)) {
-            player.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-            return true;
-        }
-
-        if (args.length < 2) {
-            party.setLocked(true);
-            party.setPassword(null);
-            player.sendMessage(LocaleLoader.getString("Party.Password.Removed"));
-            return true;
-        }
-
-        party.setLocked(true);
-        party.setPassword(args[1]);
-        player.sendMessage(LocaleLoader.getString("Party.Password.Set", args[1]));
-
+    private boolean printUsage() {
+        player.sendMessage(LocaleLoader.getString("Party.Help.0", "/party join"));
+        player.sendMessage(LocaleLoader.getString("Party.Help.1", "/party create"));
+        player.sendMessage(LocaleLoader.getString("Party.Help.2", "/party ?"));
         return true;
     }
 
-    /**
-     * Rename the current party
-     */
-    private boolean rename(String[] args) {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.party.rename")) {
-            return true;
-        }
-
-        String playerName = player.getName();
-        Party party = mcMMOPlayer.getParty();
-        String leader = party.getLeader();
-
-        if (party.getLeader().equals(playerName)) {
-            if (args.length < 2) {
-                player.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "rename", "<" + LocaleLoader.getString("Commands.Usage.PartyName") + ">"));
-                return true;
-            }
-
-            String newPartyName = args[1];
-
-            // This is to prevent party leaders from spamming other players with the rename message
-            if (!party.getName().equals(newPartyName)) {
-                Party newParty = PartyManager.getParty(newPartyName);
+    private String[] extractArgs(String[] args) {
+        String[] newArgs = new String[args.length - 1];
 
-                // Check to see if the party exists, and if it does cancel renaming the party
-                if (newParty != null) {
-                    player.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", newPartyName));
-                    return true;
-                }
-
-                for (Player onlineMembers : party.getOnlineMembers()) {
-                    McMMOPartyChangeEvent event = new McMMOPartyChangeEvent(onlineMembers, party.getName(), newPartyName, EventReason.CHANGED_PARTIES);
-                    mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-                    if (event.isCancelled()) {
-                        return true;
-                    }
-
-                    if (!onlineMembers.getName().equals(leader)) {
-                        onlineMembers.sendMessage(LocaleLoader.getString("Party.InformedOnNameChange", leader, newPartyName));
-                    }
-                }
-
-                party.setName(newPartyName);
-            }
-
-            player.sendMessage(LocaleLoader.getString("Commands.Party.Rename", newPartyName));
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Party.NotOwner"));
+        for (int i = 1; i < args.length; i++) {
+            newArgs[i - 1] = args[1];
         }
 
-        return true;
+        return newArgs;
     }
 }

+ 43 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyDisbandCommand.java

@@ -0,0 +1,43 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class PartyDisbandCommand implements CommandExecutor {
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.disband")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        switch (args.length) {
+        case 1:
+            Party playerParty = Users.getPlayer((Player) sender).getParty();
+
+            for (Player member : playerParty.getOnlineMembers()) {
+                if (!PartyManager.handlePartyChangeEvent(member, playerParty.getName(), null, EventReason.KICKED_FROM_PARTY)) {
+                    return true;
+                }
+
+                member.sendMessage(LocaleLoader.getString("Party.Disband"));
+            }
+
+            PartyManager.disbandParty(playerParty);
+            return true;
+
+        default:
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "disband"));
+            return true;
+        }
+    }
+}

+ 7 - 8
src/main/java/com/gmail/nossr50/party/commands/PartyExpShareCommand.java

@@ -5,6 +5,7 @@ import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.Party;
 import com.gmail.nossr50.party.ShareHandler;
@@ -14,11 +15,15 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PartyExpShareCommand implements CommandExecutor {
-    private Player player;
     private Party playerParty;
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Config.getInstance().getExpShareEnabled()) {
+            sender.sendMessage(LocaleLoader.getString("Party.ExpShare.Disabled"));
+            return true;
+        }
+
         if (!Permissions.hasPermission(sender, "mcmmo.commands.party.expshare")) {
             sender.sendMessage(command.getPermissionMessage());
             return true;
@@ -26,13 +31,7 @@ public class PartyExpShareCommand implements CommandExecutor {
 
         switch (args.length) {
         case 2:
-            player = (Player) sender;
-            playerParty = Users.getPlayer(player).getParty();
-
-            if (!playerParty.getLeader().equals(player.getName())) {
-                sender.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-                return true;
-            }
+            playerParty = Users.getPlayer((Player) sender).getParty();
 
             if (args[1].equalsIgnoreCase("none") || args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
                 handleChangingShareMode(ShareMode.NONE);

+ 30 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyHelpCommand.java

@@ -0,0 +1,30 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+
+import com.gmail.nossr50.locale.LocaleLoader;
+
+public class PartyHelpCommand implements CommandExecutor {
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        switch (args.length) {
+        case 1:
+            sender.sendMessage(LocaleLoader.getString("Party.Help.3", "/party join", "/party quit"));
+            sender.sendMessage(LocaleLoader.getString("Party.Help.1", "/party create")); 
+            sender.sendMessage(LocaleLoader.getString("Party.Help.4", "/party <lock|unlock>"));
+            sender.sendMessage(LocaleLoader.getString("Party.Help.5", "/party password"));
+            sender.sendMessage(LocaleLoader.getString("Party.Help.6", "/party kick"));
+            sender.sendMessage(LocaleLoader.getString("Party.Help.7", "/party owner"));
+            sender.sendMessage(LocaleLoader.getString("Party.Help.8", "/party disband"));
+            return true;
+
+        default:
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "help"));
+            return true;
+        }
+    }
+
+}

+ 97 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyInfoCommand.java

@@ -0,0 +1,97 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.datatypes.McMMOPlayer;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.Users;
+
+public class PartyInfoCommand implements CommandExecutor {
+    private Player player;
+    private Party playerParty;
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        player = (Player) sender;
+        McMMOPlayer mcMMOPlayer = Users.getPlayer(player);
+        playerParty = mcMMOPlayer.getParty();
+
+        displayPartyHeader();
+        displayShareModeInfo();
+        displayMemberInfo();
+        return true;
+    }
+
+    private String createMembersList() {
+        StringBuilder memberList = new StringBuilder();
+
+        for (OfflinePlayer member : playerParty.getMembers()) {
+            if (playerParty.getLeader().equals(member.getName())) {
+                memberList.append(ChatColor.GOLD).append(member.getName()).append(" ");
+            }
+            else if (member.isOnline()) {
+                memberList.append(ChatColor.WHITE).append(member.getName()).append(" ");
+            }
+            else {
+                memberList.append(ChatColor.GRAY).append(member.getName()).append(" ");
+            }
+        }
+
+        return memberList.toString();
+    }
+
+    private void displayShareModeInfo() {
+        boolean xpShareEnabled = Config.getInstance().getExpShareEnabled();
+        boolean itemShareEnabled = Config.getInstance().getItemShareEnabled();
+
+        if (!xpShareEnabled && !itemShareEnabled) {
+            return;
+        }
+
+        String expShareInfo = "";
+        String itemShareInfo = "";
+        String separator = "";
+
+        if (xpShareEnabled) {
+            expShareInfo = LocaleLoader.getString("Commands.Party.ExpShare", playerParty.getXpShareMode().toString());
+        }
+
+        if (itemShareEnabled) {
+            itemShareInfo = LocaleLoader.getString("Commands.Party.ItemShare", playerParty.getItemShareMode().toString());
+        }
+
+        if (xpShareEnabled && itemShareEnabled) {
+            separator = ChatColor.DARK_GRAY + " || ";
+        }
+
+        player.sendMessage(LocaleLoader.getString("Commands.Party.ShareMode") + expShareInfo + separator + itemShareInfo);
+    }
+
+    private void displayPartyHeader() {
+        player.sendMessage(LocaleLoader.getString("Commands.Party.Header"));
+
+        if (playerParty.isLocked()) {
+            player.sendMessage(LocaleLoader.getString("Commands.Party.Status", playerParty.getName(), LocaleLoader.getString("Party.Status.Locked")));
+        }
+        else {
+            player.sendMessage(LocaleLoader.getString("Commands.Party.Status", playerParty.getName(), LocaleLoader.getString("Party.Status.Unlocked")));
+        }
+    }
+
+    private void displayMemberInfo() {
+        int membersNear = PartyManager.getNearMembers(player, playerParty, Config.getInstance().getPartyShareRange()).size();
+        int membersOnline = playerParty.getOnlineMembers().size() - 1;
+
+        player.sendMessage(LocaleLoader.getString("Commands.Party.Members.Header"));
+        player.sendMessage(LocaleLoader.getString("Commands.Party.MembersNear", membersNear, membersOnline));
+        player.sendMessage(LocaleLoader.getString("Commands.Party.Members", createMembersList()));
+    }
+}

+ 7 - 2
src/main/java/com/gmail/nossr50/party/commands/PartyInviteCommand.java

@@ -32,20 +32,25 @@ public class PartyInviteCommand implements CommandExecutor {
         case 2:
             if (!mcMMO.p.getServer().getOfflinePlayer(args[1]).isOnline()) {
                 sender.sendMessage(LocaleLoader.getString("Party.NotOnline", args[1]));
-                return false;
+                return true;
             }
 
             mcMMOTarget = Users.getPlayer(args[1]);
 
             if (mcMMOTarget == null) {
                 sender.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
-                return false;
+                return true;
             }
 
             target = mcMMOTarget.getPlayer();
             mcMMOPlayer = Users.getPlayer((Player) sender);
             player = mcMMOPlayer.getPlayer();
 
+            if (player.equals(target)) {
+                sender.sendMessage(LocaleLoader.getString("Party.Invite.Self"));
+                return true;
+            }
+
             if (PartyManager.inSameParty(player, target)) {
                 sender.sendMessage(LocaleLoader.getString("Party.Player.InSameParty", target.getName()));
                 return true;

+ 7 - 8
src/main/java/com/gmail/nossr50/party/commands/PartyItemShareCommand.java

@@ -5,6 +5,7 @@ import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
+import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.Party;
 import com.gmail.nossr50.party.ShareHandler;
@@ -14,11 +15,15 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PartyItemShareCommand implements CommandExecutor {
-    private Player player;
     private Party playerParty;
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Config.getInstance().getItemShareEnabled()) {
+            sender.sendMessage(LocaleLoader.getString("Party.ItemShare.Disabled"));
+            return true;
+        }
+
         if (!Permissions.hasPermission(sender, "mcmmo.commands.party.itemshare")) {
             sender.sendMessage(command.getPermissionMessage());
             return true;
@@ -26,13 +31,7 @@ public class PartyItemShareCommand implements CommandExecutor {
 
         switch (args.length) {
         case 2:
-            player = (Player) sender;
-            playerParty = Users.getPlayer(player).getParty();
-
-            if (!playerParty.getLeader().equals(player.getName())) {
-                sender.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-                return true;
-            }
+            playerParty = Users.getPlayer((Player) sender).getParty();
 
             if (args[1].equalsIgnoreCase("none") || args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
                 handleChangingShareMode(ShareMode.NONE);

+ 7 - 30
src/main/java/com/gmail/nossr50/party/commands/PartyKickCommand.java

@@ -7,9 +7,6 @@ import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.commands.CommandHelper;
-import com.gmail.nossr50.datatypes.McMMOPlayer;
-import com.gmail.nossr50.events.party.McMMOPartyChangeEvent;
 import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.party.Party;
@@ -18,9 +15,6 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PartyKickCommand implements CommandExecutor {
-    private Player player;
-    private Party playerParty;
-
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         if (!Permissions.hasPermission(sender, "mcmmo.commands.party.kick")) {
@@ -30,40 +24,24 @@ public class PartyKickCommand implements CommandExecutor {
 
         switch (args.length) {
         case 2:
-            player = (Player) sender;
-            playerParty = Users.getPlayer(player).getParty();
-
-            if (!playerParty.getLeader().equals(player.getName())) {
-                sender.sendMessage(LocaleLoader.getString("Party.NotOwner"));
-                return true;
-            }
+            Party playerParty = Users.getPlayer((Player) sender).getParty();
 
-            McMMOPlayer mcMMOTarget = Users.getPlayer(args[1]);
+            OfflinePlayer target = mcMMO.p.getServer().getOfflinePlayer(args[1]);
 
-            // Would be nice to find a way to check if a player is valid here - this won't work directly because it'll also throw null for an offline player
-//            if (mcMMOTarget == null) {
-//                sender.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
-//                return false;
-//            }
-
-            Player target = mcMMOTarget.getPlayer();
-
-            if (!PartyManager.inSameParty(player, target)) {
+            if (!playerParty.getMembers().contains(target)) {
                 sender.sendMessage(LocaleLoader.getString("Party.NotInYourParty", args[1]));
                 return true;
             }
 
-            if (mcMMO.p.getServer().getOfflinePlayer(args[1]).isOnline()) {
+            if (target.isOnline()) {
+                Player onlineTarget = target.getPlayer();
                 String partyName = playerParty.getName();
 
-                McMMOPartyChangeEvent event = new McMMOPartyChangeEvent(target, partyName, null, EventReason.KICKED_FROM_PARTY);
-                mcMMO.p.getServer().getPluginManager().callEvent(event);
-
-                if (event.isCancelled()) {
+                if (!PartyManager.handlePartyChangeEvent(onlineTarget, partyName, null, EventReason.KICKED_FROM_PARTY)) {
                     return true;
                 }
 
-                target.sendMessage(LocaleLoader.getString("Commands.Party.Kick", partyName));
+                onlineTarget.sendMessage(LocaleLoader.getString("Commands.Party.Kick", partyName));
             }
 
             PartyManager.removeFromParty(target, playerParty);
@@ -74,5 +52,4 @@ public class PartyKickCommand implements CommandExecutor {
             return true;
         }
     }
-
 }

+ 97 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyLockCommand.java

@@ -0,0 +1,97 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class PartyLockCommand implements CommandExecutor {
+    private Party playerParty;
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        playerParty = Users.getPlayer((Player) sender).getParty();
+
+        switch (args.length) {
+        case 1:
+            if (args[0].equalsIgnoreCase("lock")) {
+                lockParty(sender, command);
+            }
+            else if (args[0].equalsIgnoreCase("unlock")) {
+                unlockParty(sender, command);
+            }
+
+            return true;
+
+        case 2:
+            if (!args[0].equalsIgnoreCase("lock")) {
+                sendUsageStrings(sender);
+                return true;
+            }
+
+            if (args[1].equalsIgnoreCase("on") || args[1].equalsIgnoreCase("true")) {
+                lockParty(sender, command);
+            }
+            else if (args[1].equalsIgnoreCase("off") || args[1].equalsIgnoreCase("false")) {
+                unlockParty(sender, command);
+            }
+            else {
+                sendUsageStrings(sender);
+            }
+
+            return true;
+
+        default:
+            sendUsageStrings(sender);
+            return true;
+        }
+    }
+
+    /**
+     * Handle locking a party.
+     */
+    private void lockParty(CommandSender sender, Command command) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.lock")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return;
+        }
+
+        if (playerParty.isLocked()) {
+            sender.sendMessage(LocaleLoader.getString("Party.IsLocked"));
+            return;
+        }
+
+        playerParty.setLocked(true);
+        sender.sendMessage(LocaleLoader.getString("Party.Locked"));
+    }
+
+    /**
+     * Handle unlocking a party.
+     *
+     * @return true if party is successfully unlocked, false otherwise.
+     */
+    private void unlockParty(CommandSender sender, Command command) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.unlock")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return;
+        }
+
+        if (!playerParty.isLocked()) {
+            sender.sendMessage(LocaleLoader.getString("Party.IsntLocked"));
+            return;
+        }
+
+        playerParty.setLocked(false);
+        sender.sendMessage(LocaleLoader.getString("Party.Unlocked"));
+    }
+
+    private void sendUsageStrings(CommandSender sender) {
+        sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "lock", "[on|off]"));
+        sender.sendMessage(LocaleLoader.getString("Commands.Usage.1", "party", "unlock"));
+    }
+}

+ 65 - 0
src/main/java/com/gmail/nossr50/party/commands/PartyRenameCommand.java

@@ -0,0 +1,65 @@
+package com.gmail.nossr50.party.commands;
+
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import com.gmail.nossr50.events.party.McMMOPartyChangeEvent.EventReason;
+import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.party.Party;
+import com.gmail.nossr50.party.PartyManager;
+import com.gmail.nossr50.util.Permissions;
+import com.gmail.nossr50.util.Users;
+
+public class PartyRenameCommand implements CommandExecutor {
+
+    @Override
+    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+        if (!Permissions.hasPermission(sender, "mcmmo.commands.party.rename")) {
+            sender.sendMessage(command.getPermissionMessage());
+            return true;
+        }
+
+        Party playerParty = Users.getPlayer((Player) sender).getParty();
+        String leaderName = playerParty.getLeader();
+
+        switch (args.length) {
+        case 2:
+            String newPartyName = args[1];
+
+            // This is to prevent party leaders from spamming other players with the rename message
+            if (playerParty.getName().equalsIgnoreCase(newPartyName)) {
+                sender.sendMessage(LocaleLoader.getString("Party.Rename.Same"));
+                return true;
+            }
+
+            Party newParty = PartyManager.getParty(newPartyName);
+
+            // Check to see if the party exists, and if it does cancel renaming the party
+            if (newParty != null) {
+                sender.sendMessage(LocaleLoader.getString("Commands.Party.AlreadyExists", newPartyName));
+                return true;
+            }
+
+            for (Player member : playerParty.getOnlineMembers()) {
+                if (!PartyManager.handlePartyChangeEvent(member, playerParty.getName(), newPartyName, EventReason.CHANGED_PARTIES)) {
+                    return true;
+                }
+
+                if (!member.getName().equals(leaderName)) {
+                    member.sendMessage(LocaleLoader.getString("Party.InformedOnNameChange", leaderName, newPartyName));
+                }
+            }
+
+            playerParty.setName(newPartyName);
+
+            sender.sendMessage(LocaleLoader.getString("Commands.Party.Rename", newPartyName));
+            return true;
+
+        default:
+            sender.sendMessage(LocaleLoader.getString("Commands.Usage.2", "party", "rename", "<" + LocaleLoader.getString("Commands.Usage.PartyName") + ">"));
+            return true;
+        }
+    }
+}

+ 45 - 0
src/main/java/com/gmail/nossr50/party/commands/PartySubcommandType.java

@@ -0,0 +1,45 @@
+package com.gmail.nossr50.party.commands;
+
+public enum PartySubcommandType {
+    JOIN,
+    ACCEPT,
+    CREATE,
+    HELP,
+    INFO,
+    QUIT,
+    EXPSHARE,
+    ITEMSHARE,
+    INVITE,
+    KICK,
+    DISBAND,
+    OWNER,
+    LOCK,
+    UNLOCK,
+    PASSWORD,
+    RENAME,
+    TELEPORT,
+    CHAT;
+
+    public static PartySubcommandType getSubcommand(String commandName) {
+        for (PartySubcommandType command : values()) {
+            if (command.name().equalsIgnoreCase(commandName)) {
+                return command;
+            }
+        }
+
+        if (commandName.equalsIgnoreCase("?")) {
+            return HELP;
+        }
+        else if (commandName.equalsIgnoreCase("q") || commandName.equalsIgnoreCase("leave")) {
+            return QUIT;
+        }
+        else if (commandName.equalsIgnoreCase("xpshare") || commandName.equalsIgnoreCase("shareexp") || commandName.equalsIgnoreCase("sharexp")) {
+            return EXPSHARE;
+        }
+        else if (commandName.equalsIgnoreCase("shareitem") || commandName.equalsIgnoreCase("shareitems")) {
+            return ITEMSHARE;
+        }
+
+        return null;
+    }
+}

+ 92 - 94
src/main/java/com/gmail/nossr50/party/commands/PtpCommand.java

@@ -18,36 +18,40 @@ import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Users;
 
 public class PtpCommand implements CommandExecutor {
-    private final mcMMO plugin;
     private Player player;
     private McMMOPlayer mcMMOPlayer;
+    private PlayerProfile playerProfile;
 
-    public PtpCommand(mcMMO instance) {
-        this.plugin = instance;
-    }
+    private Player target;
+    private McMMOPlayer mcMMOTarget;
 
     @Override
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
-        String usage = LocaleLoader.getString("Commands.Usage.1", "ptp", "<" + LocaleLoader.getString("Commands.Usage.Player") + ">");
-
         if (CommandHelper.noConsoleUsage(sender)) {
             return true;
         }
 
-        if (CommandHelper.noCommandPermissions(sender, "mcmmo.commands.ptp")) {
-            return true;
-        }
-
         switch (args.length) {
         case 1:
             player = (Player) sender;
             mcMMOPlayer = Users.getPlayer(player);
-            PlayerProfile playerProfile = mcMMOPlayer.getProfile();
+            playerProfile = mcMMOPlayer.getProfile();
 
             if (args[0].equalsIgnoreCase("toggle")) {
+                if (!Permissions.hasPermission(sender, "mcmmo.commands.ptp.toggle")) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
                 return togglePartyTeleportation();
             }
-            else if (args[0].equalsIgnoreCase("acceptany") || args[0].equalsIgnoreCase("acceptall")) {
+
+            if (args[0].equalsIgnoreCase("acceptany") || args[0].equalsIgnoreCase("acceptall")) {
+                if (!Permissions.hasPermission(sender, "mcmmo.commands.ptp.acceptall")) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
                 return acceptAnyTeleportRequest();
             }
 
@@ -59,68 +63,37 @@ public class PtpCommand implements CommandExecutor {
             }
 
             if (args[0].equalsIgnoreCase("accept")) {
+                if (!Permissions.hasPermission(sender, "mcmmo.commands.ptp.accept")) {
+                    sender.sendMessage(command.getPermissionMessage());
+                    return true;
+                }
+
                 return acceptTeleportRequest();
             }
 
             return sendTeleportRequest(args[0]);
 
         default:
-            sender.sendMessage(usage);
-            return true;
+            return false;
         }
     }
 
-    private boolean sendTeleportRequest(String args) {
-        Player target = plugin.getServer().getPlayer(args);
-
-        if (player.equals(target)) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Self"));
+    private boolean sendTeleportRequest(String targetName) {
+        if (!canTeleport(targetName)) {
             return true;
         }
 
-        if (target == null) {
-            player.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
-            return true;
+        if (!mcMMOTarget.getPtpConfirmRequired()) {
+            return handlePartyTeleportEvent();
         }
 
-        if (target.isDead()) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Dead"));
-            return true;
-        }
-
-        if (PartyManager.inSameParty(player, target)) {
-            McMMOPlayer targetMcMMOPlayer = Users.getPlayer(target);
-
-            if (!targetMcMMOPlayer.getPtpEnabled()) {
-                player.sendMessage(LocaleLoader.getString("Party.Teleport.Disabled", target.getName()));
-                return true;
-            }
+        mcMMOTarget.setPtpRequest(player);
+        mcMMOTarget.actualizePtpTimeout();
+        player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
 
-            if (!targetMcMMOPlayer.getPtpConfirmRequired()) {
-                McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(player, target, mcMMOPlayer.getParty().getName());
-                plugin.getServer().getPluginManager().callEvent(event);
-
-                if (event.isCancelled()) {
-                    return true;
-                }
-
-                player.teleport(target);
-                player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", player.getName()));
-                target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", target.getName()));
-                mcMMOPlayer.getProfile().setRecentlyHurt(System.currentTimeMillis());
-            } else {
-                targetMcMMOPlayer.setPtpRequest(player);
-                targetMcMMOPlayer.actualizePtpTimeout();
-                player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
-
-                int ptpRequestExpire = Config.getInstance().getPTPCommandTimeout();
-                target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
-                target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", ptpRequestExpire));
-            }
-        }
-        else {
-            player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", target.getName()));
-        }
+        int ptpRequestExpire = Config.getInstance().getPTPCommandTimeout();
+        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
+        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", ptpRequestExpire));
         return true;
     }
 
@@ -130,10 +103,6 @@ public class PtpCommand implements CommandExecutor {
             return true;
         }
 
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.ptp.accept")) {
-            return true;
-        }
-
         int ptpRequestExpire = Config.getInstance().getPTPCommandTimeout();
 
         if ((mcMMOPlayer.getPtpTimeout() + ptpRequestExpire) * Misc.TIME_CONVERSION_FACTOR < System.currentTimeMillis()) {
@@ -144,48 +113,28 @@ public class PtpCommand implements CommandExecutor {
 
         Player target = mcMMOPlayer.getPtpRequest();
 
-        if (target == null) {
-            player.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
+        if (!canTeleport(target.getName())) {
             return true;
         }
 
-        if (target.isDead()) {
-            player.sendMessage(LocaleLoader.getString("Party.Teleport.Dead"));
-            return true;
-        }
-
-        if(Config.getInstance().getPTPCommandWorldPermissions()) {
+        //TODO: Someone want to clarify what's going on with these dynamic permissions?
+        if (Config.getInstance().getPTPCommandWorldPermissions()) {
             String perm = "mcmmo.commands.ptp.world.";
 
-            if(!Permissions.hasDynamicPermission(target, perm + "all", "op")) {
-                if(!Permissions.hasDynamicPermission(target, perm + target.getWorld().getName(), "op")) {
+            if (!Permissions.hasDynamicPermission(target, perm + "all", "op")) {
+                if (!Permissions.hasDynamicPermission(target, perm + target.getWorld().getName(), "op")) {
                     return true;
                 }
-                else if(target.getWorld() != player.getWorld() && !Permissions.hasDynamicPermission(target, perm + player.getWorld().getName(), "op")) {
+                else if (target.getWorld() != player.getWorld() && !Permissions.hasDynamicPermission(target, perm + player.getWorld().getName(), "op")) {
                     return true;
                 }
             }
         }
 
-        McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(target, player, mcMMOPlayer.getParty().getName());
-        plugin.getServer().getPluginManager().callEvent(event);
-
-        if (event.isCancelled()) {
-            return true;
-        }
-
-        target.teleport(player);
-        target.sendMessage(LocaleLoader.getString("Party.Teleport.Player", player.getName()));
-        player.sendMessage(LocaleLoader.getString("Party.Teleport.Target", target.getName()));
-        mcMMOPlayer.getProfile().setRecentlyHurt(System.currentTimeMillis());
-        return true;
+        return handlePartyTeleportEvent();
     }
 
     private boolean acceptAnyTeleportRequest() {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.ptp.acceptall")) {
-            return true;
-        }
-
         if (mcMMOPlayer.getPtpConfirmRequired()) {
             player.sendMessage(LocaleLoader.getString("Commands.ptp.AcceptAny.Disabled"));
         }
@@ -198,10 +147,6 @@ public class PtpCommand implements CommandExecutor {
     }
 
     private boolean togglePartyTeleportation() {
-        if (CommandHelper.noCommandPermissions(player, "mcmmo.commands.ptp.toggle")) {
-            return true;
-        }
-
         if (mcMMOPlayer.getPtpEnabled()) {
             player.sendMessage(LocaleLoader.getString("Commands.ptp.Disabled"));
         }
@@ -212,4 +157,57 @@ public class PtpCommand implements CommandExecutor {
         mcMMOPlayer.togglePtpUse();
         return true;
     }
+
+    private boolean canTeleport(String targetName) {
+        if (!mcMMO.p.getServer().getOfflinePlayer(targetName).isOnline()) {
+            player.sendMessage(LocaleLoader.getString("Party.NotOnline", targetName));
+            return false;
+        }
+
+        mcMMOTarget = Users.getPlayer(targetName);
+
+        if (mcMMOTarget == null) {
+            player.sendMessage(LocaleLoader.getString("Party.Player.Invalid"));
+            return false;
+        }
+
+        target = mcMMOTarget.getPlayer();
+
+        if (player.equals(target)) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Self"));
+            return false;
+        }
+
+        if (!PartyManager.inSameParty(player, target)) {
+            player.sendMessage(LocaleLoader.getString("Party.NotInYourParty", targetName));
+            return false;
+        }
+
+        if (!mcMMOTarget.getPtpEnabled()) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Disabled", target.getName()));
+            return false;
+        }
+
+        if (target.isDead()) {
+            player.sendMessage(LocaleLoader.getString("Party.Teleport.Dead"));
+            return false;
+        }
+
+        return true;
+    }
+
+    private boolean handlePartyTeleportEvent() {
+        McMMOPartyTeleportEvent event = new McMMOPartyTeleportEvent(player, target, mcMMOPlayer.getParty().getName());
+        mcMMO.p.getServer().getPluginManager().callEvent(event);
+
+        if (event.isCancelled()) {
+            return true;
+        }
+
+        player.teleport(target);
+        player.sendMessage(LocaleLoader.getString("Party.Teleport.Player", player.getName()));
+        target.sendMessage(LocaleLoader.getString("Party.Teleport.Target", target.getName()));
+        playerProfile.setRecentlyHurt(System.currentTimeMillis());
+        return true;
+    }
 }

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/runnables/PartiesLoader.java → src/main/java/com/gmail/nossr50/party/runnables/PartiesLoader.java

@@ -1,4 +1,4 @@
-package com.gmail.nossr50.skills.runnables;
+package com.gmail.nossr50.party.runnables;
 
 import com.gmail.nossr50.party.PartyManager;
 

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/runnables/PartyAutoKick.java → src/main/java/com/gmail/nossr50/party/runnables/PartyAutoKick.java

@@ -1,4 +1,4 @@
-package com.gmail.nossr50.skills.runnables;
+package com.gmail.nossr50.party.runnables;
 
 import org.bukkit.OfflinePlayer;
 

+ 1 - 3
src/main/java/com/gmail/nossr50/skills/SkillGuide.java

@@ -50,9 +50,7 @@ public final class SkillGuide {
     }
 
     public static void clearChat(Player player) {
-        for (int x = 0; x < 20; x++) {
-            player.sendMessage("");
-        }
+        player.sendMessage("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
     }
 
     public static boolean grabGuidePageForSkill(SkillType skilltype, Player player, String[] args) {

+ 1 - 4
src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java

@@ -49,10 +49,7 @@ public class AxeManager extends SkillManager {
     public void impact(EntityDamageByEntityEvent event, LivingEntity target) {
         ImpactEventHandler eventHandler = new ImpactEventHandler(this, event, target);
 
-        if (Misc.hasArmor(target)) {
-            eventHandler.damageArmor();
-        }
-        else {
+        if (!eventHandler.applyImpact()) {
             eventHandler.applyGreaterImpact();
         }
     }

+ 23 - 31
src/main/java/com/gmail/nossr50/skills/axes/ImpactEventHandler.java

@@ -8,6 +8,7 @@ import org.bukkit.inventory.EntityEquipment;
 import org.bukkit.inventory.ItemStack;
 
 import com.gmail.nossr50.locale.LocaleLoader;
+import com.gmail.nossr50.util.ItemChecks;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Permissions;
 
@@ -16,38 +17,45 @@ public class ImpactEventHandler {
     private Player player;
     private EntityDamageByEntityEvent event;
     private short durabilityDamage = 1;
-    private EntityEquipment equipment;
-    private ItemStack[] armorContents;
+    private EntityEquipment entityEquipment;
     protected LivingEntity defender;
+    boolean impactApplied;
 
     public ImpactEventHandler(AxeManager manager, EntityDamageByEntityEvent event, LivingEntity defender) {
         this.manager = manager;
         this.player = manager.getMcMMOPlayer().getPlayer();
         this.event = event;
         this.defender = defender;
-        this.equipment = defender.getEquipment();
-        this.armorContents = equipment.getArmorContents();
+        this.entityEquipment = defender.getEquipment();
     }
 
-    protected void damageArmor() {
+    protected boolean applyImpact() {
         // Every 50 Skill Levels you gain 1 durability damage (default values)
         durabilityDamage += (short) (manager.getSkillLevel() / Axes.impactIncreaseLevel);
+        // getArmorContents.length can't be used because it's always equal to 4 (no armor = air block)
+        boolean hasArmor = false;
 
-        for (ItemStack armor : armorContents) {
-            if (Misc.getRandom().nextInt(100) > 75) {
+        for (ItemStack itemStack : entityEquipment.getArmorContents()) {
+            if (ItemChecks.isArmor(itemStack)) {
+                hasArmor = true;
 
-                for (int i = 0; i <= durabilityDamage; i++) {
-                    if (armor.containsEnchantment(Enchantment.DURABILITY)) {
-                        handleDurabilityEnchantment(armor);
-                    }
+                if (Misc.getRandom().nextInt(100) < 25) {
+                    damageArmor(itemStack);
                 }
-
-                damageValidation(armor);
-                armor.setDurability((short) (armor.getDurability() + durabilityDamage));
             }
         }
 
-        equipment.setArmorContents(armorContents);
+        return hasArmor;
+    }
+
+    private void damageArmor(ItemStack armor) {
+        float modifier = 1;
+
+        if (armor.containsEnchantment(Enchantment.DURABILITY)) {
+            modifier /= armor.getEnchantmentLevel(Enchantment.DURABILITY) + 1;
+        }
+
+        armor.setDurability((short) (durabilityDamage * modifier + armor.getDurability()));
     }
 
     protected void applyGreaterImpact() {
@@ -73,20 +81,4 @@ public class ImpactEventHandler {
             ((Player) defender).sendMessage(LocaleLoader.getString("Axes.Combat.GI.Struck"));
         }
     }
-
-    private void handleDurabilityEnchantment(ItemStack armor) {
-        int enchantmentLevel = armor.getEnchantmentLevel(Enchantment.DURABILITY);
-
-        if (Misc.getRandom().nextInt(enchantmentLevel + 1) > 0) {
-            durabilityDamage--;
-        }
-    }
-
-    private void damageValidation(ItemStack armor) {
-        short maxDurability = (short) (armor.getType().getMaxDurability() * Axes.impactMaxDurabilityDamageModifier);
-
-        if (durabilityDamage > maxDurability) {
-            durabilityDamage = maxDurability;
-        }
-    }
 }

+ 2 - 2
src/main/java/com/gmail/nossr50/skills/fishing/ShakeMob.java

@@ -138,7 +138,7 @@ public final class ShakeMob {
             possibleDrops.put(new ItemStack(Material.RED_ROSE), 85);
             break;
         case MAGMA_CUBE:
-            possibleDrops.put(new ItemStack(Material.MAGMA_CREAM), 3);
+            possibleDrops.put(new ItemStack(Material.MAGMA_CREAM), 100);
             break;
         case MUSHROOM_COW:
             possibleDrops.put(new ItemStack(Material.MILK_BUCKET), 5);
@@ -148,7 +148,7 @@ public final class ShakeMob {
             possibleDrops.put(new ItemStack(Material.RED_MUSHROOM, Misc.getRandom().nextInt(3) + 1), 30);
             break;
         case PIG:
-            possibleDrops.put(new ItemStack(Material.PORK), 3);
+            possibleDrops.put(new ItemStack(Material.PORK), 100);
             break;
         case PIG_ZOMBIE:
             possibleDrops.put(new ItemStack(Material.ROTTEN_FLESH), 50);

+ 3 - 3
src/main/java/com/gmail/nossr50/skills/repair/Salvage.java

@@ -124,7 +124,7 @@ public class Salvage {
         else if (ItemChecks.isChestplate(inHand)) {
             return 8;
         }
-        else if (ItemChecks.isPants(inHand)) {
+        else if (ItemChecks.isLeggings(inHand)) {
             return 7;
         }
         else if (ItemChecks.isBoots(inHand)) {
@@ -141,10 +141,10 @@ public class Salvage {
      * @return true if the item is salvageable, false otherwise
      */
     public static boolean isSalvageable(final ItemStack is) {
-        if (configInstance.getSalvageTools() && (ItemChecks.isTool(is) || ItemChecks.isStringTool(is) || is.getType() == Material.BUCKET)) {
+        if (configInstance.getSalvageTools() && (ItemChecks.isMinecraftTool(is) || ItemChecks.isStringTool(is) || is.getType() == Material.BUCKET)) {
             return true;
         }
-        if (configInstance.getSalvageArmor() && ItemChecks.isArmor(is)) {
+        if (configInstance.getSalvageArmor() && ItemChecks.isMinecraftArmor(is)) {
             return true;
         }
         return false;

+ 13 - 3
src/main/java/com/gmail/nossr50/util/ItemChecks.java

@@ -207,7 +207,7 @@ public class ItemChecks {
      * @param is Item to check
      * @return true if the item is a pair of pants, false otherwise
      */
-    public static boolean isPants(ItemStack is) {
+    public static boolean isLeggings(ItemStack is) {
         switch (is.getType()) {
         case DIAMOND_LEGGINGS:
         case GOLD_LEGGINGS:
@@ -254,7 +254,17 @@ public class ItemChecks {
      * @return true if the item is armor, false otherwise
      */
     public static boolean isArmor(ItemStack is) {
-        return isLeatherArmor(is) || isGoldArmor(is) || isIronArmor(is) || isDiamondArmor(is);
+        return isHelmet(is) || isChestplate(is) || isLeggings(is) || isBoots(is);
+    }
+
+    /**
+     * Checks to see if an item is a wearable armor piece.
+     *
+     * @param is Item to check
+     * @return true if the item is armor, false otherwise
+     */
+    public static boolean isMinecraftArmor(ItemStack is) {
+        return isDiamondArmor(is) || isGoldArmor(is) || isIronArmor(is) || isDiamondArmor(is);
     }
 
     /**
@@ -339,7 +349,7 @@ public class ItemChecks {
      * @param is Item to check
      * @return true if the item is a tool, false otherwise
      */
-    public static boolean isTool(ItemStack is) {
+    public static boolean isMinecraftTool(ItemStack is) {
         return isStoneTool(is) || isWoodTool(is) || isGoldTool(is) || isIronTool(is) || isDiamondTool(is) || isStringTool(is);
     }
 

+ 0 - 16
src/main/java/com/gmail/nossr50/util/Misc.java

@@ -60,22 +60,6 @@ public final class Misc {
         return NORMAL_SKILL_ACTIVATION_CHANCE;
     }
 
-    /**
-     * Check if a LivingEntity has armor.
-     *
-     * @param entity LivingEntity whose armor to check
-     * @return true if the player has armor, false otherwise
-     */
-    public static boolean hasArmor(LivingEntity entity) {
-        for (ItemStack armor : entity.getEquipment().getArmorContents()) {
-            if (armor.getType() != Material.AIR) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
     public static boolean isFriendlyPet(Player attacker, Tameable pet) {
         if (pet.isTamed()) {
             AnimalTamer tamer = pet.getOwner();

+ 1 - 1
src/main/java/com/gmail/nossr50/util/Users.java

@@ -121,7 +121,7 @@ public final class Users {
      * @param player The player whose McMMOPlayer to retrieve
      * @return the player's McMMOPlayer object
      */
-    public static McMMOPlayer getPlayer(Player player) {
+    public static McMMOPlayer getPlayer(OfflinePlayer player) {
         return players.get(player.getName());
     }
 }

+ 2 - 2
src/main/resources/config.yml

@@ -118,7 +118,7 @@ Skills:
         Enabled_For_PVE: true
         Prevent_AFK_Leveling: true
         Prevent_Dodge_Lightning: false
-        Level_Cap: 0 
+        Level_Cap: 0
     Archery:
         Enabled_For_PVP: true
         Enabled_For_PVE: true
@@ -176,7 +176,7 @@ Skills:
         Requires_Axe: true
 
 #
-#  Settings for Double Drops  
+#  Settings for Double Drops
 ###
 Double_Drops:
     Herbalism:

+ 16 - 11
src/main/resources/locale/locale_en_US.properties

@@ -394,7 +394,7 @@ Combat.TouchedFuzzy=[[DARK_RED]]Touched Fuzzy. Felt Dizzy.
 
 #COMMANDS
 ##generic
-mcMMO.Description=[[DARK_AQUA]]About the [[YELLOW]]mcMMO[[DARK_AQUA]] Project:,[[GOLD]]mcMMO is an [[RED]]open source[[GOLD]] RPG mod created in February 2011,[[GOLD]]by [[BLUE]]nossr50[[GOLD]]. The goal is to provide a quality RPG experience.,[[DARK_AQUA]]Tips:,[[GOLD]] - [[GREEN]]Use [[RED]]/mcc[[GREEN]] to see commands,[[GOLD]] - [[GREEN]]Type [[RED]]/SKILLNAME[[GREEN]] to see detailed skill info,[[DARK_AQUA]]Developers:,[[GOLD]] - [[GREEN]]nossr50 [[BLUE]](Founder),[[GOLD]] - [[GREEN]]GJ [[BLUE]](Project Lead),[[GOLD]] - [[GREEN]]NuclearW [[BLUE]](Developer),[[GOLD]] - [[GREEN]]bm01 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]TfT_02 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]Glitchfinder [[BLUE]](Developer),[[GOLD]] - [[GREEN]]toothplck1 [[BLUE]](Developer),[[DARK_AQUA]]Useful Links:,[[GOLD]] - [[GREEN]]https://github.com/mcMMO-Dev/mcMMO/issues[[GOLD]] Bug Reporting,[[GOLD]] - [[GREEN]]#mcmmo @ irc.esper.net[[GOLD]] IRC Chat,[[GOLD]] - [[GREEN]]http://bit.ly/H6XwFb[[GOLD]] Bukkit Forum Thread
+mcMMO.Description=[[DARK_AQUA]]About the [[YELLOW]]mcMMO[[DARK_AQUA]] Project:,[[GOLD]]mcMMO is an [[RED]]open source[[GOLD]] RPG mod created in February 2011,[[GOLD]]by [[BLUE]]nossr50[[GOLD]]. The goal is to provide a quality RPG experience.,[[DARK_AQUA]]Tips:,[[GOLD]] - [[GREEN]]Use [[RED]]/mcmmo help[[GREEN]] to see commands,[[GOLD]] - [[GREEN]]Type [[RED]]/SKILLNAME[[GREEN]] to see detailed skill info,[[DARK_AQUA]]Developers:,[[GOLD]] - [[GREEN]]nossr50 [[BLUE]](Founder),[[GOLD]] - [[GREEN]]GJ [[BLUE]](Project Lead),[[GOLD]] - [[GREEN]]NuclearW [[BLUE]](Developer),[[GOLD]] - [[GREEN]]bm01 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]TfT_02 [[BLUE]](Developer),[[GOLD]] - [[GREEN]]Glitchfinder [[BLUE]](Developer),[[GOLD]] - [[GREEN]]toothplck1 [[BLUE]](Developer),[[DARK_AQUA]]Useful Links:,[[GOLD]] - [[GREEN]]https://github.com/mcMMO-Dev/mcMMO/issues[[GOLD]] Bug Reporting,[[GOLD]] - [[GREEN]]#mcmmo @ irc.esper.net[[GOLD]] IRC Chat,
 Commands.addlevels.AwardAll.1=[[GREEN]]You were awarded {0} levels in all skills!
 Commands.addlevels.AwardAll.2=[[RED]]All skills have been modified for {0}.
 Commands.addlevels.AwardSkill.1=[[GREEN]]You were awarded {0} levels in {1}!
@@ -495,7 +495,7 @@ Commands.Usage.3=[[RED]]Proper usage is /{0} {1} {2} {3}
 Commands.Usage.Level=level
 Commands.Usage.Message=message
 Commands.Usage.Page=page
-Commands.Usage.PartyName=party-name
+Commands.Usage.PartyName=name
 Commands.Usage.Password=password
 Commands.Usage.Player=player
 Commands.Usage.Rate=rate
@@ -507,19 +507,20 @@ mcMMO.NoSkillNote=[[DARK_GRAY]]If you don't have access to a skill it will not b
 
 ##party
 Party.Forbidden=[mcMMO] Parties not permitted on this world (See Permissions)
-Party.Help.0=[[RED]]Proper usage is [[DARK_AQUA]]/party join <player> [password].
-Party.Help.1=[[RED]]To create a party, use [[DARK_AQUA]]/party create <name> [password]
-Party.Help.2=[[RED]]Consult [[DARK_AQUA]]/party ? [[RED]]for more information
-Party.Help.3=[[RED]]Use [[DARK_AQUA]]/party join <player> [[RED]]to join or [[DARK_AQUA]]/party quit [[RED]]to quit
-Party.Help.4=[[RED]]To lock or unlock your party, use [[DARK_AQUA]]/party <lock>
-Party.Help.5=[[RED]]To password protect your party, use [[DARK_AQUA]]/party password <password>
-Party.Help.6=[[RED]]To kick a player from your party, use [[DARK_AQUA]]/party kick <player>
-Party.Help.7=[[RED]]To transfer ownership of your party, use [[DARK_AQUA]]/party owner <player>
-Party.Help.8=[[RED]]To disband your party, use [[DARK_AQUA]]/party disband
+Party.Help.0=[[RED]]Proper usage is [[DARK_AQUA]]{0} <player> [password].
+Party.Help.1=[[RED]]To create a party, use [[DARK_AQUA]]{0} <name> [password].
+Party.Help.2=[[RED]]Consult [[DARK_AQUA]]{0} [[RED]]for more information
+Party.Help.3=[[RED]]Use [[DARK_AQUA]]{0} <player> [password] [[RED]]to join or [[DARK_AQUA]]{1} [[RED]]to quit
+Party.Help.4=[[RED]]To lock or unlock your party, use [[DARK_AQUA]]{0}
+Party.Help.5=[[RED]]To password protect your party, use [[DARK_AQUA]]{0} <password>
+Party.Help.6=[[RED]]To kick a player from your party, use [[DARK_AQUA]]{0} <player>
+Party.Help.7=[[RED]]To transfer ownership of your party, use [[DARK_AQUA]]{0} <player>
+Party.Help.8=[[RED]]To disband your party, use [[DARK_AQUA]]{0}
 Party.InformedOnJoin={0} [[GREEN]]has joined your party
 Party.InformedOnQuit={0} [[GREEN]]has left your party
 Party.InformedOnNameChange=[[GOLD]]{0} [[GREEN]]has set the party name to [[WHITE]]{1}
 Party.InvalidName=[[DARK_RED]]That is not a valid party name.
+Party.Invite.Self=[[RED]]You can't invite yourself!
 Party.IsLocked=[[RED]]This party is already locked!
 Party.IsntLocked=[[RED]]This party is not locked!
 Party.Locked=[[RED]]Party is locked, only party leader may invite.
@@ -543,6 +544,7 @@ Party.Teleport.Player=[[GREEN]]You have teleported to {0}.
 Party.Teleport.Self=[[RED]]You can't teleport to yourself!
 Party.Teleport.Target=[[GREEN]]{0} has teleported to you.
 Party.Teleport.Disabled=[[RED]]{0} doesn't allow party teleportation.
+Party.Rename.Same=[[RED]]That is already the name of your party!
 Party.Join.Self=[[RED]]You can't join to yourself!
 Party.Unlocked=[[GRAY]]Party is unlocked
 Party.Disband=[[GRAY]]The party has been disbanded
@@ -553,6 +555,8 @@ Party.ShareType.Item=ITEM
 Party.ShareMode.None=NONE
 Party.ShareMode.Equal=EQUAL
 Party.ShareMode.Random=RANDOM
+Party.ExpShare.Disabled=[[RED]]Party experience sharing is disabled.
+Party.ItemShare.Disabled=[[RED]]Party item sharing is disabled.
 
 ##xp
 Commands.XPGain.Acrobatics=Falling
@@ -706,6 +710,7 @@ Commands.Description.mmoedit=Edit mcMMO levels for a user
 Commands.Description.mmoupdate=Convert mcMMO database from Flatfile to MySQL
 Commands.Description.party=Control various mcMMO party settings
 Commands.Description.partychat=Toggle mcMMO party chat on/off or send party chat messages
+Commands.Description.ptp=Teleport to an mcMMO party member
 Commands.Description.Skill=Display detailed mcMMO skill info for {0}
 Commands.Description.skillreset=Reset mcMMO levels for a user
 Commands.Description.xplock=Lock your mcMMO XP bar to a specific mcMMO skill

+ 8 - 8
src/main/resources/plugin.yml

@@ -28,9 +28,6 @@ commands:
     xprate:
         aliases: [mcxprate]
         description: Modify the xp rate or start an event
-    mcc:
-        aliases: []
-        description: Lists mcMMO commands
     mcmmo:
         description: Shows a brief mod description
     mctop:
@@ -55,7 +52,6 @@ commands:
     mmoedit:
         description: Edit the mcMMO skill values for a user
     ptp:
-        aliases: []
         description: Teleport to a party member
     party:
         description: Create/join a party
@@ -565,9 +561,8 @@ permissions:
             mcmmo.commands.herbalism: true
             mcmmo.commands.inspect: true
             mcmmo.commands.mcability: true
-            mcmmo.commands.mcc: true
             mcmmo.commands.mchud: true
-            mcmmo.commands.mcmmo: true
+            mcmmo.commands.mcmmo.all: true
             mcmmo.commands.mcrank: true
             mcmmo.commands.mcstats: true
             mcmmo.commands.mctop.all: true
@@ -652,16 +647,21 @@ permissions:
         description: Allows access to the mcability command
     mcmmo.commands.mcability.others:
         description: Allows access to the mcability command for other players
-    mcmmo.commands.mcc:
-        description: Allows access to the mcc command
     mcmmo.commands.mcgod:
         description: Allows access to the mcgod command
     mcmmo.commands.mcgod.others:
         description: Allows access to the mcgod command for other players
     mcmmo.commands.mchud:
         description: Allows access to the mchud command
+    mcmmo.commands.mcmmo.all:
+        description: Implies access to all mcmmo.commands.mcmmo permissions.
+        children:
+            mcmmo.commands.mcmmo: true
+            mcmmo.commands.mcmmo.help: true
     mcmmo.commands.mcmmo:
         description: Allows access to the mcmmo command
+    mcmmo.commands.mcmmo.help:
+        description: Allows access to the mcmmo help command
     mcmmo.commands.mcpurge:
         default: false
         description: Allows access to the mcpurge command