Browse Source

Update to SpoutStuff.java

GJ 13 years ago
parent
commit
f2be996e3d

+ 69 - 3
src/main/java/com/gmail/nossr50/datatypes/HUDmmo.java

@@ -236,7 +236,7 @@ public class HUDmmo
 		((GenericTexture) xpicon).setUrl(m.getCapitalized(theType.toString())+".png");
 		xpicon.setDirty(true);
 
-		((GenericTexture) xpbar).setUrl(SpoutStuff.getUrlBar(SpoutStuff.getXpInc(PP.getSkillXpLevel(theType), PP.getXpToLevel(theType), HUDType.STANDARD)));
+		((GenericTexture) xpbar).setUrl(getUrlBar(getXpInc(PP.getSkillXpLevel(theType), PP.getXpToLevel(theType), HUDType.STANDARD)));
 		xpbar.setDirty(true);
 		
 		SpoutManager.getPlayer(player).getMainScreen().setDirty(true);
@@ -256,16 +256,82 @@ public class HUDmmo
 		if(theType == null)
 			return;
 		
-		Color color = SpoutStuff.getRetroColor(theType);
+		Color color = getRetroColor(theType);
 		
 		if(xpicon != null && theType != null)
 			xpicon.setUrl(m.getCapitalized(theType.toString())+"_r.png");
 		
 		if(theType != null)
-			xpfill.setBottomColor(color).setTopColor(color).setWidth(SpoutStuff.getXpInc(PP.getSkillXpLevel(theType), PP.getXpToLevel(theType), HUDType.RETRO)).setDirty(true);
+			xpfill.setBottomColor(color).setTopColor(color).setWidth(getXpInc(PP.getSkillXpLevel(theType), PP.getXpToLevel(theType), HUDType.RETRO)).setDirty(true);
 		else
 			System.out.println("theType was null!");
 		
 		SpoutManager.getPlayer(player).getMainScreen().setDirty(true);
 	}
+	
+    private static Color getRetroColor(SkillType type) {
+        switch (type) {
+            case ACROBATICS:
+                return new Color((float) LoadProperties.acrobatics_r, (float) LoadProperties.acrobatics_g, (float) LoadProperties.acrobatics_b, 1f);
+            case ARCHERY:
+                return new Color((float) LoadProperties.archery_r, (float)LoadProperties.archery_g, (float)LoadProperties.archery_b, 1f);
+            case AXES:
+                return new Color((float) LoadProperties.axes_r, (float)LoadProperties.axes_g, (float)LoadProperties.axes_b, 1f);
+            case EXCAVATION:
+                return new Color((float)LoadProperties.excavation_r, (float)LoadProperties.excavation_g, (float)LoadProperties.excavation_b, 1f);
+            case HERBALISM:
+                return new Color((float)LoadProperties.herbalism_r, (float)LoadProperties.herbalism_g, (float)LoadProperties.herbalism_b, 1f);
+            case MINING:
+                return new Color((float)LoadProperties.mining_r, (float)LoadProperties.mining_g, (float)LoadProperties.mining_b, 1f);
+            case REPAIR:
+                return new Color((float)LoadProperties.repair_r, (float)LoadProperties.repair_g, (float)LoadProperties.repair_b, 1f);
+            case SWORDS:
+                return new Color((float)LoadProperties.swords_r, (float)LoadProperties.swords_g, (float)LoadProperties.swords_b, 1f);
+            case TAMING:
+                return new Color((float)LoadProperties.taming_r, (float)LoadProperties.taming_g, (float)LoadProperties.taming_b, 1f);
+            case UNARMED:
+                return new Color((float)LoadProperties.unarmed_r, (float)LoadProperties.unarmed_g, (float)LoadProperties.unarmed_b, 1f);
+            case WOODCUTTING:
+                return new Color((float)LoadProperties.woodcutting_r, (float)LoadProperties.woodcutting_g, (float)LoadProperties.woodcutting_b, 1f);
+            case FISHING:
+                return new Color((float)LoadProperties.fishing_r, (float)LoadProperties.fishing_g, (float)LoadProperties.fishing_b, 1f);
+            default:
+                return new Color(0.3f, 0.3f, 0.75f, 1f);
+        }
+    }
+
+    private static String getUrlBar(Integer number) {
+        char[] num = number.toString().toCharArray();
+
+        switch (num.length) {
+        case 1:
+            return "xpbar_inc00"+number+".png";
+
+        case 2:
+            return "xpbar_inc0"+number+".png";
+
+        default:
+            return "xpbar_inc"+number+".png";
+        }
+    }
+
+    private static Integer getXpInc(int skillxp, int xptolevel, HUDType hud) {
+        double percentage = (double) skillxp / xptolevel;
+        double inc;
+
+        switch (hud) {
+        case RETRO:
+            inc = 0.0079365079365079;
+            break;
+
+        case STANDARD:
+            inc = 0.0039370078740157;
+            break;
+
+        default:
+            return 1;
+        }
+
+        return (int) (percentage / inc);
+    }
 }

+ 3 - 4
src/main/java/com/gmail/nossr50/listeners/mcBlockListener.java

@@ -16,8 +16,7 @@ import com.gmail.nossr50.skills.Herbalism;
 import com.gmail.nossr50.skills.Mining;
 import com.gmail.nossr50.skills.Skills;
 import com.gmail.nossr50.skills.WoodCutting;
-import com.gmail.nossr50.spout.SpoutStuff;
-
+import com.gmail.nossr50.spout.SpoutSounds;
 
 import org.bukkit.Bukkit;
 import org.bukkit.CropState;
@@ -274,7 +273,7 @@ public class mcBlockListener implements Listener {
 
         /* TREE FELLER SOUNDS */
         if (LoadProperties.spoutEnabled && mat.equals(Material.LOG) && PP.getTreeFellerMode()) {
-            SpoutStuff.playSoundForPlayer(SoundEffect.FIZZ, player, block.getLocation());
+            SpoutSounds.playSoundForPlayer(SoundEffect.FIZZ, player, block.getLocation());
         }
 
         /*
@@ -302,7 +301,7 @@ public class mcBlockListener implements Listener {
             }
 
             if (LoadProperties.spoutEnabled) {
-                SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
+                SpoutSounds.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
             }
         }
         else if (PP.getSuperBreakerMode() && Skills.triggerCheck(player, block, AbilityType.SUPER_BREAKER)) {

+ 2 - 2
src/main/java/com/gmail/nossr50/party/Party.java

@@ -14,14 +14,14 @@ import java.util.Iterator;
 
 import org.bukkit.Bukkit;
 import org.bukkit.entity.Player;
+
 import com.gmail.nossr50.Users;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.locale.mcLocale;
 
 
-public class Party 
-{
+public class Party {
 	/*
 	 * This file is part of mmoMinecraft (http://code.google.com/p/mmo-minecraft/).
 	 * 

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

@@ -11,7 +11,7 @@ import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.event.player.PlayerAnimationEvent;
 
-import com.gmail.nossr50.spout.SpoutStuff;
+import com.gmail.nossr50.spout.SpoutSounds;
 import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
 import com.gmail.nossr50.mcPermissions;
@@ -139,7 +139,7 @@ public class Excavation {
         }
 
         if (LoadProperties.spoutEnabled) {
-            SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
+            SpoutSounds.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
         }
     }
 }

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

@@ -15,7 +15,7 @@ import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
 import com.gmail.nossr50.mcPermissions;
 import com.gmail.nossr50.config.LoadProperties;
-import com.gmail.nossr50.spout.SpoutStuff;
+import com.gmail.nossr50.spout.SpoutSounds;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.datatypes.SkillType;
 
@@ -259,7 +259,7 @@ public class Mining
             miningBlockCheck(player, block);
 
             if (LoadProperties.spoutEnabled) {
-                SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
+                SpoutSounds.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
             }
         }
     }

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

@@ -15,7 +15,7 @@ import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
 import com.gmail.nossr50.mcPermissions;
 import com.gmail.nossr50.config.LoadProperties;
-import com.gmail.nossr50.spout.SpoutStuff;
+import com.gmail.nossr50.spout.SpoutSounds;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.datatypes.SkillType;
 import com.gmail.nossr50.locale.mcLocale;
@@ -145,7 +145,7 @@ public class Repair {
 
         //CLANG CLANG
         if (LoadProperties.spoutEnabled) {
-            SpoutStuff.playRepairNoise(player);
+            SpoutSounds.playRepairNoise(player);
         }
     }
 

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

@@ -20,7 +20,7 @@ import com.gmail.nossr50.config.LoadProperties;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.datatypes.SkillType;
 import com.gmail.nossr50.locale.mcLocale;
-import com.gmail.nossr50.spout.SpoutStuff;
+import com.gmail.nossr50.spout.SpoutSounds;
 
 import org.getspout.spoutapi.sound.SoundEffect;
 
@@ -311,7 +311,7 @@ public class WoodCutting {
         }
 
         if (LoadProperties.spoutEnabled) {
-            SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
+            SpoutSounds.playSoundForPlayer(SoundEffect.POP, player, block.getLocation());
         }
     }
 }

+ 52 - 0
src/main/java/com/gmail/nossr50/spout/SpoutSounds.java

@@ -0,0 +1,52 @@
+package com.gmail.nossr50.spout;
+
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.entity.Player;
+import org.getspout.spoutapi.SpoutManager;
+import org.getspout.spoutapi.player.SpoutPlayer;
+import org.getspout.spoutapi.sound.SoundEffect;
+import org.getspout.spoutapi.sound.SoundManager;
+
+public class SpoutSounds {
+
+    /**
+     * Play sound effect through Spout.
+     *
+     * @param effect The sound effect to play
+     * @param player The player to play the sound to
+     * @param location The location the sound should come from
+     */
+    public static void playSoundForPlayer(SoundEffect effect, Player player, Location location) {
+        SoundManager SM = SpoutManager.getSoundManager();
+        SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
+
+        SM.playSoundEffect(sPlayer, effect, location);
+    }
+
+    /**
+     * Play noise on successful repair.
+     *
+     * @param player The player who repaired an item
+     */
+    public static void playRepairNoise(Player player) {
+        SoundManager SM = SpoutManager.getSoundManager();
+        SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
+
+        //If this is pulling from online, why have it in the jar?
+        SM.playCustomSoundEffect(Bukkit.getServer().getPluginManager().getPlugin("mcMMO"), sPlayer, "repair.wav", false);
+    }
+
+    /**
+     * Play noise on level-up.
+     *
+     * @param player The player who leveled up
+     */
+    protected static void playLevelUpNoise(Player player) {
+        SoundManager SM = SpoutManager.getSoundManager();
+        SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
+
+        //If this is pulling from online, why have it in the jar?
+        SM.playCustomSoundEffect(Bukkit.getServer().getPluginManager().getPlugin("mcMMO"), sPlayer, "level.wav", false);
+    }
+}

+ 552 - 525
src/main/java/com/gmail/nossr50/spout/SpoutStuff.java

@@ -14,21 +14,15 @@ import java.util.jar.JarFile;
 
 import org.bukkit.Bukkit;
 import org.bukkit.ChatColor;
-import org.bukkit.Location;
 import org.bukkit.Material;
 import org.bukkit.entity.Player;
 import org.getspout.spoutapi.SpoutManager;
-import org.getspout.spoutapi.gui.Color;
 import org.getspout.spoutapi.keyboard.Keyboard;
 import org.getspout.spoutapi.player.SpoutPlayer;
-import org.getspout.spoutapi.sound.SoundEffect;
-import org.getspout.spoutapi.sound.SoundManager;
 
 import com.gmail.nossr50.Users;
 import com.gmail.nossr50.m;
 import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.config.LoadProperties;
-import com.gmail.nossr50.datatypes.HUDType;
 import com.gmail.nossr50.datatypes.HUDmmo;
 import com.gmail.nossr50.datatypes.PlayerProfile;
 import com.gmail.nossr50.datatypes.popups.PopupMMO;
@@ -37,523 +31,556 @@ import com.gmail.nossr50.listeners.mcSpoutInputListener;
 import com.gmail.nossr50.listeners.mcSpoutListener;
 import com.gmail.nossr50.listeners.mcSpoutScreenListener;
 
-public class SpoutStuff 
-{
-	static mcMMO plugin = (mcMMO) Bukkit.getServer().getPluginManager().getPlugin("mcMMO");
-	
-	private final static mcSpoutListener spoutListener = new mcSpoutListener(plugin);
-	private final static mcSpoutInputListener spoutInputListener = new mcSpoutInputListener(plugin);
-	private final static mcSpoutScreenListener spoutScreenListener = new mcSpoutScreenListener(plugin);
-	
-	public static HashMap<Player, HUDmmo> playerHUDs = new HashMap<Player, HUDmmo>();
-	public static HashMap<SpoutPlayer, PopupMMO> playerScreens = new HashMap<SpoutPlayer, PopupMMO>();
-	
-	public static Keyboard keypress;
-	
-	public static void writeFile(String theFileName, String theFilePath)
-	{
-	    try {
-	        File currentFile = new File("plugins/mcMMO/Resources/"+theFilePath+theFileName);
-	        @SuppressWarnings("static-access")
-	        JarFile jar = new JarFile(plugin.mcmmo);
-	        JarEntry entry = jar.getJarEntry("resources/"+theFileName);
-	        InputStream is = jar.getInputStream(entry);
-	        byte[] buf = new byte[2048];
-	        int nbRead;
-	        OutputStream os = new BufferedOutputStream(new FileOutputStream(currentFile));
-	        while((nbRead = is.read(buf)) != -1) {
-	            os.write(buf, 0, nbRead);
-	        }
-	        os.flush();
-	        os.close();
-	    } catch (FileNotFoundException e) {
-	        e.printStackTrace();
-	    } catch (IOException e) {
-	        e.printStackTrace();
-	    }
-	}
-	
-	public static void extractFiles()
-	{
-		//Setup directories
-		new File("plugins/mcMMO/Resources/").mkdir();
-		new File("plugins/mcMMO/Resources/HUD/").mkdir();
-		new File("plugins/mcMMO/Resources/HUD/Standard/").mkdir();
-		new File("plugins/mcMMO/Resources/HUD/Retro/").mkdir();
-		new File("plugins/mcMMO/Resources/Sound/").mkdir();
-		
-		//Xp Bar images
-		for(int x =0; x < 255; x++)
-		{
-			//String s = File.separator;
-			String theFilePath = "HUD/Standard/";
-			if(x < 10)
-			{
-				String theFileName = "xpbar_inc00"+x+".png";
-				writeFile(theFileName, theFilePath);
-			} else if (x < 100)
-			{
-				String theFileName = "xpbar_inc0"+x+".png";
-				writeFile(theFileName, theFilePath);
-			} else 
-			{
-				String theFileName = "xpbar_inc"+x+".png";
-				writeFile(theFileName, theFilePath);
-			}
-		}
-		
-		//Standard XP Icons
-		
-		String theFilePathA = "HUD/Standard/";
-		String theFilePathB = "HUD/Retro/";
-		
-		for(SkillType y : SkillType.values())
-		{
-			if(y == SkillType.ALL)
-				continue;
-			
-			String theFileNameA = m.getCapitalized(y.toString())+".png";
-			String theFileNameB = m.getCapitalized(y.toString())+"_r.png";
-			
-			writeFile(theFileNameA, theFilePathA);
-			writeFile(theFileNameB, theFilePathB);
-		}
-		
-		//Blank icons
-		
-		writeFile("Icon.png", theFilePathA);
-		writeFile("Icon_r.png", theFilePathB);
-		
-		String theSoundFilePath = "Sound/";
-		//Repair SFX
-		writeFile("repair.wav", theSoundFilePath);
-		writeFile("level.wav", theSoundFilePath);
-	}
-	
-	public static void setupSpoutConfigs()
-	{
-		 String temp = plugin.getConfig().getString("Spout.Menu.Key", "KEY_M");
-	        
-	        for(Keyboard x : Keyboard.values())
-	        {
-	        	if(x.toString().equalsIgnoreCase(temp))
-	        	{
-	        		keypress = x;
-	        	}
-	        }
-	        
-     	if(keypress == null)
-     	{
-     		System.out.println("Invalid KEY for Spout.Menu.Key, using KEY_M");
-     		keypress = Keyboard.KEY_M;
-     	}
-	}
-	public static ArrayList<File> getFiles()
-	{
-		ArrayList<File> files = new ArrayList<File>();
-		String dir = "plugins/mcMMO/Resources/";
-		int x = 0;
-		
-		//XP BAR
-		while(x < 255)
-		{
-			if(x < 10)
-			{
-				files.add(new File(dir+"HUD/Standard/xpbar_inc00"+x+".png"));
-			} else if (x < 100)
-			{
-				files.add(new File(dir+"HUD/Standard/xpbar_inc0"+x+".png"));
-			} else 
-			{
-				files.add(new File(dir+"HUD/Standard/xpbar_inc"+x+".png"));
-			}
-			x++;
-		}
-		
-		//Standard XP Icons
-		for(SkillType y : SkillType.values())
-		{
-			if(y == SkillType.ALL)
-				continue;
-			files.add(new File(dir+"HUD/Standard/"+m.getCapitalized(y.toString())+".png"));
-			files.add(new File(dir+"HUD/Retro/"+m.getCapitalized(y.toString())+"_r.png"));
-		}
-		
-		//Blank icons
-		files.add(new File(dir+"HUD/Standard/Icon.png"));
-		files.add(new File(dir+"HUD/Retro/Icon_r.png"));
-		//Repair SFX
-		files.add(new File(dir+"Sound/repair.wav"));
-		//Level SFX
-		files.add(new File(dir+"Sound/level.wav"));
-		
-		return files;
-	}
-	public static void registerCustomEvent()
-	{
-		Bukkit.getServer().getPluginManager().registerEvents(spoutListener, plugin);
-		Bukkit.getServer().getPluginManager().registerEvents(spoutInputListener, plugin);
-		Bukkit.getServer().getPluginManager().registerEvents(spoutScreenListener, plugin);
-	}
-	
-	public static Color getRetroColor(SkillType type)
-	{
-		switch(type)
-		{
-			case ACROBATICS:
-				return new Color((float) LoadProperties.acrobatics_r, (float) LoadProperties.acrobatics_g, (float) LoadProperties.acrobatics_b, 1);
-			case ARCHERY:
-				return new Color((float) LoadProperties.archery_r, (float)LoadProperties.archery_g, (float)LoadProperties.archery_b, 1f);
-			case AXES:
-				return new Color((float) LoadProperties.axes_r, (float)LoadProperties.axes_g, (float)LoadProperties.axes_b, 1f);
-			case EXCAVATION:
-				return new Color((float)LoadProperties.excavation_r, (float)LoadProperties.excavation_g, (float)LoadProperties.excavation_b, 1f);
-			case HERBALISM:
-				return new Color((float)LoadProperties.herbalism_r, (float)LoadProperties.herbalism_g, (float)LoadProperties.herbalism_b, 1f);
-			case MINING:
-				return new Color((float)LoadProperties.mining_r, (float)LoadProperties.mining_g, (float)LoadProperties.mining_b, 1f);
-			case REPAIR:
-				return new Color((float)LoadProperties.repair_r, (float)LoadProperties.repair_g, (float)LoadProperties.repair_b, 1f);
-			case SWORDS:
-				return new Color((float)LoadProperties.swords_r, (float)LoadProperties.swords_g, (float)LoadProperties.swords_b, 1f);
-			case TAMING:
-				return new Color((float)LoadProperties.taming_r, (float)LoadProperties.taming_g, (float)LoadProperties.taming_b, 1f);
-			case UNARMED:
-				return new Color((float)LoadProperties.unarmed_r, (float)LoadProperties.unarmed_g, (float)LoadProperties.unarmed_b, 1f);
-			case WOODCUTTING:
-				return new Color((float)LoadProperties.woodcutting_r, (float)LoadProperties.woodcutting_g, (float)LoadProperties.woodcutting_b, 1f);
-			case FISHING:
-				return new Color((float)LoadProperties.fishing_r, (float)LoadProperties.fishing_g, (float)LoadProperties.fishing_b, 1f);
-			default:
-				return new Color(0.3f, 0.3f, 0.75f, 1f);
-		}
-	}
-	public static SpoutPlayer getSpoutPlayer(String playerName)
-	{
-		for(Player x : Bukkit.getServer().getOnlinePlayers())
-		{
-			if(x.getName().equalsIgnoreCase(playerName))
-			{
-				return SpoutManager.getPlayer(x);
-			}
-		}
-		return null;
-	}
-	
-	public static void playSoundForPlayer(SoundEffect effect, Player player, Location location)
-	{
-		//Contrib stuff
-		SoundManager SM = SpoutManager.getSoundManager();
-		SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
-		SM.playSoundEffect(sPlayer, effect, location);
-	}
-	
-	public static void playRepairNoise(Player player)
-	{
-		SoundManager SM = SpoutManager.getSoundManager();
-		SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
-		SM.playCustomSoundEffect(Bukkit.getServer().getPluginManager().getPlugin("mcMMO"), sPlayer, "http://mcmmo.rycochet.net/mcmmo/Sound/repair.wav", false);
-	}
-	
-	public static void playLevelUpNoise(Player player)
-	{
-		SoundManager SM = SpoutManager.getSoundManager();
-		SpoutPlayer sPlayer = SpoutManager.getPlayer(player);
-		SM.playCustomSoundEffect(Bukkit.getServer().getPluginManager().getPlugin("mcMMO"), sPlayer, "http://mcmmo.rycochet.net/mcmmo/Sound/level.wav", false);
-	}
-	
-	public static void levelUpNotification(SkillType skillType, SpoutPlayer sPlayer)
-	{
-		PlayerProfile PP = Users.getProfile(sPlayer);
-		
-		Material mat = null;
-		switch(skillType)
-		{
-		case TAMING:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.PORK;
-				break;
-			case 2:
-				mat = Material.PORK;
-				break;
-			case 3:
-				mat = Material.GRILLED_PORK;
-				break;
-			case 4:
-				mat = Material.GRILLED_PORK;
-				break;
-			case 5:
-				mat = Material.BONE;
-				break;
-			}
-			break;
-		case MINING:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.COAL_ORE;
-				break;
-			case 2:
-				mat = Material.IRON_ORE;
-				break;
-			case 3:
-				mat = Material.GOLD_ORE;
-				break;
-			case 4:
-				mat = Material.LAPIS_ORE;
-				break;
-			case 5:
-				mat = Material.DIAMOND_ORE;
-				break;
-			}
-			break;
-		case WOODCUTTING:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.WOOD;
-				break;
-			case 2:
-				mat = Material.WOOD;
-				break;
-			case 3:
-				mat = Material.WOOD;
-				break;
-			case 4:
-				mat = Material.LOG;
-				break;
-			case 5:
-				mat = Material.LOG;
-				break;
-			}
-			break;
-		case REPAIR:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.COBBLESTONE;
-				break;
-			case 2:
-				mat = Material.IRON_BLOCK;
-				break;
-			case 3:
-				mat = Material.GOLD_BLOCK;
-				break;
-			case 4:
-				mat = Material.LAPIS_BLOCK;
-				break;
-			case 5:
-				mat = Material.DIAMOND_BLOCK;
-				break;
-			}
-			break;
-		case HERBALISM:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.YELLOW_FLOWER;
-				break;
-			case 2:
-				mat = Material.RED_ROSE;
-				break;
-			case 3:
-				mat = Material.BROWN_MUSHROOM;
-				break;
-			case 4:
-				mat = Material.RED_MUSHROOM;
-				break;
-			case 5:
-				mat = Material.PUMPKIN;
-				break;
-			}
-			break;
-		case ACROBATICS:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.LEATHER_BOOTS;
-				break;
-			case 2:
-				mat = Material.CHAINMAIL_BOOTS;
-				break;
-			case 3:
-				mat = Material.IRON_BOOTS;
-				break;
-			case 4:
-				mat = Material.GOLD_BOOTS;
-				break;
-			case 5:
-				mat = Material.DIAMOND_BOOTS;
-				break;
-			}
-			break;
-		case SWORDS:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.WOOD_SWORD;
-				break;
-			case 2:
-				mat = Material.STONE_SWORD;
-				break;
-			case 3:
-				mat = Material.IRON_SWORD;
-				break;
-			case 4:
-				mat = Material.GOLD_SWORD;
-				break;
-			case 5:
-				mat = Material.DIAMOND_SWORD;
-				break;
-			}
-			break;
-		case ARCHERY:
-			mat = Material.ARROW;
-			break;
-		case UNARMED:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.LEATHER_HELMET;
-				break;
-			case 2:
-				mat = Material.CHAINMAIL_HELMET;
-				break;
-			case 3:
-				mat = Material.IRON_HELMET;
-				break;
-			case 4:
-				mat = Material.GOLD_HELMET;
-				break;
-			case 5:
-				mat = Material.DIAMOND_HELMET;
-				break;
-			}
-			break;
-		case EXCAVATION:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.WOOD_SPADE;
-				break;
-			case 2:
-				mat = Material.STONE_SPADE;
-				break;
-			case 3:
-				mat = Material.IRON_SPADE;
-				break;
-			case 4:
-				mat = Material.GOLD_SPADE;
-				break;
-			case 5:
-				mat = Material.DIAMOND_SPADE;
-				break;
-			}
-			break;
-		case AXES:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.WOOD_AXE;
-				break;
-			case 2:
-				mat = Material.STONE_AXE;
-				break;
-			case 3:
-				mat = Material.IRON_AXE;
-				break;
-			case 4:
-				mat = Material.GOLD_AXE;
-				break;
-			case 5:
-				mat = Material.DIAMOND_AXE;
-				break;
-			}
-			break;
-		case FISHING:
-			switch(getNotificationTier(PP.getSkillLevel(skillType)))
-			{
-			case 1:
-				mat = Material.RAW_FISH;
-				break;
-			case 2:
-				mat = Material.RAW_FISH;
-				break;
-			case 3:
-				mat = Material.COOKED_FISH;
-				break;
-			case 4:
-				mat = Material.COOKED_FISH;
-				break;
-			case 5:
-				mat = Material.FISHING_ROD;
-				break;
-			}
-		default:
-			mat = Material.WATCH;
-			break;
-		}
-			sPlayer.sendNotification(ChatColor.GREEN+"Level Up!", ChatColor.YELLOW+m.getCapitalized(skillType.toString())+ChatColor.DARK_AQUA+" ("+ChatColor.GREEN+PP.getSkillLevel(skillType)+ChatColor.DARK_AQUA+")", mat);
-			playLevelUpNoise(sPlayer);
-	}
-	
-	public static Integer getNotificationTier(Integer level)
-	{
-		if(level < 200)
-			return 1;
-		else if (level >= 200 && level < 400)
-			return 2;
-		else if (level >= 400 && level < 600)
-			return 3;
-		else if (level >= 600 && level < 800)
-			return 4;
-		else
-			return 5;
-	}
-	
-	public static Integer getXpInc(int skillxp, int xptolevel, HUDType hud)
-	{
-		if(hud == HUDType.STANDARD)
-		{
-			double percentage = (double) skillxp/xptolevel;
-			double inc = 0.0039370078740157;
-			return (int) (percentage/inc);
-		} else if (hud == HUDType.RETRO)
-		{
-			double percentage = (double) skillxp/xptolevel;
-			double inc = 0.0079365079365079;
-			return (int) (percentage/inc);
-		} else {
-			return 1;
-		}
-	}
-	
-	public static void updateXpBar(Player player)
-	{
-		playerHUDs.get(player).updateXpBarDisplay(Users.getProfile(player).getHUDType(), player);
-	}
-	
-	public static String getUrlBar(Integer number)
-	{
-		if(number.toString().toCharArray().length == 1)
-		{
-			return "xpbar_inc00"+number+".png";
-		} else if (number.toString().toCharArray().length == 2)
-		{
-			return "xpbar_inc0"+number+".png";
-		} else {
-			return "xpbar_inc"+number+".png";
-		}
-	}
-	
-	public static String getUrlIcon(SkillType skillType)
-	{
-		return m.getCapitalized(skillType.toString())+".png";
-	}
-	public static boolean shouldBeFilled(PlayerProfile PP)
-	{
-		return PP.getXpBarInc() < getXpInc(PP.getSkillXpLevel(PP.getLastGained()), PP.getXpToLevel(PP.getLastGained()), HUDType.STANDARD);
-	}
+public class SpoutStuff {
+
+    static mcMMO plugin = (mcMMO) Bukkit.getServer().getPluginManager().getPlugin("mcMMO");
+
+    private final static mcSpoutListener spoutListener = new mcSpoutListener(plugin);
+    private final static mcSpoutInputListener spoutInputListener = new mcSpoutInputListener(plugin);
+    private final static mcSpoutScreenListener spoutScreenListener = new mcSpoutScreenListener(plugin);
+
+    public static HashMap<Player, HUDmmo> playerHUDs = new HashMap<Player, HUDmmo>();
+    public static HashMap<SpoutPlayer, PopupMMO> playerScreens = new HashMap<SpoutPlayer, PopupMMO>();
+
+    public static Keyboard keypress;
+
+    /**
+     * Write file to disk.
+     *
+     * @param theFileName The name of the file
+     * @param theFilePath The name of the file path
+     */
+    public static void writeFile(String theFileName, String theFilePath) {
+        try {
+            File currentFile = new File("plugins/mcMMO/Resources/" + theFilePath + theFileName);
+
+            @SuppressWarnings("static-access")
+            JarFile jar = new JarFile(plugin.mcmmo);
+            JarEntry entry = jar.getJarEntry("resources/" + theFileName);
+            InputStream is = jar.getInputStream(entry);
+
+            byte[] buf = new byte[2048];
+            int nbRead;
+
+            OutputStream os = new BufferedOutputStream(new FileOutputStream(currentFile));
+
+            while ((nbRead = is.read(buf)) != -1) {
+                os.write(buf, 0, nbRead);
+            }
+
+            os.flush();
+            os.close();
+        }
+        catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * Extract Spout files to the Resources directory.
+     */
+    public static void extractFiles() {
+
+        //Setup directories
+        new File("plugins/mcMMO/Resources/").mkdir();
+        new File("plugins/mcMMO/Resources/HUD/").mkdir();
+        new File("plugins/mcMMO/Resources/HUD/Standard/").mkdir();
+        new File("plugins/mcMMO/Resources/HUD/Retro/").mkdir();
+        new File("plugins/mcMMO/Resources/Sound/").mkdir();
+
+        //XP Bar images
+        for (int x = 0; x < 255; x++) {
+            String theFilePath = "HUD/Standard/";
+            String theFileName;
+
+            if (x < 10) {
+                theFileName = "xpbar_inc00" + x + ".png";
+            }
+            else if (x < 100) {
+                theFileName = "xpbar_inc0" + x + ".png";
+            }
+            else {
+                theFileName = "xpbar_inc" + x + ".png";
+            }
+
+            writeFile(theFileName, theFilePath);
+        }
+
+        //Standard XP Icons
+        String standardFilePath = "HUD/Standard/";
+        String retroFilePath = "HUD/Retro/";
+
+        for (SkillType y : SkillType.values()) {
+            if (y.equals(SkillType.ALL)) {
+                continue;
+            }
+
+            String standardFileName = m.getCapitalized(y.toString())+".png";
+            String retroFileName = m.getCapitalized(y.toString())+"_r.png";
+
+            writeFile(standardFileName, standardFilePath);
+            writeFile(retroFileName, retroFilePath);
+        }
+
+        //Blank icons
+        writeFile("Icon.png", standardFilePath);
+        writeFile("Icon_r.png", retroFilePath);
+
+        //Sound FX
+        String theSoundFilePath = "Sound/";
+
+        writeFile("repair.wav", theSoundFilePath);
+        writeFile("level.wav", theSoundFilePath);
+    }
+
+    /**
+     * Setup Spout config options
+     */
+    public static void setupSpoutConfigs() {
+        String temp = plugin.getConfig().getString("Spout.Menu.Key", "KEY_M");
+
+        for (Keyboard x : Keyboard.values()) {
+            if (x.toString().equalsIgnoreCase(temp)) {
+                keypress = x;
+            }
+        }
+
+        if (keypress == null) {
+            System.out.println("Invalid KEY for Spout.Menu.Key, using KEY_M");
+            keypress = Keyboard.KEY_M;
+        }
+    }
+
+    /**
+     * Get all the Spout files in the Resources folder.
+     *
+     * @return a list of all files is the Resources folder
+     */
+    public static ArrayList<File> getFiles() {
+        ArrayList<File> files = new ArrayList<File>();
+        String dir = "plugins/mcMMO/Resources/";
+
+        /* XP BAR */
+        for (int x = 0; x < 255; x++) {
+            if (x < 10) {
+                files.add(new File(dir + "HUD/Standard/xpbar_inc00" + x + ".png"));
+            }
+            else if (x < 100) {
+                files.add(new File(dir + "HUD/Standard/xpbar_inc0" + x + ".png"));
+            }
+            else {
+                files.add(new File(dir + "HUD/Standard/xpbar_inc" + x + ".png"));
+            }
+        }
+
+        /* Standard XP Icons */
+        for (SkillType y : SkillType.values()) {
+            if (y.equals(SkillType.ALL)) {
+                continue;
+            }
+
+            files.add(new File(dir + "HUD/Standard/" + m.getCapitalized(y.toString()) + ".png"));
+            files.add(new File(dir + "HUD/Retro/" + m.getCapitalized(y.toString()) + "_r.png"));
+        }
+        
+        /* Blank icons */
+        files.add(new File(dir + "HUD/Standard/Icon.png"));
+        files.add(new File(dir + "HUD/Retro/Icon_r.png"));
+
+        //Repair SFX
+        files.add(new File(dir + "Sound/repair.wav"));
+
+        //Level SFX
+        files.add(new File(dir + "Sound/level.wav"));
+
+        return files;
+    }
+
+    /**
+     * Register custom Spout events.
+     */
+    public static void registerCustomEvent() {
+        Bukkit.getServer().getPluginManager().registerEvents(spoutListener, plugin);
+        Bukkit.getServer().getPluginManager().registerEvents(spoutInputListener, plugin);
+        Bukkit.getServer().getPluginManager().registerEvents(spoutScreenListener, plugin);
+    }
+
+    /**
+     * Gets a Spout player from a player name.
+     *
+     * @param playerName The player name
+     * @return the SpoutPlayer related to this player name, null if there's no player online with that name.
+     */
+    public static SpoutPlayer getSpoutPlayer(String playerName) {
+        for (Player x : Bukkit.getServer().getOnlinePlayers()) {
+            if (x.getName().equalsIgnoreCase(playerName)) {
+                return SpoutManager.getPlayer(x);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Handle level-up notifications through Spout.
+     *
+     * @param skillType The skill that leveled up
+     * @param sPlayer The player that leveled up
+     */
+    public static void levelUpNotification(SkillType skillType, SpoutPlayer sPlayer) {
+        PlayerProfile PP = Users.getProfile(sPlayer);
+        int notificationTier = getNotificationTier(PP.getSkillLevel(skillType));
+        Material mat = null;
+
+        switch (skillType) {
+        case TAMING:
+            switch (notificationTier) {
+            case 1:
+            case 2:
+                mat = Material.PORK;
+                break;
+
+            case 3:
+            case 4:
+                mat = Material.GRILLED_PORK;
+                break;
+
+            case 5:
+                mat = Material.BONE;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case MINING:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.COAL_ORE;
+                break;
+
+            case 2:
+                mat = Material.IRON_ORE;
+                break;
+
+            case 3:
+                mat = Material.GOLD_ORE;
+                break;
+
+            case 4:
+                mat = Material.LAPIS_ORE;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_ORE;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case WOODCUTTING:
+            switch (notificationTier) {
+            case 1:
+            case 2:
+            case 3:
+                mat = Material.WOOD;
+                break;
+
+            case 4:
+            case 5:
+                mat = Material.LOG;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case REPAIR:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.COBBLESTONE;
+                break;
+
+            case 2:
+                mat = Material.IRON_BLOCK;
+                break;
+
+            case 3:
+                mat = Material.GOLD_BLOCK;
+                break;
+
+            case 4:
+                mat = Material.LAPIS_BLOCK;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_BLOCK;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case HERBALISM:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.YELLOW_FLOWER;
+                break;
+
+            case 2:
+                mat = Material.RED_ROSE;
+                break;
+
+            case 3:
+                mat = Material.BROWN_MUSHROOM;
+                break;
+
+            case 4:
+                mat = Material.RED_MUSHROOM;
+                break;
+
+            case 5:
+                mat = Material.PUMPKIN;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case ACROBATICS:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.LEATHER_BOOTS;
+                break;
+
+            case 2:
+                mat = Material.CHAINMAIL_BOOTS;
+                break;
+
+            case 3:
+                mat = Material.IRON_BOOTS;
+                break;
+
+            case 4:
+                mat = Material.GOLD_BOOTS;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_BOOTS;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case SWORDS:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.WOOD_SWORD;
+                break;
+
+            case 2:
+                mat = Material.STONE_SWORD;
+                break;
+
+            case 3:
+                mat = Material.IRON_SWORD;
+                break;
+
+            case 4:
+                mat = Material.GOLD_SWORD;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_SWORD;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case ARCHERY:
+            switch (notificationTier) {
+            case 1:
+            case 2:
+            case 3:
+                mat = Material.ARROW;
+                break;
+
+            case 4:
+            case 5:
+                mat = Material.BOW;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case UNARMED:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.LEATHER_HELMET;
+                break;
+
+            case 2:
+                mat = Material.CHAINMAIL_HELMET;
+                break;
+
+            case 3:
+                mat = Material.IRON_HELMET;
+                break;
+
+            case 4:
+                mat = Material.GOLD_HELMET;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_HELMET;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case EXCAVATION:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.WOOD_SPADE;
+                break;
+
+            case 2:
+                mat = Material.STONE_SPADE;
+                break;
+
+            case 3:
+                mat = Material.IRON_SPADE;
+                break;
+
+            case 4:
+                mat = Material.GOLD_SPADE;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_SPADE;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case AXES:
+            switch (notificationTier) {
+            case 1:
+                mat = Material.WOOD_AXE;
+                break;
+
+            case 2:
+                mat = Material.STONE_AXE;
+                break;
+
+            case 3:
+                mat = Material.IRON_AXE;
+                break;
+
+            case 4:
+                mat = Material.GOLD_AXE;
+                break;
+
+            case 5:
+                mat = Material.DIAMOND_AXE;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        case FISHING:
+            switch (notificationTier) {
+            case 1:
+            case 2:
+                mat = Material.RAW_FISH;
+                break;
+
+            case 3:
+            case 4:
+                mat = Material.COOKED_FISH;
+                break;
+
+            case 5:
+                mat = Material.FISHING_ROD;
+                break;
+
+            default:
+                break;
+            }
+
+            break;
+
+        default:
+            mat = Material.WATCH;
+            break;
+        }
+
+        //TODO: Use Locale
+        sPlayer.sendNotification(ChatColor.GREEN + "Level Up!", ChatColor.YELLOW + m.getCapitalized(skillType.toString()) + ChatColor.DARK_AQUA + " (" + ChatColor.GREEN + PP.getSkillLevel(skillType) + ChatColor.DARK_AQUA + ")", mat);
+        SpoutSounds.playLevelUpNoise(sPlayer);
+    }
+
+    /**
+     * Gets the notification tier of a skill.
+     *
+     * @param level The level of the skill
+     * @return the notification tier of the skill
+     */
+    private static Integer getNotificationTier(Integer level) {
+        if (level >= 800) {
+            return 5;
+        }
+        else if (level >= 600) {
+            return 4;
+        }
+        else if (level >= 400) {
+            return 3;
+        }
+        else if (level >= 200) {
+            return 2;
+        }
+        else {
+            return 1;
+        }
+    }
+
+    /**
+     * Update a player's Spout XP bar.
+     *
+     * @param player The player whose bar to update
+     */
+    public static void updateXpBar(Player player) {
+        playerHUDs.get(player).updateXpBarDisplay(Users.getProfile(player).getHUDType(), player);
+    }
 }