Browse Source

Another WIP of 0.9.15 + vChat stuff

nossr50 14 years ago
parent
commit
7782c3c03c

+ 189 - 0
mcMMO/Changelog.txt

@@ -1,5 +1,194 @@
 Changelog:
 #Versions without changelogs probably had very small misc fixes, like tweaks to the source code#
+Version 0.9.15
+AoE Abilities will only hit wolves attacking you
+Added "all" parameter to /mmoedit & /addxp
+After giving XP to a player it will now check for level ups in skills
+
+Version 0.9.14
+mcMMO checks for abilities being active before sending the fake block break event
+
+Version 0.9.13
+Fixed excavation ignoring the xpGainMultiplier
+Now compatible with CB 600+
+Fixed bug where Dodge acted maxed out no matter your skill level
+
+Version 0.9.12
+mcMMO now fakes a block break event for abilities to maximize plugin compatibility
+/herbalism will return the correct values now
+New /addxp command
+
+Version 0.9.11
+PVE Combat Skills experience is now based on damage dealt
+The Timer will no longer break from Bleed Simulation
+Tree feller no longer "damages" saplings
+Bleed+ (Serrated Strikes) lasts 5 ticks down from 12
+Bleed/Bleed+ now do 2 damage instead of 1
+Power Level is now based on permissions
+Counter Attack added to swords
+Parry is now based directly on Swords skill level
+Parry maximum proc chance raised to 30% from 20%
+Serrated Strikes now properly applies Bleed+ to targets
+Players who parry can no longer be disarmed
+Acrobatics now has a Dodge passive skill reducing damage
+Repair skill now effects how much durability is restored
+Super repair now doubles the repair amount on proc
+Unarmed now starts with a bonus to damage to encourage use
+Unarmed now has two steps to damage scaling, Appentice, and Mastery
+Unarmed disarm now caps at 25% for 1000 skill
+Fixed problem where Archery skill procs would ignore other plugins
+Ignition changed to 25% chance
+Ignition length will be based on archery skill level
+/myspawn now has a warning about the inventory loss penalty in /mcc
+mcMMO Timer now runs in 1 second intervals rather than 2
+
+Version 0.9.10
+Party invites now show who they are from
+Mushrooms added to Dirt/Grass excavation loot tables, drops with 500+ skill
+mcMMO configuration files property setting names have been changed for readability
+Fixed bug where Gold and Iron wouldn't drop anything during Super Breaker
+Added /mcability info to /mcc
+Potentially fixed NPE error when checking players for being in same party for PVP XP
+Removed sand specific diamond drop from sand excavation loot table, Diamonds can still drop globally for sand
+Added a global XP gain multiplier, increase it to increase XP gained
+Reduced PVE XP for Unarmed, now identical to Axes/Swords
+Changed Chat priority in mcMMO to be higher, this should help plugin conflicts
+Mushroom XP raised to 40 from 10
+Flower XP raised to 10 from 3
+
+Version 0.9.9
+Fixed problem where entities never got removed from the arrow retrieval list of entities
+
+Version 0.9.8
+EntityLiving shouldn't be cast to entities that are not an instance of EntityLiving
+Added a null check in the timer for players being null before proceeding
+
+Version 0.9.7
+Procs/XP Gain will no longer happen when the Entity is immune to damage (Thanks EdwardHand!)
+Axes critical damage versus players reduced to 150% damage from 200% damage
+Fixed bug where Daze might not proc
+Changed archery Daze to follow smooth transition
+Added archery Daze chance info to /archery
+Cooldown lengths are now customizable, they are in seconds and multiplied by 2 by mcMMO
+
+Version 0.9.6
+Timer checks for player being null before adding them to the mcUsers system
+Cooldowns will now show how much time is remaining when trying to use their respective abilities
+SkullSpliiter will now correctly inform the player when they are too tired to use it
+Acrobatics will no longer give XP if the event was cancelled by another plugin
+Version 0.9.5
+Super Breaker now gives a chance for Triple Drops based on mining skill
+Ability durability loss down from 15 to 2
+Ability durability loss is now toggle-able
+Ability durability loss can be adjusted in the configuration file
+Mining Picks are no longer lowered after activating Super Breaker
+
+Version 0.9.4
+Flowers won't drop wheat anymore
+Signs won't trigger ability readiness anymore
+Version 0.9.3
+Bug stopping abilities from never wearing of may have been fixed
+Changed color of "X Ability has worn off" to RED from GRAY
+Super Breaker, Giga Drill Breaker, and Tree Feller now damage the tool significantly during use
+Netherrack and Glowstone now give Mining XP
+Netherrack and Glowstone are now effected by Super Breaker
+Abilities will no longer be readied when you right click signs or beds
+Chimaera Wings won't activate on blocks you can interact with and signs
+Abilities now adjust their effects depending on tool quality
+Superbreaker won't break things that tool couldn't normally break
+Giga Drill Breaker will only give triple xp and triple drops for diamond tools, with a reduced effect for lesser tools
+Skull Splitter now has a limit of opponents nearby it will strike based on your tool quality
+Serrated Strikes now has a limit of opponents nearby it will strike based on your tool quality
+Modified /mcmmo description to be a little bit more relevant.
+
+Version 0.9.2
+Changed priority of some of the mcMMO listeners
+Now when certain abilities are activated it shouldn't say "You lower your x"
+
+Version 0.9.1
+Fixed "Unknown console command" errors with CB 556
+Added /mcability command to toggle being able to trigger abilities with right click
+Added some more nullchecks for people reporting NPE errors
+Compatibility with NPC mods improved (Mainly for archery!)
+Other plugins can now call inSameParty() from mcMMO to increase compatibility
+
+Version 0.9
+--NEW CONTENT--
+Woodcutting now has the "Tree Feller" Ability
+Unarmed now has the "Berserk" Ability
+Swords now has the "Serrated Strikes" Ability
+Mining now has the "Super Breaker" Ability
+Axes now has the "Skull Splitter" Ability
+Excavation now has the "Giga Drill Breaker" Ability
+Added /mcrefresh <playername> - tool for refreshing cooldowns
+Unarmed now has the "Deflect Arrows" passive skill
+Chimaera Wing Item Added
+
+--CHANGES--
+HP Regen & Bleed are back
+Woodcutting will drop the appropriate log on double drop procs
+Herbalism now applies double drops to herbs
+/<skillname> now shows much more information to the player regarding their stats
+Axes skill Critical Strikes are now based directly on your skill level
+Swords skill Bleed chance is now based directly on your skill level
+Unarmed disarm chance is now based directly on your skill level
+Acrobatics now gives XP when you roll
+
+--BUGFIXES--
+Memory Leak Fixed
+Axes not doing critical strikes
+Gold Armor repair
+Capped skills now have the correct proc chance
+/mmoedit is no longer case sensitive
+More NPE errors fixed
+Many bugs I forgot to write down
+
+--PLUGIN COMPATABILITY FIXES--
+If combat interactions are cancelled by other plugins mcMMO should ignore the event
+If block damage interactions are cancelled by other plugins mcMMO should ignore the event
+	
+Version 0.8.22
+	Fixed bug where Axes did less damage than normal
+	Acrobatic rolls now give XP
+	Acrobatics XP increased for non-rolls
+Version 0.8.21
+	Fixed bug where axe criticals would dupe items
+Version 0.8.20
+	99.99% sure I fixed anvils that suddenly stop working
+Version 0.8.19
+	Fixed being able to excavate placed blocks
+	Added toggle option to mining requiring a pickaxe
+	Added toggle option to woodcutting requiring an axe
+	PVP interactions now reward XP based on the damage caused (this is effected by skills)
+	PVP XP gain can be disabled in the configuration file
+	PVP XP has a modifier, increase the modifier for higher XP rewards from PVP combat
+Version 0.8.18
+	Fixed sandstone not being watched for exploitation
+Version 0.8.17
+	mcmmo.users moved to plugins/mcMMO/
+	Snowballs and Eggs will no longer trigger Ignition
+	Loot tables for excavation adjusted
+	Mining benefits now require the player to be holding a mining pick
+	Woodcutting benefits now require the player to be holding an axe
+Version 0.8.16
+	Moved configuration file to /plugins/mcMMO
+	Arrows now have a chance to Ignite enemiesw
+	Fixed arrows not being retrievable from corpses
+	Added info about ignition to /archery
+Version 0.8.14
+	Mining, Woodcutting, Herbalism, and Acrobatics proc rates now are based on your skill level directly rather than tiers you unlock via skill levels
+	Archery's ability to retrieve arrows from corpses now is based on your skill level directly rather than tiers you unlock via skill levels
+	Mining, Woodcutting, Herbalism, Archery, and Acrobatics now show their proc % relative to your skill if you type /<skillname>
+	You can now adjust what level is required to repair diamond in the configuration file
+	Changed mining XP rates to be a tad higher for some things
+	You can now get XP from sandstone
+	XP rates increased for gathering glowstone with excavation
+	XP rates increased a bit for excavation
+	Skill info is now a bit more detailed for certain skills
+	Added info about arrow retrieval to /archery
+Version 0.8.13
+	Enemies no longer look like they have frozen when they die
+	Item duping fix
 Version 0.8.11
 	Performance improvements
 	Memory leak fixed

+ 11 - 0
mcMMO/com/gmail/nossr50/FakeBlockBreakEvent.java

@@ -0,0 +1,11 @@
+package com.gmail.nossr50;
+
+import org.bukkit.block.Block;
+import org.bukkit.entity.Player;
+import org.bukkit.event.block.BlockBreakEvent;
+
+public class FakeBlockBreakEvent extends BlockBreakEvent {
+	public FakeBlockBreakEvent(Block theBlock, Player player) {
+		super(theBlock, player);
+	}
+}

+ 12 - 62
mcMMO/com/gmail/nossr50/mcAcrobatics.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50;
 
-import org.bukkit.ChatColor;
 import org.bukkit.Location;
 import org.bukkit.entity.Player;
 import org.bukkit.event.entity.EntityDamageEvent;
@@ -14,69 +13,20 @@ public class mcAcrobatics {
     	return instance;
     	}
 	public void acrobaticsCheck(Player player, EntityDamageEvent event, Location loc, int xx, int y, int z){
-    	if(player != null && mcUsers.getProfile(player).getAcrobaticsInt() >= 50 
-				&& mcUsers.getProfile(player).getAcrobaticsInt() < 250
-				&& mcPermissions.getInstance().acrobatics(player)){
-			if(Math.random() * 10 > 8){
-				event.setCancelled(true);
+    	if(player != null && mcPermissions.getInstance().acrobatics(player)){
+			if(Math.random() * 1000 <= mcUsers.getProfile(player).getAcrobaticsInt()){
 				player.sendMessage("**ROLLED**");
-				return;
+				if(!mcConfig.getInstance().isBlockWatched(loc.getWorld().getBlockAt(xx, y, z))){
+					if(!event.isCancelled())
+						mcUsers.getProfile(player).addAcrobaticsGather((event.getDamage() * 8) * mcLoadProperties.xpGainMultiplier);
+					mcSkills.getInstance().XpCheck(player);
+					event.setCancelled(true);
+				}
+			} else if (!mcConfig.getInstance().isBlockWatched(loc.getWorld().getBlockAt(xx, y, z)) && !event.isCancelled()){
+				mcUsers.getProfile(player).addAcrobaticsGather((event.getDamage() * 12) * mcLoadProperties.xpGainMultiplier);
+				mcSkills.getInstance().XpCheck(player);
 			}
-		}
-		if(player != null && mcUsers.getProfile(player).getAcrobaticsInt() >= 250 
-				&& mcUsers.getProfile(player).getAcrobaticsInt() < 450 
-				&& mcPermissions.getInstance().acrobatics(player)){
-			if(Math.random() * 10 > 6){
-				event.setCancelled(true);
-				player.sendMessage("**ROLLED**");
-				return;
-			}
-		}
-		if(player != null && mcUsers.getProfile(player).getAcrobaticsInt() >= 450 
-				&& mcUsers.getProfile(player).getAcrobaticsInt() < 750 
-				&& mcPermissions.getInstance().acrobatics(player)){
-			if(Math.random() * 10 > 4){
-				event.setCancelled(true);
-				player.sendMessage("**ROLLED**");
-				return;
-			}
-		}
-		if(player != null && mcUsers.getProfile(player).getAcrobaticsInt() >= 750 
-				&& mcUsers.getProfile(player).getAcrobaticsInt() < 950 
-				&& mcPermissions.getInstance().acrobatics(player)){
-			if(Math.random() * 10 > 2){
-				event.setCancelled(true);
-				player.sendMessage("**BARREL ROLLED**");
-				return;
-			}
-		}
-		if(player != null && mcUsers.getProfile(player).getAcrobaticsInt() >= 950
-				&& mcPermissions.getInstance().acrobatics(player)){
-				event.setCancelled(true);
-				player.sendMessage("**ROLLED... LIKE A BOSS**");
-				return;
-			}
-		if(player != null && player.getHealth() - event.getDamage() <= 0)
-			return;
-		if(!mcConfig.getInstance().isBlockWatched(loc.getWorld().getBlockAt(xx, y, z)) 
-				&& mcPermissions.getInstance().acrobatics(player)){
-		mcUsers.getProfile(player).addAcrobaticsGather(event.getDamage() * 3);
-		if(player != null && mcUsers.getProfile(player).getAcrobaticsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("acrobatics")){
-			int skillups = 0;
-			while(mcUsers.getProfile(player).getAcrobaticsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("acrobatics")){
-				skillups++;
-				mcUsers.getProfile(player).removeAcrobaticsGather(mcUsers.getProfile(player).getXpToLevel("acrobatics"));
-				mcUsers.getProfile(player).skillUpAcrobatics(1);
-			}
-			player.sendMessage(ChatColor.YELLOW+"Acrobatics skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getAcrobatics()+")");	
-		}
-		mcConfig.getInstance().addBlockWatch(loc.getWorld().getBlockAt(xx, y, z));
-		if(player.getHealth() - event.getDamage() <= 0){
-			if(mcUsers.getProfile(player).isDead())
-    			return;
-			mcUsers.getProfile(player).setDead(true);
-		}
-		}
+    	}
     }
 	
 }

+ 169 - 59
mcMMO/com/gmail/nossr50/mcBlockListener.java

@@ -1,14 +1,16 @@
 package com.gmail.nossr50;
 
 import org.bukkit.ChatColor;
-import org.bukkit.Location;
+import org.bukkit.Material;
 import org.bukkit.World;
 import org.bukkit.block.Block;
 import org.bukkit.entity.Player;
+import org.bukkit.event.block.BlockBreakEvent;
 import org.bukkit.event.block.BlockDamageEvent;
 import org.bukkit.event.block.BlockFromToEvent;
 import org.bukkit.event.block.BlockListener;
 import org.bukkit.event.block.BlockPlaceEvent;
+import org.bukkit.inventory.ItemStack;
 
 public class mcBlockListener extends BlockListener {
     private final mcMMO plugin;
@@ -16,81 +18,189 @@ public class mcBlockListener extends BlockListener {
     public mcBlockListener(final mcMMO plugin) {
         this.plugin = plugin;
     }
+    
     public void onBlockPlace(BlockPlaceEvent event) {
     	Block block;
-    	if (event.getBlockReplacedState().getTypeId() == 78) {
-    		block = event.getBlockAgainst();
+    	Player player = event.getPlayer();
+    	if (event.getBlock() != null && event.getBlockReplacedState() != null && event.getBlockReplacedState().getTypeId() == 78) {
+    			block = event.getBlockAgainst();
     		}
     		else {
-    		block = event.getBlock();
+    			block = event.getBlock();
     		}
-    	int x = block.getX();
-    	int y = block.getY();
-    	int z = block.getZ();
-    	String xyz = x+","+y+","+z;
-    	if(mcm.getInstance().shouldBeWatched(block))
-    	mcConfig.getInstance().addBlockWatch(block);
+    	if(player != null && mcm.getInstance().shouldBeWatched(block))
+    		mcConfig.getInstance().addBlockWatch(block);
     	if(block.getTypeId() == 42 && mcLoadProperties.anvilmessages)
     		event.getPlayer().sendMessage(ChatColor.DARK_RED+"You have placed an anvil, anvils can repair tools and armor.");
     }
-    //put all Block related code here
-    public void onBlockDamage(BlockDamageEvent event) {
-    		//STARTED(0), DIGGING(1), BROKEN(3), STOPPED(2);
-    		Player player = event.getPlayer();
-    		//player.sendMessage("mcMMO DEBUG: EVENT-OK DMG LEVEL ("+event.getDamageLevel().getLevel()+")");
-    		Block block = event.getBlock();
-    		int x = block.getX();
-        	int y = block.getY();
-        	int z = block.getZ();
-        	String xyz = x+","+y+","+z;
-    		Location loc = block.getLocation();
-    		int dmg = event.getDamageLevel().getLevel();
-    		/*
-    		 * HERBALISM
-    		 */
-    		if(dmg == 3){
-        		if(mcPermissions.getInstance().herbalism(player))
-        		mcHerbalism.getInstance().herbalismProcCheck(block, player);
+    
+    public void onBlockBreak(BlockBreakEvent event) {
+    	Player player = event.getPlayer();
+    	Block block = event.getBlock();
+    	ItemStack inhand = player.getItemInHand();
+    	
+    	if (event instanceof FakeBlockBreakEvent) {
+    		return;
+    	}
+    	
+    	/*
+    	 * MINING
+    	 */
+    	if(mcPermissions.getInstance().mining(player)){
+    		if(mcLoadProperties.miningrequirespickaxe){
+    			if(mcm.getInstance().isMiningPick(inhand))
+    				mcMining.getInstance().miningBlockCheck(player, block);
+    		} else {
+    			mcMining.getInstance().miningBlockCheck(player, block);
     		}
+    	}
+    	/*
+   		 * WOOD CUTTING
+   		 */
+    	
+   		if(player != null && block.getTypeId() == 17 && mcPermissions.getInstance().woodcutting(player)){
+   			if(mcLoadProperties.woodcuttingrequiresaxe){
+				if(mcm.getInstance().isAxes(inhand)){
+					if(!mcConfig.getInstance().isBlockWatched(block)){
+	    				mcWoodCutting.getInstance().woodCuttingProcCheck(player, block);
+	    				mcUsers.getProfile(player).addWoodcuttingGather(7 * mcLoadProperties.xpGainMultiplier);
+					}
+    			}
+    		} else {
+    			if(!mcConfig.getInstance().isBlockWatched(block)){
+	    			mcWoodCutting.getInstance().woodCuttingProcCheck(player, block);
+					mcUsers.getProfile(player).addWoodcuttingGather(7 * mcLoadProperties.xpGainMultiplier);	
+    			}
+   			}
+    		mcSkills.getInstance().XpCheck(player);
+    			
     		/*
-    		 * MINING
-    		 */
-    		if(player != null && dmg == 2 && !mcConfig.getInstance().isBlockWatched(block)){
-    		if(mcPermissions.getInstance().mining(player))
-    		mcMining.getInstance().miningBlockCheck(player, block);
-    		/*
-    		 * WOOD CUTTING
+    		 * IF PLAYER IS USING TREEFELLER
     		 */
-    		if(player != null && block.getTypeId() == 17 && mcPermissions.getInstance().woodcutting(player)){    		
-    				mcWoodCutting.getInstance().woodCuttingProcCheck(player, block, loc);
-    				mcUsers.getProfile(player).addWoodcuttingGather(7);
-    				if(mcPermissions.getInstance().woodcuttingability(player)){
-    					
+   			if(mcPermissions.getInstance().woodCuttingAbility(player) 
+   					&& mcUsers.getProfile(player).getTreeFellerMode() 
+   					&& block.getTypeId() == 17
+   					&& mcm.getInstance().blockBreakSimulate(block, player, plugin)){
+    			mcWoodCutting.getInstance().treeFeller(block, player);
+    			for(Block blockx : mcConfig.getInstance().getTreeFeller()){
+    				if(blockx != null){
+    					Material mat = Material.getMaterial(block.getTypeId());
+    					byte type = 0;
+    					if(block.getTypeId() == 17)
+    						type = block.getData();
+    					ItemStack item = new ItemStack(mat, 1, (byte)0, type);
+    					if(blockx.getTypeId() == 17){
+    						blockx.getLocation().getWorld().dropItemNaturally(blockx.getLocation(), item);
+    						//XP WOODCUTTING
+    						if(!mcConfig.getInstance().isBlockWatched(block)){
+	    						mcWoodCutting.getInstance().woodCuttingProcCheck(player, blockx);
+	    						mcUsers.getProfile(player).addWoodcuttingGather(7);
+    						}
+    					}
+    					if(blockx.getTypeId() == 18){
+    						mat = Material.getMaterial(6);
+    						item = new ItemStack(mat, 1, (byte)0, (byte) 0);
+    						if(Math.random() * 10 > 8)
+    							blockx.getLocation().getWorld().dropItemNaturally(blockx.getLocation(), item);
+    					}
+    					blockx.setType(Material.AIR);
     				}
-    		}
-    		/*
-    		 * EXCAVATION
-    		 */
-    		if(mcPermissions.getInstance().excavation(player) && block != null && player != null)
-    		mcExcavation.getInstance().excavationProcCheck(block, player);
-    		/*
-    		 * EXPLOIT COUNTERMEASURES
-    		 */
-    		mcConfig.getInstance().addBlockWatch(block);
-    		if(player != null && mcUsers.getProfile(player).getWoodCuttingGatherInt() >= mcUsers.getProfile(player).getXpToLevel("woodcutting")){
-    			int skillups = 0;
-    			while(mcUsers.getProfile(player).getWoodCuttingGatherInt() >= mcUsers.getProfile(player).getXpToLevel("woodcutting")){
-    				skillups++;
-    				mcUsers.getProfile(player).removeWoodCuttingGather(mcUsers.getProfile(player).getXpToLevel("woodcutting"));
-    				mcUsers.getProfile(player).skillUpWoodCutting(1);
     			}
-    			player.sendMessage(ChatColor.YELLOW+"WoodCutting skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getWoodCutting()+")");	
+    			if(mcLoadProperties.toolsLoseDurabilityFromAbilities)
+    		    	mcm.getInstance().damageTool(player, (short) mcLoadProperties.abilityDurabilityLoss);
+    				/*
+    				 * NOTE TO SELF
+    				 * I NEED TO REMOVE TREE FELL BLOCKS FROM BEING WATCHED AFTER THIS CODE IS EXECUTED
+    				 * OR ELSE IT COULD BE A MEMORY LEAK SITUATION
+    				 */
+    				mcConfig.getInstance().clearTreeFeller();
     		}
+    	}
+    	/*
+    	 * EXCAVATION
+    	 */
+    	if(mcPermissions.getInstance().excavation(player) && block != null && player != null)
+    		mcExcavation.getInstance().excavationProcCheck(block, player);
+    	/*
+    	 * HERBALISM
+    	 */
+    	if(mcPermissions.getInstance().herbalism(player))
+       		mcHerbalism.getInstance().herbalismProcCheck(block, player);
+    }
+    public void onBlockDamage(BlockDamageEvent event) {
+    	if(event.isCancelled())
+    		return;
+    	Player player = event.getPlayer();
+    	ItemStack inhand = player.getItemInHand();
+    	Block block = event.getBlock();
+    	
+    	/*
+    	 * ABILITY PREPARATION CHECKS
+    	 */
+    	if(mcUsers.getProfile(player).getAxePreparationMode() && block.getTypeId() == 17)
+    		mcWoodCutting.getInstance().treeFellerCheck(player, block);
+    	if(mcUsers.getProfile(player).getPickaxePreparationMode())
+    		mcMining.getInstance().superBreakerCheck(player, block);
+    	if(mcUsers.getProfile(player).getShovelPreparationMode() && mcExcavation.getInstance().canBeGigaDrillBroken(block))
+    		mcExcavation.getInstance().gigaDrillBreakerActivationCheck(player, block);
+    	if(mcUsers.getProfile(player).getFistsPreparationMode() && mcExcavation.getInstance().canBeGigaDrillBroken(block))
+    		mcSkills.getInstance().berserkActivationCheck(player);
+    	/*
+    	 * GIGA DRILL BREAKER CHECKS
+    	 */
+    	if(mcUsers.getProfile(player).getGigaDrillBreakerMode() 
+    			&& mcm.getInstance().blockBreakSimulate(block, player, plugin) 
+    			&& mcExcavation.getInstance().canBeGigaDrillBroken(block) 
+    			&& mcm.getInstance().isShovel(inhand)){
+    		if(mcm.getInstance().getTier(player) >= 2)
+    			mcExcavation.getInstance().excavationProcCheck(block, player);
+    		if(mcm.getInstance().getTier(player) >= 3)
+    			mcExcavation.getInstance().excavationProcCheck(block, player);
+    		if(mcm.getInstance().getTier(player) >= 4)
+    			mcExcavation.getInstance().excavationProcCheck(block, player);
+    		Material mat = Material.getMaterial(block.getTypeId());
+    		if(block.getTypeId() == 2)
+    			mat = Material.DIRT;
+			byte type = block.getData();
+			ItemStack item = new ItemStack(mat, 1, (byte)0, type);
+			block.setType(Material.AIR);
+			if(mcLoadProperties.toolsLoseDurabilityFromAbilities)
+	    		mcm.getInstance().damageTool(player, (short) mcLoadProperties.abilityDurabilityLoss);
+			block.getLocation().getWorld().dropItemNaturally(block.getLocation(), item);
+    	}
+    	/*
+    	 * BERSERK MODE CHECKS
+    	 */
+    	if(mcUsers.getProfile(player).getBerserkMode() 
+    			&& mcm.getInstance().blockBreakSimulate(block, player, plugin) 
+    			&& player.getItemInHand().getTypeId() == 0 
+    			&& mcExcavation.getInstance().canBeGigaDrillBroken(block)){
+		    		Material mat = Material.getMaterial(block.getTypeId());
+		    		if(block.getTypeId() == 2)
+		    			mat = Material.DIRT;
+					byte type = block.getData();
+					ItemStack item = new ItemStack(mat, 1, (byte)0, type);
+					block.setType(Material.AIR);
+					block.getLocation().getWorld().dropItemNaturally(block.getLocation(), item);
+    	}
+    	
+    	/*
+    	 * SUPER BREAKER CHECKS
+    	 */
+    	if(mcUsers.getProfile(player).getSuperBreakerMode() 
+    			&& mcMining.getInstance().canBeSuperBroken(block)
+    			&& mcm.getInstance().blockBreakSimulate(block, player, plugin)){
+    		if(mcLoadProperties.miningrequirespickaxe){
+    			if(mcm.getInstance().isMiningPick(inhand))
+    				mcMining.getInstance().SuperBreakerBlockCheck(player, block);
+    		} else {
+    			mcMining.getInstance().SuperBreakerBlockCheck(player, block);
     		}
+    	}
+    	
     }
     
-    
-    public void onBlockFlow(BlockFromToEvent event) {
+    public void onBlockFromTo(BlockFromToEvent event) {
     	//Code borrowed from WorldGuard by sk89q
         World world = event.getBlock().getWorld();
         int radius = 1;

File diff suppressed because it is too large
+ 301 - 546
mcMMO/com/gmail/nossr50/mcCombat.java


+ 75 - 0
mcMMO/com/gmail/nossr50/mcConfig.java

@@ -17,7 +17,73 @@ public class mcConfig {
     HashMap<Entity, Integer> arrowTracker = new HashMap<Entity, Integer>();
     static ArrayList<Entity> bleedTracker = new ArrayList<Entity>();
     static ArrayList<Entity> mobSpawnTracker = new ArrayList<Entity>();
+    
+    /*
+     * The Bleed Que Stuff
+     */
+    public Entity[] bleedQue = new Entity[20];
+    public int bleedQuePos = 0;
+    
+    public void addToBleedQue(Entity entity){
+    	//Assign entity to empty position
+    	bleedQue[bleedQuePos] = entity;
+    	//Move position up by 1 increment
+    	bleedQuePos++;
+    	
+    	//Check if array is full
+    	if(bleedQuePos >= bleedQue.length){
+    		//Create new temporary array
+    		Entity[] temp = new Entity[bleedQue.length*2];
+    		//Copy data from bleedQue to temporary array
+    		System.arraycopy(bleedQue, 0, temp, 0, bleedQue.length);
+    		//Point bleedQue to new array
+    		bleedQue = temp;
+    	}
+    }
+    
+    public Entity[] getBleedQue(){return bleedQue;}
+    
+    public void clearBleedQue(){
+    	bleedQue = new Entity[bleedQue.length];
+    	setBleedQuePos(0);
+    }
+    public void setBleedQuePos(int x){bleedQuePos = x;}
+    
+    /*
+     * The Bleed Removal Que Stuff
+     */
+    
+    public Entity[] bleedRemovalQue = new Entity[20];
+    public int bleedRemovalQuePos = 0;
+    
+    public void addToBleedRemovalQue(Entity entity){
+    	//Assign entity to empty position
+    	bleedRemovalQue[bleedRemovalQuePos] = entity;
+    	//Move position up by 1 increment
+    	bleedRemovalQuePos++;
+    	
+    	//Check if array is full
+    	if(bleedRemovalQuePos >= bleedRemovalQue.length){
+    		//Create new temporary array
+    		Entity[] temp = new Entity[bleedRemovalQue.length*2];
+    		//Copy data from bleedRemovalQue to temporary array
+    		System.arraycopy(bleedRemovalQue, 0, temp, 0, bleedRemovalQue.length);
+    		//Point bleedRemovalQue to new array
+    		bleedRemovalQue = temp;
+    	}
+    }
+    
+    public Entity[] getBleedRemovalQue(){return bleedRemovalQue;}
+    
+    public void clearBleedRemovalQue(){
+    	bleedQue = new Entity[bleedRemovalQue.length];
+    	setBleedQuePos(0);
+    }
+    public void setBleedRemovalQuePos(int x){bleedRemovalQuePos = x;}
+    
+    
     public boolean isBlockWatched(Block block) {return blockWatchList.contains(block);}
+    public boolean isTreeFellerWatched(Block block) {return treeFeller.contains(block);}
     public ArrayList<Block> getTreeFeller() {return treeFeller;}
     public void removeBlockWatch(Block block) {blockWatchList.remove(blockWatchList.indexOf(block));}
     public void addBlockWatch(Block block) {blockWatchList.add(block);}
@@ -25,12 +91,21 @@ public class mcConfig {
     public void addTreeFeller(Block block) {treeFeller.add(block);}
     public void addBleedTrack(Entity entity) {bleedTracker.add(entity);}
     public void addMobSpawnTrack(Entity entity) {mobSpawnTracker.add(entity);}
+    public void removeMobSpawnTrack(Entity entity) {mobSpawnTracker.remove(entity);}
     public ArrayList<Entity> getBleedTracked() {return bleedTracker;}
     public void addArrowTrack(Entity entity, Integer arrowcount) {arrowTracker.put(entity, arrowcount);}
     public Integer getArrowCount(Entity entity) {return arrowTracker.get(entity);}
+    public void removeArrowTracked(Entity entity){
+    	if(arrowTracker.containsKey(entity)){
+    		arrowTracker.remove(entity);
+    	}
+    }
     public void removeBleedTrack(Entity entity){
     	bleedTracker.remove(entity);
     }
+    public void clearTreeFeller(){
+    	treeFeller.clear();
+    }
     public void setBleedCount(Entity entity, Integer newvalue){
     	bleedTracker.add(entity);
     }

+ 137 - 31
mcMMO/com/gmail/nossr50/mcEntityListener.java

@@ -1,7 +1,12 @@
 package com.gmail.nossr50;
 
+import net.minecraft.server.EntityLiving;
+
+import org.bukkit.ChatColor;
 import org.bukkit.Location;
+import org.bukkit.craftbukkit.entity.CraftEntity;
 import org.bukkit.entity.Animals;
+import org.bukkit.entity.Arrow;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.Monster;
 import org.bukkit.entity.Player;
@@ -13,6 +18,7 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
 import org.bukkit.event.entity.EntityDeathEvent;
 import org.bukkit.event.entity.EntityListener;
 import org.bukkit.inventory.ItemStack;
+import org.bukkit.util.Vector;
 
 public class mcEntityListener extends EntityListener {
 	private final mcMMO plugin;
@@ -35,6 +41,14 @@ public class mcEntityListener extends EntityListener {
     	}
     }
     public void onEntityDamage(EntityDamageEvent event) {
+    	/*
+    	 * CHECK FOR INVULNERABILITY
+    	 */
+    	if(event.getEntity() instanceof CraftEntity){
+    	CraftEntity cEntity = (CraftEntity)event.getEntity();
+    	if(cEntity.getHandle() instanceof EntityLiving){
+    	EntityLiving entityliving = (EntityLiving)cEntity.getHandle();
+    	if(entityliving.noDamageTicks < entityliving.maxNoDamageTicks/2.0F){
     	Entity x = event.getEntity();
     	DamageCause type = event.getCause();
     	/*
@@ -50,42 +64,65 @@ public class mcEntityListener extends EntityListener {
     		mcAcrobatics.getInstance().acrobaticsCheck(player, event, loc, xx, y, z);
     		}
     	}
-    	/*
-    	 * ARCHERY CHECKS
-    	 */
-    	if(event instanceof EntityDamageByProjectileEvent){
-    		EntityDamageByProjectileEvent c = (EntityDamageByProjectileEvent)event;
-    		mcCombat.getInstance().archeryCheck(c);
-    	}
+    	
     	/*
     	 * Entity Damage by Entity checks
     	 */
-    	if(event instanceof EntityDamageByEntityEvent){
+    	if(event instanceof EntityDamageByEntityEvent && event.getDamage() >= 1){
+    		if(event.isCancelled()){
+    			return;
+    		}
     		EntityDamageByEntityEvent eventb = (EntityDamageByEntityEvent)event;
     		Entity e = eventb.getEntity(); //Defender
         	Entity f = eventb.getDamager(); //Attacker
         	/*
-        	 * IF DEFENDER IS PLAYER
+        	 * DEFENDER PROC/GODMODE CHECKS
         	 */
         	if(e instanceof Player){
         		Player defender = (Player)e;
         		if(defender != null && mcConfig.getInstance().isGodModeToggled(defender.getName()))
         			event.setCancelled(true);
-        		if(f instanceof Monster && defender != null){
-        			mcUsers.getProfile(defender).setRecentlyHurt(30);
-        		}
         		/*
         		 * PARRYING CHECK, CHECK TO SEE IF ITS A SUCCESSFUL PARRY OR NOT
         		 */
         		mcCombat.getInstance().parryCheck(defender, eventb, f);
         	}
+        	
+        	/*
+        	 * ARCHERY CHECKS
+        	 */
+        	if(!event.isCancelled() && event instanceof EntityDamageByProjectileEvent && event.getDamage() >= 1){
+        		EntityDamageByProjectileEvent c = (EntityDamageByProjectileEvent)event;
+        		mcCombat.getInstance().archeryCheck(c);
+        	}
+        	
+        	/*
+        	 * CHECK FOR PVP INTERACTIONS
+        	 */
+        	if(f instanceof Player && e instanceof Player && !mcLoadProperties.pvp)
+        		event.setCancelled(true);
+        	
         	/*
         	 * IF ATTACKER IS PLAYER
         	 */
-        	if(f instanceof Player){
+        	if(f instanceof Player && !event.isCancelled()){
         		//((Player) f).sendMessage("DEBUG: EntityDamageByEntity cast correctly!");
         		int typeid = ((Player) f).getItemInHand().getTypeId();
         		Player attacker = (Player)f;
+        		/*
+        		 * ACTIVATE ABILITIES
+        		 */
+        		if(mcUsers.getProfile(attacker).getAxePreparationMode())
+        			mcSkills.getInstance().skullSplitterCheck(attacker);
+        		if(mcUsers.getProfile(attacker).getSwordsPreparationMode())
+        			mcSkills.getInstance().serratedStrikesActivationCheck(attacker);
+        		if(mcUsers.getProfile(attacker).getFistsPreparationMode())
+        			mcSkills.getInstance().berserkActivationCheck(attacker);
+        		/*
+        		 * BERSERK DAMAGE MODIFIER
+        		 */
+        		if(mcUsers.getProfile(attacker).getBerserkMode())
+        			event.setDamage(event.getDamage() + (event.getDamage() / 2));
         		/*
         		 * Player versus Monster checks, this handles all skill damage modifiers and any procs.
         		 */
@@ -98,38 +135,107 @@ public class mcEntityListener extends EntityListener {
         		 * Player versus Player checks, these checks make sure players are not in the same party, etc. They also check for any procs from skills and handle damage modifiers.
         		 */
         		if(mcm.getInstance().isPvpEnabled())
-        		mcCombat.getInstance().playerVersusPlayerChecks(e, attacker, eventb);
+        			mcCombat.getInstance().playerVersusPlayerChecks(e, attacker, eventb);
         		/*
         		 * Player versus Animals checks, these checks handle any skill modifiers or procs
         		 */
         		mcCombat.getInstance().playerVersusAnimalsChecks(e, attacker, eventb, typeid);
+        		/*
+        		 * This will do AOE damage from the axes ability
+        		 */
+        		
+        		if(!event.isCancelled() && mcUsers.getProfile(attacker).getSkullSplitterMode() && mcm.getInstance().isAxes(attacker.getItemInHand()))
+            		mcCombat.getInstance().applyAoeDamage(attacker, eventb, x);
+        		if(!event.isCancelled() && mcUsers.getProfile(attacker).getSerratedStrikesMode() && mcm.getInstance().isSwords(attacker.getItemInHand()))
+            		mcCombat.getInstance().applySerratedStrikes(attacker, eventb, x);
         	}
-        	if(f instanceof Player && e instanceof Player && !mcLoadProperties.pvp)
-        		event.setCancelled(true);
-        	if(e instanceof Monster || e instanceof Animals){
-        		if(e instanceof Monster){
-        			Monster monster = (Monster)e;
-        			if(monster.getHealth() <= 0){
-        				mcConfig.getInstance().removeBleedTrack(e);
-        			}
-        		}
-        		if(e instanceof Animals){
-        			Animals animals = (Animals)e;
-        			if(animals.getHealth() <= 0){
-        				mcConfig.getInstance().removeBleedTrack(e);
+        	/*
+        	 * DODGE / COUNTERATTACK CHECKS
+        	 */
+        	if(e instanceof Player){
+        		Player defender = (Player)e;
+        		if(f instanceof Player){
+        			Player attacker = (Player)f;
+        			if(mcParty.getInstance().inSameParty(defender, attacker)){
+        				return;
         			}
         		}
+        		
+        		/*
+        		 * COUNTER ATTACK STUFF
+        		 */
+	        	if(mcPermissions.getInstance().swords(defender) 
+	        			&& mcm.getInstance().isSwords(defender.getItemInHand())){
+	        		boolean isArrow = false;
+	        		if (event instanceof EntityDamageByProjectileEvent) {
+	        		  final EntityDamageByProjectileEvent realEvent =
+	        		    (EntityDamageByProjectileEvent) event;
+	        		  isArrow = (realEvent.getProjectile() instanceof Arrow);
+	        		}
+	        		if(isArrow == false){
+	        			//defender.sendMessage("isArrow ="+isArrow);
+			    		if(mcUsers.getProfile(defender).getSwordsInt() >= 600){
+			    			if(Math.random() * 2000 <= 600){
+			    				mcCombat.getInstance().dealDamage(f, event.getDamage() / 2);
+			    				defender.sendMessage(ChatColor.GREEN+"**COUNTER-ATTACKED**");
+			    				if(f instanceof Player)
+			    					((Player) f).sendMessage(ChatColor.DARK_RED+"Hit with counterattack!");
+			    			}
+			    		} else if (Math.random() * 2000 <= mcUsers.getProfile(defender).getSwordsInt()){
+			    			mcCombat.getInstance().dealDamage(f, event.getDamage() / 2);
+			    			defender.sendMessage(ChatColor.GREEN+"**COUNTER-ATTACKED**");
+		    				if(f instanceof Player)
+		    					((Player) f).sendMessage(ChatColor.DARK_RED+"Hit with counterattack!");
+			    		}
+	        		}
+	    		}
+	        	/*
+	        	 * DODGE STUFF
+	        	 */
+	    		if(mcPermissions.getInstance().acrobatics(defender)){
+	    			if(mcUsers.getProfile(defender).getAcrobaticsInt() <= 800){
+			    		if(Math.random() * 4000 <= mcUsers.getProfile(defender).getAcrobaticsInt()){
+			    			defender.sendMessage(ChatColor.RED+"**DODGE - DAMAGE REDUCED**");
+			    			mcUsers.getProfile(defender).addAcrobaticsGather(event.getDamage() * 12);
+			    			mcSkills.getInstance().XpCheck(defender);
+			    			event.setDamage(event.getDamage() / 2);
+			    		}
+	    			} else if(Math.random() * 4000 <= 800) {
+		    			defender.sendMessage(ChatColor.RED+"**DODGE - DAMAGE REDUCED**");
+		    			mcUsers.getProfile(defender).addAcrobaticsGather(event.getDamage() * 12);
+		    			mcSkills.getInstance().XpCheck(defender);
+		    			event.setDamage(event.getDamage() / 2);
+		    		}
+	    		}
         	}
     	}
+    	
+    	/*
+    	 * Check to see if the defender took damage so we can apply recently hurt
+    	 */
+    	if(x instanceof Player && !event.isCancelled()){
+    		Player herpderp = (Player)x;
+    		mcUsers.getProfile(herpderp).setRecentlyHurt(30);
+    	}
+    	}
+    	}
+    	}
     }
     public void onEntityDeath(EntityDeathEvent event) {
     	Entity x = event.getEntity();
+    	x.setFireTicks(0);
+    	
+    	//Remove bleed track
+    	if(mcConfig.getInstance().isBleedTracked(x))
+    		mcConfig.getInstance().addToBleedRemovalQue(x);
+    	
+		mcSkills.getInstance().arrowRetrievalCheck(x);
+		if(mcConfig.getInstance().isMobSpawnTracked(x)){
+			mcConfig.getInstance().removeMobSpawnTrack(x);
+		}
     	if(x instanceof Player){
     		Player player = (Player)x;
-    		if(mcUsers.getProfile(player).isDead()){
-    			 mcUsers.getProfile(player).setDead(false);
-    			 return;
-    		}
+    		mcUsers.getProfile(player).setBleedTicks(0);
     	}
     }
     public boolean isPlayer(Entity entity){

+ 105 - 61
mcMMO/com/gmail/nossr50/mcExcavation.java

@@ -19,63 +19,111 @@ public class mcExcavation {
     	}
     	return instance;
     	}
-	
+	public void gigaDrillBreakerActivationCheck(Player player, Block block){
+		if(mcm.getInstance().isShovel(player.getItemInHand())){
+	    	if(block != null){
+		    	if(!mcm.getInstance().abilityBlockCheck(block))
+		    		return;
+	    	}
+	    	if(mcUsers.getProfile(player).getShovelPreparationMode()){
+    			mcUsers.getProfile(player).setShovelPreparationMode(false);
+    			mcUsers.getProfile(player).setShovelPreparationTicks(0);
+    		}
+	    	int ticks = 2;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 750)
+    			ticks++;
+    		
+	    	if(!mcUsers.getProfile(player).getGigaDrillBreakerMode() && mcUsers.getProfile(player).getGigaDrillBreakerCooldown() == 0){
+	    		player.sendMessage(ChatColor.GREEN+"**GIGA DRILL BREAKER ACTIVATED**");
+	    		mcUsers.getProfile(player).setGigaDrillBreakerTicks(ticks * 2);
+	    		mcUsers.getProfile(player).setGigaDrillBreakerMode(true);
+	    	}
+	    	
+	    }
+	}
+	public boolean canBeGigaDrillBroken(Block block){
+		int i = block.getTypeId();
+		if(i == 2||i == 3||i == 12||i == 13){
+			return true;
+		} else {
+			return false;
+		}
+	}
 	public void excavationProcCheck(Block block, Player player){
     	int type = block.getTypeId();
     	Location loc = block.getLocation();
     	ItemStack is = null;
     	Material mat = null;
-    	if(type == 2 && mcUsers.getProfile(player).getExcavationInt() > 250){
-    		//CHANCE TO GET EGGS
-    		if(mcLoadProperties.eggs == true && Math.random() * 100 > 99){
-    			mcUsers.getProfile(player).addExcavationGather(10);
-				mat = Material.getMaterial(344);
-				is = new ItemStack(mat, 1, (byte)0, (byte)0);
-				loc.getWorld().dropItemNaturally(loc, is);
-    		}
-    		//CHANCE TO GET APPLES
-    		if(mcLoadProperties.apples == true && Math.random() * 100 > 99){
-    			mcUsers.getProfile(player).addExcavationGather(10);
-    			mat = Material.getMaterial(260);
-				is = new ItemStack(mat, 1, (byte)0, (byte)0);
-				loc.getWorld().dropItemNaturally(loc, is);
+    	if(mcConfig.getInstance().isBlockWatched(block)){
+    		return;
+    	}
+    	if(type == 2){
+    		if(mcUsers.getProfile(player).getExcavationInt() > 250){
+	    		//CHANCE TO GET EGGS
+	    		if(mcLoadProperties.eggs == true && Math.random() * 100 > 99){
+	    			mcUsers.getProfile(player).addExcavationGather(10 * mcLoadProperties.xpGainMultiplier);
+					mat = Material.getMaterial(344);
+					is = new ItemStack(mat, 1, (byte)0, (byte)0);
+					loc.getWorld().dropItemNaturally(loc, is);
+	    		}
+	    		//CHANCE TO GET APPLES
+	    		if(mcLoadProperties.apples == true && Math.random() * 100 > 99){
+	    			mcUsers.getProfile(player).addExcavationGather(10 * mcLoadProperties.xpGainMultiplier);
+	    			mat = Material.getMaterial(260);
+					is = new ItemStack(mat, 1, (byte)0, (byte)0);
+					loc.getWorld().dropItemNaturally(loc, is);
+	    		}
     		}
     	}
     	//DIRT SAND OR GRAVEL
     	if(type == 3 || type == 13 || type == 2 || type == 12){
-    			mcUsers.getProfile(player).addExcavationGather(3);
+    			mcUsers.getProfile(player).addExcavationGather(4 * mcLoadProperties.xpGainMultiplier);
     		if(mcUsers.getProfile(player).getExcavationInt() > 750){
     			//CHANCE TO GET CAKE
     			if(mcLoadProperties.cake == true && Math.random() * 2000 > 1999){
-    				mcUsers.getProfile(player).addExcavationGather(300);
+    				mcUsers.getProfile(player).addExcavationGather(300 * mcLoadProperties.xpGainMultiplier);
     				mat = Material.getMaterial(354);
     				is = new ItemStack(mat, 1, (byte)0, (byte)0);
     				loc.getWorld().dropItemNaturally(loc, is);
     			}
     		}
-    		if(mcUsers.getProfile(player).getExcavationInt() > 150){
-    			//CHANCE TO GET MUSIC
-    			if(mcLoadProperties.music == true && Math.random() * 2000 > 1999){
-    				mcUsers.getProfile(player).addExcavationGather(300);
-    				mat = Material.getMaterial(2256);
-    				is = new ItemStack(mat, 1, (byte)0, (byte)0);
-    				loc.getWorld().dropItemNaturally(loc, is);
-    			}
-    			
-    		}
     		if(mcUsers.getProfile(player).getExcavationInt() > 350){
     			//CHANCE TO GET DIAMOND
-    			if(mcLoadProperties.diamond == true && Math.random() * 500 > 499){
-    				mcUsers.getProfile(player).addExcavationGather(100);
+    			if(mcLoadProperties.diamond == true && Math.random() * 750 > 749){
+    				mcUsers.getProfile(player).addExcavationGather(100 * mcLoadProperties.xpGainMultiplier);
         				mat = Material.getMaterial(264);
         				is = new ItemStack(mat, 1, (byte)0, (byte)0);
         				loc.getWorld().dropItemNaturally(loc, is);
     			}
     		}
     		if(mcUsers.getProfile(player).getExcavationInt() > 250){
-    			//CHANCE TO GET MUSIC
+    			//CHANCE TO GET YELLOW MUSIC
+    			if(mcLoadProperties.music == true && Math.random() * 2000 > 1999){
+    				mcUsers.getProfile(player).addExcavationGather(300 * mcLoadProperties.xpGainMultiplier);
+    				mat = Material.getMaterial(2256);
+    				is = new ItemStack(mat, 1, (byte)0, (byte)0);
+    				loc.getWorld().dropItemNaturally(loc, is);
+    			}
+    			
+    		}
+    		if(mcUsers.getProfile(player).getExcavationInt() > 350){
+    			//CHANCE TO GET GREEN MUSIC
     			if(mcLoadProperties.music == true && Math.random() * 2000 > 1999){
-    				mcUsers.getProfile(player).addExcavationGather(300);
+    				mcUsers.getProfile(player).addExcavationGather(300 * mcLoadProperties.xpGainMultiplier);
     				mat = Material.getMaterial(2257);
     				is = new ItemStack(mat, 1, (byte)0, (byte)0);
     				loc.getWorld().dropItemNaturally(loc, is);
@@ -86,31 +134,35 @@ public class mcExcavation {
     	if(type == 12){
     		//CHANCE TO GET GLOWSTONE
     		if(mcLoadProperties.glowstone == true && mcUsers.getProfile(player).getExcavationInt() > 50 && Math.random() * 100 > 95){
-    			mcUsers.getProfile(player).addExcavationGather(3);
+    			mcUsers.getProfile(player).addExcavationGather(8 * mcLoadProperties.xpGainMultiplier);
 				mat = Material.getMaterial(348);
 				is = new ItemStack(mat, 1, (byte)0, (byte)0);
 				loc.getWorld().dropItemNaturally(loc, is);
     		}
     		//CHANCE TO GET SLOWSAND
     		if(mcLoadProperties.slowsand == true && mcUsers.getProfile(player).getExcavationInt() > 650 && Math.random() * 200 > 199){
-    			mcUsers.getProfile(player).addExcavationGather(5);
+    			mcUsers.getProfile(player).addExcavationGather(8 * mcLoadProperties.xpGainMultiplier);
 				mat = Material.getMaterial(88);
 				is = new ItemStack(mat, 1, (byte)0, (byte)0);
 				loc.getWorld().dropItemNaturally(loc, is);
     		}
-    		//CHANCE TO GET DIAMOND
-    		if(mcLoadProperties.diamond == true && mcUsers.getProfile(player).getExcavationInt() > 500 && Math.random() * 500 > 499){
-    			mcUsers.getProfile(player).addExcavationGather(100);
-				mat = Material.getMaterial(264);
+    	}
+    	//GRASS OR DIRT
+    	if(type == 2 || type == 3){
+    		//CHANCE FOR SHROOMS
+    		if(mcLoadProperties.mushrooms == true && mcUsers.getProfile(player).getExcavationInt() > 500 && Math.random() * 200 > 199){
+    			mcUsers.getProfile(player).addExcavationGather(8 * mcLoadProperties.xpGainMultiplier);
+    			if(Math.random() * 10 > 5){
+    				mat = Material.getMaterial(39);
+    			} else {
+    				mat = Material.getMaterial(40);
+    			}
 				is = new ItemStack(mat, 1, (byte)0, (byte)0);
 				loc.getWorld().dropItemNaturally(loc, is);
     		}
-    	}
-    	//GRASS OR DIRT
-    	if((type == 2 || type == 3) && mcUsers.getProfile(player).getExcavationInt() > 25){
     		//CHANCE TO GET GLOWSTONE
-    		if(mcLoadProperties.glowstone == true && Math.random() * 100 > 95){
-    			mcUsers.getProfile(player).addExcavationGather(5);
+    		if(mcLoadProperties.glowstone == true && mcUsers.getProfile(player).getExcavationInt() > 25 && Math.random() * 100 > 95){
+    			mcUsers.getProfile(player).addExcavationGather(8 * mcLoadProperties.xpGainMultiplier);
     			mat = Material.getMaterial(348);
 				is = new ItemStack(mat, 1, (byte)0, (byte)0);
 				loc.getWorld().dropItemNaturally(loc, is);
@@ -120,38 +172,30 @@ public class mcExcavation {
     	if(type == 13){
     		//CHANCE TO GET NETHERRACK
     		if(mcLoadProperties.netherrack == true && mcUsers.getProfile(player).getExcavationInt() > 850 && Math.random() * 200 > 199){
-    			mcUsers.getProfile(player).addExcavationGather(3);
+    			mcUsers.getProfile(player).addExcavationGather(3 * mcLoadProperties.xpGainMultiplier);
 				mat = Material.getMaterial(87);
 				is = new ItemStack(mat, 1, (byte)0, (byte)0);
 				loc.getWorld().dropItemNaturally(loc, is);
     		}
     		//CHANCE TO GET SULPHUR
     		if(mcLoadProperties.sulphur == true && mcUsers.getProfile(player).getExcavationInt() > 75){
-    		if(Math.random() * 10 > 9){
-    			mcUsers.getProfile(player).addExcavationGather(3);
-    			mat = Material.getMaterial(289);
-				is = new ItemStack(mat, 1, (byte)0, (byte)0);
-				loc.getWorld().dropItemNaturally(loc, is);
-    		}
+	    		if(Math.random() * 10 > 9){
+	    			mcUsers.getProfile(player).addExcavationGather(3 * mcLoadProperties.xpGainMultiplier);
+	    			mat = Material.getMaterial(289);
+					is = new ItemStack(mat, 1, (byte)0, (byte)0);
+					loc.getWorld().dropItemNaturally(loc, is);
+	    		}
     		}
     		//CHANCE TO GET BONES
     		if(mcLoadProperties.bones == true && mcUsers.getProfile(player).getExcavationInt() > 175){
-        		if(Math.random() * 10 > 6){
-        			mcUsers.getProfile(player).addExcavationGather(3);
+        		if(Math.random() * 10 > 9){
+        			mcUsers.getProfile(player).addExcavationGather(3 * mcLoadProperties.xpGainMultiplier);
         			mat = Material.getMaterial(352);
     				is = new ItemStack(mat, 1, (byte)0, (byte)0);
     				loc.getWorld().dropItemNaturally(loc, is);
         		}
-        		}
+        	}
     	}
-    	if(mcUsers.getProfile(player).getExcavationGatherInt() >= mcUsers.getProfile(player).getXpToLevel("excavation")){
-			int skillups = 0;
-			while(mcUsers.getProfile(player).getExcavationGatherInt() >= mcUsers.getProfile(player).getXpToLevel("excavation")){
-				skillups++;
-				mcUsers.getProfile(player).removeExcavationGather(mcUsers.getProfile(player).getXpToLevel("excavation"));
-				mcUsers.getProfile(player).skillUpExcavation(1);
-			}
-			player.sendMessage(ChatColor.YELLOW+"Excavation skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getExcavation()+")");	
-		}
+    	mcSkills.getInstance().XpCheck(player);
     }
 }

+ 32 - 33
mcMMO/com/gmail/nossr50/mcHerbalism.java

@@ -24,49 +24,48 @@ public class mcHerbalism {
     	Location loc = block.getLocation();
     	ItemStack is = null;
     	Material mat = null;
-    	//player.sendMessage("mcMMO DEBUG: Data ("+block.getData()+")"+" TYPEID ("+block.getTypeId()+")");
+    	
+    	if(mcConfig.getInstance().isBlockWatched(block)){
+    		return;
+    	}
     	if(type == 59 && block.getData() == (byte) 0x7){
     		mat = Material.getMaterial(296);
 			is = new ItemStack(mat, 1, (byte)0, (byte)0);
-    		mcUsers.getProfile(player).addHerbalismGather(5);
-    		if(mcUsers.getProfile(player).getHerbalismInt() >= 50 && mcUsers.getProfile(player).getHerbalismInt() < 150){
-    		if(Math.random() * 10 > 8)
-			loc.getWorld().dropItemNaturally(loc, is);
-    		}
-    		if(mcUsers.getProfile(player).getHerbalismInt() >= 150 && mcUsers.getProfile(player).getHerbalismInt() < 350 ){
-    			if(Math.random() * 10 > 6)
-    				loc.getWorld().dropItemNaturally(loc, is);
-    		}
-    		if(mcUsers.getProfile(player).getHerbalismInt() >= 350 && mcUsers.getProfile(player).getHerbalismInt() < 500 ){
-    			if(Math.random() * 10 > 4)
-    				loc.getWorld().dropItemNaturally(loc, is);
-    		}
-    		if(mcUsers.getProfile(player).getHerbalismInt() >= 500 && mcUsers.getProfile(player).getHerbalismInt() < 750 ){
-    			if(Math.random() * 10 > 2)
-    				loc.getWorld().dropItemNaturally(loc, is);
+    		mcUsers.getProfile(player).addHerbalismGather(5 * mcLoadProperties.xpGainMultiplier);
+    		if(player != null){
+	    		if(Math.random() * 1000 <= mcUsers.getProfile(player).getHerbalismInt()){
+	    			loc.getWorld().dropItemNaturally(loc, is);
+	    		}
     		}
     	}
     	/*
     	 * We need to check not-wheat stuff for if it was placed by the player or not
     	 */
     	if(!mcConfig.getInstance().isBlockWatched(block)){
-    		//player.sendMessage("DEBUG CODE 2");
-    	if(type == 39 || type == 40){
-    			mcUsers.getProfile(player).addHerbalismGather(10);
-    		}
-    	if(type == 37 || type == 38){
-    			mcUsers.getProfile(player).addHerbalismGather(3);
-    	}
+    		//Mushroom
+	    	if(type == 39 || type == 40){
+	    		mat = Material.getMaterial(block.getTypeId());
+				is = new ItemStack(mat, 1, (byte)0, (byte)0);
+	    		if(player != null){
+		    		if(Math.random() * 1000 <= mcUsers.getProfile(player).getHerbalismInt()){
+		    			loc.getWorld().dropItemNaturally(loc, is);
+		    		}
+	    		}
+	    		mcUsers.getProfile(player).addHerbalismGather(40 * mcLoadProperties.xpGainMultiplier);
+	    	}
+	    	//Flower
+	    	if(type == 37 || type == 38){
+	    		mat = Material.getMaterial(block.getTypeId());
+				is = new ItemStack(mat, 1, (byte)0, (byte)0);
+	    		if(player != null){
+		    		if(Math.random() * 1000 <= mcUsers.getProfile(player).getHerbalismInt()){
+		    			loc.getWorld().dropItemNaturally(loc, is);
+		    		}
+	    		}
+	    		mcUsers.getProfile(player).addHerbalismGather(10 * mcLoadProperties.xpGainMultiplier);
+	    	}
     	}
-    	if(mcUsers.getProfile(player).getHerbalismGatherInt() >= mcUsers.getProfile(player).getXpToLevel("herbalism")){
-			int skillups = 0;
-			while(mcUsers.getProfile(player).getHerbalismGatherInt() >= mcUsers.getProfile(player).getXpToLevel("herbalism")){
-				skillups++;
-				mcUsers.getProfile(player).removeHerbalismGather(mcUsers.getProfile(player).getXpToLevel("herbalism"));
-				mcUsers.getProfile(player).skillUpHerbalism(1);
-			}
-			player.sendMessage(ChatColor.YELLOW+"Herbalism skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getHerbalism()+")");	
-		}
+    	mcSkills.getInstance().XpCheck(player);
     }
 	public void breadCheck(Player player, ItemStack is){
     	if(is.getTypeId() == 297){

+ 54 - 27
mcMMO/com/gmail/nossr50/mcLoadProperties.java

@@ -1,55 +1,82 @@
 package com.gmail.nossr50;
 
 public class mcLoadProperties {
-	public static Boolean pvp, eggs, apples, myspawnclearsinventory, cake, music, diamond, glowstone, slowsand, sulphur, netherrack, bones, coal, clay, anvilmessages;
-	public static String mcmmo, mcc, mcgod, stats, mmoedit, ptp, party, myspawn, setmyspawn, whois, invite, accept, clearmyspawn;
-	public static int globalxpmodifier, miningxpmodifier, repairxpmodifier, woodcuttingxpmodifier, unarmedxpmodifier, herbalismxpmodifier, excavationxpmodifier, archeryxpmodifier, swordsxpmodifier, axesxpmodifier, acrobaticsxpmodifier;
+	public static Boolean mushrooms, toolsLoseDurabilityFromAbilities, pvpxp, miningrequirespickaxe, woodcuttingrequiresaxe, pvp, eggs, apples, myspawnclearsinventory, cake, music, diamond, glowstone, slowsand, sulphur, netherrack, bones, coal, clay, anvilmessages;
+	public static String addxp, mcability, mcmmo, mcc, mcrefresh, mcitem, mcgod, stats, mmoedit, ptp, party, myspawn, setmyspawn, whois, invite, accept, clearmyspawn;
+	public static int xpGainMultiplier, superBreakerCooldown, gigaDrillBreakerCooldown, treeFellerCooldown, berserkCooldown, serratedStrikeCooldown, skullSplitterCooldown, abilityDurabilityLoss, feathersConsumedByChimaeraWing, pvpxprewardmodifier, repairdiamondlevel, globalxpmodifier, miningxpmodifier, repairxpmodifier, woodcuttingxpmodifier, unarmedxpmodifier, herbalismxpmodifier, excavationxpmodifier, archeryxpmodifier, swordsxpmodifier, axesxpmodifier, acrobaticsxpmodifier;
 	
 	public static void loadMain(){
     	String propertiesFile = mcMMO.maindirectory + "mcmmo.properties";
     	mcProperties properties = new mcProperties(propertiesFile);
     	properties.load();
     	
+    	/*
+    	 * COOLDOWN CONTROL
+    	 */
+    	superBreakerCooldown = properties.getInteger("superBreakerCooldown", 240);
+    	gigaDrillBreakerCooldown = properties.getInteger("gigaDrillBreakerCooldown", 240);
+    	treeFellerCooldown = properties.getInteger("treeFellerCooldown", 240);
+    	berserkCooldown = properties.getInteger("berserkCooldown", 240);
+    	serratedStrikeCooldown = properties.getInteger("serratedStrikeCooldown", 240);
+    	skullSplitterCooldown = properties.getInteger("skullSplitterCooldown", 240);
+    	/*
+    	 * OTHER
+    	 */
+    	myspawnclearsinventory = properties.getBoolean("mySpawnClearsInventory", true);
+    	xpGainMultiplier = properties.getInteger("xpGainMultiplier", 1);
+    	toolsLoseDurabilityFromAbilities = properties.getBoolean("toolsLoseDurabilityFromAbilities", true);
+    	abilityDurabilityLoss = properties.getInteger("abilityDurabilityLoss", 2);
+    	feathersConsumedByChimaeraWing = properties.getInteger("feathersConsumedByChimaeraWing", 10);
+    	pvpxp = properties.getBoolean("pvpGivesXP", true);
+    	pvpxprewardmodifier = properties.getInteger("pvpXpRewardModifier", 1);
+    	miningrequirespickaxe = properties.getBoolean("miningRequiresPickaxe", true);
+    	woodcuttingrequiresaxe = properties.getBoolean("woodcuttingRequiresAxe", true);
+    	repairdiamondlevel = properties.getInteger("repairDiamondLevel", 50);
     	/*
     	 * EXPERIENCE RATE MODIFIER
     	 */
-    	globalxpmodifier = properties.getInteger("globalxpmodifier", 1);
-    	miningxpmodifier = properties.getInteger("miningxpmodifier", 2);
-    	repairxpmodifier = properties.getInteger("repairxpmodifier", 2);
-    	woodcuttingxpmodifier = properties.getInteger("woodcuttingxpmodifier", 2);
-    	unarmedxpmodifier = properties.getInteger("unarmedxpmodifier", 2);
-    	herbalismxpmodifier = properties.getInteger("herbalismxpmodifier", 2);
-    	excavationxpmodifier = properties.getInteger("excavationxpmodifier", 2);
-    	archeryxpmodifier = properties.getInteger("archeryxpmodifier", 2);
-    	swordsxpmodifier = properties.getInteger("swordsxpmodifier", 2);
-    	axesxpmodifier = properties.getInteger("axesxpmodifier", 2);
-    	acrobaticsxpmodifier = properties.getInteger("acrobaticsxpmodifier", 2);
+    	globalxpmodifier = properties.getInteger("globalXpModifier", 1);
+    	miningxpmodifier = properties.getInteger("miningXpModifier", 2);
+    	repairxpmodifier = properties.getInteger("repairXpModifier", 2);
+    	woodcuttingxpmodifier = properties.getInteger("woodcuttingXpModifier", 2);
+    	unarmedxpmodifier = properties.getInteger("unarmedXpModifier", 2);
+    	herbalismxpmodifier = properties.getInteger("herbalismXpModifier", 2);
+    	excavationxpmodifier = properties.getInteger("excavationXpModifier", 2);
+    	archeryxpmodifier = properties.getInteger("archeryXpModifier", 2);
+    	swordsxpmodifier = properties.getInteger("swordsXpModifier", 2);
+    	axesxpmodifier = properties.getInteger("axesXpModifier", 2);
+    	acrobaticsxpmodifier = properties.getInteger("acrobaticsXpModifier", 2);
     	/*
     	 * TOGGLE CLAY
     	 */
-    	clay = properties.getBoolean("graveltoclay", true);
+    	clay = properties.getBoolean("gravelToClay", true);
     	/*
     	 * ANVIL MESSAGES
     	 */
-    	anvilmessages = properties.getBoolean("anvilmessages", true);
+    	anvilmessages = properties.getBoolean("anvilMessages", true);
     	/*
     	 * EXCAVATION LOOT TOGGLES
     	 */
-    	myspawnclearsinventory = properties.getBoolean("myspawnclearsinventory", true);
-    	glowstone = properties.getBoolean("canexcavateglowstone", true);
+    	mushrooms = properties.getBoolean("canExcavateMushrooms", true);
+    	glowstone = properties.getBoolean("canExcavateGlowstone", true);
     	pvp = properties.getBoolean("pvp", true);
-    	eggs = properties.getBoolean("canexcavateeggs", true);
-    	apples = properties.getBoolean("canexcavateapples", true);
-    	cake = properties.getBoolean("canexcavatecake", true);
-    	music = properties.getBoolean("canexcavatemusic", true);
-    	diamond = properties.getBoolean("canexcavatediamond", true);
-    	slowsand = properties.getBoolean("canexcavateslowsand", true);
-    	sulphur = properties.getBoolean("canexcavatesulphur", true);
-    	netherrack = properties.getBoolean("canexcavatenetherrack", true);
-    	bones = properties.getBoolean("canexcavatebones", true);
+    	eggs = properties.getBoolean("canExcavateEggs", true);
+    	apples = properties.getBoolean("canExcavateApples", true);
+    	cake = properties.getBoolean("canExcavateCake", true);
+    	music = properties.getBoolean("canExcavateMusic", true);
+    	diamond = properties.getBoolean("canExcavateDiamond", true);
+    	slowsand = properties.getBoolean("canExcavateSlowSand", true);
+    	sulphur = properties.getBoolean("canExcavateSulphur", true);
+    	netherrack = properties.getBoolean("canExcavateNetherrack", true);
+    	bones = properties.getBoolean("canExcavateBones", true);
+    	
     	/*
     	 * CUSTOM COMMANDS
     	 */
+    	addxp = properties.getString("/addxp", "addxp");
+    	mcability = properties.getString("/mcability", "mcability");
+    	mcrefresh = properties.getString("/mcrefresh", "mcrefresh");
+    	mcitem = properties.getString("/mcitem", "mcitem");
     	mcmmo = properties.getString("/mcmmo", "mcmmo");
     	mcc = properties.getString("/mcc", "mcc");
     	mcgod = properties.getString("/mcgod", "mcgod");

+ 25 - 10
mcMMO/com/gmail/nossr50/mcMMO.java

@@ -18,7 +18,7 @@ import org.bukkit.entity.Player;
 
 
 public class mcMMO extends JavaPlugin {
-	static String maindirectory = "mcMMO/";
+	static String maindirectory = "plugins/mcMMO/";
 	static File Properties = new File(maindirectory + "mcmmo.properties");
     public static final Logger log = Logger.getLogger("Minecraft");
     private final mcPlayerListener playerListener = new mcPlayerListener(this);
@@ -30,9 +30,8 @@ public class mcMMO extends JavaPlugin {
     private Permissions permissions;
     private Timer mcMMO_Timer = new Timer(true);
     
-    //herp
     public void onEnable() {
-    	//mcMMO_Timer.schedule(new mcTimer(this), 0, (long)(2000));
+    	mcMMO_Timer.schedule(new mcTimer(this), 0, (long)(1000));
     	//Make the directory if it does not exist
     	new File(maindirectory).mkdir();
     	//Make the file if it does not exist
@@ -61,19 +60,24 @@ public class mcMMO extends JavaPlugin {
     	//Load the file
     	mcLoadProperties.loadMain();
     	mcUsers.getInstance().loadUsers();
+    	for(Player player : getServer().getOnlinePlayers()){
+         	mcUsers.addUser(player);
+        }
         PluginManager pm = getServer().getPluginManager();
         pm.registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal, this);
         pm.registerEvent(Event.Type.PLAYER_LOGIN, playerListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.BLOCK_DAMAGED, blockListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Monitor, this);
-        pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, playerListener, Priority.High, this);
+        pm.registerEvent(Event.Type.BLOCK_DAMAGE, blockListener, Priority.Highest, this);
+        pm.registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Lowest, this);
+        pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, playerListener, Priority.Normal, this);
         pm.registerEvent(Event.Type.ENTITY_DEATH, entityListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.BLOCK_FLOW, blockListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.BLOCK_PLACED, blockListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.PLAYER_ITEM, playerListener, Priority.Monitor, this);
+        pm.registerEvent(Event.Type.BLOCK_BREAK, blockListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.BLOCK_FROMTO, blockListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.BLOCK_PLACE, blockListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.PLAYER_INTERACT, playerListener, Priority.Monitor, this);
         pm.registerEvent(Event.Type.PLAYER_RESPAWN, playerListener, Priority.Normal, this);
         pm.registerEvent(Event.Type.PLAYER_ITEM_HELD, playerListener, Priority.Normal, this);
-        pm.registerEvent(Event.Type.ENTITY_DAMAGED, entityListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.ENTITY_DAMAGE, entityListener, Priority.Highest, this);
+        
         //pm.registerEvent(Event.Type.CREATURE_SPAWN, entityListener, Priority.Normal, this);
         //Displays a message when plugin is loaded
         PluginDescriptionFile pdfFile = this.getDescription();
@@ -98,6 +102,17 @@ public class mcMMO extends JavaPlugin {
     		return false;
     	}
     }
+    public boolean inSameParty(Player playera, Player playerb){
+    	if(mcUsers.getProfile(playera).inParty() && mcUsers.getProfile(playerb).inParty()){
+	        if(mcUsers.getProfile(playera).getParty().equals(mcUsers.getProfile(playerb).getParty())){
+	            return true;
+	        } else {
+	            return false;
+	        }
+    	} else {
+    		return false;
+    	}
+    }
     public boolean isAdminChatToggled(Player player){
     	if(mcConfig.getInstance().isAdminToggled(player.getName())){
     		return true;

+ 247 - 85
mcMMO/com/gmail/nossr50/mcMining.java

@@ -19,14 +19,54 @@ public class mcMining {
     	}
     	return instance;
     	}
+	public void superBreakerCheck(Player player, Block block){
+	    if(mcm.getInstance().isMiningPick(player.getItemInHand())){
+	    	if(block != null){
+		    	if(!mcm.getInstance().abilityBlockCheck(block))
+		    		return;
+	    	}
+	    	if(mcUsers.getProfile(player).getPickaxePreparationMode()){
+    			mcUsers.getProfile(player).setPickaxePreparationMode(false);
+    			mcUsers.getProfile(player).setPickaxePreparationTicks(0);
+    		}
+	    	int ticks = 2;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 750)
+    			ticks++;
+    		
+	    	if(!mcUsers.getProfile(player).getSuperBreakerMode() && mcUsers.getProfile(player).getSuperBreakerCooldown() == 0){
+	    		player.sendMessage(ChatColor.GREEN+"**SUPER BREAKER ACTIVATED**");
+	    		mcUsers.getProfile(player).setSuperBreakerTicks(ticks * 2);
+	    		mcUsers.getProfile(player).setSuperBreakerMode(true);
+	    	}
+	    	
+	    }
+	}
 	public void blockProcSimulate(Block block){
     	Location loc = block.getLocation();
     	Material mat = Material.getMaterial(block.getTypeId());
 		byte damage = 0;
 		ItemStack item = new ItemStack(mat, 1, (byte)0, damage);
-		if(block.getTypeId() != 73 && block.getTypeId() != 74 && block.getTypeId() != 56 && block.getTypeId() != 21 && block.getTypeId() != 1 && block.getTypeId() != 16)
-		loc.getWorld().dropItemNaturally(loc, item);
-		//hurrdurr
+		if(block.getTypeId() != 89 && block.getTypeId() != 73 && block.getTypeId() != 74 && block.getTypeId() != 56 && block.getTypeId() != 21 && block.getTypeId() != 1 && block.getTypeId() != 16)
+			loc.getWorld().dropItemNaturally(loc, item);
+		if(block.getTypeId() == 89){
+			mat = Material.getMaterial(348);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+		}
 		if(block.getTypeId() == 73 || block.getTypeId() == 74){
 			mat = Material.getMaterial(331);
 			item = new ItemStack(mat, 1, (byte)0, damage);
@@ -37,104 +77,226 @@ public class mcMining {
 				loc.getWorld().dropItemNaturally(loc, item);
 			}
 		}
-			if(block.getTypeId() == 21){
-				mat = Material.getMaterial(351);
-				item = new ItemStack(mat, 1, (byte)0,(byte)0x4);
-				loc.getWorld().dropItemNaturally(loc, item);
-				loc.getWorld().dropItemNaturally(loc, item);
-				loc.getWorld().dropItemNaturally(loc, item);
-				loc.getWorld().dropItemNaturally(loc, item);
-			}
-			if(block.getTypeId() == 56){
-				mat = Material.getMaterial(264);
-				item = new ItemStack(mat, 1, (byte)0, damage);
-				loc.getWorld().dropItemNaturally(loc, item);
-			}
-			if(block.getTypeId() == 1){
-				mat = Material.getMaterial(4);
-				item = new ItemStack(mat, 1, (byte)0, damage);
-				loc.getWorld().dropItemNaturally(loc, item);
-			}
-			if(block.getTypeId() == 16){
-				mat = Material.getMaterial(263);
-				item = new ItemStack(mat, 1, (byte)0, damage);
-				loc.getWorld().dropItemNaturally(loc, item);
-			}
+		if(block.getTypeId() == 21){
+			mat = Material.getMaterial(351);
+			item = new ItemStack(mat, 1, (byte)0,(byte)0x4);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+		}
+		if(block.getTypeId() == 56){
+			mat = Material.getMaterial(264);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+		}
+		if(block.getTypeId() == 1){
+			mat = Material.getMaterial(4);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+		}
+		if(block.getTypeId() == 16){
+			mat = Material.getMaterial(263);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+		}
     }
     public void blockProcCheck(Block block, Player player){
-    	if(mcUsers.getProfile(player).getMiningInt() > 2000){
-    		blockProcSimulate(block);
-			return;
-    	}
-    	if(mcUsers.getProfile(player).getMiningInt() > 1250){
-    		if((Math.random() * 10) > 2){
-    		blockProcSimulate(block);
-    		return;
-    		}
-    	}
-    	if(mcUsers.getProfile(player).getMiningInt() > 750){
-    		if((Math.random() * 10) > 4){
-    		blockProcSimulate(block);
-			return;
-    		}
-    	}
-    	if(mcUsers.getProfile(player).getMiningInt() > 150){
-    		if((Math.random() * 10) > 6){
-    		blockProcSimulate(block);
-			return;
-    		}
-    	}
-    	if(mcUsers.getProfile(player).getMiningInt() > 25){
-    		if((Math.random() * 10) > 8){
+    	if(player != null){
+    		if(Math.random() * 1000 <= mcUsers.getProfile(player).getMiningInt()){
     		blockProcSimulate(block);
 			return;
     		}
     	}		
 	}
     public void miningBlockCheck(Player player, Block block){
-    	if(block.getTypeId() == 1){
-    		mcUsers.getProfile(player).addMiningGather(1);
+    	if(mcConfig.getInstance().isBlockWatched(block))
+    		return;
+    	int xp = 0;
+    	if(block.getTypeId() == 1 || block.getTypeId() == 24){
+    		xp += 3;
     		blockProcCheck(block, player);
-    		}
-    		//COAL
-    		if(block.getTypeId() == 16){
-    		mcUsers.getProfile(player).addMiningGather(5);
+    	}
+    	//NETHERRACK
+    	if(block.getTypeId() == 87){
+    		xp += 3;
     		blockProcCheck(block, player);
-    		}
-    		//GOLD
-    		if(block.getTypeId() == 14){
-    		mcUsers.getProfile(player).addMiningGather(35);
+    	}
+    	//GLOWSTONE
+    	if(block.getTypeId() == 89){
+    		xp += 3;
     		blockProcCheck(block, player);
-    		}
-    		//DIAMOND
-    		if(block.getTypeId() == 56){
-    		mcUsers.getProfile(player).addMiningGather(75);
+    	}
+    	//COAL
+    	if(block.getTypeId() == 16){
+    		xp += 10;
     		blockProcCheck(block, player);
-    		}
-    		//IRON
-    		if(block.getTypeId() == 15){
-    		mcUsers.getProfile(player).addMiningGather(20);
+    	}
+    	//GOLD
+    	if(block.getTypeId() == 14){
+    		xp += 35;
     		blockProcCheck(block, player);
-    		}
-    		//REDSTONE
-    		if(block.getTypeId() == 73 || block.getTypeId() == 74){
-    		mcUsers.getProfile(player).addMiningGather(15);
+    	}
+    	//DIAMOND
+    	if(block.getTypeId() == 56){
+    		xp += 75;
     		blockProcCheck(block, player);
-    		}
-    		//LAPUS
-    		if(block.getTypeId() == 21){
-    		mcUsers.getProfile(player).addMiningGather(40);
+    	}
+    	//IRON
+    	if(block.getTypeId() == 15){
+    		xp += 25;
+    		blockProcCheck(block, player);
+    	}
+    	//REDSTONE
+    	if(block.getTypeId() == 73 || block.getTypeId() == 74){
+    		xp += 15;
+    		blockProcCheck(block, player);
+    	}
+    	//LAPUS
+    	if(block.getTypeId() == 21){
+    		xp += 40;
     		blockProcCheck(block, player);
+    	}
+    	mcUsers.getProfile(player).addMiningGather(xp * mcLoadProperties.xpGainMultiplier);
+    	mcSkills.getInstance().XpCheck(player);
+    }
+    /*
+     * Handling SuperBreaker stuff
+     */
+    public Boolean canBeSuperBroken(Block block){
+    	int t = block.getTypeId();
+    	if(t == 87 || t == 89 || t == 73 || t == 74 || t == 56 || t == 21 || t == 1 || t == 16 || t == 14 || t == 15){
+    		return true;
+    	} else {
+    		return false;
+    	}
+    }
+    public void SuperBreakerBlockCheck(Player player, Block block){
+    	if(mcLoadProperties.toolsLoseDurabilityFromAbilities)
+    		mcm.getInstance().damageTool(player, (short) mcLoadProperties.abilityDurabilityLoss);
+    	Location loc = block.getLocation();
+    	Material mat = Material.getMaterial(block.getTypeId());
+    	int xp = 0;
+		byte damage = 0;
+		ItemStack item = new ItemStack(mat, 1, (byte)0, damage);
+    	if(block.getTypeId() == 1 || block.getTypeId() == 24){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 3;
+    			blockProcCheck(block, player);
+    			blockProcCheck(block, player);
     		}
-    		if(player != null && mcUsers.getProfile(player).getMiningGatherInt() >= mcUsers.getProfile(player).getXpToLevel("mining")){
-    			int skillups = 0;
-    			while(mcUsers.getProfile(player).getMiningGatherInt() >= mcUsers.getProfile(player).getXpToLevel("mining")){
-    				skillups++;
-    				mcUsers.getProfile(player).removeMiningGather(mcUsers.getProfile(player).getXpToLevel("mining"));
-    				mcUsers.getProfile(player).skillUpMining(1);
-    			}
-    			player.sendMessage(ChatColor.YELLOW+"Mining skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getMining()+")");	
+    		if(block.getTypeId() == 1){
+    			mat = Material.COBBLESTONE;
+    		} else {
+    			mat = Material.SANDSTONE;
     		}
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//NETHERRACK
+    	if(block.getTypeId() == 87){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 3;
+    			blockProcCheck(block, player);
+    			blockProcCheck(block, player);
+    		}
+    		mat = Material.getMaterial(87);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//GLOWSTONE
+    	if(block.getTypeId() == 89){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 3;
+    			blockProcCheck(block, player);
+    			blockProcCheck(block, player);
+    		}
+    		mat = Material.getMaterial(348);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//COAL
+    	if(block.getTypeId() == 16){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 10;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        		}
+    		mat = Material.getMaterial(263);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//GOLD
+    	if(block.getTypeId() == 14 && mcm.getInstance().getTier(player) >= 3){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 35;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        		}
+    		item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//DIAMOND
+    	if(block.getTypeId() == 56 && mcm.getInstance().getTier(player) >= 3){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 75;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        	}
+    		mat = Material.getMaterial(264);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//IRON
+    	if(block.getTypeId() == 15 && mcm.getInstance().getTier(player) >= 2){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 25;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        	}
+    		item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	//REDSTONE
+    	if((block.getTypeId() == 73 || block.getTypeId() == 74) && mcm.getInstance().getTier(player) >= 4){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 15;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        	}
+    		mat = Material.getMaterial(331);
+			item = new ItemStack(mat, 1, (byte)0, damage);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			if(Math.random() * 10 > 5){
+				loc.getWorld().dropItemNaturally(loc, item);
+			}
+    		block.setType(Material.AIR);
+    	}
+    	//LAPUS
+    	if(block.getTypeId() == 21 && mcm.getInstance().getTier(player) >= 3){
+    		if(!mcConfig.getInstance().isBlockWatched(block)){
+    			xp += 40;
+        		blockProcCheck(block, player);
+        		blockProcCheck(block, player);
+        	}
+    		mat = Material.getMaterial(351);
+			item = new ItemStack(mat, 1, (byte)0,(byte)0x4);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+			loc.getWorld().dropItemNaturally(loc, item);
+    		block.setType(Material.AIR);
+    	}
+    	mcUsers.getProfile(player).addMiningGather(xp * mcLoadProperties.xpGainMultiplier);
+    	mcSkills.getInstance().XpCheck(player);
     }
-
 }

+ 13 - 5
mcMMO/com/gmail/nossr50/mcParty.java

@@ -16,11 +16,19 @@ public class mcParty {
     	return instance;
     	}
     public boolean inSameParty(Player playera, Player playerb){
-        if(mcUsers.getProfile(playera).getParty().equals(mcUsers.getProfile(playerb).getParty())){
-            return true;
-        } else {
-            return false;
-        }
+    	if(mcUsers.getProfile(playera) == null || mcUsers.getProfile(playerb) == null){
+    		mcUsers.addUser(playera);
+    		mcUsers.addUser(playerb);
+    	}
+    	if(mcUsers.getProfile(playera).inParty() && mcUsers.getProfile(playerb).inParty()){
+	        if(mcUsers.getProfile(playera).getParty().equals(mcUsers.getProfile(playerb).getParty())){
+	            return true;
+	        } else {
+	            return false;
+	        }
+    	} else {
+    		return false;
+    	}
     }
 	public int partyCount(Player player, Player[] players){
         int x = 0;

+ 64 - 1
mcMMO/com/gmail/nossr50/mcPermissions.java

@@ -30,6 +30,13 @@ public class mcPermissions {
     private boolean permission(Player player, String string) {
         return permissionsPlugin.Security.permission(player, string);  
     }
+    public boolean mcrefresh(Player player) {
+        if (permissionsEnabled) {
+            return permission(player, "mcmmo.tools.mcrefresh");
+        } else {
+            return true;
+        }
+    }
     public boolean mmoedit(Player player) {
         if (permissionsEnabled) {
             return permission(player, "mcmmo.tools.mmoedit");
@@ -37,7 +44,49 @@ public class mcPermissions {
             return true;
         }
     }
-    public boolean woodcuttingability(Player player) {
+    public boolean excavationAbility(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.ability.excavation");
+        } else {
+            return true;
+        }
+    }
+    public boolean unarmedAbility(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.ability.unarmed");
+        } else {
+            return true;
+        }
+    }
+    public boolean chimaeraWing(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.item.chimaerawing");
+        } else {
+            return true;
+        }
+    }
+    public boolean miningAbility(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.ability.mining");
+        } else {
+            return true;
+        }
+    }
+    public boolean axesAbility(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.ability.axes");
+        } else {
+            return true;
+        }
+    }
+    public boolean swordsAbility(Player player){
+    	if (permissionsEnabled) {
+            return permission(player, "mcmmo.ability.swords");
+        } else {
+            return true;
+        }
+    }
+    public boolean woodCuttingAbility(Player player) {
     	if (permissionsEnabled) {
             return permission(player, "mcmmo.ability.woodcutting");
         } else {
@@ -65,6 +114,13 @@ public class mcPermissions {
             return true;
         }
     }
+    public boolean mcAbility(Player player) {
+        if (permissionsEnabled) {
+            return permission(player, "mcmmo.commands.ability");
+        } else {
+            return true;
+        }
+    }
     public boolean mySpawn(Player player) {
         if (permissionsEnabled) {
             return permission(player, "mcmmo.commands.myspawn");
@@ -79,6 +135,13 @@ public class mcPermissions {
             return true;
         }
     }
+    public boolean setMySpawnOther(Player player) {
+        if (permissionsEnabled) {
+            return permission(player, "mcmmo.commands.setmyspawnother");
+        } else {
+            return true;
+        }
+    }
     public boolean partyChat(Player player) {
         if (permissionsEnabled) {
             return permission(player, "mcmmo.chat.partychat");

+ 149 - 25
mcMMO/com/gmail/nossr50/mcPlayerListener.java

@@ -5,11 +5,15 @@ import java.util.logging.Logger;
 
 import org.bukkit.ChatColor;
 import org.bukkit.Location;
+import org.bukkit.Material;
 import org.bukkit.block.Block;
 import org.bukkit.entity.Player;
+import org.bukkit.event.block.Action;
 import org.bukkit.event.player.PlayerChatEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
 import org.bukkit.event.player.PlayerEvent;
-import org.bukkit.event.player.PlayerItemEvent;
+import org.bukkit.event.player.PlayerInteractEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
 import org.bukkit.event.player.PlayerListener;
 import org.bukkit.event.player.PlayerLoginEvent;
 import org.bukkit.event.player.PlayerRespawnEvent;
@@ -57,35 +61,114 @@ public class mcPlayerListener extends PlayerListener {
     	Player player = event.getPlayer();
     	mcUsers.addUser(player);
     }
-    public void onPlayerJoin(PlayerEvent event) {
+    public void onPlayerJoin(PlayerJoinEvent event) {
     	Player player = event.getPlayer();
     	if(mcPermissions.getInstance().motd(player)){
-    	player.sendMessage(ChatColor.BLUE + "This server is running mcMMO "+plugin.getDescription().getVersion()+" type /"+ChatColor.YELLOW+mcLoadProperties.mcmmo+ChatColor.BLUE+ " for help.");
+    		player.sendMessage(ChatColor.BLUE + "This server is running mcMMO "+plugin.getDescription().getVersion()+" type /"+ChatColor.YELLOW+mcLoadProperties.mcmmo+ChatColor.BLUE+ " for help.");
     	}
     }
-    //Check if string is a player
-    
-    public void onPlayerItem(PlayerItemEvent event) {
-    	Block block = event.getBlockClicked();
+    public void onPlayerInteract(PlayerInteractEvent event) {
     	Player player = event.getPlayer();
-    	ItemStack is = player.getItemInHand();
-    	if(mcPermissions.getInstance().herbalism(player)){
-    	//BREADCHECK, CHECKS HERBALISM SKILL FOR BREAD HP MODIFIERS
-    	mcHerbalism.getInstance().breadCheck(player, is);
-    	//STEW, CHECKS HERBALISM SKILL FOR BREAD HP MODIFIERS
-    	mcHerbalism.getInstance().stewCheck(player, is);
+    	Action action = event.getAction();
+    	Block block = event.getClickedBlock();
+    	/*
+    	 * Ability checks
+    	 */
+    	if(action == Action.RIGHT_CLICK_BLOCK){
+    		ItemStack is = player.getItemInHand();
+        	if(block != null && player != null && mcPermissions.getInstance().repair(player) && event.getClickedBlock().getTypeId() == 42){
+            	mcRepair.getInstance().repairCheck(player, is, event.getClickedBlock());
+            }
+        	if(mcm.getInstance().abilityBlockCheck(block))
+	    	{
+	    		mcSkills.getInstance().abilityActivationCheck(player);
+	    	}
+    	}
+    	if(action == Action.RIGHT_CLICK_AIR){
+		    mcSkills.getInstance().abilityActivationCheck(player);
+		    
+		    /*
+        	 * HERBALISM MODIFIERS
+        	 */
+        	if(mcPermissions.getInstance().herbalism(player)){
+        		mcHerbalism.getInstance().breadCheck(player, player.getItemInHand());
+        		mcHerbalism.getInstance().stewCheck(player, player.getItemInHand());
+        	}
     	}
-    	if(block != null && player != null && mcPermissions.getInstance().repair(player) && block.getTypeId() == 42){
-    	//REPAIRCHECK, CHECKS TO MAKE SURE PLAYER IS RIGHT CLICKING AN ANVIL, PLAYER HAS ENOUGH RESOURCES, AND THE ITEM IS NOT AT FULL DURABILITY.
-    	mcRepair.getInstance().repairCheck(player, is, block);
+    	if(action == Action.RIGHT_CLICK_AIR || action == action.RIGHT_CLICK_BLOCK){
+    		/*
+        	 * ITEM INTERACTIONS
+        	 */
+        	mcItem.getInstance().itemChecks(player);
     	}
     }
-    public void onPlayerCommandPreprocess(PlayerChatEvent event){
+    public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
     	Player player = event.getPlayer();
     	String[] split = event.getMessage().split(" ");
     	String playerName = player.getName();
     	//Check if the command is an mcMMO related help command
     	mcm.getInstance().mcmmoHelpCheck(split, player, event);
+    	if(mcPermissions.permissionsEnabled && split[0].equalsIgnoreCase("/"+mcLoadProperties.mcability)){
+    		event.setCancelled(true);
+    		if(mcUsers.getProfile(player).getAbilityUse()){
+    			player.sendMessage("Ability use toggled off");
+    			mcUsers.getProfile(player).toggleAbilityUse();
+    		} else {
+    			player.sendMessage("Ability use toggled on");
+    			mcUsers.getProfile(player).toggleAbilityUse();
+    		}
+    	}
+		if(mcPermissions.getInstance().mcAbility(player) && split[0].equalsIgnoreCase("/"+mcLoadProperties.mcrefresh)){
+			event.setCancelled(true);
+    		if(!mcPermissions.getInstance().mcrefresh(player)){
+    			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
+    			return;
+    		}
+    		if(split.length >= 2 && isPlayer(split[1])){
+    			player.sendMessage("You have refreshed "+split[1]+"'s cooldowns!");
+    			player = getPlayer(split[1]);
+    		}
+			/*
+			 * AXE PREPARATION MODE
+			 */
+    		mcUsers.getProfile(player).setAxePreparationMode(false);
+    		mcUsers.getProfile(player).setAxePreparationTicks(0);
+    		/*
+    		 * GIGA DRILL BREAKER
+    		 */
+    		mcUsers.getProfile(player).setGigaDrillBreakerCooldown(0);
+    		mcUsers.getProfile(player).setGigaDrillBreakerMode(false);
+    		mcUsers.getProfile(player).setGigaDrillBreakerTicks(0);
+    		/*
+    		 * SERRATED STRIKE
+    		 */
+    		mcUsers.getProfile(player).setSerratedStrikesCooldown(0);
+    		mcUsers.getProfile(player).setSerratedStrikesMode(false);
+    		mcUsers.getProfile(player).setSerratedStrikesTicks(0);
+    		/*
+    		 * SUPER BREAKER
+    		 */
+    		mcUsers.getProfile(player).setSuperBreakerCooldown(0);
+    		mcUsers.getProfile(player).setSuperBreakerMode(false);
+    		mcUsers.getProfile(player).setSuperBreakerTicks(0);
+    		/*
+    		 * TREE FELLER
+    		 */
+    		mcUsers.getProfile(player).setTreeFellerCooldown(0);
+    		mcUsers.getProfile(player).setTreeFellerMode(false);
+    		mcUsers.getProfile(player).setTreeFellerTicks(0);
+    		/*
+    		 * BERSERK
+    		 */
+    		mcUsers.getProfile(player).setBerserkCooldown(0);
+    		mcUsers.getProfile(player).setBerserkMode(false);
+    		mcUsers.getProfile(player).setBerserkTicks(0);
+    		
+    		player.sendMessage(ChatColor.GREEN+"**ABILITIES REFRESHED!**");
+    	}
+    	if(split[0].equalsIgnoreCase("/"+mcLoadProperties.mcitem)){
+    		
+    	}
     	/*
     	 * GODMODE COMMAND
     	 */
@@ -113,6 +196,7 @@ public class mcPlayerListener extends PlayerListener {
     		player.sendMessage(ChatColor.DARK_AQUA+"Myspawn is now cleared.");
     	}
     	if(mcPermissions.permissionsEnabled && split[0].equalsIgnoreCase("/"+mcLoadProperties.mmoedit)){
+    		event.setCancelled(true);
     		if(!mcPermissions.getInstance().mmoedit(player)){
     			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
     			return;
@@ -135,9 +219,43 @@ public class mcPlayerListener extends PlayerListener {
     				player.sendMessage(ChatColor.RED+split[1]+" has been modified.");
     			}
     		} else {
-    			player.sendMessage(ChatColor.RED+"Usage is /mmoedit playername skillname newvalue");
+    			player.sendMessage(ChatColor.RED+"Usage is /"+mcLoadProperties.mmoedit+" playername skillname newvalue");
     		}
     	}
+    	/*
+    	 * ADD EXPERIENCE COMMAND
+    	 */
+    	if(mcPermissions.permissionsEnabled && split[0].equalsIgnoreCase("/"+mcLoadProperties.addxp)){
+    		event.setCancelled(true);
+    		if(!mcPermissions.getInstance().mmoedit(player)){
+    			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
+    			return;
+    		}
+    		if(split.length < 3){
+    			player.sendMessage(ChatColor.RED+"Usage is /"+mcLoadProperties.addxp+" playername skillname xp");
+    			return;
+    		}
+    		if(split.length == 4){
+    			if(isPlayer(split[1]) && mcm.getInstance().isInt(split[3]) && mcSkills.getInstance().isSkill(split[2])){
+    				int newvalue = Integer.valueOf(split[3]);
+    				mcUsers.getProfile(getPlayer(split[1])).addXpToSkill(newvalue, split[2]);
+    				getPlayer(split[1]).sendMessage(ChatColor.GREEN+"Experience granted!");
+    				player.sendMessage(ChatColor.RED+split[2]+" has been modified.");
+    				mcSkills.getInstance().XpCheck(getPlayer(split[1]));
+    			}
+    		}
+    		else if(split.length == 3){
+    			if(mcm.getInstance().isInt(split[2]) && mcSkills.getInstance().isSkill(split[1])){
+    				int newvalue = Integer.valueOf(split[2]);
+    				mcUsers.getProfile(player).addXpToSkill(newvalue, split[1]);
+    				player.sendMessage(ChatColor.RED+split[1]+" has been modified.");
+    				mcSkills.getInstance().XpCheck(player);
+    			}
+    		} else {
+    			player.sendMessage(ChatColor.RED+"Usage is /"+mcLoadProperties.addxp+" playername skillname xp");
+    		}
+    	}
+    	
     	if(mcUsers.getProfile(player).inParty() && split[0].equalsIgnoreCase("/"+mcLoadProperties.ptp)){
     		event.setCancelled(true);
     		if(!mcPermissions.getInstance().partyTeleport(player)){
@@ -245,17 +363,21 @@ public class mcPlayerListener extends PlayerListener {
     	 * SETMYSPAWN COMMAND
     	 */
     	if(split[0].equalsIgnoreCase("/"+mcLoadProperties.setmyspawn)){
+    		event.setCancelled(true);
     		if(!mcPermissions.getInstance().setMySpawn(player)){
     			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
     			return;
     		}
-    		event.setCancelled(true);
+    		if((mcPermissions.getInstance().setMySpawnOther(player) || player.isOp()) && split.length >= 2 && isPlayer(split[1])){
+    			player.sendMessage("You have set "+split[1]+"'s spawn!");
+    			player = getPlayer(split[1]);
+    		}
     		double x = player.getLocation().getX();
     		double y = player.getLocation().getY();
     		double z = player.getLocation().getZ();
     		String myspawnworld = player.getWorld().getName();
     		mcUsers.getProfile(player).setMySpawn(x, y, z, myspawnworld);
-    		player.sendMessage(ChatColor.DARK_AQUA + "Myspawn has been set to your current location.");
+    		player.sendMessage(ChatColor.DARK_AQUA + "Myspawn has been set.");
     	}
     	/*
     	 * STATS COMMAND
@@ -264,7 +386,7 @@ public class mcPlayerListener extends PlayerListener {
     		event.setCancelled(true);
     		player.sendMessage(ChatColor.GREEN + "Your mcMMO Stats");
     		if(mcPermissions.getInstance().permissionsEnabled)
-    		player.sendMessage(ChatColor.DARK_GRAY+"If you don't have access to a skill it will not be shown here.");
+    			player.sendMessage(ChatColor.DARK_GRAY+"If you don't have access to a skill it will not be shown here.");
     		if(mcPermissions.getInstance().mining(player))
     		player.sendMessage(ChatColor.YELLOW + "Mining Skill: " + ChatColor.GREEN + mcUsers.getProfile(player).getMining()+ChatColor.DARK_AQUA 
     				+ " XP("+mcUsers.getProfile(player).getMiningGather()
@@ -320,6 +442,7 @@ public class mcPlayerListener extends PlayerListener {
     	}
     	//Invite Command
     	if(mcPermissions.getInstance().party(player) && split[0].equalsIgnoreCase("/"+mcLoadProperties.invite)){
+    		event.setCancelled(true);
     		if(!mcUsers.getProfile(player).inParty()){
     			player.sendMessage(ChatColor.RED+"You are not in a party.");
     			return;
@@ -332,12 +455,13 @@ public class mcPlayerListener extends PlayerListener {
     			Player target = getPlayer(split[1]);
     			mcUsers.getProfile(target).modifyInvite(mcUsers.getProfile(player).getParty());
     			player.sendMessage(ChatColor.GREEN+"Invite sent successfully");
-    			target.sendMessage(ChatColor.RED+"ALERT: "+ChatColor.GREEN+"You have received a party invite for "+mcUsers.getProfile(target).getInvite());
+    			target.sendMessage(ChatColor.RED+"ALERT: "+ChatColor.GREEN+"You have received a party invite for "+mcUsers.getProfile(target).getInvite()+" from "+player.getName());
     			target.sendMessage(ChatColor.YELLOW+"Type "+ChatColor.GREEN+"/"+mcLoadProperties.accept+ChatColor.YELLOW+" to accept the invite");
     		}
     	}
     	//Accept invite
     	if(mcPermissions.getInstance().party(player) && split[0].equalsIgnoreCase("/"+mcLoadProperties.accept)){
+    		event.setCancelled(true);
     		if(mcUsers.getProfile(player).hasPartyInvite()){
     			if(mcUsers.getProfile(player).inParty()){
     				mcParty.getInstance().informPartyMembersQuit(player, getPlayersOnline());
@@ -351,11 +475,11 @@ public class mcPlayerListener extends PlayerListener {
     	}
     	//Party command
     	if(split[0].equalsIgnoreCase("/"+mcLoadProperties.party)){
+    		event.setCancelled(true);
     		if(!mcPermissions.getInstance().party(player)){
     			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
     			return;
     		}
-    		event.setCancelled(true);
     		if(split.length == 1 && !mcUsers.getProfile(player).inParty()){
     			player.sendMessage("Proper usage is "+"/"+mcLoadProperties.party+" <name> or 'q' to quit");
     			return;
@@ -394,11 +518,11 @@ public class mcPlayerListener extends PlayerListener {
 	    		}
     	}
     	if(split[0].equalsIgnoreCase("/p")){
+    		event.setCancelled(true);
     		if(!mcPermissions.getInstance().party(player)){
     			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
     			return;
     		}
-    		event.setCancelled(true);
     		if(mcConfig.getInstance().isAdminToggled(player.getName()))
     		mcConfig.getInstance().toggleAdminChat(playerName);
     		mcConfig.getInstance().togglePartyChat(playerName);
@@ -427,11 +551,11 @@ public class mcPlayerListener extends PlayerListener {
     	 * MYSPAWN
     	 */
     	if(split[0].equalsIgnoreCase("/"+mcLoadProperties.myspawn)){
+    		event.setCancelled(true);
     		if(!mcPermissions.getInstance().mySpawn(player)){
     			player.sendMessage(ChatColor.YELLOW+"[mcMMO]"+ChatColor.DARK_RED +" Insufficient permissions.");
     			return;
     		}
-    		event.setCancelled(true);
     		if(mcUsers.getProfile(player).getMySpawn(player) != null){
     		if(mcLoadProperties.myspawnclearsinventory)
     		player.getInventory().clear();

+ 90 - 75
mcMMO/com/gmail/nossr50/mcRepair.java

@@ -28,22 +28,22 @@ public class mcRepair {
         			/*
         			 * DIAMOND ARMOR
         			 */
-        			if(isDiamondArmor(is) && hasDiamond(player) && mcUsers.getProfile(player).getRepairInt() >= 50){
+        			if(isDiamondArmor(is) && hasDiamond(player) && mcUsers.getProfile(player).getRepairInt() >= mcLoadProperties.repairdiamondlevel){
 	        			removeDiamond(player);
 	        			player.getItemInHand().setDurability(getArmorRepairAmount(is, player));
-	        			mcUsers.getProfile(player).addRepairGather(75);
+	        			mcUsers.getProfile(player).addRepairGather(75 * mcLoadProperties.xpGainMultiplier);
         			} else if (isIronArmor(is) && hasIron(player)){
         			/*
         			 * IRON ARMOR
         			 */
 	        			removeIron(player);
 	            		player.getItemInHand().setDurability(getArmorRepairAmount(is, player));
-	            		mcUsers.getProfile(player).addRepairGather(20);
+	            		mcUsers.getProfile(player).addRepairGather(20 * mcLoadProperties.xpGainMultiplier);
 	            	//GOLD ARMOR
         			} else if (isGoldArmor(is) && hasGold(player)){
         				removeGold(player);
         				player.getItemInHand().setDurability(getArmorRepairAmount(is, player));
-        				mcUsers.getProfile(player).addRepairGather(50);
+        				mcUsers.getProfile(player).addRepairGather(50 * mcLoadProperties.xpGainMultiplier);
         			} else {
         				needMoreVespeneGas(is, player);
         			}
@@ -58,18 +58,18 @@ public class mcRepair {
             		if(isIronTools(is) && hasIron(player)){
             			is.setDurability(getToolRepairAmount(is, player));
             			removeIron(player);
-            			mcUsers.getProfile(player).addRepairGather(20);
-            		} else if (isDiamondTools(is) && hasDiamond(player) && mcUsers.getProfile(player).getRepairInt() >= 50){ //Check if its diamond and the player has diamonds
+            			mcUsers.getProfile(player).addRepairGather(20 * mcLoadProperties.xpGainMultiplier);
+            		} else if (isDiamondTools(is) && hasDiamond(player) && mcUsers.getProfile(player).getRepairInt() >= mcLoadProperties.repairdiamondlevel){ //Check if its diamond and the player has diamonds
             			/*
             			 * DIAMOND TOOLS
             			 */
             			is.setDurability(getToolRepairAmount(is, player));
             			removeDiamond(player);
-            			mcUsers.getProfile(player).addRepairGather(75);
+            			mcUsers.getProfile(player).addRepairGather(75 * mcLoadProperties.xpGainMultiplier);
             		} else if(isGoldTools(is) && hasGold(player)){
             			is.setDurability(getToolRepairAmount(is, player));
             			removeGold(player);
-            			mcUsers.getProfile(player).addRepairGather(50);
+            			mcUsers.getProfile(player).addRepairGather(50 * mcLoadProperties.xpGainMultiplier);
             		} else {
             			needMoreVespeneGas(is, player);
             		}
@@ -82,15 +82,7 @@ public class mcRepair {
         	/*
         	 * GIVE SKILL IF THERE IS ENOUGH XP
         	 */
-        	if(mcUsers.getProfile(player).getRepairGatherInt() >= mcUsers.getProfile(player).getXpToLevel("repair")){
-    			int skillups = 0;
-    			while(mcUsers.getProfile(player).getRepairGatherInt() >= mcUsers.getProfile(player).getXpToLevel("repair")){
-    				skillups++;
-    				mcUsers.getProfile(player).removeRepairGather(mcUsers.getProfile(player).getXpToLevel("repair"));
-    				mcUsers.getProfile(player).skillUpRepair(1);
-    			}
-    			player.sendMessage(ChatColor.YELLOW+"Repair skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getRepair()+")");	
-    		}
+        	mcSkills.getInstance().XpCheck(player);
         	}
     }
 	public boolean isArmor(ItemStack is){
@@ -234,100 +226,138 @@ public class mcRepair {
     	}
     	return false;
     }
+    public short repairCalculate(Player player, short durability, short ramt){
+    	float bonus = (mcUsers.getProfile(player).getRepairInt() / 500);
+    	bonus = (ramt * bonus);
+    	ramt = ramt+=bonus;
+    	if(checkPlayerProcRepair(player)){
+    		ramt = (short) (ramt * 2);
+    	}
+    	durability-=ramt;
+    	if(durability < 0){
+    		durability = 0;
+    	}
+    	return durability;
+    }
     public short getToolRepairAmount(ItemStack is, Player player){
     	short durability = is.getDurability();
+    	short ramt = 0;
     	switch(is.getTypeId())
 		{
+    	//GOLD SHOVEL
     	case 284:
-    		durability = 0;
+    		ramt = 33;
     		break;
+    	//IRON SHOVEL
     	case 256:
-    		durability = 0;
+    		ramt = 251;
     		break;
+    	//DIAMOND SHOVEL
     	case 277:
-    		durability = 0;
+    		ramt = 1562;
     		break;
+    	//IRON PICK
     	case 257:
-    		durability -= 84;
+    		ramt = 84;
     		break;
+    	//IRON AXE
     	case 258:
-    		durability -= 84;
+    		ramt = 84;
     		break;
+    	//IRON SWORD
     	case 267:
-    		durability -= 84;
+    		ramt = 126;
     		break;
+    	//IRON HOE
     	case 292:
-    		durability -= 84;
+    		ramt = 126;
     		break;
+    	//DIAMOND SWORD
     	case 276:
-    		durability -= 509;
+    		ramt = 781;
     		break;
+    	//DIAMOND PICK
     	case 278:
-    		durability -= 509;
+    		ramt = 521;
     		break;
+    	//DIAMOND AXE
     	case 279:
-    		durability -= 509;
+    		ramt = 521;
     		break;
+    	//DIAMOND HOE
     	case 293:
-    		durability -= 509;
+    		ramt = 781;
     		break;
+    	//GOLD SWORD
     	case 283:
-    		durability -= 13;
+    		ramt = 17;
     		break;
+    	//GOLD PICK
     	case 285:
-    		durability -= 13;
+    		ramt = 11;
     		break;
+    	//GOLD AXE
     	case 286:
-    		durability -= 13;
+    		ramt = 11;
     		break;
+    	//GOLD HOE
     	case 294:
-    		durability -= 13;
+    		ramt = 17;
     		break;
 		}
-    	if(durability < 0)
-			durability = 0;
-		if(checkPlayerProcRepair(player))
-	    	durability = 0;
-		return durability;
+		return repairCalculate(player, durability, ramt);
     }
     //This determines how much we repair
     public short getArmorRepairAmount(ItemStack is, Player player){
     		short durability = is.getDurability();
+    		short ramt = 0;
     		switch(is.getTypeId())
     		{
     		case 306:
-    		durability -= 27;
-    		break;
+    			ramt = 27;
+    			break;
     		case 310:
-	    	durability -= 55;
-	    	break;
+    			ramt = 55;
+	    		break;
     		case 307:
-	    	durability -= 24;
-	    	break;
+    			ramt = 24;
+	    		break;
     		case 311:
-	    	durability -= 48;
-	    	break;
+    			ramt = 48;
+	    		break;
     		case 308:
-	    	durability -= 27;
-	    	break;
+    			ramt = 27;
+	    		break;
     		case 312:
-	    	durability -= 53;
-	    	break;
+    			ramt = 53;
+	    		break;
     		case 309:
-	    	durability -= 40;
-	    	break;
+    			ramt = 40;
+	    		break;
     		case 313:
-	    	durability -= 80;
-	    	break;
+    			ramt = 80;
+	    		break;
+    		case 314:
+        		ramt = 13;
+        		break;
+    		case 315:
+        		ramt = 12;
+        		break;
+    		case 316:
+        		ramt = 14;
+        		break;
+    		case 317:
+        		ramt = 20;
+        		break;
     		}
 			if(durability < 0)
-			durability = 0;
+				durability = 0;
 			if(checkPlayerProcRepair(player))
-	    	durability = 0;
-			return durability;
+				durability = 0;
+			return repairCalculate(player, durability, ramt);
     }
     public void needMoreVespeneGas(ItemStack is, Player player){
-    	if ((isDiamondTools(is) || isDiamondArmor(is)) && mcUsers.getProfile(player).getRepairInt() < 50){
+    	if ((isDiamondTools(is) || isDiamondArmor(is)) && mcUsers.getProfile(player).getRepairInt() < mcLoadProperties.repairdiamondlevel){
 			player.sendMessage(ChatColor.DARK_RED +"You're not adept enough to repair Diamond");
 		} else if (isDiamondTools(is) && !hasDiamond(player) || isIronTools(is) && !hasIron(player) || isGoldTools(is) && !hasGold(player)){
 			if(isDiamondTools(is) && !hasDiamond(player))
@@ -345,27 +375,12 @@ public class mcRepair {
 			player.sendMessage(ChatColor.DARK_RED+"You need more "+ChatColor.GOLD+"Gold");
 		}
     public boolean checkPlayerProcRepair(Player player){
-		if(mcUsers.getProfile(player).getRepairInt() >= 750){
-			if(Math.random() * 10 > 2){
-				player.sendMessage(ChatColor.GRAY + "That took no effort.");
-				return true;
-			}
-		} else if (mcUsers.getProfile(player).getRepairInt() >= 450 && mcUsers.getProfile(player).getRepairInt() < 750){
-			if(Math.random() * 10 > 4){
-				player.sendMessage(ChatColor.GRAY + "That felt really easy.");
-				return true;
-			}
-		} else if (mcUsers.getProfile(player).getRepairInt() >= 150 && mcUsers.getProfile(player).getRepairInt() < 450){
-			if(Math.random() * 10 > 6){
-				player.sendMessage(ChatColor.GRAY + "That felt pretty easy.");
-				return true;
-			}
-		} else if (mcUsers.getProfile(player).getRepairInt() >= 50  && mcUsers.getProfile(player).getRepairInt() < 150){
-			if(Math.random() * 10 > 8){
+		if(player != null){
+			if(Math.random() * 1000 <= mcUsers.getProfile(player).getRepairInt()){
 				player.sendMessage(ChatColor.GRAY + "That felt easy.");
 				return true;
 			}
 		}
 		return false;
-}
+    }
 }

+ 441 - 0
mcMMO/com/gmail/nossr50/mcSkills.java

@@ -1,5 +1,7 @@
 package com.gmail.nossr50;
 
+import org.bukkit.ChatColor;
+import org.bukkit.block.Block;
 import org.bukkit.entity.Entity;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
@@ -32,7 +34,445 @@ public class mcSkills {
     		}
     	}
     }
+    public void decreaseCooldowns(Player player){
+    	if(mcUsers.getProfile(player).getTreeFellerCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseTreeFellerCooldown();
+    		if(mcUsers.getProfile(player).getTreeFellerCooldown() == 0){
+    			player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Tree Feller "+ChatColor.GREEN+"ability is refreshed!");
+    		}
+    	}
+    	if(mcUsers.getProfile(player).getSuperBreakerCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseSuperBreakerCooldown();
+			if(mcUsers.getProfile(player).getSuperBreakerCooldown() == 0){
+				player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Super Breaker "+ChatColor.GREEN+"ability is refreshed!");
+			}
+    	}
+    	if(mcUsers.getProfile(player).getSerratedStrikesCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseSerratedStrikesCooldown();
+			if(mcUsers.getProfile(player).getSerratedStrikesCooldown() == 0){
+				player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Serrated Strikes "+ChatColor.GREEN+"ability is refreshed!");
+			}
+    	}
+    	if(mcUsers.getProfile(player).getBerserkCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseBerserkCooldown();
+			if(mcUsers.getProfile(player).getBerserkCooldown() == 0){
+				player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Berserk "+ChatColor.GREEN+"ability is refreshed!");
+			}
+    	}
+    	if(mcUsers.getProfile(player).getSkullSplitterCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseSkullSplitterCooldown();
+			if(mcUsers.getProfile(player).getSkullSplitterCooldown() == 0){
+				player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Skull Splitter "+ChatColor.GREEN+"ability is refreshed!");
+			}
+    	}
+    	if(mcUsers.getProfile(player).getGigaDrillBreakerCooldown() >= 1){
+    		mcUsers.getProfile(player).decreaseGigaDrillBreakerCooldown();
+			if(mcUsers.getProfile(player).getGigaDrillBreakerCooldown() == 0){
+				player.sendMessage(ChatColor.GREEN+"Your "+ChatColor.YELLOW+"Giga Drill Breaker "+ChatColor.GREEN+"ability is refreshed!");
+			}
+    	}
+    }
+    public void abilityActivationCheck(Player player){
+    	if(!mcUsers.getProfile(player).getAbilityUse())
+    		return;
+    	if(mcPermissions.getInstance().miningAbility(player) && mcm.getInstance().isMiningPick(player.getItemInHand()) && !mcUsers.getProfile(player).getPickaxePreparationMode()){
+    		if(!mcUsers.getProfile(player).getSuperBreakerMode() && mcUsers.getProfile(player).getSuperBreakerCooldown() >= 1){
+	    		player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."+ChatColor.YELLOW+" ("
+	    				+mcUsers.getProfile(player).getSuperBreakerCooldown()+"s)");
+	    		return;
+	    	}
+    		player.sendMessage(ChatColor.GREEN+"**YOU READY YOUR PICKAXE**");
+			mcUsers.getProfile(player).setPickaxePreparationTicks(4);
+			mcUsers.getProfile(player).setPickaxePreparationMode(true);
+    	}
+    	if(mcPermissions.getInstance().excavationAbility(player) && mcm.getInstance().isShovel(player.getItemInHand()) && !mcUsers.getProfile(player).getShovelPreparationMode()){
+    		if(!mcUsers.getProfile(player).getGigaDrillBreakerMode() && mcUsers.getProfile(player).getGigaDrillBreakerCooldown() >= 1){
+	    		player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."
+	    				+ChatColor.YELLOW+" ("+mcUsers.getProfile(player).getGigaDrillBreakerCooldown()+"s)");
+	    		return;
+	    	}
+    		player.sendMessage(ChatColor.GREEN+"**YOU READY YOUR SHOVEL**");
+			mcUsers.getProfile(player).setShovelPreparationTicks(4);
+			mcUsers.getProfile(player).setShovelPreparationMode(true);
+    	}
+    	if(mcPermissions.getInstance().swordsAbility(player) && mcm.getInstance().isSwords(player.getItemInHand()) && !mcUsers.getProfile(player).getSwordsPreparationMode()){
+    		if(!mcUsers.getProfile(player).getSerratedStrikesMode() && mcUsers.getProfile(player).getSerratedStrikesCooldown() >= 1){
+	    		player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."
+	    				+ChatColor.YELLOW+" ("+mcUsers.getProfile(player).getSerratedStrikesCooldown()+"s)");
+	    		return;
+	    	}
+    		player.sendMessage(ChatColor.GREEN+"**YOU READY YOUR SWORD**");
+			mcUsers.getProfile(player).setSwordsPreparationTicks(4);
+			mcUsers.getProfile(player).setSwordsPreparationMode(true);
+    	}
+    	if(mcPermissions.getInstance().unarmedAbility(player) && player.getItemInHand().getTypeId() == 0 && !mcUsers.getProfile(player).getFistsPreparationMode()){
+	    	if(!mcUsers.getProfile(player).getBerserkMode() && mcUsers.getProfile(player).getBerserkCooldown() >= 1){
+	    		player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."
+	    				+ChatColor.YELLOW+" ("+mcUsers.getProfile(player).getBerserkCooldown()+"s)");
+	    		return;
+	    	}
+    		player.sendMessage(ChatColor.GREEN+"**YOU READY YOUR FISTS**");
+			mcUsers.getProfile(player).setFistsPreparationTicks(4);
+			mcUsers.getProfile(player).setFistsPreparationMode(true);
+    	}
+    	if((mcPermissions.getInstance().axes(player) || mcPermissions.getInstance().woodcutting(player)) && !mcUsers.getProfile(player).getAxePreparationMode()){
+    		if(mcm.getInstance().isAxes(player.getItemInHand())){
+    			player.sendMessage(ChatColor.GREEN+"**YOU READY YOUR AXE**");
+    			mcUsers.getProfile(player).setAxePreparationTicks(4);
+    			mcUsers.getProfile(player).setAxePreparationMode(true);
+    		}
+    	}
+    }
+    public void serratedStrikesActivationCheck(Player player){
+		if(mcm.getInstance().isSwords(player.getItemInHand())){
+			if(mcUsers.getProfile(player).getSwordsPreparationMode()){
+    			mcUsers.getProfile(player).setSwordsPreparationMode(false);
+    			mcUsers.getProfile(player).setSwordsPreparationTicks(0);
+    		}
+	    	int ticks = 2;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 750)
+    			ticks++;
+    		
+	    	if(!mcUsers.getProfile(player).getSerratedStrikesMode() && mcUsers.getProfile(player).getSerratedStrikesCooldown() == 0){
+	    		player.sendMessage(ChatColor.GREEN+"**SERRATED STRIKES ACTIVATED**");
+	    		mcUsers.getProfile(player).setSerratedStrikesTicks(ticks * 2);
+	    		mcUsers.getProfile(player).setSerratedStrikesMode(true);
+	    	}
+	    	
+	    }
+	}
+    public void berserkActivationCheck(Player player){
+		if(player.getItemInHand().getTypeId() == 0){
+			if(mcUsers.getProfile(player).getFistsPreparationMode()){
+    			mcUsers.getProfile(player).setFistsPreparationMode(false);
+    			mcUsers.getProfile(player).setFistsPreparationTicks(0);
+    		}
+	    	int ticks = 2;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 750)
+    			ticks++;
+    		
+	    	if(!mcUsers.getProfile(player).getBerserkMode() && mcUsers.getProfile(player).getBerserkCooldown() == 0){
+	    		player.sendMessage(ChatColor.GREEN+"**BERSERK ACTIVATED**");
+	    		mcUsers.getProfile(player).setBerserkTicks(ticks * 2);
+	    		mcUsers.getProfile(player).setBerserkMode(true);
+	    	}
+
+	    }
+	}
+    public void skullSplitterCheck(Player player){
+    	if(mcm.getInstance().isAxes(player.getItemInHand())){
+    		/*
+    		 * CHECK FOR AXE PREP MODE
+    		 */
+    		if(mcUsers.getProfile(player).getAxePreparationMode()){
+    			mcUsers.getProfile(player).setAxePreparationMode(false);
+    			mcUsers.getProfile(player).setAxePreparationTicks(0);
+    		}
+    		int ticks = 2;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 750)
+    			ticks++;
+
+    		if(!mcUsers.getProfile(player).getSkullSplitterMode() && mcUsers.getProfile(player).getSkullSplitterCooldown() == 0){
+    			player.sendMessage(ChatColor.GREEN+"**SKULL SPLITTER ACTIVATED**");
+    			mcUsers.getProfile(player).setSkullSplitterTicks(ticks * 2);
+    			mcUsers.getProfile(player).setSkullSplitterMode(true);
+    		}
+    		if(!mcUsers.getProfile(player).getSkullSplitterMode() && mcUsers.getProfile(player).getSkullSplitterCooldown() >= 1){
+    			player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."
+    					+ChatColor.YELLOW+" ("+mcUsers.getProfile(player).getSkullSplitterCooldown()+"s)");
+    		}
+    	}
+    }
+    public void monitorSkills(Player player){
+    	/*
+    	 * AXE PREPARATION MODE
+    	 */
+    	if(mcUsers.getProfile(player) == null)
+    		mcUsers.addUser(player);
+		if(mcUsers.getProfile(player).getAxePreparationMode()){
+			mcUsers.getProfile(player).decreaseAxePreparationTicks();
+			if(mcUsers.getProfile(player).getAxePreparationTicks() <= 0){
+				mcUsers.getProfile(player).setAxePreparationMode(false);
+				player.sendMessage(ChatColor.GRAY+"**YOU LOWER YOUR AXE**");
+			}
+		}
+		if(mcUsers.getProfile(player).getPickaxePreparationMode()){
+			mcUsers.getProfile(player).decreasePickaxePreparationTicks();
+			if(mcUsers.getProfile(player).getPickaxePreparationTicks() <= 0){
+				mcUsers.getProfile(player).setPickaxePreparationMode(false);
+				player.sendMessage(ChatColor.GRAY+"**YOU LOWER YOUR PICKAXE**");
+			}
+		}
+		if(mcUsers.getProfile(player).getSwordsPreparationMode()){
+			mcUsers.getProfile(player).decreaseSwordsPreparationTicks();
+			if(mcUsers.getProfile(player).getSwordsPreparationTicks() <= 0){
+				mcUsers.getProfile(player).setSwordsPreparationMode(false);
+				player.sendMessage(ChatColor.GRAY+"**YOU LOWER YOUR SWORD**");
+			}
+		}
+		if(mcUsers.getProfile(player).getFistsPreparationMode()){
+			mcUsers.getProfile(player).decreaseFistsPreparationTicks();
+			if(mcUsers.getProfile(player).getFistsPreparationTicks() <= 0){
+				mcUsers.getProfile(player).setFistsPreparationMode(false);
+				player.sendMessage(ChatColor.GRAY+"**YOU LOWER YOUR FISTS**");
+			}
+		}
+		if(mcUsers.getProfile(player).getShovelPreparationMode()){
+			mcUsers.getProfile(player).decreaseShovelPreparationTicks();
+			if(mcUsers.getProfile(player).getShovelPreparationTicks() <= 0){
+				mcUsers.getProfile(player).setShovelPreparationMode(false);
+				player.sendMessage(ChatColor.GRAY+"**YOU LOWER YOUR SHOVEL**");
+			}
+		}
+    	/*
+    	 * AXES ABILITY
+    	 */
+    	if(mcPermissions.getInstance().axesAbility(player)){
+			//Monitor the length of Skull Splitter mode
+			if(mcUsers.getProfile(player).getSkullSplitterMode()){
+				mcUsers.getProfile(player).decreaseSkullSplitterTicks();
+				if(mcUsers.getProfile(player).getSkullSplitterTicks() <= 0){
+					mcUsers.getProfile(player).setSkullSplitterMode(false);
+					mcUsers.getProfile(player).setSkullSplitterCooldown(mcLoadProperties.skullSplitterCooldown);
+					player.sendMessage(ChatColor.RED+"**Skull Splitter has worn off**");
+				}
+			}
+		}
+    	/*
+		 * WOODCUTTING ABILITY
+		 */
+		if(mcPermissions.getInstance().woodCuttingAbility(player)){
+			if(mcUsers.getProfile(player).getTreeFellerMode()){
+				mcUsers.getProfile(player).decreaseTreeFellerTicks();
+				if(mcUsers.getProfile(player).getTreeFellerTicks() <= 0){
+					mcUsers.getProfile(player).setTreeFellerMode(false);
+					mcUsers.getProfile(player).setTreeFellerCooldown(mcLoadProperties.treeFellerCooldown);
+					player.sendMessage(ChatColor.RED+"**Tree Feller has worn off**");
+				}
+			}
+		}
+		/*
+		 * MINING ABILITY
+		 */
+		if(mcPermissions.getInstance().miningAbility(player)){
+			if(mcUsers.getProfile(player).getSuperBreakerMode()){
+				mcUsers.getProfile(player).decreaseSuperBreakerTicks();
+				if(mcUsers.getProfile(player).getSuperBreakerTicks() <= 0){
+					mcUsers.getProfile(player).setSuperBreakerMode(false);
+					mcUsers.getProfile(player).setSuperBreakerCooldown(mcLoadProperties.superBreakerCooldown);
+					player.sendMessage(ChatColor.RED+"**Super Breaker has worn off**");
+				}
+			}
+		}
+		/*
+		 * EXCAVATION ABILITY
+		 */
+		if(mcPermissions.getInstance().excavationAbility(player)){
+			if(mcUsers.getProfile(player).getGigaDrillBreakerMode()){
+				mcUsers.getProfile(player).decreaseGigaDrillBreakerTicks();
+				if(mcUsers.getProfile(player).getGigaDrillBreakerTicks() <= 0){
+					mcUsers.getProfile(player).setGigaDrillBreakerMode(false);
+					mcUsers.getProfile(player).setGigaDrillBreakerCooldown(mcLoadProperties.gigaDrillBreakerCooldown);
+					player.sendMessage(ChatColor.RED+"**You feel spiral energy leaving you**");
+				}
+			}
+		}
+		/*
+		 * SWORDS ABILITY
+		 */
+		if(mcPermissions.getInstance().swordsAbility(player)){
+			if(mcUsers.getProfile(player).getSerratedStrikesMode()){
+				mcUsers.getProfile(player).decreaseSerratedStrikesTicks();
+				if(mcUsers.getProfile(player).getSerratedStrikesTicks() <= 0){
+					mcUsers.getProfile(player).setSerratedStrikesMode(false);
+					mcUsers.getProfile(player).setSerratedStrikesCooldown(mcLoadProperties.serratedStrikeCooldown);
+					player.sendMessage(ChatColor.RED+"**Serrated Strikes has worn off**");
+				}
+			}
+		}
+		/*
+		 * UNARMED ABILITY
+		 */
+		if(mcPermissions.getInstance().unarmedAbility(player)){
+			if(mcUsers.getProfile(player).getBerserkMode()){
+				mcUsers.getProfile(player).decreaseBerserkTicks();
+				if(mcUsers.getProfile(player).getBerserkTicks() <= 0){
+					mcUsers.getProfile(player).setBerserkMode(false);
+					mcUsers.getProfile(player).setBerserkCooldown(mcLoadProperties.berserkCooldown);
+					player.sendMessage(ChatColor.RED+"**Berserk has worn off**");
+				}
+			}
+		}
+    }
+    public void XpCheck(Player player){
+    	/*
+    	 * ACROBATICS
+    	 */
+    	if(player != null && mcUsers.getProfile(player).getAcrobaticsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("acrobatics")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getAcrobaticsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("acrobatics")){
+				skillups++;
+				mcUsers.getProfile(player).removeAcrobaticsGather(mcUsers.getProfile(player).getXpToLevel("acrobatics"));
+				mcUsers.getProfile(player).skillUpAcrobatics(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Acrobatics skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getAcrobatics()+")");	
+		}
+    	/*
+    	 * ARCHERY
+    	 */
+    	if(mcUsers.getProfile(player).getArcheryGatherInt() >= mcUsers.getProfile(player).getXpToLevel("archery")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getArcheryGatherInt() >= mcUsers.getProfile(player).getXpToLevel("archery")){
+				skillups++;
+				mcUsers.getProfile(player).removeArcheryGather(mcUsers.getProfile(player).getXpToLevel("archery"));
+				mcUsers.getProfile(player).skillUpArchery(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Archery skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getArchery()+")");	
+		}
+    	/*
+    	 * SWORDS
+    	 */
+    	if(mcUsers.getProfile(player).getSwordsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("swords")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getSwordsGatherInt() >= mcUsers.getProfile(player).getXpToLevel("swords")){
+				skillups++;
+				mcUsers.getProfile(player).removeSwordsGather(mcUsers.getProfile(player).getXpToLevel("swords"));
+				mcUsers.getProfile(player).skillUpSwords(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Swords skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getSwords()+")");	
+		}
+    	/*
+    	 * AXES
+    	 */
+		if(mcUsers.getProfile(player).getAxesGatherInt() >= mcUsers.getProfile(player).getXpToLevel("axes")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getAxesGatherInt() >= mcUsers.getProfile(player).getXpToLevel("axes")){
+				skillups++;
+				mcUsers.getProfile(player).removeAxesGather(mcUsers.getProfile(player).getXpToLevel("axes"));
+				mcUsers.getProfile(player).skillUpAxes(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Axes skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getAxes()+")");	
+		}
+		/*
+		 * UNARMED
+		 */
+		if(mcUsers.getProfile(player).getUnarmedGatherInt() >= mcUsers.getProfile(player).getXpToLevel("unarmed")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getUnarmedGatherInt() >= mcUsers.getProfile(player).getXpToLevel("unarmed")){
+				skillups++;
+				mcUsers.getProfile(player).removeUnarmedGather(mcUsers.getProfile(player).getXpToLevel("unarmed"));
+				mcUsers.getProfile(player).skillUpUnarmed(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Unarmed skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getUnarmed()+")");	
+		}
+		/*
+		 * HERBALISM
+		 */
+		if(mcUsers.getProfile(player).getHerbalismGatherInt() >= mcUsers.getProfile(player).getXpToLevel("herbalism")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getHerbalismGatherInt() >= mcUsers.getProfile(player).getXpToLevel("herbalism")){
+				skillups++;
+				mcUsers.getProfile(player).removeHerbalismGather(mcUsers.getProfile(player).getXpToLevel("herbalism"));
+				mcUsers.getProfile(player).skillUpHerbalism(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Herbalism skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getHerbalism()+")");	
+		}
+		/*
+		 * MINING
+		 */
+		if(player != null && mcUsers.getProfile(player).getMiningGatherInt() >= mcUsers.getProfile(player).getXpToLevel("mining")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getMiningGatherInt() >= mcUsers.getProfile(player).getXpToLevel("mining")){
+				skillups++;
+				mcUsers.getProfile(player).removeMiningGather(mcUsers.getProfile(player).getXpToLevel("mining"));
+				mcUsers.getProfile(player).skillUpMining(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Mining skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getMining()+")");	
+		}
+		/*
+		 * WOODCUTTING
+		 */
+		if(player != null && mcUsers.getProfile(player).getWoodCuttingGatherInt() >= mcUsers.getProfile(player).getXpToLevel("woodcutting")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getWoodCuttingGatherInt() >= mcUsers.getProfile(player).getXpToLevel("woodcutting")){
+				skillups++;
+				mcUsers.getProfile(player).removeWoodCuttingGather(mcUsers.getProfile(player).getXpToLevel("woodcutting"));
+				mcUsers.getProfile(player).skillUpWoodCutting(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"WoodCutting skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getWoodCutting()+")");	
+		}
+		/*
+		 * REPAIR
+		 */
+		if(mcUsers.getProfile(player).getRepairGatherInt() >= mcUsers.getProfile(player).getXpToLevel("repair")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getRepairGatherInt() >= mcUsers.getProfile(player).getXpToLevel("repair")){
+				skillups++;
+				mcUsers.getProfile(player).removeRepairGather(mcUsers.getProfile(player).getXpToLevel("repair"));
+				mcUsers.getProfile(player).skillUpRepair(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Repair skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getRepair()+")");	
+		}
+		/*
+		 * EXCAVATION
+		 */
+		if(mcUsers.getProfile(player).getExcavationGatherInt() >= mcUsers.getProfile(player).getXpToLevel("excavation")){
+			int skillups = 0;
+			while(mcUsers.getProfile(player).getExcavationGatherInt() >= mcUsers.getProfile(player).getXpToLevel("excavation")){
+				skillups++;
+				mcUsers.getProfile(player).removeExcavationGather(mcUsers.getProfile(player).getXpToLevel("excavation"));
+				mcUsers.getProfile(player).skillUpExcavation(1);
+			}
+			player.sendMessage(ChatColor.YELLOW+"Excavation skill increased by "+skillups+"."+" Total ("+mcUsers.getProfile(player).getExcavation()+")");	
+		}
+    }
     public boolean isSkill(String skillname){
+    	skillname = skillname.toLowerCase();
+    	if(skillname.equals("all")){
+    		return true;
+    	}
 		if(skillname.equals("mining")){
 			return true;
 		}
@@ -75,5 +515,6 @@ public class mcSkills {
     		x++;
     		}
     	}
+    	mcConfig.getInstance().removeArrowTracked(entity);
     }
 }

+ 62 - 40
mcMMO/com/gmail/nossr50/mcTimer.java

@@ -1,6 +1,8 @@
 package com.gmail.nossr50;
+import java.awt.Color;
 import java.util.TimerTask;
 
+import org.bukkit.ChatColor;
 import org.bukkit.entity.*;
 
 public class mcTimer extends TimerTask{
@@ -13,50 +15,70 @@ public class mcTimer extends TimerTask{
     
 	public void run() {
 		Player[] playerlist = plugin.getServer().getOnlinePlayers();
-		if(thecount == 5 || thecount == 10 || thecount == 15 || thecount == 20){
-			for(Player player : playerlist){
-		    	if(player != null &&
-		    			player.getHealth() > 0 && player.getHealth() < 20 
-		    			&& mcUsers.getProfile(player).getPowerLevel() >= 1000 
-		    			&& mcUsers.getProfile(player).getRecentlyHurt() == 0 
-		    			&& mcPermissions.getInstance().regeneration(player)){
-		    		player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
-		    	}
-		    }
-		}
-		if(thecount == 10 || thecount == 20){
-			for(Player player : playerlist){
-	    		if(player != null &&
-	    				player.getHealth() > 0 && player.getHealth() < 20 
-	    				&& mcUsers.getProfile(player).getPowerLevel() >= 500 
-	    				&& mcUsers.getProfile(player).getPowerLevel() < 1000  
-	    				&& mcUsers.getProfile(player).getRecentlyHurt() == 0 
-	    				&& mcPermissions.getInstance().regeneration(player)){
-	    			player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
-	    		}
-	    	}
-		}
-		if(thecount == 20){
-			for(Player player : playerlist){
-	    		if(player != null &&
-	    				player.getHealth() > 0 && player.getHealth() < 20  
-	    				&& mcUsers.getProfile(player).getPowerLevel() < 500  
-	    				&& mcUsers.getProfile(player).getRecentlyHurt() == 0 
-	    				&& mcPermissions.getInstance().regeneration(player)){
-	    			player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
-	    		}
-	    	}
-		}
 		for(Player player : playerlist){
-			if(player != null && mcUsers.getProfile(player).getRecentlyHurt() >= 1){
-				mcUsers.getProfile(player).decreaseLastHurt();
+			if(player == null)
+				continue;
+			if(mcUsers.getProfile(player) == null)
+	    		mcUsers.addUser(player);
+			/*
+			 * MONITOR SKILLS
+			 */
+			mcSkills.getInstance().monitorSkills(player);
+			/*
+			 * COOLDOWN MONITORING
+			 */
+			mcSkills.getInstance().decreaseCooldowns(player);
+			
+			/*
+			 * PLAYER BLEED MONITORING
+			 */
+			if(thecount % 2 == 0 && player != null && mcUsers.getProfile(player).getBleedTicks() >= 1){
+        		player.damage(2);
+        		mcUsers.getProfile(player).decreaseBleedTicks();
+        	}
+			
+			if(mcPermissions.getInstance().regeneration(player)){
+				if(thecount == 10 || thecount == 20 || thecount == 30 || thecount == 40){
+				    if(player != null &&
+				    	player.getHealth() > 0 && player.getHealth() < 20 
+				    	&& mcUsers.getProfile(player).getPowerLevel(player) >= 1000 
+				    	&& mcUsers.getProfile(player).getRecentlyHurt() == 0){
+				    	player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
+				    }
+				}
+				if(thecount == 20 || thecount == 40){
+			   		if(player != null &&
+			   			player.getHealth() > 0 && player.getHealth() < 20 
+			    		&& mcUsers.getProfile(player).getPowerLevel(player) >= 500 
+			    		&& mcUsers.getProfile(player).getPowerLevel(player) < 1000  
+			    		&& mcUsers.getProfile(player).getRecentlyHurt() == 0){
+			    		player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
+			    	}
+				}
+				if(thecount == 40){
+			    	if(player != null &&
+			    		player.getHealth() > 0 && player.getHealth() < 20  
+			    		&& mcUsers.getProfile(player).getPowerLevel(player) < 500  
+			    		&& mcUsers.getProfile(player).getRecentlyHurt() == 0){
+			    		player.setHealth(mcm.getInstance().calculateHealth(player.getHealth(), 1));
+			    	}
+				}
+				if(player != null && mcUsers.getProfile(player).getRecentlyHurt() >= 1){
+					mcUsers.getProfile(player).decreaseLastHurt();
+				}
 			}
 		}
-		if(thecount < 20){
-		thecount++;
+		
+		/*
+		 * NON-PLAYER BLEED MONITORING
+		 */
+		if(thecount % 2 == 0)
+			mcCombat.getInstance().bleedSimulate();
+		
+		if(thecount < 40){
+			thecount++;
 		} else {
-		thecount = 1;
+			thecount = 1;
 		}
-		mcCombat.getInstance().bleedSimulate();
 	}
 }

+ 423 - 17
mcMMO/com/gmail/nossr50/mcUsers.java

@@ -13,7 +13,7 @@ import org.bukkit.plugin.Plugin;
 public class mcUsers {
     private static volatile mcUsers instance;
     protected static final Logger log = Logger.getLogger("Minecraft");
-    String location = "mcmmo.users";
+    String location = "plugins/mcMMO/mcmmo.users";
     public static PlayerList players = new PlayerList();
     private Properties properties = new Properties();
     
@@ -156,12 +156,14 @@ class PlayerList
 	    protected final Logger log = Logger.getLogger("Minecraft");
 		private String playerName, gather, wgather, woodcutting, repair, mining, party, myspawn, myspawnworld, unarmed, herbalism, excavation,
 		archery, swords, axes, invite, acrobatics, repairgather, unarmedgather, herbalismgather, excavationgather, archerygather, swordsgather, axesgather, acrobaticsgather;
-		private boolean dead;
-		private int recentlyhurt = 0, bleedticks = 0;
+		private boolean dead, abilityuse = true, treeFellerMode, superBreakerMode, gigaDrillBreakerMode, serratedStrikesMode, shovelPreparationMode, swordsPreparationMode, fistsPreparationMode, pickaxePreparationMode, axePreparationMode, skullSplitterMode, berserkMode;
+		private int recentlyhurt = 0, bleedticks = 0, gigaDrillBreakerCooldown = 0, gigaDrillBreakerTicks = 0, berserkTicks = 0, berserkCooldown = 0, superBreakerTicks = 0, superBreakerCooldown = 0, 
+		serratedStrikesTicks = 0, skullSplitterTicks = 0, skullSplitterCooldown = 0, serratedStrikesCooldown = 0, treeFellerTicks = 0, treeFellerCooldown = 0,
+		axePreparationTicks = 0, pickaxePreparationTicks = 0, fistsPreparationTicks = 0, shovelPreparationTicks = 0, swordsPreparationTicks = 0;
 		Player thisplayer;
 		char defaultColor;
 
-        String location = "mcmmo.users";
+        String location = "plugins/mcMMO/mcmmo.users";
 		
 		
 		//=====================================================================
@@ -206,7 +208,7 @@ class PlayerList
             //gather = "0";
             party = null;
             dead = false;
-            
+            treeFellerMode = false;
             //Try to load the player and if they aren't found, append them
             if(!load())
             	addPlayer();
@@ -417,6 +419,16 @@ class PlayerList
 		{
 			return player.getName().equals(playerName);
 		}
+		public boolean getAbilityUse(){
+			return abilityuse;
+		}
+		public void toggleAbilityUse(){
+			if(abilityuse == false){
+				abilityuse = true;
+			} else {
+				abilityuse = false;
+			}
+		}
 		public void decreaseLastHurt(){
 			if(recentlyhurt >= 1){
 				recentlyhurt--;
@@ -433,6 +445,303 @@ class PlayerList
 		public void setBleedTicks(Integer newvalue){
 			bleedticks = newvalue;
 		}
+		public void addBleedTicks(Integer newvalue){
+			bleedticks+=newvalue;
+		}
+		public Boolean hasCooldowns(){
+			if((treeFellerCooldown + superBreakerCooldown) >= 1){
+				return true;
+			} else {
+				return false;
+			}
+		}
+		/*
+		 * SWORDS PREPARATION
+		 */
+		public boolean getSwordsPreparationMode(){
+			return swordsPreparationMode;
+		}
+		public void setSwordsPreparationMode(Boolean bool){
+			swordsPreparationMode = bool;
+		}
+		public Integer getSwordsPreparationTicks(){
+			return swordsPreparationTicks;
+		}
+		public void setSwordsPreparationTicks(Integer newvalue){
+			swordsPreparationTicks = newvalue;
+		}
+		public void decreaseSwordsPreparationTicks(){
+			if(swordsPreparationTicks >= 1){
+				swordsPreparationTicks--;
+			}
+		}
+		/*
+		 * SHOVEL PREPARATION
+		 */
+		public boolean getShovelPreparationMode(){
+			return shovelPreparationMode;
+		}
+		public void setShovelPreparationMode(Boolean bool){
+			shovelPreparationMode = bool;
+		}
+		public Integer getShovelPreparationTicks(){
+			return shovelPreparationTicks;
+		}
+		public void setShovelPreparationTicks(Integer newvalue){
+			shovelPreparationTicks = newvalue;
+		}
+		public void decreaseShovelPreparationTicks(){
+			if(shovelPreparationTicks >= 1){
+				shovelPreparationTicks--;
+			}
+		}
+		/*
+		 * FISTS PREPARATION
+		 */
+		public boolean getFistsPreparationMode(){
+			return fistsPreparationMode;
+		}
+		public void setFistsPreparationMode(Boolean bool){
+			fistsPreparationMode = bool;
+		}
+		public Integer getFistsPreparationTicks(){
+			return fistsPreparationTicks;
+		}
+		public void setFistsPreparationTicks(Integer newvalue){
+			fistsPreparationTicks = newvalue;
+		}
+		public void decreaseFistsPreparationTicks(){
+			if(fistsPreparationTicks >= 1){
+				fistsPreparationTicks--;
+			}
+		}
+		/*
+		 * AXE PREPARATION
+		 */
+		public boolean getAxePreparationMode(){
+			return axePreparationMode;
+		}
+		public void setAxePreparationMode(Boolean bool){
+			axePreparationMode = bool;
+		}
+		public Integer getAxePreparationTicks(){
+			return axePreparationTicks;
+		}
+		public void setAxePreparationTicks(Integer newvalue){
+			axePreparationTicks = newvalue;
+		}
+		public void decreaseAxePreparationTicks(){
+			if(axePreparationTicks >= 1){
+				axePreparationTicks--;
+			}
+		}
+		/*
+		 * PICKAXE PREPARATION
+		 */
+		public boolean getPickaxePreparationMode(){
+			return pickaxePreparationMode;
+		}
+		public void setPickaxePreparationMode(Boolean bool){
+			pickaxePreparationMode = bool;
+		}
+		public Integer getPickaxePreparationTicks(){
+			return pickaxePreparationTicks;
+		}
+		public void setPickaxePreparationTicks(Integer newvalue){
+			pickaxePreparationTicks = newvalue;
+		}
+		public void decreasePickaxePreparationTicks(){
+			if(pickaxePreparationTicks >= 1){
+				pickaxePreparationTicks--;
+			}
+		}
+		/*
+		 * BERSERK MODE
+		 */
+		public boolean getBerserkMode(){
+			return berserkMode;
+		}
+		public void setBerserkMode(Boolean bool){
+			berserkMode = bool;
+		}
+		public Integer getBerserkTicks(){
+			return berserkTicks;
+		}
+		public void setBerserkTicks(Integer newvalue){
+			berserkTicks = newvalue;
+		}
+		public void decreaseBerserkTicks(){
+			if(berserkTicks >= 1){
+				berserkTicks--;
+			}
+		}
+		public void setBerserkCooldown(Integer newvalue){
+			berserkCooldown = newvalue;
+		}
+		public int getBerserkCooldown(){
+			return berserkCooldown;
+		}
+		public void decreaseBerserkCooldown(){
+			if(berserkCooldown >= 1){
+				berserkCooldown--;
+			}
+		}
+		/*
+		 * SKULL SPLITTER
+		 */
+		public boolean getSkullSplitterMode(){
+			return skullSplitterMode;
+		}
+		public void setSkullSplitterMode(Boolean bool){
+			skullSplitterMode = bool;
+		}
+		public Integer getSkullSplitterTicks(){
+			return skullSplitterTicks;
+		}
+		public void setSkullSplitterTicks(Integer newvalue){
+			skullSplitterTicks = newvalue;
+		}
+		public void decreaseSkullSplitterTicks(){
+			if(skullSplitterTicks >= 1){
+				skullSplitterTicks--;
+			}
+		}
+		public void setSkullSplitterCooldown(Integer newvalue){
+			skullSplitterCooldown = newvalue;
+		}
+		public int getSkullSplitterCooldown(){
+			return skullSplitterCooldown;
+		}
+		public void decreaseSkullSplitterCooldown(){
+			if(skullSplitterCooldown >= 1){
+				skullSplitterCooldown--;
+			}
+		}
+		/*
+		 * SERRATED STRIKES
+		 */
+		public boolean getSerratedStrikesMode(){
+			return serratedStrikesMode;
+		}
+		public void setSerratedStrikesMode(Boolean bool){
+			serratedStrikesMode = bool;
+		}
+		public Integer getSerratedStrikesTicks(){
+			return serratedStrikesTicks;
+		}
+		public void setSerratedStrikesTicks(Integer newvalue){
+			serratedStrikesTicks = newvalue;
+		}
+		public void decreaseSerratedStrikesTicks(){
+			if(serratedStrikesTicks >= 1){
+				serratedStrikesTicks--;
+			}
+		}
+		public void setSerratedStrikesCooldown(Integer newvalue){
+			serratedStrikesCooldown = newvalue;
+		}
+		public int getSerratedStrikesCooldown(){
+			return serratedStrikesCooldown;
+		}
+		public void decreaseSerratedStrikesCooldown(){
+			if(serratedStrikesCooldown >= 1){
+				serratedStrikesCooldown--;
+			}
+		}
+		/*
+		 * GIGA DRILL BREAKER
+		 */
+		public boolean getGigaDrillBreakerMode(){
+			return gigaDrillBreakerMode;
+		}
+		public void setGigaDrillBreakerMode(Boolean bool){
+			gigaDrillBreakerMode = bool;
+		}
+		public Integer getGigaDrillBreakerTicks(){
+			return gigaDrillBreakerTicks;
+		}
+		public void setGigaDrillBreakerTicks(Integer newvalue){
+			gigaDrillBreakerTicks = newvalue;
+		}
+		public void decreaseGigaDrillBreakerTicks(){
+			if(gigaDrillBreakerTicks >= 1){
+				gigaDrillBreakerTicks--;
+			}
+		}
+		public void setGigaDrillBreakerCooldown(Integer newvalue){
+			gigaDrillBreakerCooldown = newvalue;
+		}
+		public int getGigaDrillBreakerCooldown(){
+			return gigaDrillBreakerCooldown;
+		}
+		public void decreaseGigaDrillBreakerCooldown(){
+			if(gigaDrillBreakerCooldown >= 1){
+				gigaDrillBreakerCooldown--;
+			}
+		}
+		/*
+		 * TREE FELLER STUFF
+		 */
+		public boolean getTreeFellerMode(){
+			return treeFellerMode;
+		}
+		public void setTreeFellerMode(Boolean bool){
+			treeFellerMode = bool;
+		}
+		public Integer getTreeFellerTicks(){
+			return treeFellerTicks;
+		}
+		public void setTreeFellerTicks(Integer newvalue){
+			treeFellerTicks = newvalue;
+		}
+		public void decreaseTreeFellerTicks(){
+			if(treeFellerTicks >= 1){
+				treeFellerTicks--;
+			}
+		}
+		public void setTreeFellerCooldown(Integer newvalue){
+			treeFellerCooldown = newvalue;
+		}
+		public int getTreeFellerCooldown(){
+			return treeFellerCooldown;
+		}
+		public void decreaseTreeFellerCooldown(){
+			if(treeFellerCooldown >= 1){
+				treeFellerCooldown--;
+			}
+		}
+		/*
+		 * MINING
+		 */
+		public boolean getSuperBreakerMode(){
+			return superBreakerMode;
+		}
+		public void setSuperBreakerMode(Boolean bool){
+			superBreakerMode = bool;
+		}
+		public Integer getSuperBreakerTicks(){
+			return superBreakerTicks;
+		}
+		public void setSuperBreakerTicks(Integer newvalue){
+			superBreakerTicks = newvalue;
+		}
+		public void decreaseSuperBreakerTicks(){
+			if(superBreakerTicks >= 1){
+				superBreakerTicks--;
+			}
+		}
+		public void setSuperBreakerCooldown(Integer newvalue){
+			superBreakerCooldown = newvalue;
+		}
+		public int getSuperBreakerCooldown(){
+			return superBreakerCooldown;
+		}
+		public void decreaseSuperBreakerCooldown(){
+			if(superBreakerCooldown >= 1){
+				superBreakerCooldown--;
+			}
+		}
+		
 		public Integer getRecentlyHurt(){
 			return recentlyhurt;
 		}
@@ -1129,35 +1438,113 @@ class PlayerList
 				return 0;
 			}
 		}
+		public void addXpToSkill(int newvalue, String skillname){
+			if(!isInt(gather))
+				gather = String.valueOf(0);
+			if(!isInt(wgather))
+				wgather = String.valueOf(0);
+			if(!isInt(repairgather))
+				repairgather = String.valueOf(0);
+			if(!isInt(herbalismgather))
+				herbalismgather = String.valueOf(0);
+			if(!isInt(acrobaticsgather))
+				acrobaticsgather = String.valueOf(0);
+			if(!isInt(swordsgather))
+				swordsgather = String.valueOf(0);
+			if(!isInt(archerygather))
+				archerygather = String.valueOf(0);
+			if(!isInt(unarmedgather))
+				unarmedgather = String.valueOf(0);
+			if(!isInt(excavationgather))
+				excavationgather = String.valueOf(0);
+			if(!isInt(axesgather))
+				axesgather = String.valueOf(0);
+			
+			if(skillname.toLowerCase().equals("mining")){
+				gather = String.valueOf(Integer.valueOf(gather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("woodcutting")){
+				wgather = String.valueOf(Integer.valueOf(wgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("repair")){
+				repairgather = String.valueOf(Integer.valueOf(repairgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("herbalism")){
+				herbalismgather = String.valueOf(Integer.valueOf(herbalismgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("acrobatics")){
+				acrobaticsgather = String.valueOf(Integer.valueOf(acrobaticsgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("swords")){
+				swordsgather = String.valueOf(Integer.valueOf(swordsgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("archery")){
+				archerygather = String.valueOf(Integer.valueOf(archerygather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("unarmed")){
+				unarmedgather = String.valueOf(Integer.valueOf(unarmedgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("excavation")){
+				excavationgather = String.valueOf(Integer.valueOf(excavationgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("axes")){
+				axesgather = String.valueOf(Integer.valueOf(axesgather)+newvalue);
+			}
+			if(skillname.toLowerCase().equals("all")){
+				gather = String.valueOf(Integer.valueOf(gather)+newvalue);
+				wgather = String.valueOf(Integer.valueOf(wgather)+newvalue);
+				repairgather = String.valueOf(Integer.valueOf(repairgather)+newvalue);
+				herbalismgather = String.valueOf(Integer.valueOf(herbalismgather)+newvalue);
+				acrobaticsgather = String.valueOf(Integer.valueOf(acrobaticsgather)+newvalue);
+				swordsgather = String.valueOf(Integer.valueOf(swordsgather)+newvalue);
+				archerygather = String.valueOf(Integer.valueOf(archerygather)+newvalue);
+				unarmedgather = String.valueOf(Integer.valueOf(unarmedgather)+newvalue);
+				excavationgather = String.valueOf(Integer.valueOf(excavationgather)+newvalue);
+				axesgather = String.valueOf(Integer.valueOf(axesgather)+newvalue);
+			}
+			save();
+		}
 		public void modifyskill(int newvalue, String skillname){
-			if(skillname.equals("mining")){
+			if(skillname.toLowerCase().equals("mining")){
 				 mining = String.valueOf(newvalue);
 			}
-			if(skillname.equals("woodcutting")){
+			if(skillname.toLowerCase().equals("woodcutting")){
 				 woodcutting = String.valueOf(newvalue);
 			}
-			if(skillname.equals("repair")){
+			if(skillname.toLowerCase().equals("repair")){
 				 repair = String.valueOf(newvalue);
 			}
-			if(skillname.equals("herbalism")){
+			if(skillname.toLowerCase().equals("herbalism")){
 				 herbalism = String.valueOf(newvalue);
 			}
-			if(skillname.equals("acrobatics")){
+			if(skillname.toLowerCase().equals("acrobatics")){
 				 acrobatics = String.valueOf(newvalue);
 			}
-			if(skillname.equals("swords")){
+			if(skillname.toLowerCase().equals("swords")){
 				 swords = String.valueOf(newvalue);
 			}
-			if(skillname.equals("archery")){
+			if(skillname.toLowerCase().equals("archery")){
 				 archery = String.valueOf(newvalue);
 			}
-			if(skillname.equals("unarmed")){
+			if(skillname.toLowerCase().equals("unarmed")){
 				 unarmed = String.valueOf(newvalue);
 			}
-			if(skillname.equals("excavation")){
+			if(skillname.toLowerCase().equals("excavation")){
 				 excavation = String.valueOf(newvalue);
 			}
-			if(skillname.equals("axes")){
+			if(skillname.toLowerCase().equals("axes")){
+				axes = String.valueOf(newvalue);
+			}
+			if(skillname.toLowerCase().equals("all")){
+				mining = String.valueOf(newvalue);
+				woodcutting = String.valueOf(newvalue);
+				repair = String.valueOf(newvalue);
+				herbalism = String.valueOf(newvalue);
+				acrobatics = String.valueOf(newvalue);
+				swords = String.valueOf(newvalue);
+				archery = String.valueOf(newvalue);
+				unarmed = String.valueOf(newvalue);
+				excavation = String.valueOf(newvalue);
 				axes = String.valueOf(newvalue);
 			}
 			save();
@@ -1196,9 +1583,28 @@ class PlayerList
 				return 0;
 			}
 		}
-		public int getPowerLevel(){
+		public int getPowerLevel(Player player){
 			int x = 0;
-			x+=getMiningInt()+getRepairInt()+getWoodCuttingInt()+getUnarmedInt()+getHerbalismInt()+getExcavationInt()+getArcheryInt()+getSwordsInt()+getAxesInt()+getAcrobaticsInt();
+			if(mcPermissions.getInstance().mining(player))
+				x+=getMiningInt();
+			if(mcPermissions.getInstance().woodcutting(player))
+				x+=getWoodCuttingInt();
+			if(mcPermissions.getInstance().unarmed(player))
+				x+=getUnarmedInt();
+			if(mcPermissions.getInstance().herbalism(player))
+				x+=getHerbalismInt();
+			if(mcPermissions.getInstance().excavation(player))
+				x+=getExcavationInt();
+			if(mcPermissions.getInstance().archery(player))
+				x+=getArcheryInt();
+			if(mcPermissions.getInstance().swords(player))
+				x+=getSwordsInt();
+			if(mcPermissions.getInstance().axes(player))
+				x+=getAxesInt();
+			if(mcPermissions.getInstance().acrobatics(player))
+				x+=getAcrobaticsInt();
+			if(mcPermissions.getInstance().repair(player))
+				x+=getRepairInt();
 			return x;
 		}
 		public int getMiningGatherInt() {

+ 114 - 38
mcMMO/com/gmail/nossr50/mcWoodCutting.java

@@ -1,5 +1,8 @@
 package com.gmail.nossr50;
 
+import java.util.ArrayList;
+
+import org.bukkit.ChatColor;
 import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.block.Block;
@@ -7,6 +10,8 @@ import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 
 public class mcWoodCutting {
+	int w = 0;
+	private boolean isdone = false;
 	private static mcMMO plugin;
 	public mcWoodCutting(mcMMO instance) {
     	plugin = instance;
@@ -18,50 +23,121 @@ public class mcWoodCutting {
     	}
     	return instance;
     	}
-    public void woodCuttingProcCheck(Player player, Block block, Location loc){
+    public void woodCuttingProcCheck(Player player, Block block){
     	byte type = block.getData();
     	Material mat = Material.getMaterial(block.getTypeId());
-    	byte damage = 0;
-    	if(mcUsers.getProfile(player).getWoodCuttingInt() > 1000){
-			ItemStack item = new ItemStack(mat, 1, type, damage);
-			loc.getWorld().dropItemNaturally(loc, item);
-			return;
+    	if(player != null){
+    		if(Math.random() * 1000 <= mcUsers.getProfile(player).getWoodCuttingInt()){
+    			ItemStack item = new ItemStack(mat, 1, (short) 0, type);
+    			block.getWorld().dropItemNaturally(block.getLocation(), item);
+    		}
     	}
-    	if(mcUsers.getProfile(player).getWoodCuttingInt() > 750){
-			if((Math.random() * 10) > 2){
-				ItemStack item = new ItemStack(mat, 1, type, damage);
-				loc.getWorld().dropItemNaturally(loc, item);
-				return;
-			}
+    }
+    public void treeFellerCheck(Player player, Block block){
+    	if(mcm.getInstance().isAxes(player.getItemInHand())){
+    		if(block != null){
+        		if(!mcm.getInstance().abilityBlockCheck(block))
+        			return;
+        	}
+    		/*
+    		 * CHECK FOR AXE PREP MODE
+    		 */
+    		if(mcUsers.getProfile(player).getAxePreparationMode()){
+    			mcUsers.getProfile(player).setAxePreparationMode(false);
+    			mcUsers.getProfile(player).setAxePreparationTicks(0);
+    		}
+    		int ticks = 2;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 750)
+    			ticks++;
+
+    		if(!mcUsers.getProfile(player).getTreeFellerMode() && mcUsers.getProfile(player).getTreeFellerCooldown() == 0){
+    			player.sendMessage(ChatColor.GREEN+"**TREE FELLING ACTIVATED**");
+    			mcUsers.getProfile(player).setTreeFellerTicks(ticks * 2);
+    			mcUsers.getProfile(player).setTreeFellerMode(true);
+    		}
+    		if(!mcUsers.getProfile(player).getTreeFellerMode() && mcUsers.getProfile(player).getTreeFellerCooldown() >= 1){
+    			player.sendMessage(ChatColor.RED+"You are too tired to use that ability again."
+    					+ChatColor.YELLOW+" ("+mcUsers.getProfile(player).getTreeFellerCooldown()+"s)");
+    		}
     	}
-	if(mcUsers.getProfile(player).getWoodCuttingInt() > 300){
-		if((Math.random() * 10) > 4){
-			ItemStack item = new ItemStack(mat, 1, type, damage);
-			loc.getWorld().dropItemNaturally(loc, item);
-			return;
-		}
-	}
-	if(mcUsers.getProfile(player).getWoodCuttingInt() > 100){
-		if((Math.random() * 10) > 6){
-			ItemStack item = new ItemStack(mat, 1, type, damage);
-			loc.getWorld().dropItemNaturally(loc, item);
-			return;
-		}
-	}
-	if(mcUsers.getProfile(player).getWoodCuttingInt() > 10){
-		if((Math.random() * 10) > 8){
-			ItemStack item = new ItemStack(mat, 1, type, damage);
-			loc.getWorld().dropItemNaturally(loc, item);
-			return;
-		}
-	}
     }
-    public void treeFeller(Block block){
-    	Location loc = block.getLocation();
+    public void treeFeller(Block block, Player player){
     	int radius = 1;
-    	int typeid = 17;
-    	if(mcm.getInstance().isBlockAround(loc, radius, typeid)){
-    		
+    	if(mcUsers.getProfile(player).getWoodCuttingGatherInt() >= 500)
+    		radius++;
+    	if(mcUsers.getProfile(player).getWoodCuttingGatherInt() >= 950)
+    		radius++;
+        ArrayList<Block> blocklist = new ArrayList<Block>();
+        ArrayList<Block> toAdd = new ArrayList<Block>();
+        if(block != null)
+        	blocklist.add(block);
+        while(isdone == false){
+        	addBlocksToTreeFelling(blocklist, toAdd, radius);
+        }
+        //This needs to be a hashmap too!
+        isdone = false;
+        /*
+         * Add blocks from the temporary 'toAdd' array list into the 'treeFeller' array list
+         * We use this temporary list to prevent concurrent modification exceptions
+         */
+        for(Block x : toAdd){
+        	if(!mcConfig.getInstance().isTreeFellerWatched(x))
+        		mcConfig.getInstance().addTreeFeller(x);
+        }
+        toAdd.clear();
+    }
+    public void addBlocksToTreeFelling(ArrayList<Block> blocklist, ArrayList<Block> toAdd, Integer radius){
+    	int u = 0;
+    	for (Block x : blocklist){
+    		u++;
+    		if(toAdd.contains(x))
+    			continue;
+    		w = 0;
+    		Location loc = x.getLocation();
+    		int vx = x.getX();
+            int vy = x.getY();
+            int vz = x.getZ();
+            
+            /*
+             * Run through the blocks around the broken block to see if they qualify to be 'felled'
+             */
+    		for (int cx = -radius; cx <= radius; cx++) {
+	            for (int cy = -radius; cy <= radius; cy++) {
+	                for (int cz = -radius; cz <= radius; cz++) {
+	                    Block blocktarget = loc.getWorld().getBlockAt(vx + cx, vy + cy, vz + cz);
+	                    if (!blocklist.contains(blocktarget) && !toAdd.contains(blocktarget) && (blocktarget.getTypeId() == 17 || blocktarget.getTypeId() == 18)) { 
+	                        toAdd.add(blocktarget);
+	                        w++;
+	                    }
+	                }
+	            }
+	        }
+    	}
+    	/*
+		 * Add more blocks to blocklist so they can be 'felled'
+		 */
+		for(Block xx : toAdd){
+    		if(!blocklist.contains(xx))
+        	blocklist.add(xx);
+        }
+    	if(u >= blocklist.size()){
+    		isdone = true;
+    	} else {
+    		isdone = false;
     	}
     }
 }

+ 404 - 97
mcMMO/com/gmail/nossr50/mcm.java

@@ -9,9 +9,7 @@ import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.block.Block;
 import org.bukkit.entity.*;
-import org.bukkit.event.entity.EntityDamageByEntityEvent;
-import org.bukkit.event.entity.EntityDamageByProjectileEvent;
-import org.bukkit.event.entity.EntityDamageEvent;
+import org.bukkit.event.block.BlockBreakEvent;
 import org.bukkit.event.player.PlayerChatEvent;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.plugin.Plugin;
@@ -29,12 +27,87 @@ public class mcm {
     	instance = new mcm(plugin);
     	}
     	return instance;
+    }
+	
+	public boolean blockBreakSimulate(Block block, Player player, Plugin plugin){
+
+    	FakeBlockBreakEvent event = new FakeBlockBreakEvent(block, player);
+    	if(block != null && plugin != null && player != null){
+    		plugin.getServer().getPluginManager().callEvent(event);
+	    	if(!event.isCancelled())
+	    	{
+	    		return true; //Return true if not cancelled
+	    	} else {
+	    		return false; //Return false if cancelled
+	    	}
+    	} else {
+    		return false; //Return false if something went wrong
     	}
-	public static double getDistance(Location loca, Location locb)
+    }
+	
+	public void damageTool(Player player, short damage){
+		if(player.getItemInHand().getTypeId() == 0)
+			return;
+		player.getItemInHand().setDurability((short) (player.getItemInHand().getDurability() + damage));
+		if(player.getItemInHand().getDurability() >= getMaxDurability(mcm.getInstance().getTier(player), player.getItemInHand())){
+			ItemStack[] inventory = player.getInventory().getContents();
+	    	for(ItemStack x : inventory){
+	    		if(x.getTypeId() == player.getItemInHand().getTypeId() && x.getDurability() == player.getItemInHand().getDurability()){
+	    			x.setTypeId(0);
+	    			x.setAmount(0);
+	    			player.getInventory().setContents(inventory);
+	    			return;
+	    		}
+	    	}
+		}
+	}
+	public Integer getTier(Player player){
+		int i = player.getItemInHand().getTypeId();
+		if(i == 268 || i == 269 || i == 270 || i == 271 || i == 290){
+			return 1; //WOOD
+		} else if (i == 272 || i == 273 || i == 274 || i == 275 || i == 291){
+			return 2; //STONE
+		} else if (i == 256 || i == 257 || i == 258 || i == 267 || i == 292){
+			return 3; //IRON
+		} else if (i == 283 || i == 284 || i == 285 || i == 286 || i == 294){
+			return 1; //GOLD
+		} else if (i == 276 || i == 277 || i == 278 || i == 279 || i == 293){
+			return 4; //DIAMOND
+		} else {
+			return 1; //UNRECOGNIZED
+		}
+	}
+	public Integer getMaxDurability(Integer tier, ItemStack item){
+		int id = item.getTypeId();
+		if(tier == 1){
+			if((id == 276 || id == 277 || id == 278 || id == 279 || id == 293)){
+				return 33;
+			} else {
+				return 60;
+			}
+		} else if (tier == 2){
+			return 132;
+		} else if (tier == 3){
+			return 251;
+		} else if (tier == 4){
+			return 1562;
+		} else {
+			return 0;
+		}
+	}
+	public double getDistance(Location loca, Location locb)
     {
-    return Math.sqrt(Math.pow(loca.getX() - locb.getX(), 2) + Math.pow(loca.getY() - locb.getY(), 2)
+	return Math.sqrt(Math.pow(loca.getX() - locb.getX(), 2) + Math.pow(loca.getY() - locb.getY(), 2)
     + Math.pow(loca.getZ() - locb.getZ(), 2));
     }
+	public boolean abilityBlockCheck(Block block){
+		int i = block.getTypeId();
+		if(i == 68 || i == 355 || i == 323 || i == 25 || i == 54 || i == 69 || i == 92 || i == 77 || i == 58 || i == 61 || i == 62 || i == 42 || i == 71 || i == 64 || i == 84 || i == 324 || i == 330){
+			return false;
+		} else {
+			return true;
+		}
+	}
 	public boolean isBlockAround(Location loc, Integer radius, Integer typeid){
 		Block blockx = loc.getBlock();
     	int ox = blockx.getX();
@@ -86,7 +159,7 @@ public class mcm {
 	}
 	public boolean shouldBeWatched(Block block){
 		int id = block.getTypeId();
-		if(id == 21 || id == 15 || id == 14 || id == 56 || id == 38 || id == 37 || id == 39 || id == 40){
+		if(id == 42 || id == 87 || id == 89 || id == 2 || id == 3 || id == 12 || id == 13 || id == 21 || id == 15 || id == 14 || id == 56 || id == 38 || id == 37 || id == 39 || id == 40 || id == 24){
 			return true;
 		} else {
 			return false;
@@ -129,70 +202,6 @@ public class mcm {
 		}
 		return true;
 	}
-    public void simulateNaturalDrops(Entity entity){
-    	Location loc = entity.getLocation();
-    	if(entity instanceof Pig){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 319); //BACON
-    			}
-    			mcDropItem(loc, 319);
-    		}
-    	}
-    	if(entity instanceof Spider){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 287); //SILK
-    			}
-    			mcDropItem(loc, 287);
-    		}
-    	}
-    	if(entity instanceof Skeleton){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 262); //ARROWS
-    			}
-    			mcDropItem(loc, 262);
-    		}
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 352); //BONES
-    			}
-    			mcDropItem(loc, 352);
-    		}
-    	}
-    	if(entity instanceof Zombie){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 288); //FEATHERS
-    			}
-    			mcDropItem(loc, 288);
-    		}
-    	}
-    	if(entity instanceof Cow){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 334); //LEATHER
-    			}
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 334);
-    			}
-    			mcDropItem(loc, 334);
-    		}
-    	}
-    	if(entity instanceof Squid){
-    		if(Math.random() * 3 > 2){
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 351); //INK SACS
-    			}
-    			if(Math.random() * 2 > 1){
-    				mcDropItem(loc, 351);
-    			}
-    			mcDropItem(loc, 351);
-    		}
-    	}
-    	mcSkills.getInstance().arrowRetrievalCheck(entity);
-    }
     public void mcDropItem(Location loc, int id){
     	if(loc != null){
     	Material mat = Material.getMaterial(id);
@@ -209,6 +218,13 @@ public class mcm {
     		return false;
     	}
     }
+    public boolean isShovel(ItemStack is){
+    	if(is.getTypeId() == 269 || is.getTypeId() == 273 || is.getTypeId() == 277 || is.getTypeId() == 284 || is.getTypeId() == 256){
+    		return true;
+    	} else {
+    		return false;
+    	}
+    }
     public boolean isAxes(ItemStack is){
     	if(is.getTypeId() == 271 || is.getTypeId() == 258 || is.getTypeId() == 286 || is.getTypeId() == 279 || is.getTypeId() == 275){
     		return true;
@@ -216,106 +232,395 @@ public class mcm {
     		return false;
     	}
     }
-    
+    public boolean isMiningPick(ItemStack is){
+    	if(is.getTypeId() == 270 || is.getTypeId() == 274 || is.getTypeId() == 285 || is.getTypeId() == 257 || is.getTypeId() == 278){
+    		return true;
+    	} else {
+    		return false;
+    	}
+    }
     public void mcmmoHelpCheck(String[] split, Player player, PlayerChatEvent event){
     	if(split[0].equalsIgnoreCase("/woodcutting")){
 			event.setCancelled(true);
+			float skillvalue = (float)mcUsers.getProfile(player).getWoodCuttingInt();
+			int ticks = 2;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getWoodCuttingInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"WOODCUTTING"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Chopping down trees");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
-			player.sendMessage(ChatColor.DARK_AQUA+"Double Drops: "+ChatColor.GREEN+"Double the normal loot");
+			player.sendMessage(ChatColor.DARK_AQUA+"Tree Feller (ABILITY): "+ChatColor.GREEN+"Make trees explode");
+			player.sendMessage(ChatColor.DARK_AQUA+"Double Drops: "+ChatColor.YELLOW+ChatColor.GREEN+"Double the normal loot");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Double Drop Chance: "+ChatColor.YELLOW+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Tree Feller Length: "+ChatColor.YELLOW+ticks+"s");
     	}
     	if(split[0].equalsIgnoreCase("/archery")){
 			event.setCancelled(true);
+			Integer rank = 0;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 50)
+    			rank++;
+    		if(mcUsers.getProfile(player).getArcheryInt() >= 250)
+    			rank++;
+    		if(mcUsers.getProfile(player).getArcheryInt() >= 575)
+    			rank++;
+    		if(mcUsers.getProfile(player).getArcheryInt() >= 725)
+    			rank++;
+    		if(mcUsers.getProfile(player).getArcheryInt() >= 1000)
+    			rank++;
+			float skillvalue = (float)mcUsers.getProfile(player).getArcheryInt();
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
+    		
+    		int ignition = 20;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 200)
+				ignition+=20;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 400)
+				ignition+=20;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 600)
+				ignition+=20;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 800)
+				ignition+=20;
+			if(mcUsers.getProfile(player).getArcheryInt() >= 1000)
+				ignition+=20;
+			
+    		String percentagedaze;
+			if(mcUsers.getProfile(player).getArcheryInt() < 1000){
+				percentagedaze = String.valueOf((skillvalue / 2000) * 100);
+			} else {
+				percentagedaze = "50";
+			}
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"ARCHERY"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Attacking Monsters");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
-			//player.sendMessage(ChatColor.DARK_AQUA+"Daze (Monsters): "+ChatColor.GREEN+"Enemies lose interest for 1 second");
+			player.sendMessage(ChatColor.DARK_AQUA+"Ignition: "+ChatColor.GREEN+"25% Chance Enemies will ignite");
 			player.sendMessage(ChatColor.DARK_AQUA+"Daze (Players): "+ChatColor.GREEN+"Disorients foes");
 			player.sendMessage(ChatColor.DARK_AQUA+"Damage+: "+ChatColor.GREEN+"Modifies Damage");
+			player.sendMessage(ChatColor.DARK_AQUA+"Arrow Retrieval: "+ChatColor.GREEN+"Chance to retrieve arrows from corpses");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Chance to Daze: "+ChatColor.YELLOW+percentagedaze+"%");
+			player.sendMessage(ChatColor.RED+"Chance to Retrieve Arrows: "+ChatColor.YELLOW+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Length of Ignition: "+ChatColor.YELLOW+(ignition / 20)+" seconds");
+			player.sendMessage(ChatColor.RED+"Damage+ (Rank"+rank+"): Bonus "+rank+" damage");
     	}
     	if(split[0].equalsIgnoreCase("/axes")){
 			event.setCancelled(true);
+			String percentage;
+			float skillvalue = (float)mcUsers.getProfile(player).getAxesInt();
+			if(mcUsers.getProfile(player).getAxesInt() < 750){
+				percentage = String.valueOf((skillvalue / 1000) * 100);
+			} else {
+				percentage = "75";
+			}
+			int ticks = 2;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getAxesInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"AXES"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Attacking Monsters");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
-			player.sendMessage(ChatColor.DARK_AQUA+"Critical Strikes (Monster): "+ChatColor.GREEN+"Instant kill");
-			player.sendMessage(ChatColor.DARK_AQUA+"Critical Strikes (Players): "+ChatColor.GREEN+"Double Damage");
+			player.sendMessage(ChatColor.DARK_AQUA+"Skull Splitter (ABILITY): "+ChatColor.GREEN+"Deal AoE Damage");
+			player.sendMessage(ChatColor.DARK_AQUA+"Critical Strikes: "+ChatColor.GREEN+"Double Damage");
 			player.sendMessage(ChatColor.DARK_AQUA+"Axe Mastery (500 SKILL): "+ChatColor.GREEN+"Modifies Damage");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Chance to crtically strike: "+ChatColor.YELLOW+percentage+"%");
+			if(mcUsers.getProfile(player).getAxesInt() < 500){
+				player.sendMessage(ChatColor.GRAY+"LOCKED UNTIL 500+ SKILL (AXEMASTERY)");
+			} else {
+				player.sendMessage(ChatColor.RED+"Axe Mastery:"+ChatColor.YELLOW+" Bonus 4 damage");
+			}
+			player.sendMessage(ChatColor.RED+"Skull Splitter Length: "+ChatColor.YELLOW+ticks+"s");
     	}
     	if(split[0].equalsIgnoreCase("/swords")){
 			event.setCancelled(true);
+			int bleedrank = 2;
+			String percentage, parrypercentage = null, counterattackpercentage;
+			float skillvalue = (float)mcUsers.getProfile(player).getSwordsInt();
+			if(mcUsers.getProfile(player).getSwordsInt() < 750){
+				percentage = String.valueOf((skillvalue / 1000) * 100);
+			} else {
+				percentage = "75";
+			}
+			if(skillvalue >= 750)
+				bleedrank+=1;
+			
+			if(mcUsers.getProfile(player).getSwordsInt() <= 900){
+				parrypercentage = String.valueOf((skillvalue / 3000) * 100);
+			} else {
+				parrypercentage = "30";
+			}
+			
+			if(mcUsers.getProfile(player).getSwordsInt() <= 600){
+				counterattackpercentage = String.valueOf((skillvalue / 2000) * 100);
+			} else {
+				counterattackpercentage = "30";
+			}
+			
+			int ticks = 2;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getSwordsInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"SWORDS"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Attacking Monsters");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.DARK_AQUA+"Counter Attack: "+ChatColor.GREEN+"Reflect 50% of damage taken");
+			player.sendMessage(ChatColor.DARK_AQUA+"Serrated Strikes (ABILITY): "+ChatColor.GREEN+"25% DMG AoE, Bleed+ AoE");
+			player.sendMessage(ChatColor.DARK_GRAY+"Serrated Strikes Bleed+: "+ChatColor.GREEN+"5 Tick Bleed");
 			player.sendMessage(ChatColor.DARK_AQUA+"Parrying: "+ChatColor.GREEN+"Negates Damage");
-			player.sendMessage(ChatColor.DARK_AQUA+"Bleed: "+ChatColor.GREEN+"Apply a 2 second bleed DoT to enemies");
+			player.sendMessage(ChatColor.DARK_AQUA+"Bleed: "+ChatColor.GREEN+"Apply a bleed DoT");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Counter Attack Chance: "+ChatColor.YELLOW+counterattackpercentage+"%");
+			player.sendMessage(ChatColor.RED+"Bleed Length: "+ChatColor.YELLOW+bleedrank+" ticks");
+			player.sendMessage(ChatColor.GRAY+"NOTE: "+ChatColor.YELLOW+"1 Tick happens every 2 seconds");
+			player.sendMessage(ChatColor.RED+"Bleed Chance: "+ChatColor.YELLOW+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Parry Chance: "+ChatColor.YELLOW+parrypercentage+"%");
+			player.sendMessage(ChatColor.RED+"Serrated Strikes Length: "+ChatColor.YELLOW+ticks+"s");
+			
     	}
     	if(split[0].equalsIgnoreCase("/acrobatics")){
 			event.setCancelled(true);
+			String dodgepercentage;
+			float skillvalue = (float)mcUsers.getProfile(player).getAcrobaticsInt();
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
+    		if(mcUsers.getProfile(player).getAcrobaticsInt() <= 800){
+    			dodgepercentage = String.valueOf((skillvalue / 4000 * 100));
+    		} else {
+    			dodgepercentage = "20";
+    		}
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"ACROBATICS"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Falling");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
 			player.sendMessage(ChatColor.DARK_AQUA+"Roll: "+ChatColor.GREEN+"Negates Damage");
+			player.sendMessage(ChatColor.DARK_AQUA+"Dodge: "+ChatColor.GREEN+"Reduce damage by half");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Roll Chance: "+ChatColor.YELLOW+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Dodge Chance: "+ChatColor.YELLOW+dodgepercentage+"%");
     	}
     	if(split[0].equalsIgnoreCase("/mining")){
+    		float skillvalue = (float)mcUsers.getProfile(player).getMiningInt();
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
+    		int ticks = 2;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getMiningInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
 			event.setCancelled(true);
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"MINING"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Mining Stone & Ore");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.DARK_AQUA+"Super Breaker (ABILITY): "+ChatColor.GREEN+"Speed+, Triple Drop Chance");
 			player.sendMessage(ChatColor.DARK_AQUA+"Double Drops: "+ChatColor.GREEN+"Double the normal loot");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Double Drop Chance: "+ChatColor.YELLOW+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Super Breaker Length: "+ChatColor.YELLOW+ticks+"s");
     	}
     	if(split[0].equalsIgnoreCase("/repair")){
+    		float skillvalue = (float)mcUsers.getProfile(player).getRepairInt();
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
+    		String repairmastery = String.valueOf((skillvalue / 500) * 100);
 			event.setCancelled(true);
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"REPAIR"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Repairing");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
 			player.sendMessage(ChatColor.DARK_AQUA+"Repair: "+ChatColor.GREEN+"Repair Iron Tools & Armor");
-			player.sendMessage(ChatColor.DARK_AQUA+"Diamond Repair (50+ SKILL): "+ChatColor.GREEN+"Repair Diamond Tools & Armor");
+			player.sendMessage(ChatColor.DARK_AQUA+"Repair Mastery: "+ChatColor.GREEN+"Increased repair amount");
+			player.sendMessage(ChatColor.DARK_AQUA+"Super Repair: "+ChatColor.GREEN+"Double effectiveness");
+			player.sendMessage(ChatColor.DARK_AQUA+"Diamond Repair ("+mcLoadProperties.repairdiamondlevel+"+ SKILL): "+ChatColor.GREEN+"Repair Diamond Tools & Armor");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Repair Mastery: "+ChatColor.YELLOW+"Extra "+repairmastery+"% durability restored");
+			player.sendMessage(ChatColor.RED+"Super Repair Chance: "+ChatColor.YELLOW+percentage+"%");
     	}
     	if(split[0].equalsIgnoreCase("/unarmed")){
 			event.setCancelled(true);
+			String percentage, arrowpercentage;
+			float skillvalue = (float)mcUsers.getProfile(player).getUnarmedInt();
+			
+			if(mcUsers.getProfile(player).getUnarmedInt() < 1000){
+				percentage = String.valueOf((skillvalue / 4000) * 100);
+			} else {
+				percentage = "25";
+			}
+			
+			if(mcUsers.getProfile(player).getUnarmedInt() < 1000){
+				arrowpercentage = String.valueOf(((skillvalue / 1000) * 100) / 2);
+			} else {
+				arrowpercentage = "50";
+			}
+			
+			
+			int ticks = 2;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getUnarmedInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
+    		
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"UNARMED"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Attacking Monsters");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.DARK_AQUA+"Berserk (ABILITY): "+ChatColor.GREEN+"+50% DMG, Breaks weak materials");
 			player.sendMessage(ChatColor.DARK_AQUA+"Disarm (Players): "+ChatColor.GREEN+"Drops the foes item held in hand");
-			player.sendMessage(ChatColor.DARK_AQUA+"Damage+: "+ChatColor.GREEN+"Modifies Damage");
+			player.sendMessage(ChatColor.DARK_AQUA+"Unarmed Mastery: "+ChatColor.GREEN+"Large Damage Upgrade");
+			player.sendMessage(ChatColor.DARK_AQUA+"Unarmed Apprentice: "+ChatColor.GREEN+"Damage Upgrade");
+			player.sendMessage(ChatColor.DARK_AQUA+"Arrow Deflect: "+ChatColor.GREEN+"Deflect arrows");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Arrow Deflect Chance: "+ChatColor.YELLOW+arrowpercentage+"%");
+			player.sendMessage(ChatColor.RED+"Disarm Chance: "+ChatColor.YELLOW+percentage+"%");
+			if(mcUsers.getProfile(player).getUnarmedInt() < 250){
+				player.sendMessage(ChatColor.GRAY+"LOCKED UNTIL 250+ SKILL (UNARMED APPRENTICE)");
+			} else if(mcUsers.getProfile(player).getUnarmedInt() >= 250 && mcUsers.getProfile(player).getUnarmedInt() < 500){
+				player.sendMessage(ChatColor.RED+"Unarmed Apprentice: "+ChatColor.YELLOW+"Damage Upgrade");
+			} else {
+				player.sendMessage(ChatColor.RED+"Unarmed Mastery: "+ChatColor.YELLOW+"Large Damage Upgrade");
+			}
+			player.sendMessage(ChatColor.RED+"Berserk Length: "+ChatColor.YELLOW+ticks+"s");
     	}
     	if(split[0].equalsIgnoreCase("/herbalism")){
 			event.setCancelled(true);
+			int rank = 0;
+			if(mcUsers.getProfile(player).getHerbalismInt() >= 50)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 150)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 250)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 350)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 450)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 550)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 650)
+    			rank++;
+    		if (mcUsers.getProfile(player).getHerbalismInt() >= 750)
+    			rank++;
+			float skillvalue = (float)mcUsers.getProfile(player).getHerbalismInt();
+    		String percentage = String.valueOf((skillvalue / 1000) * 100);
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"HERBALISM"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Harvesting Herbs");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
 			player.sendMessage(ChatColor.DARK_AQUA+"Food+: "+ChatColor.GREEN+"Modifies health received from bread/stew");
 			player.sendMessage(ChatColor.DARK_AQUA+"Double Drops (Wheat): "+ChatColor.GREEN+"Double the normal loot");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Double Drop Chance: "+percentage+"%");
+			player.sendMessage(ChatColor.RED+"Food+ (Rank"+rank+"): Bonus "+rank+" healing");
     	}
     	if(split[0].equalsIgnoreCase("/excavation")){
-
 			event.setCancelled(true);
+			int ticks = 2;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 50)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 150)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 250)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 350)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 450)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 550)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 650)
+    			ticks++;
+    		if(mcUsers.getProfile(player).getExcavationInt() >= 750)
+    			ticks++;
+    		ticks = ticks * 2;
 			player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"EXCAVATION"+ChatColor.RED+"[]-----");
 			player.sendMessage(ChatColor.DARK_GRAY+"XP GAIN: "+ChatColor.WHITE+"Digging and finding treasures");
 			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"EFFECTS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.DARK_AQUA+"Giga Drill Breaker (ABILITY): "+ChatColor.GREEN+"3x Drop Rate, 3x EXP, +Speed");
 			player.sendMessage(ChatColor.DARK_AQUA+"Treasure Hunter: "+ChatColor.GREEN+"Ability to dig for treasure");
+			player.sendMessage(ChatColor.RED+"---[]"+ChatColor.GREEN+"YOUR STATS"+ChatColor.RED+"[]---");
+			player.sendMessage(ChatColor.RED+"Giga Drill Breaker Length: "+ChatColor.YELLOW+ticks+"s");
     	}
 		if(split[0].equalsIgnoreCase("/"+mcLoadProperties.mcmmo)){
 			event.setCancelled(true);
-    		player.sendMessage(ChatColor.GRAY+"mcMMO is an RPG inspired plugin");
-    		player.sendMessage(ChatColor.GRAY+"You can gain skills in several professions by");
-    		player.sendMessage(ChatColor.GRAY+"doing things related to that profession.");
-    		player.sendMessage(ChatColor.GRAY+"Mining for example will increase your mining XP.");
-    		player.sendMessage(ChatColor.GRAY+"Wood Cutting will increase Wood Cutting, etc...");
-    		player.sendMessage(ChatColor.GRAY+"Repairing is simple in mcMMO");
-    		player.sendMessage(ChatColor.GRAY+"Say you want to repair an iron shovel");
-    		player.sendMessage(ChatColor.GRAY+"start by making an anvil by combining 9 iron ingots");
-    		player.sendMessage(ChatColor.GRAY+"on a workbench. Place the anvil and while holding the shovel");
-    		player.sendMessage(ChatColor.GRAY+"right click the anvil to interact with it, If you have spare");
-    		player.sendMessage(ChatColor.GRAY+"iron ingots in your inventory the item will be repaired.");
-    		player.sendMessage(ChatColor.GRAY+"You cannot hurt other party members");
-    		player.sendMessage(ChatColor.BLUE+"Set your own spawn with "+ChatColor.RED+"/"+mcLoadProperties.setmyspawn);
-    		player.sendMessage(ChatColor.GREEN+"Based on your skills you will get "+ChatColor.DARK_RED+"random procs "+ChatColor.GREEN+ "when");
-    		player.sendMessage(ChatColor.GREEN+"using your profession, like "+ChatColor.DARK_RED+"double drops "+ChatColor.GREEN+"or "+ChatColor.DARK_RED+"better repairs");
-    		player.sendMessage(ChatColor.GREEN+"Find out mcMMO commands with /"+mcLoadProperties.mcc);
-    		player.sendMessage(ChatColor.GREEN+"Appreciate the mod? ");
+    		player.sendMessage(ChatColor.RED+"-----[]"+ChatColor.GREEN+"mcMMO"+ChatColor.RED+"[]-----");
+    		player.sendMessage(ChatColor.YELLOW+"mcMMO is an RPG server mod for minecraft.");
+    		player.sendMessage(ChatColor.YELLOW+"There are many skills added by mcMMO to minecraft.");
+    		player.sendMessage(ChatColor.YELLOW+"They can do anything from giving a chance");
+    		player.sendMessage(ChatColor.YELLOW+"for double drops to letting you break materials instantly.");
+    		player.sendMessage(ChatColor.YELLOW+"For example, by harvesting logs from trees you will gain");
+    		player.sendMessage(ChatColor.YELLOW+"Woodcutting xp and once you have enough xp you will gain");
+    		player.sendMessage(ChatColor.YELLOW+"a skill level in Woodcutting. By raising this skill you will");
+    		player.sendMessage(ChatColor.YELLOW+"be able to receive benefits like "+ChatColor.RED+"double drops");
+    		player.sendMessage(ChatColor.YELLOW+"and increase the effects of the "+ChatColor.RED+"\"Tree Felling\""+ChatColor.YELLOW+" ability.");
+    		player.sendMessage(ChatColor.YELLOW+"mcMMO has abilities related to the skill, skills normally");
+    		player.sendMessage(ChatColor.YELLOW+"provide passive bonuses but they also have activated");
+    		player.sendMessage(ChatColor.YELLOW+"abilities too. Each ability is activated by holding");
+    		player.sendMessage(ChatColor.YELLOW+"the appropriate tool and "+ChatColor.RED+"right clicking.");
+    		player.sendMessage(ChatColor.YELLOW+"For example, if you hold a Mining Pick and right click");
+    		player.sendMessage(ChatColor.YELLOW+"you will ready your Pickaxe, attack mining materials");
+    		player.sendMessage(ChatColor.YELLOW+"and then "+ChatColor.RED+"Super Breaker "+ChatColor.YELLOW+"will activate.");
+    		player.sendMessage(ChatColor.GREEN+"Find out mcMMO commands with "+ChatColor.DARK_AQUA+"/"+mcLoadProperties.mcc);
     		player.sendMessage(ChatColor.GREEN+"You can donate via paypal to"+ChatColor.DARK_RED+" nossr50@gmail.com");
     	}
     	if(split[0].equalsIgnoreCase("/"+mcLoadProperties.mcc)){
@@ -335,12 +640,14 @@ public class mcm {
     		}
     		if(mcPermissions.getInstance().mySpawn(player)){
 	    		player.sendMessage(ChatColor.GREEN+"--MYSPAWN COMMANDS--");
-	    		player.sendMessage("/"+mcLoadProperties.myspawn+" "+ChatColor.RED+"- Teleports you to your MySpawn");
+	    		player.sendMessage("/"+mcLoadProperties.myspawn+" "+ChatColor.RED+"- Clears inventory & teleports to myspawn");
 	    		player.sendMessage("/"+mcLoadProperties.clearmyspawn+" "+ChatColor.RED+"- Clears your MySpawn");
 	    		if(mcPermissions.getInstance().setMySpawn(player))
 	    			player.sendMessage("/"+mcLoadProperties.setmyspawn+" "+ChatColor.RED+"- Set your MySpawn");
     		}
     		player.sendMessage(ChatColor.GREEN+"--OTHER COMMANDS--");
+    		if(mcPermissions.getInstance().mcAbility(player))
+    			player.sendMessage("/"+mcLoadProperties.mcability+ChatColor.RED+" - Toggle ability activation with right click");
     		if(mcPermissions.getInstance().adminChat(player)){
     			player.sendMessage("/a "+ChatColor.RED+"- Toggle admin chat");
     		}

+ 1 - 1
mcMMO/plugin.yml

@@ -1,3 +1,3 @@
 name: mcMMO
 main: com.gmail.nossr50.mcMMO
-version: 0.8.11 WIP B17
+version: 0.9.15

+ 37 - 0
vChat/com/gmail/nossr50/vChat/vChat.java

@@ -0,0 +1,37 @@
+package com.gmail.nossr50.vChat;
+
+import java.io.File;
+import java.util.HashMap;
+import org.bukkit.entity.Player;
+import org.bukkit.Server;
+import org.bukkit.event.Event.Priority;
+import org.bukkit.event.Event;
+import org.bukkit.plugin.PluginDescriptionFile;
+import org.bukkit.plugin.PluginLoader;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.plugin.PluginManager;
+
+/**
+ * vChat for Bukkit
+ *
+ * @author nossr50
+ * @author cerevisae
+ */
+public class vChat extends JavaPlugin {
+    private final vPlayerListener playerListener = new vPlayerListener(this);
+    private final HashMap<Player, Boolean> debugees = new HashMap<Player, Boolean>();
+
+    public void onEnable() {
+        PluginManager pm = getServer().getPluginManager();
+        pm.registerEvent(Event.Type.PLAYER_CHAT, playerListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, playerListener, Priority.Normal, this);
+        pm.registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal, this);
+        PluginDescriptionFile pdfFile = this.getDescription();
+        System.out.println( pdfFile.getName() + " version " + pdfFile.getVersion() + " is enabled!" );
+        //Load the users file
+        vUsers.getInstance().loadUsers();
+    }
+    public void onDisable() {
+        System.out.println("vChat Disabled!");
+    }
+}

+ 707 - 0
vChat/com/gmail/nossr50/vChat/vPlayerListener.java

@@ -0,0 +1,707 @@
+package com.gmail.nossr50.vChat;
+
+import org.bukkit.entity.Player;
+import org.bukkit.event.player.PlayerChatEvent;
+import org.bukkit.event.player.PlayerCommandPreprocessEvent;
+import org.bukkit.event.player.PlayerEvent;
+import org.bukkit.event.player.PlayerJoinEvent;
+import org.bukkit.event.player.PlayerListener;
+import org.bukkit.plugin.Plugin;
+import org.bukkit.ChatColor;
+import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import com.gmail.nossr50.mcConfig;
+import com.gmail.nossr50.mcMMO;
+
+/**
+* Handle events for all Player related events
+* @author nossr50
+*/
+public class vPlayerListener extends PlayerListener {
+    private final vChat plugin;
+    protected static final Logger log = Logger.getLogger("Minecraft");
+    //The length of a text box line in pixels
+    protected static final int lineLength = 312;
+    //Characters we will split the line at
+    protected static final String lineSplit = "/- ";
+
+    public vPlayerListener(vChat instance) {
+        plugin = instance;
+    }
+    public void onPlayerJoin(PlayerJoinEvent event) {
+    	Player player = event.getPlayer();
+    	vUsers.addUser(player);
+    	player.sendMessage(ChatColor.YELLOW+"This server is running vChat");
+    	player.sendMessage(ChatColor.YELLOW+"Type /color or /prefix to do some thangs");
+    	player.sendMessage(ChatColor.DARK_AQUA+"Currently running in Linux");
+    	player.sendMessage(ChatColor.DARK_AQUA+"Steam community: vminecraft");
+    }
+    public Boolean isPlayer(String playername){
+    	for(Player derp : plugin.getServer().getOnlinePlayers()){
+    		if(derp.getName().toLowerCase().equals(playername.toLowerCase())){
+    			return true;
+    		}
+    	}
+    	return false;
+    }
+    //Special Color Codes
+    protected static final String[] rainbow = new String[] {
+    	ChatColor.DARK_RED.toString(),
+    	ChatColor.RED.toString(),
+    	ChatColor.GOLD.toString(),
+    	ChatColor.YELLOW.toString(),
+    	ChatColor.GREEN.toString(),
+    	ChatColor.DARK_GREEN.toString(),
+    	ChatColor.BLUE.toString(),
+    	ChatColor.DARK_BLUE.toString(),
+    	ChatColor.AQUA.toString(),
+    	ChatColor.DARK_AQUA.toString(),
+    	ChatColor.DARK_PURPLE.toString(),
+    	ChatColor.LIGHT_PURPLE.toString()
+    	};
+    protected static final String[] xmas = new String[] {
+    	ChatColor.DARK_RED.toString(),
+    	ChatColor.DARK_RED.toString(),
+    	ChatColor.WHITE.toString(),
+    	ChatColor.WHITE.toString(),
+    	ChatColor.DARK_GREEN.toString(),
+    	ChatColor.DARK_GREEN.toString(),
+    	};
+    
+    public void onPlayerChat(PlayerChatEvent event) {
+    	Player player = event.getPlayer();
+    	String message = event.getMessage();
+    	String split[] = event.getMessage().split(" ");
+    	Player[] players = plugin.getServer().getOnlinePlayers();
+    	Plugin tester = plugin.getServer().getPluginManager().getPlugin("mcMMO");
+        if (tester == null) {
+        } else {
+            try {
+                mcMMO plugin = (mcMMO)tester;
+                if (plugin.isPartyChatToggled(player) || plugin.isAdminChatToggled(player)) {
+                    return;
+                } else {
+                	if(split[0].startsWith(">"))
+                		quote(player, message, players);	
+                	else{
+                		quakeColors(player, message, players);
+                	}
+                }
+            } catch (ClassCastException ex) {
+                player.sendMessage("There's a plugin disguised as mcMMO! It's not the one I was expecting!");
+            }
+        }
+    	event.setCancelled(true);
+    }
+    public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
+    	Player player = event.getPlayer();
+    	String message = event.getMessage();
+    	String split[] = event.getMessage().split(" ");
+    	/*
+    	 * COLORS
+    	 */
+    	if(split[0].equalsIgnoreCase("/color")){
+    		event.setCancelled(true);
+    		if(split.length > 1)
+        	{
+        		vUsers.getProfile(player).setColor(split[1]);
+        		player.sendMessage(ChatColor.RED
+        				+ "Default chat color set.");
+        	} else {
+    	        player.sendMessage(ChatColor.RED + "You use these color codes like in quake or MW2.");
+    	        player.sendMessage(ChatColor.RED + "^4 would make text " + ChatColor.DARK_RED
+    	        		+ "red" + ChatColor.RED + ", ^a would make it " + ChatColor.GREEN 
+    	        		+ "light green" + ChatColor.RED + ".");
+    	        player.sendMessage(
+    	        		  ChatColor.BLACK			+ "0"
+    	        		+ ChatColor.DARK_BLUE			+ "1"
+    	        		+ ChatColor.DARK_GREEN			+ "2"
+    	        		+ ChatColor.DARK_AQUA			+ "3"
+    	        		+ ChatColor.DARK_RED 			+ "4"
+    	        		+ ChatColor.DARK_PURPLE 		+ "5"
+    	        		+ ChatColor.GOLD 			+ "6"
+    	        		+ ChatColor.GRAY 		+ "7"
+    	        		+ ChatColor.DARK_GRAY 			+ "8"
+    	        		+ ChatColor.BLUE 	+ "9"
+    	        		+ ChatColor.GREEN 	+ "A"
+    	        		+ ChatColor.AQUA 		+ "B"
+    	        		+ ChatColor.RED 			+ "C"
+    	        		+ ChatColor.LIGHT_PURPLE	+ "D"
+    	        		+ ChatColor.YELLOW			+ "E"
+    	        		+ ChatColor.WHITE			+ "F");
+    					//+ "^r"					+ "[R]ainbow")
+        	}
+            event.setCancelled(true);
+        }
+    	/*
+    	 * PREFIX
+    	 */
+    	if(split[0].equalsIgnoreCase("/prefix")){
+    		event.setCancelled(true);
+    		if(split.length < 3 && player.isOp()){
+                player.sendMessage( ChatColor.RED + "Usage is /prefix [Player] [Color Code] <Tag>");
+                player.sendMessage(ChatColor.RED + "Example: /prefix " + player.getName() + " e ^0[^a<3^0]");
+                player.sendMessage( ChatColor.RED + "This would produce a name like... " + ChatColor.BLACK + "[" + ChatColor.GREEN + "<3" +ChatColor.BLACK + "]" + ChatColor.YELLOW + player.getName());
+                return;
+            }
+            
+    		if(player.isOp()){
+            //Check if the player exists
+            Player other = plugin.getServer().getPlayer(split[1]);
+            if(other == null)
+            {
+                player.sendMessage( ChatColor.RED
+                		+ "The player you specified could not be found");
+                return;
+            }
+            
+            if(split.length >= 3 && split[2] != null)
+            {
+            	vUsers.getProfile(other).setPrefix(split[2]);
+                player.sendMessage(ChatColor.RED + "Name color changed");
+            }
+            if(split.length >= 4 && msgLength(split[3]) > 60)
+            {
+                player.sendMessage( ChatColor.RED
+                		+ "The prefix you entered was too long.");
+                return;
+            }
+            if(split.length >= 4 && split[3] != null)
+            {
+               vUsers.players.findProfile(other).setTag(split[3]);
+	           player.sendMessage(ChatColor.GREEN + "Prefix changed");
+                   log.log(Level.INFO, player + " changed their prefix to " + split[3]);
+            }
+            return;
+        }
+        if(split.length < 2){
+        	 player.sendMessage( ChatColor.RED + "Usage is /prefix [Color Code] <Tag>");
+             player.sendMessage(ChatColor.RED + "Example: /prefix " + player.getName() + " e ^0[^a<3^0]");
+             player.sendMessage( ChatColor.RED + "This would produce a name like... " + ChatColor.BLACK + "[" + ChatColor.GREEN + "<3" + ChatColor.BLACK + "]" + ChatColor.YELLOW + player.getName());
+             return;
+        }       
+        //Name color
+        if(split.length >= 2 && split[1] != null){
+            vUsers.getProfile(player).setPrefix(split[1]);
+            player.sendMessage(ChatColor.RED + "Name color changed");
+        }
+        //Prefix
+        if(split.length >= 3 && split[2] != null){
+        //Check if the prefix is too long        
+	        if(msgLength(split[1]) > 60)
+	        {
+	            player.sendMessage( ChatColor.RED
+	            		+ "The prefix you entered was too long.");
+	            return;
+	        }
+	           vUsers.players.findProfile(player).setTag(split[2]);
+	           player.sendMessage(ChatColor.GREEN + "Prefix changed");
+        }
+    	}
+    	/*
+    	 * SUFFIX	
+    	 */
+    	if(split[0].equalsIgnoreCase("/suffix")){
+    		event.setCancelled(true);
+    	}
+    	if(split[0].equalsIgnoreCase("/rprefix")){
+    		
+    		if(!player.isOp()){
+    			player.sendMessage("Op Only");
+    		}
+    		if(split.length < 2){
+    			player.sendMessage("Usage is /rprefix <name>");
+    			return;
+    		}
+    		if(isPlayer(split[1])){
+    			Player target = plugin.getServer().getPlayer(split[1]);
+    			vUsers.getProfile(target).setPrefix("");
+    			vUsers.getProfile(target).setTag("");
+    		}
+    	}
+    }
+    //=====================================================================
+	//Function:	quakeColors
+	//Input:	Player player: The player talking
+    //			String message: The message to apply the effect to
+	//Output:	boolean: If this feature is enabled
+	//Use:		Displays a message in red
+	//=====================================================================
+	public static void quakeColors(Player player, String message, Player[] players)
+	{
+		//Format the name
+		String playerName = "<"
+				//Insert their tag
+				+ vUsers.getProfile(player).getTag()
+				//Color their name
+				+ colorChange(vUsers.getProfile(player).getPrefix().charAt(0))
+				//Insert their name
+				+ player.getName() +ChatColor.WHITE+ "> ";
+
+			String color = vUsers.getProfile(player).getColor();
+			//Log the chat
+			log.log(Level.INFO, "<"+player.getName()+"> " + message);
+			
+			//Output the message
+			gmsg(player, playerName + color + message, players);
+
+			//Loop through the string finding the color codes and inserting them
+	}
+  //=====================================================================
+  //Function: gmsg
+  //Input: Player sender: The player sending the message
+  // String msg: The message to be broadcast to all players
+  //Output: None
+  //Use: Outputs a message to everybody
+  //=====================================================================
+      public static void gmsg(Player sender, String msg, Player[] players){
+    	/* Disabled for now
+       if(sender != null && sender.isMuted())
+       sender.sendMessage(ChatColor.DARK_RED + "You have been muted.");
+       	*/
+      
+          for (Player receiver : players) {
+          
+              if (receiver == null) return;
+              
+           //if(vUsers.getProfile(receiver) == null) return;
+          
+           //Check if the person has the sender ignored
+           /* Disabled for now
+           if(sender != null)
+           if(vUsers.getProfile(receiver).isIgnored(sender))
+           return;
+           */
+		  String[] message = applyColors(wordWrap(msg));
+		  for(String out : message)
+		  receiver.sendMessage(out);
+          }
+      }
+    //=====================================================================
+    //Function: gmsg
+    //Input: String msg: The message to be broadcast to all players
+    //Output: None
+    //Use: Outputs a message to everybody
+    //=====================================================================
+        public static void gmsg(String msg){gmsg(null, msg, null);}
+        public static void gmsg(Player player, String msg){gmsg(player, msg, null);}
+      //=====================================================================
+      //Function: wordWrap
+      //Input: String msg: The message to be wrapped
+      //Output: String[]: The array of substrings
+      //Use: Cuts the message apart into whole words short enough to fit
+          // on one line
+      //=====================================================================
+          public static String[] wordWrap(String msg){
+           //Split each word apart
+           ArrayList<String> split = new ArrayList<String>();
+           for(String in : msg.split(" "))
+           split.add(in);
+          
+           //Create an arraylist for the output
+           ArrayList<String> out = new ArrayList<String>();
+           //While i is less than the length of the array of words
+           while(!split.isEmpty()){
+           int len = 0;
+              
+           //Create an arraylist to hold individual words
+           ArrayList<String> words = new ArrayList<String>();
+
+           //Loop through the words finding their length and increasing
+           //j, the end point for the sub string
+           while(!split.isEmpty() && split.get(0) != null && len <= lineLength)
+           {
+           int wordLength = msgLength(split.get(0)) + 4;
+          
+           //If a word is too long for a line
+           if(wordLength > lineLength)
+           {
+               String[] tempArray = wordCut(len, split.remove(0));
+               words.add(tempArray[0]);
+               split.add(tempArray[1]);
+           }
+
+           //If the word is not too long to fit
+           len += wordLength;
+           if( len < lineLength)
+           words.add(split.remove(0));
+           }
+           //Merge them and add them to the output array.
+           out.add(combineSplit(words.toArray(new String[words.size()]), " ") + " " );
+           }
+           //Convert to an array and return
+           return out.toArray(new String[out.size()]);
+          }
+          
+          //CombineSplit
+          public static String combineSplit(String[] array, String merge) {
+        	    String out = "";
+        	    for(String word : array)
+        	        out += word + merge;
+        	    return out;
+        	}
+
+      	//=====================================================================
+      	//Function:	msgLength
+      	//Input:	String str: The string to find the length of
+      	//Output:	int: The length on the screen of a string
+      	//Use:		Finds the length on the screen of a string. Ignores colors.
+      	//=====================================================================
+          public static int msgLength(String str){
+      		int length = 0;
+      		//Loop through all the characters, skipping any color characters
+      		//and their following color codes
+      		for(int x = 0; x<str.length(); x++)
+      		{
+      			if((x+1 <= str.length()) && (str.charAt(x) == '^' || str.charAt(x) == ChatColor.WHITE.toString().charAt(0)))
+      			{
+                                      if(colorChange(str.charAt(x + 1)) != null)
+      				{
+      					x++;
+                                              continue;
+      				}
+      			}
+      			int len = charLength(str.charAt(x));
+      			length += len;
+      		}
+      		return length;
+          }
+  //=====================================================================
+  //Function: colorChange
+  //Input: char colour: The color code to find the color for
+  //Output: String: The color that the code identified
+  //Use: Finds a color giving a color code
+  //=====================================================================
+    public static String colorChange(char colour)
+    {
+	    String color;
+	    switch(colour)
+	    {
+	    case '0':
+	    color = ChatColor.BLACK.toString();
+	    break;
+	    case '1':
+	    color = ChatColor.DARK_BLUE.toString();
+	    break;
+	    case '2':
+	    color = ChatColor.DARK_GREEN.toString();
+	    break;
+	    case '3':
+	    color = ChatColor.DARK_AQUA.toString();
+	    break;
+	    case '4':
+	    color = ChatColor.DARK_RED.toString();
+	    break;
+	    case '5':
+	    color = ChatColor.DARK_PURPLE.toString();
+	    break;
+	    case '6':
+	    color = ChatColor.GOLD.toString();
+	    break;
+	    case '7':
+	    color = ChatColor.GRAY.toString();
+	    break;
+	    case '8':
+	    color = ChatColor.DARK_GRAY.toString();
+	    break;
+	    case '9':
+	    color = ChatColor.BLUE.toString();
+	    break;
+	    case 'a':
+	    color = ChatColor.GREEN.toString();
+	    break;
+	    case 'b':
+	    color = ChatColor.AQUA.toString();
+	    break;
+	    case 'c':
+	    color = ChatColor.RED.toString();
+	    break;
+	    case 'd':
+	    color = ChatColor.LIGHT_PURPLE.toString();
+	    break;
+	    case 'e':
+	    color = ChatColor.YELLOW.toString();
+	    break;
+	    case 'f':
+	    color = ChatColor.WHITE.toString();
+	    break;
+	    case 'A':
+	    color = ChatColor.GREEN.toString();
+	    break;
+	    case 'B':
+	    color = ChatColor.AQUA.toString();
+	    break;
+	    case 'C':
+	    color = ChatColor.RED.toString();
+	    break;
+	    case 'D':
+	    color = ChatColor.LIGHT_PURPLE.toString();
+	    break;
+	    case 'E':
+	    color = ChatColor.YELLOW.toString();
+	    break;
+	    case 'F':
+	    color = ChatColor.WHITE.toString();
+	    break;
+	    case 'R':
+	    color = "^r";
+	    break;
+	    case 'r':
+	    color = "^r";
+	    break;
+        case 'x':
+        color = "^x";
+        break;
+        case 'X':
+        color = "^x";
+        break;
+        default:
+        color = null;
+        break;
+    }
+                    return color;
+    }
+    
+    private static String[] wordCut(int lengthBefore, String str){
+    	int length = lengthBefore;
+    	//Loop through all the characters, skipping any color characters
+    	//and their following color codes
+    	String[] output = new String[2];
+    	int x = 0;
+    	while(length < lineLength && x < str.length())
+    	{
+    	int len = charLength(str.charAt(x));
+    	if( len > 0)
+    	length += len;
+    	else
+    	x++;
+    	x++;
+    	}
+    	if(x > str.length())
+    	x = str.length();
+    	//Add the substring to the output after cutting it
+    	output[0] = str.substring(0, x);
+    	//Add the last of the string to the output.
+    	output[1] = str.substring(x);
+    	return output;
+    	    }
+    
+    private static int charLength(char x)
+    {
+    if("i.:,;|!".indexOf(x) != -1)
+	return 2;
+	else if("l'".indexOf(x) != -1)
+	return 3;
+	else if("tI[]".indexOf(x) != -1)
+	return 4;
+	else if("fk{}<>\"*()".indexOf(x) != -1)
+	return 5;
+	else if("abcdeghjmnopqrsuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ1234567890\\/#?$%-=_+&^".indexOf(x) != -1)
+	return 6;
+	else if("@~".indexOf(x) != -1)
+	return 7;
+	else if(x==' ')
+	return 4;
+	else
+	return -1;
+    }
+    
+  //=====================================================================
+  //Function: rainbow
+  //Input: String msg: The string to colorify
+  //Output: String: The rainbowed result
+  //Use: Rainbowifies a string;
+  //=====================================================================
+      public static String rainbow(String msg){
+       String temp = "";
+	  int counter=0;
+	  //Loop through the message applying the colors
+	  for(int x=0; x<msg.length(); x++)
+	  {
+	  temp += rainbow[counter]+msg.charAt(x);
+	
+	  if(msg.charAt(x)!=' ') counter++;
+	  if(counter==rainbow.length) counter = 0;
+	  }
+	  return temp;
+      }
+  //=====================================================================
+  //Function: xmas
+  //Input: String msg: The string to colorify
+  //Output: String: The xmas colored result
+  //Use: Makes a string more festive
+  //=====================================================================
+      public static String xmas(String msg){
+       String temp = "";
+	  int counter=0;
+	  //Loop through the message applying the colors
+	  for(int x=0; x<msg.length(); x++)
+	  {
+	  temp += xmas[counter]+msg.charAt(x);
+	
+	  if(msg.charAt(x)!=' ') counter++;
+	  if(counter==xmas.length) counter = 0;
+	  }
+	  return temp;
+      }
+      
+    //=====================================================================
+    //Function: quote
+    //Input: Player player: The player talking
+        // String message: The message to apply the effect to
+    //Output: boolean: If this feature is enabled
+    //Use: Displays a message as a quote
+    //=====================================================================
+    public void quote(Player player, String message, Player[] players)
+    {
+    //Format the name
+    	//Format the name
+		String playerName = "<"+
+				//Insert their tag
+				vUsers.getProfile(player).getTag()
+				//Color their name
+				+ colorChange(vUsers.getProfile(player).getPrefix().charAt(0))
+				//Insert their name
+				+ player.getName() +ChatColor.WHITE+ "> ";
+    //Log the chat
+    log.log(Level.INFO, "<"+player.getName()+"> " + message);
+    //Output the message
+    gmsg(player, playerName + ChatColor.GREEN + message, players);
+    }
+    
+    //=====================================================================
+	//Function:	applyColors
+	//Input:	String[] message: The lines to be colored
+	//Output:	String[]: The lines, but colorful
+	//Use:		Colors each line
+	//=====================================================================
+	public static String[] applyColors(String[] message)
+	{
+		if(message != null && message[0] != null && !message[0].isEmpty()){
+			//The color to start the line with
+			String recentColor = ChatColor.WHITE.toString();
+			
+			//Go through each line
+			int counter = 0;
+			int i = 0;
+			boolean taste = false;
+            boolean xmasparty = false;
+			
+			for(String msg: message)
+			{	
+				//Start the line with the most recent color
+				String temp = "";
+				if(!recentColor.equals("^r") && !recentColor.equals("^x") && recentColor != null)
+					temp += recentColor;
+				
+				//Loop through looking for a color code
+				for(int x = 0; x< msg.length(); x++)
+				{
+					//If the char is a ^ or
+					if(taste || msg.charAt(x) == '^'
+							|| msg.charAt(x) == ChatColor.DARK_RED.toString().charAt(0))
+					{
+						if(x != msg.length() - 1)
+						{
+							//If the following character is a color code
+							if(colorChange(msg.charAt(x+1)) != null)
+							{
+								//Set the most recent color to the new color
+								recentColor = colorChange(msg.charAt(x+1));
+								
+								//If the color specified is rainbow
+								if(taste || recentColor.equals("^r"))
+								{
+									/*
+									//Skip the quake code for rainbow
+									if(recentColor.equals("^r"))
+									{
+										x += 2;
+									}
+									
+									//Taste keeps it going with rainbow if there
+									//are more lines
+									taste = true;
+									//Loop through the message applying the colors
+									while(x < msg.length() && msg.charAt(x) != '^'
+										&& msg.charAt(x) != ChatColor.DARK_RED.toString().charAt(0))
+									{
+										temp += rainbow[i] + msg.charAt(x);
+										if(msg.charAt(x) != ' ') i++;
+										if(i == rainbow.length) i = 0;
+										x++;
+									}
+									
+									//If it reached another color instead of the end
+									if(x < msg.length() && msg.charAt(x) == '^')
+									{
+										taste = false;
+										i = 0;
+										x--;
+									}
+									*/
+								}
+                                if(xmasparty || recentColor.equals("^x"))
+								{
+                                	/*
+									//Skip the quake code for xmas
+									if(recentColor.equals("^x"))
+									{
+										x += 2;
+									}
+									
+									//xmasparty keeps it going with xmas if there
+									//are more lines
+									xmasparty = true;
+									//Loop through the message applying the colors
+									while(x < msg.length() && msg.charAt(x) != '^'
+										&& msg.charAt(x) != ChatColor.DARK_RED.toString().charAt(0))
+									{
+										temp += xmas[i] + msg.charAt(x);
+										
+										if(msg.charAt(x) != ' ') i++;
+										if(i == xmas.length) i = 0;
+										x++;
+									}
+									
+									//If it reached another color instead of the end
+									if(x < msg.length() && msg.charAt(x) == '^'
+											|| x < msg.length()
+											&&  msg.charAt(x) == ChatColor.DARK_RED.toString().charAt(0) )
+									{
+										xmasparty = false;
+										i = 0;
+										x--;
+									}
+									*/
+								}
+								else
+                                                                
+								{
+									//Add the color
+									temp += recentColor;
+									//Skip these chars
+									x++;
+								}
+								
+							//Otherwise ignore it.
+							} else {
+								temp += msg.charAt(x);
+							}
+						//Insert the character
+						} else {
+							temp += msg.charAt(x);
+						}
+					} else {
+						temp += msg.charAt(x);
+					}
+				}
+				//Replace the message with the colorful message
+				message[counter] = temp;
+				counter++;
+			}
+		}
+		return message;
+	}
+}

+ 570 - 0
vChat/com/gmail/nossr50/vChat/vUsers.java

@@ -0,0 +1,570 @@
+package com.gmail.nossr50.vChat;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.bukkit.entity.*;
+
+public class vUsers {
+    private static volatile vUsers instance;
+    protected static final Logger log = Logger.getLogger("Minecraft");
+    String location = "vChat.users";
+    public static PlayerList players = new PlayerList();
+    private Properties properties = new Properties();
+    
+    //To load
+    public void load() throws IOException {
+        properties.load(new FileInputStream(location));
+    }
+    //To save
+    public void save() {
+        try {
+        properties.store(new FileOutputStream(location), null);
+        }catch(IOException ex) {
+        }
+    }
+    
+    
+    public void loadUsers(){
+        File theDir = new File(location);
+		if(!theDir.exists()){
+			//properties = new PropertiesFile(location);
+			FileWriter writer = null;
+			try {
+				writer = new FileWriter(location);
+				writer.write("#Storage place for user information\r\n");
+                writer.write("#username:nickname:suffix:tag:ignore,list,names:alias,commands,here\r\n");
+			} catch (Exception e) {
+				log.log(Level.SEVERE, "Exception while creating " + location, e);
+			} finally {
+				try {
+					if (writer != null) {
+						writer.close();
+					}
+				} catch (IOException e) {
+					log.log(Level.SEVERE, "Exception while closing writer for " + location, e);
+				}
+			}
+
+		} else {
+			//properties = new PropertiesFile(location);
+			try {
+				load();
+			} catch (IOException e) {
+				log.log(Level.SEVERE, "Exception while loading " + location, e);
+			}
+		}
+    }
+
+	//=====================================================================
+	//Function:	addUser
+	//Input:	Player player: The player to create a profile for
+	//Output:	none
+	//Use:		Loads the profile for the specified player
+	//=====================================================================
+    public static void addUser(Player player){
+    	players.addPlayer(player);
+    }
+
+	//=====================================================================
+	//Function:	removeUser
+	//Input:	Player player: The player to stop following
+	//Output:	none
+	//Use:		Creates the player profile
+	//=====================================================================
+    public static void removeUser(Player player){
+    	players.removePlayer(player);
+    }
+
+	//=====================================================================
+	//Function:	getProfile
+	//Input:	Player player: The player to find the profile for
+	//Output:	PlayerList.PlayerProfile: The profile
+	//Use:		Gets the player profile
+	//=====================================================================
+    public static PlayerList.PlayerProfile getProfile(Player player){
+    	return players.findProfile(player);
+    }
+    
+    public static vUsers getInstance() {
+		if (instance == null) {
+			instance = new vUsers();
+		}
+		return instance;
+	}
+    public static void getRow(){
+
+    }
+}
+class PlayerList
+{       
+    protected static final Logger log = Logger.getLogger("Minecraft");
+	ArrayList<PlayerProfile> players;
+	
+	//=====================================================================
+	//Function:	PlayerList
+	//Input:	Player player: The player to create a profile object for
+	//Output:	none
+	//Use:		Initializes the ArrayList
+	//=====================================================================
+	public PlayerList() { players = new ArrayList<PlayerProfile>(); }
+
+	//=====================================================================
+	//Function:	addPlayer
+	//Input:	Player player: The player to add
+	//Output:	None
+	//Use:		Add a profile of the specified player
+	//=====================================================================
+	public void addPlayer(Player player)
+	{
+		players.add(new PlayerProfile(player));
+	}
+
+	//=====================================================================
+	//Function:	removePlayer
+	//Input:	Player player: The player to remove
+	//Output:	None
+	//Use:		Remove the profile of the specified player
+	//=====================================================================
+	public void removePlayer(Player player)
+	{
+		players.remove(findProfile(player));
+	}
+
+	//=====================================================================
+	//Function:	findProfile
+	//Input:	Player player: The player to find's profile
+	//Output:	PlayerProfile: The profile of the specified player
+	//Use:		Get the profile for the specified player
+	//=====================================================================
+	public PlayerProfile findProfile(Player player)
+	{
+		for(PlayerProfile ply : players)
+		{
+			if(ply.isPlayer(player))
+				return ply;
+		}
+		return null;
+	}
+	
+	//=====================================================================
+	//Class:	PlayerProfile
+	//Use:		Encapsulates all commands for player options
+	//Author:	cerevisiae
+	//=====================================================================
+	class PlayerProfile
+	{
+	    protected final Logger log = Logger.getLogger("Minecraft");
+		private String playerName,
+					   lastMessage,
+					   nickName,
+					   tag,
+					   suffix,
+					   prefix,
+                        party;
+		
+		private boolean dead,
+                        silent;
+		
+		char defaultColor;
+
+        String location = "vChat.users";
+		
+		private ArrayList<String> ignoreList;
+		//private commandList aliasList;
+		
+	    static final int EXIT_FAIL		= 0,
+			 			 EXIT_SUCCESS	= 1,
+			 			 EXIT_CONTINUE	= 2;
+
+		//=====================================================================
+		//Function:	PlayerProfile
+		//Input:	Player player: The player to create a profile object for
+		//Output:	none
+		//Use:		Loads settings for the player or creates them if they don't
+		//			exist.
+		//=====================================================================
+		public PlayerProfile(Player player)
+		{
+            //Declare things
+			playerName = player.getName();
+            tag = new String();
+            nickName = new String();
+            suffix = new String();
+            prefix = new String();
+            party = new String();
+            party = null;
+            defaultColor = 'f';
+			ignoreList = new ArrayList<String>();
+            dead = false;
+            
+            //Try to load the player and if they aren't found, append them
+            if(!load())
+            	addPlayer();
+		}
+		
+		public boolean load()
+		{
+            try {
+            	//Open the user file
+            	FileReader file = new FileReader(location);
+            	BufferedReader in = new BufferedReader(file);
+            	String line = "";
+            	while((line = in.readLine()) != null)
+            	{
+            		//Find if the line contains the player we want.
+            		String[] character = line.split(":");
+            		if(!character[0].equals(playerName)){continue;}
+            		
+        			//Get the tag
+        			if(character.length > 1)
+        				tag = character[1];
+        			//Get the nickname
+        			if(character.length > 2)
+        				nickName = character[2];
+        			//Get the suffix
+        			if(character.length > 3)
+        				suffix = character[3];
+        			//Get the color
+        			if(character.length > 4)
+        				defaultColor = character[4].charAt(0);
+        			//Ignore previously ignored players
+        			if(character.length > 5)
+        			{
+        				String[] ignores = character[5].split(",");
+        				if(ignores.length > 0)
+        				{
+        					for(String ignore : ignores)
+        						ignoreList.add(ignore);
+        				}
+        			}
+                	in.close();
+        			return true;
+            	}
+            	in.close();
+	        } catch (Exception e) {
+	            log.log(Level.SEVERE, "Exception while reading "
+	            		+ location + " (Are you sure you formatted it correctly?)", e);
+	        }
+	        return false;
+		}
+		
+        //=====================================================================
+        // Function:    save
+        // Input:       none
+        // Output:      None
+        // Use:         Writes current values of PlayerProfile to disk
+		//				Call this function to save current values
+        //=====================================================================
+        public void save()
+        {
+            try {
+            	//Open the file
+            	FileReader file = new FileReader(location);
+                BufferedReader in = new BufferedReader(file);
+                StringBuilder writer = new StringBuilder();
+            	String line = "";
+            	
+            	//While not at the end of the file
+            	while((line = in.readLine()) != null)
+            	{
+            		//Read the line in and copy it to the output it's not the player
+            		//we want to edit
+            		if(!line.split(":")[0].equalsIgnoreCase(playerName))
+            		{
+                        writer.append(line).append("\r\n");
+                        
+                    //Otherwise write the new player information
+            		} else {
+            			writer.append(playerName + ":");
+            			writer.append(tag + ":");
+            			writer.append(nickName + ":");
+            			writer.append(suffix + ":");
+            			writer.append(defaultColor + ":");
+            			writer.append(prefix + ":");
+                                           			
+            			int i = 0;
+            			for(String ignore : ignoreList)
+            			{
+            				writer.append(ignore);
+            				if(i < ignoreList.size() - 1)
+            					writer.append(",");
+            			}
+            			writer.append("\r\n");
+            		}
+            	}
+            	in.close();
+            	//Write the new file
+                FileWriter out = new FileWriter(location);
+                out.write(writer.toString());
+                out.close();
+	        } catch (Exception e) {
+                    log.log(Level.SEVERE, "Exception while writing to " + location + " (Are you sure you formatted it correctly?)", e);
+	        }
+		}
+        public void addPlayer()
+        {
+            try {
+            	//Open the file to write the player
+            	FileWriter file = new FileWriter(location, true);
+                BufferedWriter out = new BufferedWriter(file);
+                
+                //Add the player to the end
+                out.append(playerName + ":");
+                out.append("" + ":");
+                out.append(nickName + ":");
+                out.append(suffix + ":");
+                out.append("f" + ":");
+                out.append("f" + ":");
+                
+    			
+    			int i = 0;
+    			for(String ignore : ignoreList)
+    			{
+    				out.append(ignore);
+    				if(i < ignoreList.size() - 1)
+    					out.append(",");
+    			}
+    			out.newLine();
+    			out.close();
+	        } catch (Exception e) {
+                    log.log(Level.SEVERE, "Exception while writing to " + location + " (Are you sure you formatted it correctly?)", e);
+	        }
+        }
+
+		//=====================================================================
+		//Function:	isPlayer
+		//Input:	None
+		//Output:	Player: The player this profile belongs to
+		//Use:		Finds if this profile belongs to a specified player
+		//=====================================================================
+		public boolean isPlayer(Player player)
+		{
+			return player.getName().equals(playerName);
+		}
+
+		//=====================================================================
+		//Function:	isIgnored
+		//Input:	Player player: Checks if a player is ignored
+		//Output:	boolean: If they're ignored
+		//Use:		Finds if the specified player is in the ignore list
+		//=====================================================================
+		public boolean isIgnored(Player player){
+			return ignoreList.contains(player.getName());
+		}
+
+		//=====================================================================
+		//Function:	addIgnore
+		//Input:	Player name: The player to ignore
+		//Output:	boolean: If the player was successfully ignored
+		//Use:		Ignores a player.
+		//=====================================================================
+		public boolean addIgnore(Player name)
+		{
+			if(!ignoreList.contains(name))
+			{
+				ignoreList.add(name.getName());
+				save();
+				return true;
+			}
+			return false;
+		}
+
+		//=====================================================================
+		//Function:	removeIgnore
+		//Input:	Player name: The player to unignore
+		//Output:	boolean: If the player was successfully unignored
+		//Use:		Stops ignoring a player.
+		//=====================================================================
+		public boolean removeIgnore(Player name)
+		{
+			if(ignoreList.contains(name.getName()))
+			{
+				ignoreList.remove(name.getName());
+				save();
+				return true;
+			}
+			return false;
+		}
+
+		//=====================================================================
+		//Function:	removeIgnore
+		//Input:	Player name: The player to unignore
+		//Output:	boolean: If the player was successfully unignored
+		//Use:		Stops ignoring a player.
+		//=====================================================================
+		public String[] listIgnore()
+		{
+			return ignoreList.toArray(new String[ignoreList.size()]);
+		}
+
+		//=====================================================================
+		//Function:	setTag
+		//Input:	String newTag: The tag to set for the player
+		//Output:	None
+		//Use:		Sets a player tag
+		//=====================================================================
+		public void setTag(String newTag)
+		{
+			tag = newTag;
+			save();
+		}
+		//=====================================================================
+		//Function:	getTag
+		//Input:	None
+		//Output:	String: The player tag
+		//Use:		Gets a player tag
+		//=====================================================================
+		public String getTag() { return tag; }
+
+		//=====================================================================
+		//Function:	setNick
+		//Input:	String newTag: The nickname to set for the player
+		//Output:	None
+		//Use:		Sets a player nickname
+		//=====================================================================
+		public void setNick(String newNick)
+		{
+			nickName = newNick;
+			save();
+		}
+                
+                public void setSilent(){
+                    silent = true;
+                }
+                public void disableSilent(){
+                    silent = false;
+                }
+                public boolean isSilent(){
+                    return silent;
+                }
+                //Store the player's party
+                public void setParty(String newParty)
+                {
+                    party = newParty;
+                    save();
+                }
+                //Retrieve the player's party
+                public String getParty() {return party;}
+                //Remove party
+                public void removeParty() {
+                    party = null;
+                    save();
+                }
+                //Retrieve whether or not the player is in a party
+                public boolean inParty() {
+                    if(party != null){
+                        return true;
+                    } else {
+                        return false;
+                    }
+                }
+
+		//=====================================================================
+		//Function:	getNick
+		//Input:	None
+		//Output:	String: The player nickname
+		//Use:		Gets a player nickname
+		//=====================================================================
+		public String getNick() { return nickName; }
+
+		//=====================================================================
+		//Function:	setSuffix
+		//Input:	String newTag: The suffix to set for the player
+		//Output:	None
+		//Use:		Sets a player suffix
+		//=====================================================================
+		public void setSuffix(String newSuffix)
+		{
+			suffix = newSuffix;
+			save();
+		}
+
+		//=====================================================================
+		//Function:	getSuffix
+		//Input:	None
+		//Output:	String: The player suffix
+		//Use:		Gets a player suffix
+		//=====================================================================
+		public String getSuffix() { return suffix; }
+		
+		public void setPrefix(String newPrefix)
+		{
+			prefix = newPrefix;
+			save();
+		}
+		
+		public String getPrefix() {
+			if(prefix != null && !prefix.equals("") && !prefix.equals("null")){
+			return prefix; 
+			} else {
+				return "f";
+			}
+		}
+
+		//=====================================================================
+		//Function:	setColor
+		//Input:	String newTag: The color to set for the player
+		//Output:	None
+		//Use:		Sets a player color
+		//=====================================================================
+		public void setColor(String newColor)
+		{
+			defaultColor = newColor.charAt(0);
+			save();
+		}
+
+		//=====================================================================
+		//Function:	getColor
+		//Input:	None
+		//Output:	String: The player color
+		//Use:		Gets a player color
+		//=====================================================================
+		public String getColor() {return vPlayerListener.colorChange(defaultColor);}
+
+		//=====================================================================
+		//Function:	setMessage
+		//Input:	String newName: The name of the player they last messaged
+		//			or recieved a message from.
+		//Output:	None
+		//Use:		Sets a player tag
+		//=====================================================================
+		public void setMessage(Player newName){ lastMessage = newName.getName(); }
+
+		//=====================================================================
+		//Function:	getMessage
+		//Input:	None
+		//Output:	String: The player name
+		//Use:		Gets the name of the player they last messaged or recieved
+		//			a message from.
+		//=====================================================================
+		public Player getMessage()
+		{
+			    //if(lastMessage != null)
+				//We need the bukkit equivalent of this
+				//return matchPlayer(lastMessage);
+				return null;
+		}
+
+		//=====================================================================
+		//Function:	isDead
+		//Input:	None
+		//Output:	boolean: If the player is dead or not
+		//Use:		Gets the player is dead or not.
+		//=====================================================================
+		public boolean isDead() {return dead;}
+
+		//=====================================================================
+		//Function:	isDead
+		//Input:	boolean isded: if the player is dead or not.
+		//Output:	None
+		//Use:		Sets if the player is dead or not
+		//=====================================================================
+		public void isDead(boolean isded){dead = isded;}
+	}
+}
+
+
+

+ 2 - 2
vChat/plugin.yml

@@ -1,3 +1,3 @@
-name: vChat
-main: com.bukkit.nossr50.vChat.vChat
+name: vChat
+main: com.gmail.nossr50.vChat.vChat
 version: 1.0

Some files were not shown because too many files changed in this diff