package main; 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.io.*; 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.*; 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) }; public static Map map; public static HashMap landMap; public static HashMap structMap; public static HashMap creatureMap; public static HashMap items; public static LinkedList respawnPoints; public static LinkedList spawnPoints; 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 gems; LinkedList drops; LinkedList 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(); structMap = new HashMap(); respawnPoints = new LinkedList(); 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(); 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(); 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(); this.drops = new LinkedList(); this.projectiles = new LinkedList(); this.gems = new LinkedList(); 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 iter = spawnPoints.iterator(); while (iter.hasNext()) { SpawnPoint sp; if ((sp = iter.next()).idNum == idNum) return sp; } return null; } private void spawnCreatures() { Iterator 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 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 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 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 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 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 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 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 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 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 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 iter = spawnPoints.iterator(); while (iter.hasNext()) ((SpawnPoint)iter.next()).clear(); SpawnPoint.numSpawnPoints = 0; Iterator 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 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 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 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 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 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 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(); } System.exit(0); } }