Index: main/LostHavenRPG.java
===================================================================
--- main/LostHavenRPG.java	(revision 08704682fb409c42246c2544c64a8681a3fd9734)
+++ main/LostHavenRPG.java	(revision 8edd04e287f45041eeee2cb294847453e4c6aac4)
@@ -1,608 +1,1600 @@
 package main;
 
-import java.awt.*;
+import java.awt.Color;
+import java.awt.DisplayMode;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.MouseInfo;
+import java.awt.event.*;
 import java.awt.image.*;
-import java.awt.event.*;
 import java.io.*;
-import java.util.*;
-import javax.imageio.*;
-import java.text.*;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import javax.imageio.ImageIO;
 
 import gamegui.*;
 
-/* 
- * This is the main class in the project. It initializes wide-screen mode and is responsible for drawing to the screen and handling
- * input.
- * 
- * The classes in the gamegui folder are similar to the Swing classes in that they help in building a gui. They are all extended from
- * the Member class and instances of each of them can be added to a Window class. They also have input-handling functionality.
- */
+public class LostHavenRPG implements KeyListener, MouseListener {
 
-public class LostHavenRPG implements KeyListener, MouseListener {
-	private static DisplayMode[] BEST_DISPLAY_MODES = new DisplayMode[] {
-        new DisplayMode(800, 600, 32, 0),
-        new DisplayMode(800, 600, 16, 0),
-        new DisplayMode(800, 600, 8, 0)
+  private static DisplayMode[] BEST_DISPLAY_MODES = new DisplayMode[] {
+      new DisplayMode(800, 600, 32, 0),
+      new DisplayMode(800, 600, 16, 0), 
+      new DisplayMode(800, 600, 8, 0)
     };
-	
-	boolean done;
-	boolean changePending;
-	
-	Player player;
-	Map map;
-	
-	//all "types" should be enums so it's easier to see all possible values while programming
-	HashMap<LandType, Land> landMap;
-	HashMap<StructureType, Structure> structMap;
-	HashMap<CreatureType, Creature> creatureMap;
-	
-	BufferedImage girl;
-	BufferedImage guy;
-    
-    public GameState gameState;
-    public AuxState auxState;
-    
-    //GUI elements
-    Frame frmMain;
-    
-    gamegui.Window wndMain;
-    gamegui.Window wndCreateAccount;
-    gamegui.Window wndChooseClass;
-    gamegui.Window wndGameInfo;
-    gamegui.Window wndCredits;
-    
-    RadioGroup rdgGenderSelection;
-    RadioGroup rdgClassSelection;
-    
-    gamegui.Window wndMessage;
-    gamegui.Window wndProgress;
-    gamegui.Window wndConnecting;
-    
-    Textbox selectedText;
 
-    public LostHavenRPG(GraphicsDevice device) {
-        try {
-            GraphicsConfiguration gc = device.getDefaultConfiguration();
-            frmMain = new Frame(gc);
-            frmMain.setUndecorated(true);
-            frmMain.setIgnoreRepaint(true);
-            device.setFullScreenWindow(frmMain);
-            
-            if (device.isDisplayChangeSupported()) {
-                chooseBestDisplayMode(device);
-            }
-            
-            frmMain.addMouseListener(this);
-            frmMain.addKeyListener(this);
-            frmMain.createBufferStrategy(2);
-            BufferStrategy bufferStrategy = frmMain.getBufferStrategy();
+  public static Map map;
+  public static HashMap<LandType, Land> landMap;
+  public static HashMap<StructureType, Structure> structMap;
+  public static HashMap<CreatureType, Creature> creatureMap;
+  public static HashMap<String, Item> items;
+  public static LinkedList<RespawnPoint> respawnPoints;
+  public static LinkedList<SpawnPoint> spawnPoints;
 
-            player = new Player();
-            done = false;
-            changePending = false;
-            
-            gameState = GameState.Main;
-            auxState = AuxState.None;
-            
-            loadMap();
-        	map = new Map("mapInfo.txt", "structInfo.txt", landMap, structMap);
-        	map.getLoc(10, 10).addCreature(new Creature());
-            initGUIElements();
-            
-            while (!done) {
-                Graphics g = bufferStrategy.getDrawGraphics();
-                move();
-                render(g);
-                g.dispose();
-                bufferStrategy.show();
-            }
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-        }
-        finally {
-            device.setFullScreenWindow(null);
-        }
+  public static BufferedImage[] airSprites;
+  public static BufferedImage[] earthSprites;
+  public static BufferedImage[] fireSprites;
+  public static BufferedImage[] waterSprites;
+  public static BufferedImage[] imgBow;
+  public static BufferedImage passiveAura;
+  public static BufferedImage thornsAura;
+  public static BufferedImage confuseAura;
+  public static BufferedImage sandAura;
+  public static Model rangedModel;
+  public static Model meleeModel;
+  public static ScrollList lstInventory;
+  public static ScrollList lstGems;
+  public static Frame frmMain;
+
+  public GameState gameState;
+  public AuxState auxState;
+
+  boolean done;
+  boolean changePending;
+  Player player;
+
+  LinkedList<Gem> gems;
+  LinkedList<Item> drops;
+  LinkedList<Projectile> projectiles;
+  
+  BufferedImage imgMap;
+  
+  Window wndMain;
+  Window wndCreateAccount;
+  Window wndGameIntro;
+  Window wndGameInfo;
+  Window wndCredits;
+  Window wndStatDisplay;
+  Window wndGameInventory;
+  Window wndGameGems;
+  Window wndGameStats;
+  Window wndGameMap;
+  Window wndVictory;
+  Window[] wndTutorials;
+  Window wndTutOptions;
+  Window wndMessage;
+
+  int wndTutCur;  
+  boolean infoStart;
+  
+  Button btnMenu;
+  Button btnStats;
+  Button btnGems;
+  Button btnInventory;
+  Button btnMap;
+  
+  Label lblGemVal;
+  Label lblSpellCost;
+  
+  Graphics g;
+  
+  Point startPoint;
+  
+  Textbox selectedText;
+  
+  boolean started = false;
+  
+  public LostHavenRPG(GraphicsDevice device) {
+    try {
+      GraphicsConfiguration gc = device.getDefaultConfiguration();
+      frmMain = new Frame(gc);
+      frmMain.setUndecorated(true);
+      frmMain.setIgnoreRepaint(true);
+      device.setFullScreenWindow(frmMain);
+      if (device.isDisplayChangeSupported())
+        chooseBestDisplayMode(device); 
+      frmMain.addMouseListener(this);
+      frmMain.addKeyListener(this);
+      frmMain.createBufferStrategy(2);
+      BufferStrategy bufferStrategy = frmMain.getBufferStrategy();
+      this.g = bufferStrategy.getDrawGraphics();
+      this.done = false;
+      this.changePending = false;
+      this.gameState = GameState.Main;
+      this.auxState = AuxState.None;
+      loadMapElements();
+      this.imgMap = ImageIO.read(getClass().getResource("../images/mapLarge.png"));
+      map = new Map("map.png", "structInfo2.txt", landMap, structMap, true);
+      this.startPoint = new Point(7050, 6150);
+      loadItems();
+      loadCreatures();
+      loadSpawnPoints();
+      loadSpellSprites();
+      initGUIElements();
+      this.started = true;
+      while (!this.done) {
+        this.g = bufferStrategy.getDrawGraphics();
+        handleEvents();
+        render(this.g);
+        this.g.dispose();
+        bufferStrategy.show();
+      } 
+    } catch (Exception e) {
+      e.printStackTrace();
+    } finally {
+      device.setFullScreenWindow(null);
+    } 
+  }
+  
+  private void initGUIElements() {
+    Font font11 = new Font("Arial", 0, 11);
+    Font font12 = new Font("Arial", 0, 12);
+    Font font14 = new Font("Arial", 0, 14);
+    Font font24 = new Font("Arial", 0, 24);
+    BufferedImage imgSub = null;
+    BufferedImage imgAdd = null;
+    BufferedImage imgSkillSub = null;
+    BufferedImage imgSkillAdd = null;
+    String strengthDesc = "Raises damage inflicted by melee weapons.";
+    String dexterityDesc = "Lowers cooldown of all weapons.";
+    String constitutionDesc = "Raises starting hitpoints and hitpoints gained per level.";
+    String wisdomDesc = "Raises starting manapoints and manapoints gained per level.";
+    String lightWeaponDesc = "Raises damage inflicted by light weapons.";
+    String heavyWeaponDesc = "Raises damage inflicted by heavy weapons.";
+    String rangedWeaponDesc = "Raises damage inflicted by ranged weapons.";
+    String evocationDesc = "Raises the possible number of activated gems.";
+    this.wndMain = new Window("main", 0, 0, 800, 600, true);
+    Animation anmTitle = new Animation("title", 144, 0, 512, 95, 83, true);
+    try {
+      anmTitle.addFrame(ImageIO.read(getClass().getResource("../images/Frame1.png")));
+      anmTitle.addFrame(ImageIO.read(getClass().getResource("../images/Frame2.png")));
+      anmTitle.addFrame(ImageIO.read(getClass().getResource("../images/Frame3.png")));
+      anmTitle.addFrame(ImageIO.read(getClass().getResource("../images/Frame4.png")));
+      anmTitle.addFrame(ImageIO.read(getClass().getResource("../images/Frame5.png")));
+      imgSub = ImageIO.read(getClass().getResource("../images/imgSub.png"));
+      imgAdd = ImageIO.read(getClass().getResource("../images/imgAdd.png"));
+      imgSkillSub = ImageIO.read(getClass().getResource("../images/imgSkillSub.png"));
+      imgSkillAdd = ImageIO.read(getClass().getResource("../images/imgSkillAdd.png"));
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+    this.wndMain.add(anmTitle);
+    this.wndMain.add(new Button("new game", 500, 140, 200, 40, "New Game", font12));
+    this.wndMain.add(new Button("load game", 500, 230, 200, 40, "Load Game", font12));
+    this.wndMain.add(new Button("game info", 500, 320, 200, 40, "Game Information", font12));
+    this.wndMain.add(new Button("credits", 500, 410, 200, 40, "Credits", font12));
+    this.wndMain.add(new Button("quit", 500, 500, 200, 40, "Quit", font12));
+    this.wndStatDisplay = new Window("stat display", 0, 550, 799, 49, false);
+    this.wndGameStats = new Window("game stats", 0, 125, 320, 425);
+    this.wndGameGems = new Window("inventory", 359, 299, 220, 251);
+    lstGems = new ScrollList("gem list", 0, 0, 200, 251, null, null);
+    lstGems.addScrollBar(new ScrollBar("scrollgem", 200, 0, 20, 251, 3));
+    this.wndGameGems.add(lstGems);
+    this.wndGameInventory = new Window("inventory", 579, 299, 220, 251);
+    lstInventory = new ScrollList("inventory list", 0, 0, 200, 251, null, null);
+    lstInventory.addScrollBar(new ScrollBar("scrollinv", 200, 0, 20, 251, 3));
+    this.wndGameInventory.add(lstInventory);
+    this.wndGameMap = new Window("inventory", 443, 357, 356, 193);
+    this.btnMenu = new Button("main menu", 360, 10, 80, 20, "Main Menu", font12);
+    this.btnStats = new Button("stats", 600, 5, 80, 16, "Character", font12);
+    this.btnInventory = new Button("inventory", 700, 5, 80, 16, "Inventory", font12);
+    this.btnGems = new Button("gems", 600, 29, 80, 16, "Gems", font12);
+    this.btnMap = new Button("map", 700, 29, 80, 16, "Map", font12);
+    this.lblGemVal = new Label("gemVal", 515, 5, 67, 20, "Gem Value: 0", font12, Align.Right);
+    this.lblSpellCost = new Label("spellCost", 515, 24, 67, 20, "Spell Cost: 0", font12, Align.Right);
+    this.wndStatDisplay.add(this.btnMenu);
+    this.wndStatDisplay.add(this.btnStats);
+    this.wndStatDisplay.add(this.btnGems);
+    this.wndStatDisplay.add(this.btnInventory);
+    this.wndStatDisplay.add(this.btnMap);
+    this.wndStatDisplay.add(this.lblGemVal);
+    this.wndStatDisplay.add(this.lblSpellCost);
+    this.wndGameStats.add(new Label("strength", 10, 20, 70, 30, "Strength", font12, Align.Left));
+    this.wndGameStats.add(new Label("strengthDesc", 20, 45, 70, 15, strengthDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("dexterity", 10, 65, 70, 30, "Dexterity", font12, Align.Left));
+    this.wndGameStats.add(new Label("dexterityDesc", 20, 90, 70, 15, dexterityDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("constitution", 10, 110, 70, 30, "Constitution", font12, Align.Left));
+    this.wndGameStats.add(new Label("constitutionDesc", 20, 135, 70, 15, constitutionDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("wisdom", 10, 155, 70, 30, "Wisdom", font12, Align.Left));
+    this.wndGameStats.add(new Label("wisdomDesc", 20, 180, 70, 15, wisdomDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("strVal", 220, 20, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("dexVal", 220, 65, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("conVal", 220, 110, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("wisVal", 220, 155, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("light weapons", 10, 220, 70, 30, "Light Weapons", font12, Align.Left));
+    this.wndGameStats.add(new Label("lightWeaponDesc", 20, 245, 70, 15, lightWeaponDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("heavy weapons", 10, 265, 70, 30, "Heavy Weapons", font12, Align.Left));
+    this.wndGameStats.add(new Label("heavyWeaponDesc", 20, 290, 70, 15, heavyWeaponDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("ranged weapons", 10, 310, 70, 30, "Ranged Weapons", font12, Align.Left));
+    this.wndGameStats.add(new Label("rangedWeaponDesc", 20, 335, 70, 15, rangedWeaponDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("evocation", 10, 355, 70, 30, "Evocation", font12, Align.Left));
+    this.wndGameStats.add(new Label("evocationDesc", 20, 380, 70, 15, evocationDesc, font11, Align.Left));
+    this.wndGameStats.add(new Label("lightWeaponVal", 220, 220, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("heavyWeaponVal", 220, 265, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("rangedWeaponVal", 220, 310, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("evocationVal", 220, 355, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Label("skillVal", 130, 395, 70, 30, "0", font12, Align.Left));
+    this.wndGameStats.add(new Button("lightWeapon+", 265, 230, 20, 20, imgSkillAdd));
+    this.wndGameStats.add(new Button("heavyWeapon+", 265, 275, 20, 20, imgSkillAdd));
+    this.wndGameStats.add(new Button("rangedWeapon+", 265, 320, 20, 20, imgSkillAdd));
+    this.wndGameStats.add(new Button("evocation+", 265, 365, 20, 20, imgSkillAdd));
+    this.wndGameStats.add(new Label("skilllPoints", 50, 395, 70, 30, "Remaining Points:", font12, Align.Right));
+    this.wndCreateAccount = new Window("create account", 0, 0, 800, 600, true);
+    this.wndCreateAccount.add(new Label("title", 250, 15, 300, 20, "Create an Account", font24));
+    this.wndCreateAccount.add(new Textbox("user", 340, 100, 190, 30, "Username:", font12, false));
+    this.wndCreateAccount.add(new Label("strength", 90, 190, 70, 30, "Strength", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("strengthDesc", 115, 220, 70, 15, strengthDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("dexterity", 90, 250, 70, 30, "Dexterity", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("dexterityDesc", 115, 280, 70, 15, dexterityDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("constitution", 90, 310, 70, 30, "Constitution", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("constitutionDesc", 115, 340, 70, 15, constitutionDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("wisdom", 90, 370, 70, 30, "Wisdom", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("wisdomDesc", 115, 400, 70, 15, wisdomDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("attPoints", 110, 430, 70, 30, "Remaining Points:", font12, Align.Right));
+    this.wndCreateAccount.add(new Label("strVal", 264, 190, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("dexVal", 264, 250, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("conVal", 264, 310, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("wisVal", 264, 370, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("attVal", 215, 430, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Button("strength-", 205, 198, 20, 20, imgSub));
+    this.wndCreateAccount.add(new Button("strength+", 315, 198, 20, 20, imgAdd));
+    this.wndCreateAccount.add(new Button("dexterity-", 205, 258, 20, 20, imgSub));
+    this.wndCreateAccount.add(new Button("dexterity+", 315, 258, 20, 20, imgAdd));
+    this.wndCreateAccount.add(new Button("constitution-", 205, 318, 20, 20, imgSub));
+    this.wndCreateAccount.add(new Button("constitution+", 315, 318, 20, 20, imgAdd));
+    this.wndCreateAccount.add(new Button("wisdom-", 205, 378, 20, 20, imgSub));
+    this.wndCreateAccount.add(new Button("wisdom+", 315, 378, 20, 20, imgAdd));
+    this.wndCreateAccount.add(new Label("light weapons", 450, 190, 70, 30, "Light Weapons", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("lightWeaponDesc", 475, 220, 70, 15, lightWeaponDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("heavy weapons", 450, 250, 70, 30, "Heavy Weapons", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("heavyWeaponDesc", 475, 280, 70, 15, heavyWeaponDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("ranged weapons", 450, 310, 70, 30, "Ranged Weapons", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("rangedWeaponDesc", 475, 340, 70, 15, rangedWeaponDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("evocation", 450, 370, 70, 30, "Evocation", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("evocationDesc", 475, 400, 70, 15, evocationDesc, font11, Align.Left));
+    this.wndCreateAccount.add(new Label("skilllPoints", 475, 430, 70, 30, "Remaining Points:", font12, Align.Right));
+    this.wndCreateAccount.add(new Label("lightWeaponVal", 620, 190, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("heavyWeaponVal", 620, 250, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("rangedWeaponVal", 620, 310, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("evocationVal", 620, 370, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Label("skillVal", 575, 430, 70, 30, "0", font12, Align.Left));
+    this.wndCreateAccount.add(new Button("lightWeapon-", 565, 198, 20, 20, imgSkillSub));
+    this.wndCreateAccount.add(new Button("lightWeapon+", 675, 198, 20, 20, imgSkillAdd));
+    this.wndCreateAccount.add(new Button("heavyWeapon-", 565, 258, 20, 20, imgSkillSub));
+    this.wndCreateAccount.add(new Button("heavyWeapon+", 675, 258, 20, 20, imgSkillAdd));
+    this.wndCreateAccount.add(new Button("rangedWeapon-", 565, 318, 20, 20, imgSkillSub));
+    this.wndCreateAccount.add(new Button("rangedWeapon+", 675, 318, 20, 20, imgSkillAdd));
+    this.wndCreateAccount.add(new Button("evocation-", 565, 378, 20, 20, imgSkillSub));
+    this.wndCreateAccount.add(new Button("evocation+", 675, 378, 20, 20, imgSkillAdd));
+    this.wndCreateAccount.add(new Button("create", 245, 520, 140, 30, "Create", font12));
+    this.wndCreateAccount.add(new Button("cancel", 415, 520, 140, 30, "Cancel", font12));
+    this.wndCredits = new Window("main", 0, 0, 800, 600, true);
+    this.wndCredits.add(new Label("title", 250, 15, 300, 20, "Credits", font24));
+    this.wndCredits.add(new Label("1", 250, 160, 300, 20, "Dmitry Portnoy", font14));
+    this.wndCredits.add(new Label("2", 250, 180, 300, 20, "Team Leader", font12));
+    this.wndCredits.add(new Label("3", 250, 195, 300, 20, "Programmer", font12));
+    this.wndCredits.add(new Label("4", 250, 235, 300, 20, "Daniel Vu", font14));
+    this.wndCredits.add(new Label("5", 250, 255, 300, 20, "Graphic Artist", font12));
+    this.wndCredits.add(new Label("6", 250, 295, 300, 20, "Jason Cooper", font14));
+    this.wndCredits.add(new Label("7", 250, 315, 300, 20, "Designer", font12));
+    this.wndCredits.add(new Label("8", 250, 355, 300, 20, "Special thanks to", font14));
+    this.wndCredits.add(new Label("9", 250, 375, 300, 20, "The Game Creation Society", font12));
+    this.wndTutorials = new Window[13];
+    String[] text = new String[13];
+    this.wndTutOptions = new Window("tut", 300, 0, 499, 140, false);
+    this.wndTutOptions.add(new Button("previous", 260, 110, 60, 20, "Previous", font12, Align.Center));
+    this.wndTutOptions.add(new Button("next", 340, 110, 60, 20, "Next", font12, Align.Center));
+    this.wndTutOptions.add(new Button("skip", 420, 110, 60, 20, "Skip", font12, Align.Center));
+    this.wndTutOptions.add(new Label("num", 200, 110, 60, 20, "1 / 13", font12, Align.Center));
+    text[0] = "When you die, you will be resurrected with no penalty at the closest purple pedestal you have activated. To activate a pedestal, you must walk over it. If you have not activated any purple pedestals, you will resurrect where you started the game. It is important to activate any purple pedestals you see to save you time when you die. You can also use purple pedestals to replenish all of your HP and MP by stepping on them.";
+    text[1] = "When you kill enemies, they sometimes drop items. Left-click on an item to pick it up and place it in your inventory. Be careful when picking up items while there are many enemies around because they might kill you.";
+    text[2] = "You can open your inventory from the bar at the bottom of the screen. You can mouse over any item in your inventory and see a description and relevant stats. Left-clicking any weapon in your inventory will equip it and unequip your previously equiped weapon. Left-clicking a gem will activate it provided you have enough evocation skill to do so. ";
+    text[3] = "You can equip both melee and ranged weapons. If you have a ranged weapon, like this bow, you can fire at enemies from a safe distance. Ranged weapons never run out of ammunition. However, they cannot shoot through most obstacles.";
+    text[4] = "Melee weapons are divided into light and heavy weapons. Heavy weapons are slower, but deal much more damage when they hit. Anyone can equip light weapons, but only players with at least 12 Strenth can use heavy weapons. The damage bonus from Strength is also greater for heavy weapons. The heavy weapon skill also adds more damage per hit than the light weapon skill.";
+    text[5] = "You can open the Character window from the bottom bar. The character window shows the levels of all your skills and attributes. When you level up, you get two extra skill points and you can spend them here. Choose your skills carefully since you can't repick your skills later. You also get HP equal to your constitution and MP equal to your wisdom when you level up.";
+    text[6] = "Assuming you have at least one gem activated and enough mana, you can cast spells by right-clicking anywhere on the map.  The total mana cost of your spell is half of the value of all the gems used to cast it.Any enemies that your spell collides with will be affected. However, you use MP every time you cast a spell, so you have to be careful not run out of MP in a battle. There are many gems with different effects and you should carefully choose which gems you want to use for your spell.";
+    text[7] = "The Gems window is accessible from the bottom bar. Activated gems will appear in this window and will contribute their effects to any spells you cast. Each gem has a set amount of energy that is displayed if you mouse over it. Your evocation skill limits the amount of gems you can activate at once, so you should raise it to increase the power of your spells. You can left-click on any gem in the Gems window to place it back in your inventory if you want to activate a different gem.";
+    text[8] = "The images under the Blob indicate that it is afflicted with some status effects. Status effects caused by spells usually last a few seconds, but it varies depending on the gem.";
+    text[9] = "You can activate mutliple gems of the same type to get increased effects. Gems that have one-time effects, like dealing damage, will simply do more of that. Gems that cause the target to gain a temporary status effect will make that effect last longer if multiple gems are used.";
+    text[10] = "These red portals will open your way out of this world. However, they have been protected by the magic of powerful artifacts. These artifacts are scattered throughout the land and you will need at least four to break the enchantment and activate these portals.";
+    text[11] = "Yellow pedestals are portals to the aforementioned artifacts. Be warned that these artifacts are well-guarded and capturing them could prove deadly. To view this tutorial again, click on Game Information from the main menu. Good luck!";
+    text[12] = "You can access the world map from the bottom bar. However, it does not show the locations of respawn or teleportation points. The Rectangular areas on top of the screen are the locations of the relics, but you must use teleportation points to get to them.";
+    FontMetrics metrics = this.g.getFontMetrics(font12);
+    try {
+      for (int x = 0; x < this.wndTutorials.length; x++) {
+        this.wndTutorials[x] = new Window("tut" + x, 0, 0, 800, 600, true);
+        this.wndTutorials[x].add(new Button("screen", 0, 0, 800, 600, ImageIO.read(getClass().getResource("../images/Tutorial/ss" + (x + 1) + ".png"))));
+        this.wndTutorials[x].add(this.wndTutOptions);
+        MultiTextbox multiTextbox = new MultiTextbox("text", 305, 5, 490, 100, "", false, font12, metrics);
+        multiTextbox.setBorder(false);
+        multiTextbox.setText(text[x]);
+        this.wndTutorials[x].add(multiTextbox);
+      } 
+      this.wndTutCur = 0;
+      this.wndGameIntro = new Window("intro", 0, 0, 800, 600, true);
+      this.wndGameIntro.add(new Label("intro", 250, 15, 300, 20, "Introduction", font24));
+      MultiTextbox txt = new MultiTextbox("text", 50, 150, 650, 350, "", false, font12, metrics);
+      txt.setBorder(false);
+      txt.setText("You suddenly wake up in a strange place you do not recognize. You must find some weapons and some way to get out.\n\nKill creatures to get gems to power your spells and weapons to defend yourself with.\n\nTo get out of this world, you must unlock a portal that is protected by powerful artifacts. Each artifact can be accessed by a yellow portal somewhere in the world. You must collect at least four artifacts to unlock the portal.");
+      this.wndGameIntro.add(txt);
+      this.wndVictory = new Window("victory", 0, 0, 800, 600, true);
+      this.wndVictory.add(new Label("victory", 250, 15, 300, 20, "Victory", font24));
+      MultiTextbox txtV = new MultiTextbox("text", 50, 150, 650, 350, "", false, font12, metrics);
+      txtV.setBorder(false);
+      txtV.setText("As you strike the final blow, the specter's body evaporates, leaving behind a pile of torn clothing. In the last seconds of its existance, you manage to peer under its hood and catch a glimpse of your own face. Was that simply proof of your failing psyche or does some darker secret lie behind that horrible monster? When you once again become aware of your surroundings, you find yourself alone in a forest clearing. There is no sign of hostile monsters and the only indications of your ordeal are your incredible fatigue and a pile of rags a few feet away from you. Was the world you were trapped in merely an illusion or is there some other explanation? You cannot be sure, but you hope to never have to remember that place again.");
+      this.wndVictory.add(txtV);
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+    this.wndMessage = new Window("message", 290, 135, 220, 160);
+    this.wndMessage.add(new Label("label", 20, 15, 180, 12, "none", font12));
+    this.wndMessage.add(new Button("button", 70, 115, 80, 30, "OK", font12));
+  }
+  
+  private void loadMapElements() {
+    landMap = new HashMap<LandType, Land>();
+    structMap = new HashMap<StructureType, Structure>();
+    respawnPoints = new LinkedList<RespawnPoint>();
+    BufferedImage nullImg = null;
+    landMap.put(LandType.Lava, new Land(LandType.Lava, "Terrain/orange.png", true));
+    landMap.put(LandType.Metal, new Land(LandType.Metal, "Terrain/darkRed.png", true));
+    landMap.put(LandType.Charred, new Land(LandType.Charred, "Terrain/red.png", true));
+    landMap.put(LandType.Swamp, new Land(LandType.Swamp, "Terrain/lightBrown.png", true));
+    landMap.put(LandType.Vines, new Land(LandType.Vines, "Terrain/darkBrown.png", true));
+    landMap.put(LandType.Crystal, new Land(LandType.Crystal, "Terrain/purple.png", true));
+    landMap.put(LandType.CrystalFormation, new Land(LandType.CrystalFormation, "Terrain/darkPurple.png", false));
+    landMap.put(LandType.Water, new Land(LandType.Water, "Terrain/blue.png", true));
+    landMap.put(LandType.Forest, new Land(LandType.Forest, "Terrain/darkGreen.png", true));
+    landMap.put(LandType.Tree, new Land(LandType.Tree, "Terrain/brown.png", false));
+    landMap.put(LandType.Plains, new Land(LandType.Plains, "Terrain/lightGreen.png", true));
+    landMap.put(LandType.Desert, new Land(LandType.Desert, "Terrain/yellow.png", true));
+    landMap.put(LandType.Mountains, new Land(LandType.Mountains, "Terrain/mountain.png", false));
+    landMap.put(LandType.Cave, new Land(LandType.Cave, "Terrain/mountain.png", false));
+    landMap.put(LandType.Ocean, new Land(LandType.Ocean, "Terrain/darkBlue.png", false));
+    landMap.put(LandType.Snow, new Land(LandType.Snow, "Terrain/lightBlue.png", true));
+    landMap.put(LandType.Steam, new Land(LandType.Steam, "Terrain/lightGray.png", true));
+    structMap.put(StructureType.None, new Structure(StructureType.None, nullImg, true));
+    structMap.put(StructureType.LoginPedestal, new Structure(StructureType.LoginPedestal, "YellowPedestal.png", true));
+    structMap.put(StructureType.RejuvenationPedestal, new Structure(StructureType.RejuvenationPedestal, "PurplePedestal.png", true));
+    structMap.put(StructureType.LifePedestal, new Structure(StructureType.LifePedestal, "RedPedestal.png", true));
+    structMap.put(StructureType.ManaPedestal, new Structure(StructureType.ManaPedestal, "BluePedestal.png", true));
+    structMap.put(StructureType.RespawnPoint, new RespawnPoint(StructureType.RespawnPoint, "PurplePedestal.png", true));
+    structMap.put(StructureType.ArtifactPoint, new ArtifactPoint(StructureType.ArtifactPoint, "YellowPedestal.png", true));
+    structMap.put(StructureType.BossPoint, new ArtifactPoint(StructureType.BossPoint, "RedPedestal.png", true));
+  }
+  
+  private void loadCreatures() {
+    creatureMap = new HashMap<CreatureType, Creature>();
+    try {
+      BufferedReader in = new BufferedReader(new FileReader("creatures.txt"));
+      while (in.ready()) {
+        Creature cr = Creature.loadTemplate(in);
+        String strItem;
+        while (!(strItem = in.readLine()).equals("---"))
+          cr.addDrop(new ItemDrop(items.get(strItem.substring(0, strItem.indexOf(","))), Integer.valueOf(strItem.substring(strItem.indexOf(",") + 2)).intValue())); 
+        creatureMap.put(cr.getType(), cr);
+      } 
+      in.close();
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+    ((Player)creatureMap.get(CreatureType.Player)).initGems(this.gems);
+    meleeModel = ((Player)creatureMap.get(CreatureType.Player)).loadModel("Player");
+    rangedModel = ((Player)creatureMap.get(CreatureType.Player)).loadModel("Player/ranged");
+  }
+  
+  private void loadSpawnPoints() {
+    spawnPoints = new LinkedList<SpawnPoint>();
+    try {
+      BufferedReader in = new BufferedReader(new FileReader("spawnPoints.txt"));
+      while (in.ready()) {
+        Creature type = creatureMap.get(CreatureType.valueOf(in.readLine()));
+        String strLoc = in.readLine();
+        int x = Integer.parseInt(strLoc.substring(0, strLoc.indexOf(",")));
+        strLoc = strLoc.substring(strLoc.indexOf(",") + 1);
+        int y = Integer.parseInt(strLoc.substring(0, strLoc.indexOf(",")));
+        strLoc = strLoc.substring(strLoc.indexOf(",") + 1);
+        int xMin = Integer.parseInt(strLoc.substring(0, strLoc.indexOf(",")));
+        int yMin = Integer.parseInt(strLoc.substring(strLoc.indexOf(",") + 1));
+        Point loc = new Point(x * 100 + xMin, y * 100 + yMin);
+        SpawnPoint sp = new SpawnPoint(type, loc, Integer.parseInt(in.readLine()), Integer.parseInt(in.readLine()));
+        spawnPoints.add(sp);
+      } 
+      in.close();
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+  }
+  
+  private void loadItems() {
+    items = new HashMap<String, Item>();
+    this.drops = new LinkedList<Item>();
+    this.projectiles = new LinkedList<Projectile>();
+    this.gems = new LinkedList<Gem>();
+    try {
+      imgBow = new BufferedImage[8];
+      imgBow[0] = ImageIO.read(getClass().getResource("../images/projectiles/bowNN.png"));
+      imgBow[1] = ImageIO.read(getClass().getResource("../images/projectiles/bowNE.png"));
+      imgBow[2] = ImageIO.read(getClass().getResource("../images/projectiles/bowEE.png"));
+      imgBow[3] = ImageIO.read(getClass().getResource("../images/projectiles/bowSE.png"));
+      imgBow[4] = ImageIO.read(getClass().getResource("../images/projectiles/bowSS.png"));
+      imgBow[5] = ImageIO.read(getClass().getResource("../images/projectiles/bowSW.png"));
+      imgBow[6] = ImageIO.read(getClass().getResource("../images/projectiles/bowWW.png"));
+      imgBow[7] = ImageIO.read(getClass().getResource("../images/projectiles/bowNW.png"));
+      BufferedReader in = new BufferedReader(new FileReader("items.txt"));
+      while (in.ready()) {
+        Item item;
+        int attackSpeed, range, damage, value;
+        String name = in.readLine();
+        String img = String.valueOf(in.readLine()) + ".png";
+        ItemType type = ItemType.valueOf(in.readLine());
+        String desc = in.readLine();
+        BufferedImage[] imgProj = new BufferedImage[8];
+        switch (type) {
+          case LightWeapon:
+          case HeavyWeapon:
+            attackSpeed = Integer.valueOf(in.readLine()).intValue();
+            damage = Integer.valueOf(in.readLine()).intValue();
+            item = new Weapon(name, type, img, null, attackSpeed, 55, damage);
+            break;
+          case RangedWeapon:
+            attackSpeed = Integer.valueOf(in.readLine()).intValue();
+            range = Integer.valueOf(in.readLine()).intValue();
+            damage = Integer.valueOf(in.readLine()).intValue();
+            imgProj = imgBow;
+            item = new Weapon(name, type, img, imgProj, attackSpeed, range, damage);
+            break;
+          case Gem:
+            value = Integer.valueOf(in.readLine()).intValue();
+            item = new Gem(name, img, value, null);
+            this.gems.add((Gem)item);
+            break;
+          default:
+            item = new Item(name, type, img);
+            break;
+        } 
+        item.setDescription(desc);
+        items.put(name, item);
+      } 
+      in.close();
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+  }
+  
+  private void loadSpellSprites() {
+    airSprites = loadSprites("air");
+    earthSprites = loadSprites("earth");
+    fireSprites = loadSprites("fire");
+    waterSprites = loadSprites("water");
+    try {
+      passiveAura = ImageIO.read(getClass().getResource("../images/spells/auras/passiveAura.png"));
+      thornsAura = ImageIO.read(getClass().getResource("../images/spells/auras/thornsAura.png"));
+      confuseAura = ImageIO.read(getClass().getResource("../images/spells/auras/confuseAura.png"));
+      sandAura = ImageIO.read(getClass().getResource("../images/spells/auras/sandAura.png"));
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+  }
+  
+  private BufferedImage[] loadSprites(String name) {
+    BufferedImage[] sprites = new BufferedImage[8];
+    try {
+      sprites[0] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellNN.png"));
+      sprites[1] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellNE.png"));
+      sprites[2] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellEE.png"));
+      sprites[3] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellSE.png"));
+      sprites[4] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellSS.png"));
+      sprites[5] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellSW.png"));
+      sprites[6] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellWW.png"));
+      sprites[7] = ImageIO.read(getClass().getResource("../images/spells/" + name + "/" + name + "SpellNW.png"));
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+    return sprites;
+  }
+  
+  public static SpawnPoint getSpawnPoint(int idNum) {
+    if (idNum == -1)
+      return null; 
+    Iterator<SpawnPoint> iter = spawnPoints.iterator();
+    while (iter.hasNext()) {
+      SpawnPoint sp;
+      if ((sp = iter.next()).idNum == idNum)
+        return sp; 
+    } 
+    return null;
+  }
+  
+  private void spawnCreatures() {
+    Iterator<SpawnPoint> iter = spawnPoints.iterator();
+    while (iter.hasNext()) {
+      SpawnPoint sp = iter.next();
+      if (Point.dist(this.player.getLoc(), sp.getLoc()) >= 600.0D) {
+        Creature cr = sp.spawn();
+        if (cr != null)
+          map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).addCreature(cr); 
+      } 
+    } 
+  }
+  
+  private void moveCreatures() {
+    int xLow = this.player.getLoc().getX() / 100 - 8;
+    int xHigh = xLow + 17;
+    int yLow = this.player.getLoc().getY() / 100 - 6;
+    int yHigh = yLow + 13;
+    if (xLow < 0)
+      xLow = 0; 
+    if (xHigh > map.getLength())
+      xHigh = map.getLength(); 
+    if (yLow < 0)
+      yLow = 0; 
+    if (yHigh > map.getHeight())
+      yHigh = map.getHeight(); 
+    for (int x = 0; x < map.getLength(); x++) {
+      for (int y = 0; y < map.getHeight(); y++) {
+        Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+        while (iter.hasNext()) {
+          Creature cr = iter.next();
+          if (cr != this.player)
+            if (cr.confused > 0) {
+              cr.setEnemyTarget(findClosestTarget(cr));
+            } else {
+              cr.setEnemyTarget(this.player);
+            }  
+          if (cr.isDying() && cr.getModel().getAnimation(Direction.West, Action.Dying).reachedEnd()) {
+            cr.setDying(false);
+            if (cr == this.player) {
+              respawnPlayer();
+              continue;
+            } 
+            if (cr.getType() == CreatureType.Specter)
+              this.gameState = GameState.Victory; 
+            continue;
+          } 
+          if (!cr.getModel().hasDeath() && cr.getHitpoints() <= 0) {
+            iter.remove();
+            continue;
+          } 
+          move(cr);
+          if (cr.getLoc().getX() / 100 != x || cr.getLoc().getY() / 100 != y) {
+            iter.remove();
+            map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).addCreature(cr);
+          } 
+        } 
+      } 
+    } 
+  }
+  
+  private void move(Creature cr) {
+    if (cr.isDying())
+      return; 
+    Point newLoc = cr.move();
+    int minDist = 50;
+    boolean creatureBlocking = false;
+    cr.checkTimedEffects();
+    Iterator<Item> itemIter = this.drops.iterator();
+    while (itemIter.hasNext()) {
+      Item item = itemIter.next();
+      if (item.getLoc().equals(this.player.getLoc())) {
+        this.player.pickUp(item);
+        itemIter.remove();
+      } 
+    } 
+    int xLow = newLoc.getX() / 100 - 2;
+    int xHigh = xLow + 5;
+    int yLow = newLoc.getY() / 100 - 2;
+    int yHigh = yLow + 5;
+    if (xLow < 0)
+      xLow = 0; 
+    if (xHigh > map.getLength())
+      xHigh = map.getLength(); 
+    if (yLow < 0)
+      yLow = 0; 
+    if (yHigh > map.getHeight())
+      yHigh = map.getHeight(); 
+    for (int x = xLow; x < xHigh; x++) {
+      for (int y = yLow; y < yHigh; y++) {
+        Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+        while (iter.hasNext()) {
+          Creature temp = iter.next();
+          if (cr.getEnemyTarget() == temp && Point.dist(temp.getLoc(), newLoc) <= cr.getWeapon().getRange()) {
+            creatureBlocking = true;
+            if (temp != this.player || !temp.isDying()) {
+              Projectile proj = cr.attack(temp, AttackType.Weapon);
+              if (proj != null) {
+                proj.setCreator(cr);
+                proj.applySpawnEffects();
+                addProjectile(proj);
+                continue;
+              } 
+              if (temp.getHitpoints() <= 0) {
+                temp.setDying(true);
+                if (temp != this.player) {
+                  killCreature(temp);
+                  this.player.setEnemyTarget(null);
+                  this.player.setTarget(this.player.getLoc());
+                } 
+              } 
+            } 
+            continue;
+          } 
+          if (temp != cr && Point.dist(temp.getLoc(), newLoc) < minDist)
+            creatureBlocking = true; 
+        } 
+      } 
+    } 
+    if (map.getLoc(newLoc.getX() / 100, newLoc.getY() / 100).isPassable() && !creatureBlocking && (!cr.farFromSpawnPoint() || cr.closerToSpawnPoint(newLoc))) {
+      Location oldLoc = map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100);
+      cr.setLoc(newLoc);
+      if (cr == this.player)
+        switch (map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).getStruct().getType()) {
+          case RespawnPoint:
+            ((RespawnPoint)map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).getStruct()).mark();
+          case RejuvenationPedestal:
+            this.player.setManapoints(this.player.getMaxManapoints());
+          case LifePedestal:
+            this.player.setHitpoints(this.player.getMaxHitpoints());
+            break;
+          case ManaPedestal:
+            this.player.setManapoints(this.player.getMaxManapoints());
+            break;
+          case BossPoint:
+            if (!this.player.readyForBoss())
+              break; 
+          case ArtifactPoint:
+            if (oldLoc != map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100)) {
+              this.player.setLoc(((ArtifactPoint)map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).getStruct()).getTarget());
+              this.player.setTarget(this.player.getLoc());
+            } 
+            break;
+        }  
+    } else {
+      cr.setTarget(cr.getLoc());
+      if (cr.getModel().getAction() != Action.Attacking)
+        cr.getModel().setAction(Action.Standing); 
+    } 
+  }
+  
+  private Creature findClosestTarget(Creature cr) {
+    int xLow = cr.getLoc().getX() / 100 - 5;
+    int xHigh = xLow + 11;
+    int yLow = cr.getLoc().getY() / 100 - 5;
+    int yHigh = yLow + 11;
+    Creature closestCr = this.player;
+    double minDist = Point.dist(cr.getLoc(), this.player.getLoc());
+    if (xLow < 0)
+      xLow = 0; 
+    if (xHigh > map.getLength())
+      xHigh = map.getLength(); 
+    if (yLow < 0)
+      yLow = 0; 
+    if (yHigh > map.getHeight())
+      yHigh = map.getHeight(); 
+    for (int x = xLow; x < xHigh; x++) {
+      for (int y = yLow; y < yHigh; y++) {
+        Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+        while (iter.hasNext()) {
+          Creature cur = iter.next();
+          if (cr != cur && minDist > Point.dist(cr.getLoc(), cur.getLoc())) {
+            minDist = Point.dist(cr.getLoc(), cur.getLoc());
+            closestCr = cur;
+          } 
+        } 
+      } 
+    } 
+    return closestCr;
+  }
+  
+  private synchronized void addProjectile(Projectile proj) {
+    this.projectiles.add(proj);
+  }
+  
+  private synchronized void moveProjectiles() {
+    Iterator<Projectile> iter = this.projectiles.iterator();
+    while (iter.hasNext()) {
+      Projectile proj = iter.next();
+      move(proj);
+      if (proj.isDone())
+        iter.remove(); 
+    } 
+  }
+  
+  private void move(Projectile proj) {
+    Point newLoc = proj.move();
+    int minDist = 50;
+    for (int x = 0; x < map.getLength(); x++) {
+      for (int y = 0; y < map.getHeight(); y++) {
+        Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+        while (iter.hasNext()) {
+          Creature cr = iter.next();
+          if (Point.dist(cr.getLoc(), newLoc) < minDist && ((cr == this.player && !proj.isPlayerOwned()) || (cr != this.player && proj.isPlayerOwned()))) {
+            if (!proj.penetrates())
+              proj.setDone(true); 
+            if (!proj.creatureIsEffected(cr)) {
+              proj.applyContactEffects(cr);
+              proj.effectCreature(cr);
+            } 
+            if (cr.getHitpoints() <= 0) {
+              cr.setDying(true);
+              if (cr != this.player) {
+                killCreature(cr);
+                this.player.setEnemyTarget(null);
+                this.player.setTarget(this.player.getLoc());
+              } 
+            } 
+          } 
+        } 
+      } 
+    } 
+    Location curLoc = map.getLoc(newLoc.getX() / 100, newLoc.getY() / 100);
+    if (proj.getTarget().equals(newLoc) || (!curLoc.isPassable() && curLoc.getLand().getType() != LandType.Ocean)) {
+      proj.setDone(true);
+    } else {
+      proj.setLoc(newLoc);
+    } 
+  }
+  
+  private void killCreature(Creature cr) {
+    Iterator<Item> itemIter = cr.spawnDrops().iterator();
+    while (itemIter.hasNext())
+      this.drops.add(((Item)itemIter.next()).copy(cr.getLoc())); 
+    if (cr.getSpawnPoint() != null)
+      cr.getSpawnPoint().removeCreature(); 
+    this.player.setExperience(this.player.getExperience() + cr.getExperience());
+    if (this.player.getExperience() >= (Math.pow(this.player.getLevel(), 2.0D) + this.player.getLevel()) * 500.0D) {
+      this.player.setExperience(this.player.getExperience() - (int)((Math.pow(this.player.getLevel(), 2.0D) + this.player.getLevel()) * 500.0D));
+      this.player.increaseLevel();
+    } 
+  }
+  
+  public void respawnPlayer() {
+    Iterator<RespawnPoint> iter = respawnPoints.iterator();
+    RespawnPoint closest = null;
+    double dist = 0.0D;
+    this.player.setHitpoints(this.player.getMaxHitpoints());
+    this.player.setManapoints(this.player.getMaxManapoints());
+    while (iter.hasNext()) {
+      RespawnPoint cur = iter.next();
+      if (cur.isMarked() && (closest == null || dist > Point.dist(cur.getLoc(), this.player.getLoc()))) {
+        closest = cur;
+        dist = Point.dist(cur.getLoc(), this.player.getLoc());
+      } 
+    } 
+    if (closest == null) {
+      this.player.setLoc(this.startPoint);
+    } else {
+      this.player.setLoc(closest.getLoc());
+    } 
+    this.player.setEnemyTarget(null);
+    this.player.setTarget(this.player.getLoc());
+  }
+  
+  private void handleEvents() {
+    switch (this.gameState) {
+      case Game:
+      case GameMenu:
+      case GameStats:
+      case GameGems:
+      case GameInventory:
+      case GameMap:
+        spawnCreatures();
+        moveCreatures();
+        moveProjectiles();
+        break;
+    } 
+  }
+  
+  private void render(Graphics g) {
+    g.setColor(Color.black);
+    g.fillRect(0, 0, 800, 600);
+    switch (this.gameState) {
+      case Main:
+        drawMain(g);
+        break;
+      case CreateAccount:
+        drawCreateAccount(g);
+        break;
+      case LoadGame:
+        drawLoadGame(g);
+        break;
+      case Info:
+        drawInfo(g);
+        break;
+      case Credits:
+        drawCredits(g);
+        break;
+      case Victory:
+        this.wndVictory.draw(g);
+        break;
+      case GameIntro:
+        this.wndGameIntro.draw(g);
+        break;
+      case GameInfo:
+        this.wndTutorials[this.wndTutCur].draw(g);
+        break;
+      case Game:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        break;
+      case GameMenu:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        drawGameMenu(g);
+        break;
+      case GameStats:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        drawGameStats(g);
+        break;
+      case GameGems:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        drawGameGems(g);
+        break;
+      case GameInventory:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        drawGameInventory(g);
+        break;
+      case GameMap:
+        drawMap(g);
+        drawItems(g);
+        drawCreatures(g);
+        drawProjectiles(g);
+        drawStatDisplay(g);
+        drawGameMap(g);
+        break;
+    } 
+    switch (this.auxState) {
+      case MsgBox:
+        this.wndMessage.draw(g);
+        break;
+    } 
+  }
+  
+  public void save() {
+    PrintWriter out = null;
+    try {
+      out = new PrintWriter(new FileWriter("save.txt"));
+      for (int x = 0; x < map.getLength(); x++) {
+        for (int y = 0; y < map.getHeight(); y++) {
+          Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+          while (iter.hasNext()) {
+            Creature cr = iter.next();
+            cr.save(out);
+          } 
+        } 
+      } 
+      out.close();
+      out = new PrintWriter(new FileWriter("savedItems.txt"));
+      Iterator<Item> itrItem = this.drops.iterator();
+      while (itrItem.hasNext()) {
+        Item cur = itrItem.next();
+        out.println(cur.getName());
+        out.println(String.valueOf(cur.getLoc().getX()) + "," + cur.getLoc().getY());
+      } 
+      out.close();
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+    } 
+  }
+  
+  public void reset() {
+    this.drops.clear();
+    this.projectiles.clear();
+    map.clearCreatures();
+    lstInventory.clear();
+    Iterator<SpawnPoint> iter = spawnPoints.iterator();
+    while (iter.hasNext())
+      ((SpawnPoint)iter.next()).clear(); 
+    SpawnPoint.numSpawnPoints = 0;
+    Iterator<RespawnPoint> rpIter = respawnPoints.iterator();
+    while (rpIter.hasNext())
+      ((RespawnPoint)rpIter.next()).unmark(); 
+  }
+  
+  public void placeQuestObjects() {
+    this.drops.add(((Item)items.get("Power Sword")).copy(new Point(1650, 150)));
+    this.drops.add(((Item)items.get("Ice Scroll")).copy(new Point(3250, 150)));
+    this.drops.add(((Item)items.get("BNW Shirt")).copy(new Point(4950, 250)));
+    this.drops.add(((Item)items.get("Studded Leather Armor")).copy(new Point(6750, 150)));
+    this.drops.add(((Item)items.get("Patched Leather")).copy(new Point(8450, 150)));
+    this.drops.add(((Item)items.get("Fire Scroll")).copy(new Point(1650, 1450)));
+    Creature cr = ((Creature)creatureMap.get(CreatureType.Specter)).copy();
+    cr.setLoc(new Point(15850, 350));
+    map.getLoc(158, 3).addCreature(cr);
+  }
+  
+  public boolean load() {
+    reset();
+    try {
+      BufferedReader in = new BufferedReader(new FileReader("save.txt"));
+      while (in.ready()) {
+        CreatureType type = CreatureType.valueOf(in.readLine());
+        Creature cr = ((Creature)creatureMap.get(type)).copy();
+        cr.load(in);
+        if (cr.getType() == CreatureType.Player)
+          this.player = (Player)cr; 
+        map.getLoc(cr.getLoc().getX() / 100, cr.getLoc().getY() / 100).addCreature(cr);
+      } 
+      Iterator<Creature> iter = map.getLoc(this.player.getTarget().getX() / 100, this.player.getTarget().getY() / 100).getCreatures().iterator();
+      while (iter.hasNext()) {
+        Creature cr2 = iter.next();
+        if (cr2.getLoc().equals(this.player.getTarget()) && cr2 != this.player)
+          this.player.setEnemyTarget(cr2); 
+      } 
+      in.close();
+      in = new BufferedReader(new FileReader("savedItems.txt"));
+      while (in.ready()) {
+        Item cur = items.get(in.readLine());
+        String loc = in.readLine();
+        int x = Integer.parseInt(loc.substring(0, loc.indexOf(",")));
+        int y = Integer.parseInt(loc.substring(loc.indexOf(",") + 1));
+        this.drops.add(cur.copy(new Point(x, y)));
+      } 
+      in.close();
+    } catch (FileNotFoundException fnfe) {
+      showMessage("There is no saved game to load");
+      return false;
+    } catch (IOException ioe) {
+      ioe.printStackTrace();
+      return false;
+    } 
+    return true;
+  }
+  
+  public static String dateString() {
+    return (new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")).format(new Date());
+  }
+  
+  public void showMessage(String text) {
+    this.auxState = AuxState.MsgBox;
+    ((Label)this.wndMessage.getMember("label")).setText(text);
+  }
+  
+  private void drawMain(Graphics g) {
+    this.wndMain.draw(g);
+    g.setColor(Color.red);
+    g.drawRect(10, 100, 380, 490);
+    g.drawRect(410, 100, 380, 490);
+  }
+  
+  private void drawCreateAccount(Graphics g) {
+    ((Label)this.wndCreateAccount.getMember("strVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Strength)));
+    ((Label)this.wndCreateAccount.getMember("dexVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Dexterity)));
+    ((Label)this.wndCreateAccount.getMember("conVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Constitution)));
+    ((Label)this.wndCreateAccount.getMember("wisVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Wisdom)));
+    ((Label)this.wndCreateAccount.getMember("attVal")).setText(Integer.toString(this.player.getAttributePoints()));
+    ((Label)this.wndCreateAccount.getMember("lightWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.LightWeapons)));
+    ((Label)this.wndCreateAccount.getMember("heavyWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.HeavyWeapons)));
+    ((Label)this.wndCreateAccount.getMember("rangedWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.RangedWeapons)));
+    ((Label)this.wndCreateAccount.getMember("evocationVal")).setText(Integer.toString(this.player.getSkill(Skill.Evocation)));
+    ((Label)this.wndCreateAccount.getMember("skillVal")).setText(Integer.toString(this.player.getSkillPoints()));
+    this.wndCreateAccount.draw(g);
+  }
+  
+  private void drawLoadGame(Graphics g) {
+    Font tempFont = new Font("Arial", 0, 12);
+    FontMetrics metrics = g.getFontMetrics(tempFont);
+    g.setFont(tempFont);
+    g.setColor(Color.green);
+    g.drawString("There is not a whole lot here right now. You can click anywhere on the screen to get back to the main menu.", 0, metrics.getHeight());
+  }
+  
+  private void drawInfo(Graphics g) {
+    if (this.infoStart) {
+      this.wndGameIntro.draw(g);
+    } else {
+      this.wndTutorials[this.wndTutCur].draw(g);
+    } 
+  }
+  
+  private void drawCredits(Graphics g) {
+    this.wndCredits.draw(g);
+  }
+  
+  private void drawMap(Graphics g) {
+    int locX = this.player.getLoc().getX();
+    int locY = this.player.getLoc().getY();
+    int xLow = locX / 100 - 5;
+    int xHigh = xLow + 11;
+    int yLow = locY / 100 - 4;
+    int yHigh = yLow + 9;
+    if (xLow < 0)
+      xLow = 0; 
+    if (xHigh > map.getLength())
+      xHigh = map.getLength(); 
+    if (yLow < 0)
+      yLow = 0; 
+    if (yHigh > map.getHeight())
+      yHigh = map.getHeight(); 
+    int x;
+    for (x = xLow; x < xHigh; x++) {
+      for (int y = yLow; y < yHigh; y++) {
+        if (map.getLoc(x, y).getLand().getType() != LandType.Mountains && map.getLoc(x, y).getLand().getType() != LandType.Cave) {
+          g.drawImage(map.getLoc(x, y).getLand().getImg(), 400 + x * 100 - locX, 300 + y * 100 - locY, null);
+          g.drawImage(map.getLoc(x, y).getStruct().getImg(), 400 + x * 100 - locX, 300 + y * 100 - locY, null);
+        } else {
+          g.drawImage(((Land)landMap.get(LandType.Metal)).getImg(), 400 + x * 100 - locX, 300 + y * 100 - locY, null);
+        } 
+      } 
+    } 
+    for (x = xLow; x < xHigh; x++) {
+      for (int y = yLow; y < yHigh; y++) {
+        if (map.getLoc(x, y).getLand().getType() == LandType.Mountains || map.getLoc(x, y).getLand().getType() == LandType.Cave)
+          g.drawImage(map.getLoc(x, y).getLand().getImg(), 390 + x * 100 - locX, 290 + y * 100 - locY, null); 
+      } 
+    } 
+  }
+  
+  private void drawItems(Graphics g) {
+    Iterator<Item> iter = this.drops.iterator();
+    while (iter.hasNext())
+      ((Item)iter.next()).draw(g, this.player.getLoc().getX(), this.player.getLoc().getY()); 
+  }
+  
+  private synchronized void drawProjectiles(Graphics g) {
+    Iterator<Projectile> iter = this.projectiles.iterator();
+    while (iter.hasNext())
+      ((Projectile)iter.next()).draw(g, this.player.getLoc().getX(), this.player.getLoc().getY()); 
+  }
+  
+  private void drawCreatures(Graphics g) {
+    int xLow = this.player.getLoc().getX() / 100 - 5;
+    int xHigh = xLow + 11;
+    int yLow = this.player.getLoc().getY() / 100 - 4;
+    int yHigh = yLow + 9;
+    if (xLow < 0)
+      xLow = 0; 
+    if (xHigh > map.getLength())
+      xHigh = map.getLength(); 
+    if (yLow < 0)
+      yLow = 0; 
+    if (yHigh > map.getHeight())
+      yHigh = map.getHeight(); 
+    for (int x = xLow; x < xHigh; x++) {
+      for (int y = yLow; y < yHigh; y++) {
+        Iterator<Creature> iter = map.getLoc(x, y).getCreatures().iterator();
+        while (iter.hasNext())
+          ((Creature)iter.next()).draw(g, this.player.getLoc().getX(), this.player.getLoc().getY()); 
+      } 
+    } 
+  }
+  
+  private void drawStatDisplay(Graphics g) {
+    this.lblGemVal.setText("Gem Value: " + this.player.getGemValue());
+    this.lblSpellCost.setText("Spell Cost: " + ((this.player.getGemValue() + 1) / 2));
+    this.wndStatDisplay.draw(g);
+    g.drawString(this.player.getName(), 20, 562);
+    g.drawString("Level " + this.player.getLevel(), 20, 574);
+    g.drawString("Relics Acquired: " + this.player.getRelicCount() + "/4", 20, 591);
+    g.setColor(Color.yellow);
+    g.drawRect(240, 578, 80, 15);
+    g.fillRect(240, 578, 80 * this.player.getExperience() / (int)((Math.pow(this.player.getLevel(), 2.0D) + this.player.getLevel()) * 500.0D), 15);
+    g.setColor(Color.green);
+    g.drawRect(125, 557, 80, 15);
+    g.fillRect(125, 557, 80 * this.player.getHitpoints() / this.player.getMaxHitpoints(), 15);
+    g.setColor(Color.blue);
+    g.drawRect(240, 557, 80, 15);
+    g.fillRect(240, 557, 80 * this.player.getManapoints() / this.player.getMaxManapoints(), 15);
+    g.setColor(Color.red);
+    g.drawString("HP:", 100, 569);
+    g.drawString("MP:", 215, 569);
+    g.drawString("Experience:", 170, 591);
+    g.drawString(String.valueOf(this.player.getExperience()) + "/" + ((int)(Math.pow(this.player.getLevel(), 2.0D) + this.player.getLevel()) * 500), 245, 590);
+    g.drawString(String.valueOf(this.player.getHitpoints()) + "/" + this.player.getMaxHitpoints(), 130, 569);
+    g.drawString(String.valueOf(this.player.getManapoints()) + "/" + this.player.getMaxManapoints(), 245, 569);
+    this.player.getWeapon().drawStatic(g, 450 + this.wndStatDisplay.getX(), this.wndStatDisplay.getY());
+    int mouseX = (MouseInfo.getPointerInfo().getLocation()).x;
+    int mouseY = (MouseInfo.getPointerInfo().getLocation()).y;
+    if (450 + this.wndStatDisplay.getX() <= mouseX && mouseX < 500 + this.wndStatDisplay.getX() && this.wndStatDisplay.getY() <= mouseY && mouseY < 50 + this.wndStatDisplay.getY()) {
+      String itemType;
+      Item i = (this.player.getWeapon()).baseWeapon;
+      Window popup = new Window("popup", mouseX - 126, mouseY - 100, 126, 100, false);
+      Font font12 = new Font("Arial", 0, 12);
+      switch (i.getType()) {
+        case LightWeapon:
+          itemType = "Light Weapon";
+          break;
+        case HeavyWeapon:
+          itemType = "Heavy Weapon";
+          break;
+        case RangedWeapon:
+          itemType = "Ranged Weapon";
+          break;
+        default:
+          itemType = i.getType().toString();
+          break;
+      } 
+      popup.add(new Label("info", 8, 5, 110, 15, "Equipped Weapon", font12));
+      popup.add(new Label("name", 8, 20, 110, 15, i.getName(), font12));
+      popup.add(new Label("type", 8, 50, 110, 15, itemType, font12));
+      popup.add(new Label("damage", 8, 65, 110, 15, "Damage: " + ((Weapon)i).getDamage() + "(" + this.player.getWeapon().getDamage() + ")", font12));
+      popup.add(new Label("damage", 8, 80, 110, 15, "Cooldown: " + (((Weapon)i).getAttackSpeed() / 10.0D) + "(" + (this.player.getWeapon().getAttackSpeed() / 10.0D) + ")" + " s", font12));
+      popup.draw(g);
+    } 
+  }
+  
+  private void drawGameMenu(Graphics g) {}
+  
+  private void drawGameStats(Graphics g) {
+    ((Label)this.wndGameStats.getMember("strVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Strength)));
+    ((Label)this.wndGameStats.getMember("dexVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Dexterity)));
+    ((Label)this.wndGameStats.getMember("conVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Constitution)));
+    ((Label)this.wndGameStats.getMember("wisVal")).setText(Integer.toString(this.player.getAttribute(Attribute.Wisdom)));
+    ((Label)this.wndGameStats.getMember("lightWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.LightWeapons)));
+    ((Label)this.wndGameStats.getMember("heavyWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.HeavyWeapons)));
+    ((Label)this.wndGameStats.getMember("rangedWeaponVal")).setText(Integer.toString(this.player.getSkill(Skill.RangedWeapons)));
+    ((Label)this.wndGameStats.getMember("evocationVal")).setText(Integer.toString(this.player.getSkill(Skill.Evocation)));
+    ((Label)this.wndGameStats.getMember("skillVal")).setText(Integer.toString(this.player.getSkillPoints()));
+    this.wndGameStats.draw(g);
+  }
+  
+  private void drawGameGems(Graphics g) {
+    this.wndGameGems.draw(g);
+    int mouseX = (MouseInfo.getPointerInfo().getLocation()).x;
+    int mouseY = (MouseInfo.getPointerInfo().getLocation()).y;
+    Window w = this.wndGameGems;
+    if (w.getX() < mouseX && mouseX < w.getX() + w.getWidth() - 20 && w.getY() < mouseY && mouseY < w.getY() + w.getHeight())
+      this.player.drawInventory(g, lstGems, this.wndGameGems.getX() + 1, this.wndGameGems.getY() + 1); 
+  }
+  
+  private void drawGameInventory(Graphics g) {
+    this.wndGameInventory.draw(g);
+    int mouseX = (MouseInfo.getPointerInfo().getLocation()).x;
+    int mouseY = (MouseInfo.getPointerInfo().getLocation()).y;
+    Window w = this.wndGameInventory;
+    if (w.getX() < mouseX && mouseX < w.getX() + w.getWidth() - 20 && w.getY() < mouseY && mouseY < w.getY() + w.getHeight())
+      this.player.drawInventory(g, lstInventory, this.wndGameInventory.getX() + 1, this.wndGameInventory.getY() + 1); 
+  }
+  
+  private void drawGameMap(Graphics g) {
+    this.wndGameMap.draw(g);
+    g.drawImage(this.imgMap, this.wndGameMap.getX() + 10, this.wndGameMap.getY() + 10, null);
+  }
+  
+  private void selectText(Textbox text) {
+    if (this.selectedText != null)
+      this.selectedText.setSelected(false); 
+    this.selectedText = text;
+    if (text != null)
+      text.setSelected(true); 
+  }
+  
+  private static DisplayMode getBestDisplayMode(GraphicsDevice device) {
+    for (int x = 0; x < BEST_DISPLAY_MODES.length; x++) {
+      DisplayMode[] modes = device.getDisplayModes();
+      for (int i = 0; i < modes.length; i++) {
+        if (modes[i].getWidth() == BEST_DISPLAY_MODES[x].getWidth() && modes[i].getHeight() == BEST_DISPLAY_MODES[x].getHeight() && modes[i].getBitDepth() == BEST_DISPLAY_MODES[x].getBitDepth())
+          return BEST_DISPLAY_MODES[x]; 
+      } 
+    } 
+    return null;
+  }
+  
+  public static void chooseBestDisplayMode(GraphicsDevice device) {
+    DisplayMode best = getBestDisplayMode(device);
+    if (best != null)
+      device.setDisplayMode(best); 
+  }
+  
+  public void mousePressed(MouseEvent e) {
+    boolean targetSet;
+    if (!this.started)
+      return; 
+    switch (this.auxState) {
+      case None:
+        switch (this.gameState) {
+          case Main:
+            if (this.wndMain.getMember("new game").isClicked(e.getX(), e.getY())) {
+              this.player = (Player)((Creature)creatureMap.get(CreatureType.Player)).copy();
+              this.gameState = GameState.CreateAccount;
+              break;
+            } 
+            if (this.wndMain.getMember("load game").isClicked(e.getX(), e.getY())) {
+              if (load()) {
+                this.player.setTimeLoggedOn(System.currentTimeMillis());
+                this.gameState = GameState.Game;
+              } 
+              break;
+            } 
+            if (this.wndMain.getMember("game info").isClicked(e.getX(), e.getY())) {
+              this.infoStart = true;
+              this.gameState = GameState.Info;
+              break;
+            } 
+            if (this.wndMain.getMember("credits").isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.Credits;
+              break;
+            } 
+            if (this.wndMain.getMember("quit").isClicked(e.getX(), e.getY()))
+              this.done = true; 
+            break;
+          case CreateAccount:
+            if (this.wndCreateAccount.getMember("user").isClicked(e.getX(), e.getY())) {
+              selectText((Textbox)this.wndCreateAccount.getMember("user"));
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("create").isClicked(e.getX(), e.getY())) {
+              String user = ((Textbox)this.wndCreateAccount.getMember("user")).getText();
+              if (user.equals("")) {
+                showMessage("The username is empty");
+                break;
+              } 
+              if (this.player.getAttributePoints() > 0) {
+                showMessage("You still have attribute points remaining");
+                break;
+              } 
+              if (this.player.getSkillPoints() > 0) {
+                showMessage("You still have skill points remaining");
+                break;
+              } 
+              this.wndCreateAccount.clear();
+              reset();
+              placeQuestObjects();
+              this.player.setName(user);
+              this.player.setLoc(this.startPoint);
+              this.player.setTarget(this.player.getLoc());
+              this.player.setWeapon((Weapon)items.get("Branch"));
+              this.player.pickUp((this.player.getWeapon()).baseWeapon);
+              map.getLoc(this.startPoint.getX() / 100, this.startPoint.getY() / 100).addCreature(this.player);
+              this.gameState = GameState.GameIntro;
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("cancel").isClicked(e.getX(), e.getY())) {
+              selectText(null);
+              this.wndCreateAccount.clear();
+              this.gameState = GameState.Main;
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("strength-").isClicked(e.getX(), e.getY())) {
+              this.player.repickAttribute(Attribute.Strength);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("strength+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateAttribute(Attribute.Strength);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("dexterity-").isClicked(e.getX(), e.getY())) {
+              this.player.repickAttribute(Attribute.Dexterity);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("dexterity+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateAttribute(Attribute.Dexterity);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("constitution-").isClicked(e.getX(), e.getY())) {
+              this.player.repickAttribute(Attribute.Constitution);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("constitution+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateAttribute(Attribute.Constitution);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("wisdom-").isClicked(e.getX(), e.getY())) {
+              this.player.repickAttribute(Attribute.Wisdom);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("wisdom+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateAttribute(Attribute.Wisdom);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("lightWeapon-").isClicked(e.getX(), e.getY())) {
+              this.player.repickSkill(Skill.LightWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("lightWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.LightWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("heavyWeapon-").isClicked(e.getX(), e.getY())) {
+              this.player.repickSkill(Skill.HeavyWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("heavyWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.HeavyWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("rangedWeapon-").isClicked(e.getX(), e.getY())) {
+              this.player.repickSkill(Skill.RangedWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("rangedWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.RangedWeapons);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("evocation-").isClicked(e.getX(), e.getY())) {
+              this.player.repickSkill(Skill.Evocation);
+              break;
+            } 
+            if (this.wndCreateAccount.getMember("evocation+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.Evocation);
+              break;
+            } 
+            this.wndCreateAccount.handleEvent(e);
+            break;
+          case Info:
+            if (this.infoStart) {
+              this.infoStart = false;
+              break;
+            } 
+            if (this.wndTutOptions.getMember("previous").isClicked(e.getX(), e.getY())) {
+              if (this.wndTutCur != 0)
+                this.wndTutCur--; 
+            } else if (this.wndTutOptions.getMember("next").isClicked(e.getX(), e.getY())) {
+              this.wndTutCur++;
+              if (this.wndTutCur > 12) {
+                this.gameState = GameState.Main;
+                this.wndTutCur = 0;
+              } 
+            } else if (this.wndTutOptions.getMember("skip").isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.Main;
+              this.wndTutCur = 0;
+            } 
+            ((Label)this.wndTutOptions.getMember("num")).setText(String.valueOf(this.wndTutCur + 1) + " / 13");
+            break;
+          case Credits:
+            this.gameState = GameState.Main;
+            break;
+          case Victory:
+            this.gameState = GameState.Credits;
+            break;
+          case GameIntro:
+            this.gameState = GameState.GameInfo;
+            break;
+          case GameInfo:
+            if (this.wndTutOptions.getMember("previous").isClicked(e.getX(), e.getY())) {
+              if (this.wndTutCur != 0)
+                this.wndTutCur--; 
+            } else if (this.wndTutOptions.getMember("next").isClicked(e.getX(), e.getY())) {
+              this.wndTutCur++;
+              if (this.wndTutCur > 12) {
+                this.gameState = GameState.Game;
+                this.player.setTimeLoggedOn(System.currentTimeMillis());
+                this.wndTutCur = 0;
+              } 
+            } else if (this.wndTutOptions.getMember("skip").isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.Game;
+              this.player.setTimeLoggedOn(System.currentTimeMillis());
+              this.wndTutCur = 0;
+            } 
+            ((Label)this.wndTutOptions.getMember("num")).setText(String.valueOf(this.wndTutCur + 1) + " / 13");
+            break;
+          case Game:
+            targetSet = false;
+            if (e.getY() < 550) {
+              if (this.player.isDying())
+                return; 
+              int newX = this.player.getLoc().getX() + e.getX() - 400;
+              int newY = this.player.getLoc().getY() + e.getY() - 300;
+              if (e.getButton() == 1) {
+                Iterator<Item> itemIter = this.drops.iterator();
+                while (itemIter.hasNext()) {
+                  Item item = itemIter.next();
+                  if (item.getLoc().getX() - 25 <= newX && newX <= item.getLoc().getX() + 25 && 
+                    item.getLoc().getY() - 25 <= newY && newY <= item.getLoc().getY() + 25) {
+                    this.player.setTarget(item.getLoc());
+                    targetSet = true;
+                  } 
+                } 
+                for (int x = 0; x < map.getLength(); x++) {
+                  for (int y = 0; y < map.getHeight(); y++) {
+                    Iterator<Creature> crIter = map.getLoc(x, y).getCreatures().iterator();
+                    while (crIter.hasNext()) {
+                      Creature cr = crIter.next();
+                      if (cr.getLoc().getX() - cr.getModel().getWidth() / 2 <= newX && newX <= cr.getLoc().getX() + cr.getModel().getWidth() / 2 && cr != this.player && 
+                        cr.getLoc().getY() - cr.getModel().getHeight() <= newY && newY <= cr.getLoc().getY()) {
+                        this.player.setEnemyTarget(cr);
+                        targetSet = true;
+                      } 
+                    } 
+                  } 
+                } 
+                if (map.getLoc((int)Math.floor((newX / 100)), (int)Math.floor((newY / 100))).isPassable() && !targetSet) {
+                  this.player.setTarget(new Point(newX, newY));
+                  this.player.setEnemyTarget(null);
+                } 
+                if (this.player.getEnemyTarget() != null && this.player.getWeapon().getType() == ItemType.RangedWeapon) {
+                  Projectile proj = this.player.attack(this.player.getEnemyTarget(), AttackType.Weapon);
+                  if (proj != null) {
+                    proj.setCreator(this.player);
+                    proj.applySpawnEffects();
+                    addProjectile(proj);
+                  } 
+                  this.player.setTarget(this.player.getLoc());
+                  this.player.setEnemyTarget(null);
+                } 
+                break;
+              } 
+              if (e.getButton() == 3 && 
+                this.player.getSpell() != null && this.player.getManapoints() >= ((ManaDrain)this.player.getSpell().getSpawnEffect(EffectType.ManaDrain)).getMana()) {
+                Point loc = new Point(this.player.getLoc());
+                loc.setY(loc.getY() - 55);
+                Projectile proj = this.player.attack(new Point(newX, newY), AttackType.Spell);
+                if (proj != null) {
+                  proj.setCreator(this.player);
+                  proj.applySpawnEffects();
+                  addProjectile(proj);
+                } 
+              } 
+              break;
+            } 
+            if (this.btnMenu.isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.Main;
+              this.player.updateTimePlayed();
+              save();
+              break;
+            } 
+            if (this.btnStats.isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.GameStats;
+              break;
+            } 
+            if (this.btnGems.isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.GameGems;
+              break;
+            } 
+            if (this.btnInventory.isClicked(e.getX(), e.getY())) {
+              this.gameState = GameState.GameInventory;
+              break;
+            } 
+            if (this.btnMap.isClicked(e.getX(), e.getY()))
+              this.gameState = GameState.GameMap; 
+            break;
+          case GameStats:
+            if (this.wndGameStats.getMember("lightWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.LightWeapons);
+              break;
+            } 
+            if (this.wndGameStats.getMember("heavyWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.HeavyWeapons);
+              break;
+            } 
+            if (this.wndGameStats.getMember("rangedWeapon+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.RangedWeapons);
+              break;
+            } 
+            if (this.wndGameStats.getMember("evocation+").isClicked(e.getX(), e.getY())) {
+              this.player.allocateSkill(Skill.Evocation);
+              break;
+            } 
+            this.gameState = GameState.Game;
+            break;
+          case GameGems:
+            if (this.wndGameGems.isClicked(e.getX(), e.getY())) {
+              if (e.getX() < this.wndGameGems.getX() + this.wndGameGems.getWidth() - 20) {
+                int x = (e.getX() - this.wndGameGems.getX() - 1) / 50;
+                int y = (e.getY() - this.wndGameGems.getY() - 1 + lstGems.getTextStart()) / 50;
+                if (x + 4 * y >= 0 && x + 4 * y < lstGems.getList().size()) {
+                  Item i = this.player.getGems().get(x + y * 4);
+                  switch (i.getType()) {
+                    case Gem:
+                      this.player.deactivateGem((Gem)i);
+                      break;
+                  } 
+                } 
+              } 
+              this.wndGameGems.handleEvent(e);
+              break;
+            } 
+            this.gameState = GameState.Game;
+            break;
+          case GameInventory:
+            if (this.wndGameInventory.isClicked(e.getX(), e.getY())) {
+              if (e.getX() < this.wndGameInventory.getX() + this.wndGameInventory.getWidth() - 20) {
+                int x = (e.getX() - this.wndGameInventory.getX() - 1) / 50;
+                int y = (e.getY() - this.wndGameInventory.getY() - 1 + lstInventory.getTextStart()) / 50;
+                if (x + 4 * y >= 0 && x + 4 * y < this.player.getInventory().size()) {
+                  Item i = this.player.getInventory().get(x + y * 4);
+                  switch (i.getType()) {
+                    case HeavyWeapon:
+                      if (this.player.getAttribute(Attribute.Strength) < 12) {
+                        showMessage("You must have at least 12 Strength");
+                        break;
+                      } 
+                    case LightWeapon:
+                    case RangedWeapon:
+                      this.player.setWeapon((Weapon)i);
+                      break;
+                    case Gem:
+                      if (!this.player.activateGem((Gem)i))
+                        showMessage("You must have a higher Evocation skill"); 
+                      break;
+                  } 
+                } 
+              } 
+              this.wndGameInventory.handleEvent(e);
+              break;
+            } 
+            this.gameState = GameState.Game;
+            break;
+          case GameMap:
+            this.gameState = GameState.Game;
+            break;
+        } 
+        break;
+      case MsgBox:
+        if (this.wndMessage.getMember("button").isClicked(e.getX(), e.getY()))
+          this.auxState = AuxState.None; 
+        break;
+    } 
+  }
+  
+  public void mouseReleased(MouseEvent e) {
+  }
+  
+  public void mouseEntered(MouseEvent e) {
+  }
+  
+  public void mouseExited(MouseEvent e) {
+  }
+  
+  public void mouseClicked(MouseEvent e) {
+  }
+  
+  public void keyTyped(KeyEvent e) {
+  }
+  
+  public void keyPressed(KeyEvent e) {
+    if (this.selectedText != null)
+      this.selectedText.handleEvent(e); 
+    if (e.getKeyCode() == 27)
+      if (this.gameState == GameState.Game) {
+        this.gameState = GameState.Main;
+        save();
+      } else {
+        this.done = true;
+      }  
+  }
+
+  public void keyReleased(KeyEvent e) {
+  }
+
+  public static void main(String[] args) {
+    try {
+      PrintStream st = new PrintStream(new FileOutputStream("err.txt", true));
+      System.setErr(st);
+      System.setOut(st);
+      System.out.println("-----[ Session started on " + dateString() + " ]-----");
+      GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+      GraphicsDevice device = env.getDefaultScreenDevice();
+      new LostHavenRPG(device);
+    } catch (Exception e) {
+      e.printStackTrace();
     }
-    
-    private void initGUIElements() {    	
-    	Font font10 = new Font("Arial", Font.PLAIN, 10);
-    	Font font11 = new Font("Arial", Font.PLAIN, 11);
-    	Font font12 = new Font("Arial", Font.PLAIN, 12);
-    	Font font14 = new Font("Arial", Font.PLAIN, 14);
-    	Font font24 = new Font("Arial", Font.PLAIN, 24);
-    	
-    	wndMain = new gamegui.Window("main", 0, 0, 800, 600, true);
-    	
-    	Animation anmTitle = new Animation("title", 144, 0, 512, 95, 1000/12);
-    	
-    	try {
-    		anmTitle.addFrame(ImageIO.read(getClass().getResource("images/Frame1.png")));
-    		anmTitle.addFrame(ImageIO.read(getClass().getResource("images/Frame2.png")));
-    		anmTitle.addFrame(ImageIO.read(getClass().getResource("images/Frame3.png")));
-    		anmTitle.addFrame(ImageIO.read(getClass().getResource("images/Frame4.png")));
-    		anmTitle.addFrame(ImageIO.read(getClass().getResource("images/Frame5.png")));
-    	}catch(IOException ioe) {
-    		ioe.printStackTrace();
-    	}
-    	wndMain.add(anmTitle);
-        
-    	wndMain.add(new gamegui.Button("new game", 500, 140, 200, 40, "New Game", font12));
-    	wndMain.add(new gamegui.Button("load game", 500, 230, 200, 40, "Load Game", font12));
-    	wndMain.add(new gamegui.Button("game info", 500, 320, 200, 40, "Game Information", font12));
-    	wndMain.add(new gamegui.Button("credits", 500, 410, 200, 40, "Credits", font12));
-    	wndMain.add(new gamegui.Button("quit", 500, 500, 200, 40, "Quit", font12));
-    	
-    	wndCreateAccount = new gamegui.Window("create account", 0, 0, 800, 600, true);
-    	
-    	rdgGenderSelection = new RadioGroup("gender selection", 400, 315, 190, 30, "Gender:", font12);
-    	
-    	rdgGenderSelection.add(new RadioButton("male", 438, 318, 24, 24, "Male", font11, false));
-    	rdgGenderSelection.add(new RadioButton("female", 528, 318, 24, 24, "Female", font11, false));
-    	
-    	wndCreateAccount.add(new gamegui.Label("title", 250, 15, 300, 20, "Create an Account", font24, true));
-    	wndCreateAccount.add(new Textbox("user", 400, 150, 190, 30, "Username:", font12, false));
-    	wndCreateAccount.add(rdgGenderSelection);
-    	wndCreateAccount.add(new gamegui.Label("show class", 330, 370, 70, 30, "None", font12, false));
-    	wndCreateAccount.add(new gamegui.Button("choose class", 400, 370, 190, 30, "Choose Your Class", font12));
-    	wndCreateAccount.add(new gamegui.Button("create", 245, 520, 140, 30, "Create", font12));
-    	wndCreateAccount.add(new gamegui.Button("cancel", 415, 520, 140, 30, "Cancel", font12));
-    
-    	wndChooseClass = new gamegui.Window("choose class", 0, 0, 800, 600, true);
-    	
-    	rdgClassSelection = new RadioGroup("class selection", 0, 0, 0, 0, "", font12);
-    	
-    	rdgClassSelection.add(new RadioButton("fighter", 138, 88, 24, 24, "Fighter", font14, true));
-    	rdgClassSelection.add(new RadioButton("ranger", 138, 158, 24, 24, "Ranger", font14, true));
-    	rdgClassSelection.add(new RadioButton("barbarian", 138, 228, 24, 24, "Barbarian", font14, true));
-    	rdgClassSelection.add(new RadioButton("sorceror", 138, 298, 24, 24, "Sorceror", font14, true));
-    	rdgClassSelection.add(new RadioButton("druid", 138, 368, 24, 24, "Druid", font14, true));
-    	rdgClassSelection.add(new RadioButton("wizard", 138, 438, 24, 24, "Wizard", font14, true));
-    	
-    	wndChooseClass.add(new gamegui.Label("title", 250, 15, 300, 20, "Choose a Character", font24, true));
-    	wndChooseClass.add(rdgClassSelection);
-    	wndChooseClass.add(new gamegui.Label("fighter", 170, 114, 170, 0, "A resolute and steadfast champion who has perfected the art of battle and his skill in melee weapons", font10, false));
-    	wndChooseClass.add(new gamegui.Label("ranger", 170, 184, 170, 0, "A skilled combatant who sneaks up on his opponents or shoots them from afar before they know it", font10, false));
-    	wndChooseClass.add(new gamegui.Label("barbarian", 170, 254, 170, 0, "A wild warrior who is unstoppable in battle and uses his own fury to strengthen his attacks", font10, false));
-    	wndChooseClass.add(new gamegui.Label("sorceror", 170, 324, 170, 0, "A chaotic spellcaster who uses his charisma and force of will to power his spells", font10, false));
-    	wndChooseClass.add(new gamegui.Label("druid", 170, 394, 170, 0, "A mystical enchanter who relies on the power of nature and his wisdom to work his magic", font10, false));
-    	wndChooseClass.add(new gamegui.Label("wizard", 170, 464, 170, 0, "A methodical and studious character who studies his opponents to know how to best attack them", font10, false));
-    	wndChooseClass.add(new gamegui.Button("select", 245, 520, 140, 30, "Select", font12));
-    	wndChooseClass.add(new gamegui.Button("cancel", 415, 520, 140, 30, "Cancel", font12));
-    	
-    	wndMessage = new gamegui.Window("message", 290, 135, 220, 160, false);
-		wndMessage.add(new gamegui.Label("label", 70, 15, 80, 12, "none", font12, true));
-		wndMessage.add(new gamegui.Button("button", 70, 115, 80, 30, "OK", font12));
-    }
-    
-    private void loadMap() {
-    	landMap = new HashMap<LandType, Land>();
-    	structMap = new HashMap<StructureType, Structure>();
-    	BufferedImage nullImg = null;
-    	
-    	try {
-    		girl = ImageIO.read(getClass().getResource("images/ArmoredGirl.png"));
-    		guy = ImageIO.read(getClass().getResource("images/ArmoredGuy.png"));
-    	}catch(IOException ioe) {
-    		ioe.printStackTrace();
-    	}
-    		
-    	landMap.put(LandType.Ocean, new Land(LandType.Ocean, "Ocean.png", false));
-    	landMap.put(LandType.Grass, new Land(LandType.Grass, "Grass.png", true));
-    	
-    	structMap.put(StructureType.None, new Structure(StructureType.None, nullImg, true));
-    	structMap.put(StructureType.BlueOrb, new Structure(StructureType.BlueOrb, "Blue Orb.png", false));
-    	structMap.put(StructureType.Cave, new Structure(StructureType.Cave, "Cave.png", false));
-    	structMap.put(StructureType.Gravestone, new Structure(StructureType.Gravestone, "Gravestone.png", false));
-    	structMap.put(StructureType.GraveyardFence1, new Structure(StructureType.GraveyardFence1, "HorGrave.png", false));
-    	structMap.put(StructureType.GraveyardFence2, new Structure(StructureType.GraveyardFence2, "VerGrave.png", false));
-    	structMap.put(StructureType.PicketFence1, new Structure(StructureType.PicketFence1, "HorPalisade.png", false));
-    	structMap.put(StructureType.PicketFence2, new Structure(StructureType.PicketFence2, "VerPalisade.png", false));
-    	structMap.put(StructureType.Hut, new Structure(StructureType.Hut, "Hut.png", false));
-    	structMap.put(StructureType.WitchHut, new Structure(StructureType.WitchHut, "Witch Hut.png", false));
-    	structMap.put(StructureType.Tent, new Structure(StructureType.Tent, "Tent.png", false));
-    	structMap.put(StructureType.LargeTent, new Structure(StructureType.LargeTent, "LargeTent.png", false));
-    	structMap.put(StructureType.House, new Structure(StructureType.House, "House.png", false));
-    	structMap.put(StructureType.Tree, new Structure(StructureType.Tree, "Trees.png", false));
-    	structMap.put(StructureType.BlueOrb, new Structure(StructureType.BlueOrb, "Blue Orb.png", false));
-    	structMap.put(StructureType.RedOrb, new Structure(StructureType.RedOrb, "Red Orb.png", false));
-    	structMap.put(StructureType.LoginPedestal, new Structure(StructureType.LoginPedestal, "YellowPedestal.png", true));
-    	structMap.put(StructureType.RejuvenationPedestal, new Structure(StructureType.RejuvenationPedestal, "PurplePedestal.png", true));
-    	structMap.put(StructureType.LifePedestal, new Structure(StructureType.LifePedestal, "RedPedestal.png", true));
-    	structMap.put(StructureType.ManaPedestal, new Structure(StructureType.ManaPedestal, "BluePedestal.png", true));
-    }
-    
-    private void move() {
-    	double dist = player.getSpeed()*(System.currentTimeMillis()-player.getLastMoved())/1000;
-    	Point lastLoc = player.getLoc();
-    	Point target = player.getTarget();
-    	Point newLoc;
-    	
-    	player.setLastMoved(System.currentTimeMillis());
-    	if(Point.dist(lastLoc, player.getTarget()) <= dist)
-    		player.setLoc(player.getTarget());
-    	else {
-    		int xDif = (int)(Point.xDif(lastLoc, target)*dist/Point.dist(lastLoc, target));
-    		int yDif = (int)(Point.yDif(lastLoc, target)*dist/Point.dist(lastLoc, target));
-    		newLoc = new Point(lastLoc.getX(), lastLoc.getXMin()+xDif, lastLoc.getY(), lastLoc.getYMin()+yDif);
-    		newLoc.setX(newLoc.getX()+newLoc.getXMin()/100);
-    		newLoc.setXMin(newLoc.getXMin()%100);
-    		newLoc.setY(newLoc.getY()+newLoc.getYMin()/100);
-    		newLoc.setYMin(newLoc.getYMin()%100);
-    		if(newLoc.getXMin()<0) {
-    			newLoc.setX(newLoc.getX()-1);
-    			newLoc.setXMin(newLoc.getXMin()+100);
-    		}else if(newLoc.getYMin()<0) {
-    			newLoc.setY(newLoc.getY()-1);
-    			newLoc.setYMin(newLoc.getYMin()+100);
-    		}
-    		if(map.getLoc(newLoc.getX()/100, newLoc.getY()/100).isPassable())
-    			player.setLoc(newLoc);
-    		else
-    			player.setTarget(player.getLoc());
-    	}
-    }
-    
-    private void render(Graphics g) {
-    	g.setColor(Color.black);
-        g.fillRect(0, 0, 800, 600);
-        
-        switch(gameState) {
-		case Main:
-			drawMain(g);
-			break;
-		case CreateAccount:
-			drawCreateAccount(g);
-			break;
-		case CreateClass:
-			drawCreateClass(g);
-			break;
-		case LoadGame:
-			drawLoadGame(g);
-			break;
-		case Info:
-			drawInfo(g);
-			break;
-		case Credits:
-			drawCredits(g);
-			break;
-		case Game:
-			calculateMapVertices();
-            drawMap(g);
-            drawItems(g);
-            drawCreatures(g);
-            drawChar(g);
-            drawStatDisplay(g);
-            drawChat(g);
-			break;
-		case GameMenu:
-			calculateMapVertices();
-            drawMap(g);
-            drawItems(g);
-            drawCreatures(g);
-            drawChar(g);
-            drawStatDisplay(g);
-            drawChat(g);
-            drawGameMenu(g);
-			break;
-		case GameInventory:
-			calculateMapVertices();
-            drawMap(g);
-            drawItems(g);
-            drawCreatures(g);
-            drawChar(g);
-            drawStatDisplay(g);
-            drawChat(g);
-            drawGameInventory(g);
-			break;
-		case GameStats:
-			calculateMapVertices();
-            drawMap(g);
-            drawItems(g);
-            drawCreatures(g);
-            drawChar(g);
-            drawStatDisplay(g);
-            drawChat(g);
-            drawGameStats(g);
-			break;
-		}
-        
-        switch(auxState) {
-		case None:
-			break;
-		case MsgBox:
-			wndMessage.draw(g);
-			break;
-		}
-    }
-    
-    public static String dateString() {
-		return new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date());
-	}
-    
-    public void showMessage(String text) {
-    	auxState = AuxState.MsgBox;
-    	((gamegui.Label)wndMessage.getMember("label")).setText(text);
-    }
-    
-    private void calculateMapVertices() {
-    
-    }
-    
-    private void drawMain(Graphics g) {
-    	wndMain.draw(g);
-    	
-    	g.setColor(Color.red);
-		g.drawRect(10, 100, 380, 490);
-		g.drawRect(410, 100, 380, 490);
-    }
-    
-    private void drawCreateAccount(Graphics g) {    	
-    	wndCreateAccount.draw(g);
-    }
-    
-    private void drawCreateClass(Graphics g) {
-    	wndChooseClass.draw(g);
-    }
-    
-    private void drawLoadGame(Graphics g) {
-    	Font tempFont = new Font("Arial", Font.PLAIN, 12);
-    	FontMetrics metrics = g.getFontMetrics(tempFont);
-    	
-    	g.setFont(tempFont);
-    	g.setColor(Color.green);
-    	g.drawString("There is not a whole lot here right now. You can click anywhere on the screen to get back to the main menu.", 0, metrics.getHeight());
-    }
-    
-    private void drawInfo(Graphics g) {
-    	Font tempFont = new Font("Arial", Font.PLAIN, 12);
-    	FontMetrics metrics = g.getFontMetrics(tempFont);
-    	
-    	g.setFont(tempFont);
-    	g.setColor(Color.green);
-    	g.drawString("There is not a whole lot here right now. You can click anywhere on the screen to get back to the main menu.", 0, metrics.getHeight());
-    }
-    
-    private void drawCredits(Graphics g) {
-    	Font tempFont = new Font("Arial", Font.PLAIN, 12);
-    	FontMetrics metrics = g.getFontMetrics(tempFont);
-    	
-    	g.setFont(tempFont);
-    	g.setColor(Color.green);
-    	g.drawString("There is not a whole lot here right now. You can click anywhere on the screen to get back to the main menu.", 0, metrics.getHeight());
-    }
-    
-    private void drawMap(Graphics g) {
-    	int locX = player.getLoc().getX();
-    	int locY = player.getLoc().getY();
-    	int xLow = locX/100-4;
-    	int xHigh = xLow+9;
-    	int yLow = locY/100-3;
-    	int yHigh = yLow+7;
-    	
-    	if(xLow<0)
-    		xLow = 0;
-    	if(xHigh>=map.getLength())
-    		xHigh = map.getLength()-1;
-    	if(yLow<0)
-    		yLow = 0;
-    	if(yHigh>=map.getHeight())
-    		yHigh = map.getHeight()-1;
-
-		for(int x=xLow; x<xHigh; x++) {
-			for(int y=yLow; y<yHigh; y++) {
-				g.drawImage(map.getLoc(x, y).getLand().getImg(), 400+x*100-locX, 300+y*100-locY, null);				
-				g.drawImage(map.getLoc(x, y).getStruct().getImg(), 400+x*100-locX, 300+y*100-locY, null);
-			}
-		}
-    }
-    
-    private void drawItems(Graphics g) {
-    
-    }
-    
-    private void drawCreatures(Graphics g) {
-    
-    }
-    
-    private void drawChar(Graphics g) {
-    	switch(player.getGender()) {
-		case Female:
-			g.drawImage(girl, 375, 200, null);
-			break;
-		case Male:
-			g.drawImage(guy, 375, 200, null);
-			break;
-		}
-    }
-    
-    private void drawStatDisplay(Graphics g) {
-    
-    }
-    
-    private void drawChat(Graphics g) {
-    
-    }
-    
-    private void drawGameMenu(Graphics g) {
-    
-    }
-    
-    private void drawGameInventory(Graphics g) {
-    
-    }
-    
-    private void drawGameStats(Graphics g) {
-    
-    }
-    
-    private void selectText(Textbox text) {
-    	if(selectedText != null)
-			selectedText.setSelected(false);
-		selectedText = text;
-		
-		if(text != null)
-			text.setSelected(true);
-    }
-    
-    private static DisplayMode getBestDisplayMode(GraphicsDevice device) {
-        for (int x = 0; x < BEST_DISPLAY_MODES.length; x++) {
-            DisplayMode[] modes = device.getDisplayModes();
-            for (int i = 0; i < modes.length; i++) {
-                if (modes[i].getWidth() == BEST_DISPLAY_MODES[x].getWidth()
-                   && modes[i].getHeight() == BEST_DISPLAY_MODES[x].getHeight()
-                   && modes[i].getBitDepth() == BEST_DISPLAY_MODES[x].getBitDepth()) 
-                {
-                    return BEST_DISPLAY_MODES[x];
-                }
-            }
-        }
-        return null;
-    }
-    
-    public static void chooseBestDisplayMode(GraphicsDevice device) {
-        DisplayMode best = getBestDisplayMode(device);
-        if (best != null) {
-            device.setDisplayMode(best);
-        }
-    }
-    
-    public void mousePressed(MouseEvent e) {
-    	switch(auxState) {
-		case None:
-			switch(gameState) {
-			case Main:				
-				if(wndMain.getMember("new game").isClicked(e.getX(),e.getY()))
-					gameState = GameState.CreateAccount;
-				else if(wndMain.getMember("load game").isClicked(e.getX(),e.getY()))
-					gameState = GameState.LoadGame;
-				else if(wndMain.getMember("game info").isClicked(e.getX(),e.getY()))
-					gameState = GameState.Info;
-				else if(wndMain.getMember("credits").isClicked(e.getX(),e.getY()))
-					gameState = GameState.Credits;
-				else if(wndMain.getMember("quit").isClicked(e.getX(),e.getY()))
-					done = true;
-				break;
-			case CreateAccount:
-				if(wndCreateAccount.getMember("user").isClicked(e.getX(),e.getY()))
-					selectText((Textbox)wndCreateAccount.getMember("user"));
-				else if(wndCreateAccount.getMember("choose class").isClicked(e.getX(),e.getY())) {
-					selectText(null);
-					gameState = GameState.CreateClass;
-				}else if(wndCreateAccount.getMember("create").isClicked(e.getX(),e.getY())) {
-					String user = ((Textbox)wndCreateAccount.getMember("user")).getText();
-					Gender gender = Gender.valueOf(rdgGenderSelection.getButton(rdgGenderSelection.getSelected()).getLabel());
-					
-					if(user.equals("")) {
-						showMessage("The username is empty");
-					}else if(gender == Gender.None) {
-						showMessage("No gender has been selected");
-					}else{
-						player = new Player(user, gender);
-						player.setSpeed(200);
-						player.setLoc(new Point(750, 860));
-						player.setTarget(player.getLoc());
-						gameState = GameState.Game;
-					}
-				}else if(wndCreateAccount.getMember("cancel").isClicked(e.getX(),e.getY())) {
-					selectText(null);
-					wndCreateAccount.clear();
-					wndChooseClass.clear();
-					gameState = GameState.Main;
-				}else if(wndCreateAccount.handleEvent(e)) {
-				}
-				break;
-			case CreateClass:
-				if(wndChooseClass.getMember("select").isClicked(e.getX(),e.getY())) {
-					gameState = GameState.CreateAccount;
-				}
-				else if(wndChooseClass.getMember("cancel").isClicked(e.getX(),e.getY())) {
-					gameState = GameState.CreateAccount;
-				}else if(wndChooseClass.handleEvent(e)) {
-				}
-				break;
-			case LoadGame:
-				gameState = GameState.Main;
-				break;
-			case Info:
-				gameState = GameState.Main;
-				break;
-			case Credits:
-				gameState = GameState.Main;
-				break;
-			case Game:
-				int newX = player.getLoc().getX()+e.getX()-400;
-				int newY = player.getLoc().getY()+e.getY()-300;
-				if(map.getLoc((int)(Math.floor(newX/100)), (int)(Math.floor(newY/100))).isPassable()) {
-					player.setTarget(new Point(newX, newY));
-					player.setLastMoved(System.currentTimeMillis());
-				}
-				break;
-			case GameMenu:
-				break;
-			case GameInventory:
-				break;
-			case GameStats:
-				break;
-			}
-			break;
-		case MsgBox:
-			if(wndMessage.getMember("button").isClicked(e.getX(), e.getY())) {
-				auxState = AuxState.None;
-			}
-			break;
-		}
-	}
-	
-	public void mouseReleased(MouseEvent e) {
-		
-	}
-	
-	public void mouseEntered(MouseEvent e) {
-
-	}
-	
-	public void mouseExited(MouseEvent e) {
-	    
-	}
-	
-	public void mouseClicked(MouseEvent e) {
-		
-	}
- 
-	public void keyTyped(KeyEvent e) {
-		
-	}
-	
-	public void keyPressed(KeyEvent e) {
-		if(selectedText != null)
-			selectedText.handleEvent(e);
-		
-		if(e.getKeyCode() == KeyEvent.VK_ESCAPE) 
-			if(gameState == GameState.Game)
-				gameState = GameState.Main;
-			else
-				done = true;
-	}
-	
-	public void keyReleased(KeyEvent e) {
-	
-	}
-    
-	public static void main(String[] args) {
-		try {
-			PrintStream st = new PrintStream(new FileOutputStream("err.txt", true));
-			System.setErr(st);
-			System.setOut(st);
-			System.out.println("-----[ Session started on " + dateString() + " ]-----");
-			
-			GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
-			GraphicsDevice device = env.getDefaultScreenDevice();
-			new LostHavenRPG(device);
-        }
-		catch (Exception e) {
-			e.printStackTrace();
-        }
-		System.exit(0);
-	}
+    System.exit(0);
+  }
 }
