diff --git a/json/character_transitions.json b/json/character_transitions.json new file mode 100644 index 00000000..23f3a3b2 --- /dev/null +++ b/json/character_transitions.json @@ -0,0 +1,23 @@ +{ + "Sewer Rat": { + "kill": { + "Brotherhood Member": { + "Sewer Rat": -1, + "Brotherhood Member": -1, + "Syndicate Member": 1 + }, + "Syndicate Member": { + "Sewer Rat": -1, + "Brotherhood Member": 1, + "Syndicate Member": -1 + }, + "Recruit": { + "Recruit": -1 + } + } + }, + "Recruit": { + "kill": { + } + } +} diff --git a/json/npcs.json b/json/npcs.json index 8458f569..583080cd 100644 --- a/json/npcs.json +++ b/json/npcs.json @@ -2,6 +2,17 @@ "npcs": { "guide": { "name": "Guide", + "health":100, + "healthMax": 100, + "damage": 1000, + "armour": 0, + "level": 1, + "xp": 0, + "strength": 0, + "intelligence": 0, + "dexterity": 0, + "stealth": 0, + "relationships": [ { "recruit": "ally" @@ -119,7 +130,34 @@ "rightHand": "hands" } ], - "intro": "Hello. Can I help you with something? A service perhaps? Anything and everything you need I have. For a price of course. . . ", + "conversations": [ + { + "condition":"none", + "player":"", + "text":"Hello. Can I help you with something? A service perhaps? Anything and everything you need I have. For a price of course. . . ", + "response":[1, 2], + "action": "no action" + }, + { + "condition": "none", + "player":"How about a potion?", + "text": "Of course, I have many at my disposal. Unfortunately, you'd need to be a syndicate member to be able to buy any.", + "response":[2, 3], + "action": "no action" + }, + { + "condition": "None", + "player": "Never mind then", + "text": "*bows*\n Until next time", + "action": "no action" + }, + { + "condition": "None", + "player": "How do I become a syndicate member?", + "text": "Very simple actually. Just kill one of the brotherhood members for me.", + "action": "no action" + } + ], "relationships": [ { "recruit": "enemy", @@ -181,7 +219,7 @@ { "condition": "ally", "player": "", - "text": "I have a task for you...", + "text": "Hey, I have a task for you...", "response": [2, 3], "action": "no action" }, @@ -194,16 +232,22 @@ { "condition": "none", "player": "What is it?", - "text": "insert quest here", - "response": [3], + "text": "There's a syndicate member hanging out up north near their headquarters. We've been needing some fresh blood around here. Kill him for me and there'll be some valuable perks in it for you", + "response": [3, 4], "action": "no action" }, { "condition": "none", "player": "I'm busy", - "text": "See you around", + "text": "Whatever, the offer always stands though", "action": "no action" - } + }, + { + "condition": "none", + "player": "Sure, why not?", + "text": "Thanks! Report back to me when you're one of us and I'll show you around", + "action": "no action" + } ] }, "recruit": { diff --git a/src/main/java/com/jadventure/game/CharacterChange.java b/src/main/java/com/jadventure/game/CharacterChange.java new file mode 100644 index 00000000..05a1c92f --- /dev/null +++ b/src/main/java/com/jadventure/game/CharacterChange.java @@ -0,0 +1,91 @@ +package com.jadventure.game; + +import com.jadventure.game.entities.Player; +import com.jadventure.game.QueueProvider; + +import com.google.gson.JsonObject; +import com.google.gson.Gson; +import com.google.gson.JsonParser; +import com.google.gson.JsonElement; + +import java.io.FileReader; +import java.io.Reader; +import java.io.FileNotFoundException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +public class CharacterChange { + public void trigger(Player player, String triggerType, String keyword) { + JsonParser parser = new JsonParser(); + String fileName = "json/character_transitions.json"; + try { + Reader reader = new FileReader(fileName); + JsonObject json = parser.parse(reader).getAsJsonObject(); + + String currentCharacter = player.getCurrentCharacterType(); + + JsonObject currentCharacterTransitions; + JsonObject events; + JsonObject characterEffects = new JsonObject(); + boolean goAhead = false; + if (json.has(currentCharacter)) { + currentCharacterTransitions = json.get(currentCharacter).getAsJsonObject(); + if (currentCharacterTransitions.has(triggerType)) { + events = currentCharacterTransitions.get(triggerType).getAsJsonObject(); + if (events.has(keyword)) { + characterEffects = events.get(keyword).getAsJsonObject(); + goAhead = true; + } else { + //QueueProvider.offer("Warning: The effects for the '" + triggerType + "' event and the '" + currentCharacter + "' character was not found"); + } + } else { + //QueueProvider.offer("Warning: The event '" + triggerType + "' for the '" + currentCharacter + "' character was not found"); + } + } else { + //QueueProvider.offer("Warning: The character '" + currentCharacter + "' was not found"); + } + + if (goAhead == true) { + for (Map.Entry entry : characterEffects.entrySet()) { + String characterName = entry.getKey(); + int characterLevelEffect = entry.getValue().getAsInt(); + int characterLevel = player.getCharacterLevel(characterName); + int newCharacterLevel = characterLevel + characterLevelEffect; + player.setCharacterLevel(characterName, newCharacterLevel); + checkForCharacterChange(player); + } + } + + } catch (FileNotFoundException ex) { + ex.printStackTrace(); + } + } + + public void checkForCharacterChange(Player player) { + HashMap characterLevels = player.getCharacterLevels(); + String currentCharacter = player.getCurrentCharacterType(); + int highestCharacterLevel = player.getCharacterLevel(currentCharacter); + String highestCharacter = currentCharacter; + Iterator it = characterLevels.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pairs = (Map.Entry)it.next(); + int value = (int)pairs.getValue(); + if (value > highestCharacterLevel) { + highestCharacterLevel = value; + highestCharacter = (String)pairs.getKey(); + } + } + if (!highestCharacter.equals(currentCharacter)) { + player.setCurrentCharacterType(highestCharacter); + QueueProvider.offer("You're character type is now changed! You are now a " + highestCharacter + "!"); + } + it = characterLevels.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pairs = (Map.Entry)it.next(); + player.setCharacterLevel((String)pairs.getKey(), (int)pairs.getValue()); + } + } + +} diff --git a/src/main/java/com/jadventure/game/entities/NPC.java b/src/main/java/com/jadventure/game/entities/NPC.java index b5086f6e..43d6d19a 100644 --- a/src/main/java/com/jadventure/game/entities/NPC.java +++ b/src/main/java/com/jadventure/game/entities/NPC.java @@ -17,6 +17,7 @@ * with variables not unique to the NPC, place it in the entity class. */ public class NPC extends Entity { + private int xpGain; String id; public NPC(String entityID) { @@ -34,11 +35,28 @@ public NPC(String entityID) { } } setName(json.get("name").getAsString()); + setHealth(json.get("health").getAsInt()); + setDamage(json.get("damage").getAsInt()); + setArmour(json.get("armour").getAsInt()); + setHealthMax(json.get("healthMax").getAsInt()); + setLevel(json.get("level").getAsInt()); + setStrength(json.get("strength").getAsInt()); + setIntelligence(json.get("intelligence").getAsInt()); + setDexterity(json.get("dexterity").getAsInt()); + setStealth(json.get("stealth").getAsInt()); } catch (FileNotFoundException ex) { QueueProvider.offer("Unable to open file '" + fileName + "'."); } } + public int getXPGain() { + return xpGain; + } + + public void setXPGain(int xpGain) { + this.xpGain = xpGain; + } + public String getId() { return id; } diff --git a/src/main/java/com/jadventure/game/entities/Player.java b/src/main/java/com/jadventure/game/entities/Player.java index 97890825..99203109 100644 --- a/src/main/java/com/jadventure/game/entities/Player.java +++ b/src/main/java/com/jadventure/game/entities/Player.java @@ -55,10 +55,39 @@ public class Player extends Entity { private int xp; /** Player type */ private String type; - + private static HashMapcharacterLevels = new HashMap(); + public Player() { } + protected static void setUpCharacterLevels() { + characterLevels.put("Sewer Rat", 5); + characterLevels.put("Recruit", 3); + characterLevels.put("Syndicate Member", 4); + characterLevels.put("Brotherhood Member", 4); + } + + public HashMap getCharacterLevels() { + return characterLevels; + } + + public String getCurrentCharacterType() { + return this.type; + } + + public void setCurrentCharacterType(String newCharacterType) { + this.type = newCharacterType; + } + + public void setCharacterLevel(String characterType, int level) { + this.characterLevels.put(characterType, level); + } + + public int getCharacterLevel(String characterType) { + int characterLevel = this.characterLevels.get(characterType); + return characterLevel; + } + protected static String getProfileFileName(String name) { return "json/profiles/" + name + "/" + name + "_profile.json"; } @@ -106,6 +135,7 @@ public static Player load(String name) { Coordinate coordinate = new Coordinate(json.get("location").getAsString()); player.setLocation(LocationManager.getLocation(coordinate)); reader.close(); + setUpCharacterLevels(); } catch (FileNotFoundException ex) { QueueProvider.offer( "Unable to open file '" + fileName + "'."); } catch (IOException ex) { @@ -155,6 +185,7 @@ public static Player getInstance(String playerClass){ QueueProvider.offer("Not a valid class"); } reader.close(); + setUpCharacterLevels(); } catch (FileNotFoundException ex) { QueueProvider.offer( "Unable to open file '" + fileName + "'."); } catch (IOException ex) { @@ -406,15 +437,25 @@ public LocationType getLocationType(){ } public void attack(String opponentName) throws DeathException { - Monster opponent = null; + Monster monsterOpponent = null; + NPC npcOpponent = null; List monsters = getLocation().getMonsters(); + List npcs = getLocation().getNPCs(); for (int i = 0; i < monsters.size(); i++) { - if (monsters.get(i).monsterType.equalsIgnoreCase(opponentName)) { - opponent = monsters.get(i); + if (monsters.get(i).monsterType.equalsIgnoreCase(opponentName)) { + monsterOpponent = monsters.get(i); } } - if (opponent != null) { - new BattleMenu(opponent, this); + for (int i=0; i < npcs.size(); i++) { + if (npcs.get(i).getName().equalsIgnoreCase(opponentName)) { + npcOpponent = npcs.get(i); + } + } + if (monsterOpponent != null) { + monsterOpponent.setName(monsterOpponent.monsterType); + new BattleMenu(monsterOpponent, this); + } else if (npcOpponent != null) { + new BattleMenu(npcOpponent, this); } else { QueueProvider.offer("Opponent not found"); } diff --git a/src/main/java/com/jadventure/game/menus/BattleMenu.java b/src/main/java/com/jadventure/game/menus/BattleMenu.java index 65c9eff5..84aedb36 100644 --- a/src/main/java/com/jadventure/game/menus/BattleMenu.java +++ b/src/main/java/com/jadventure/game/menus/BattleMenu.java @@ -3,31 +3,34 @@ import com.jadventure.game.DeathException; import com.jadventure.game.entities.Entity; import com.jadventure.game.entities.Player; +import com.jadventure.game.entities.NPC; import com.jadventure.game.monsters.Monster; import com.jadventure.game.QueueProvider; +import com.jadventure.game.CharacterChange; import java.util.Random; public class BattleMenu extends Menus { - private Monster opponent; + private Monster monsterOpponent; + private NPC npcOpponent; private Player player; private Random random; private int armour; private double damage; - public BattleMenu(Monster opponent, Player player) throws DeathException { + public BattleMenu(NPC npcOpponent, Player player) throws DeathException { this.random = new Random(); - this.opponent = opponent; + this.npcOpponent = npcOpponent; this.player = player; - this.menuItems.add(new MenuItem("Attack", "Attack " + opponent.monsterType + ".")); - this.menuItems.add(new MenuItem("Defend", "Defend against " + opponent.monsterType + "'s attack.")); + this.menuItems.add(new MenuItem("Attack", "Attack " + npcOpponent.getName() + ".")); + this.menuItems.add(new MenuItem("Defend", "Defend against " + npcOpponent.getName() + "'s attack.")); this.menuItems.add(new MenuItem("Equip", "Equip an item")); this.menuItems.add(new MenuItem("Unequip", "Unequip an item")); this.menuItems.add(new MenuItem("View", "View details about your character")); this.armour = player.getArmour(); this.damage = player.getDamage(); - while (opponent.getHealth() > 0 && player.getHealth() > 0) { + while (npcOpponent.getHealth() > 0 && player.getHealth() > 0) { QueueProvider.offer("\nWhat is your choice?"); MenuItem selectedItem = displayMenu(this.menuItems); testSelected(selectedItem); @@ -44,18 +47,65 @@ public BattleMenu(Monster opponent, Player player) throws DeathException { } else if (reply.startsWith("n")) { throw new DeathException("close"); } - } else if (opponent.getHealth() == 0) { - int xp = opponent.getXPGain(); + } else if (npcOpponent.getHealth() == 0) { + int xp = npcOpponent.getXPGain(); this.player.setXP(this.player.getXP() + xp); int oldLevel = this.player.getLevel(); int newLevel = (int) (0.075 * Math.sqrt(this.player.getXP()) + 1); this.player.setLevel(newLevel); - this.player.getLocation().removeMonster(opponent); - this.player.setGold(this.player.getGold() + opponent.getGold()); - QueueProvider.offer("You killed a " + opponent.monsterType + "\nYou have gained " + xp + " XP and " + opponent.getGold() + " gold"); + //this.player.getLocation().removeMonster(npcOpponent); + this.player.setGold(this.player.getGold() + npcOpponent.getGold()); + QueueProvider.offer("You killed a " + npcOpponent.getName() + "\nYou have gained " + xp + " XP and " + npcOpponent.getGold() + " gold"); if (oldLevel < newLevel) { QueueProvider.offer("You've are now level " + newLevel + "!"); } + CharacterChange cc = new CharacterChange(); + cc.trigger(this.player, "kill", npcOpponent.getName()); + } + } + + public BattleMenu(Monster monsterOpponent, Player player) throws DeathException { + this.random = new Random(); + this.monsterOpponent = monsterOpponent; + this.player = player; + this.menuItems.add(new MenuItem("Attack", "Attack " + monsterOpponent.getName() + ".")); + this.menuItems.add(new MenuItem("Defend", "Defend against " + monsterOpponent.getName() + "'s attack.")); + this.menuItems.add(new MenuItem("Equip", "Equip an item")); + this.menuItems.add(new MenuItem("Unequip", "Unequip an item")); + this.menuItems.add(new MenuItem("View", "View details about your character")); + this.armour = player.getArmour(); + this.damage = player.getDamage(); + while (monsterOpponent.getHealth() > 0 && player.getHealth() > 0) { + QueueProvider.offer("\nWhat is your choice?"); + MenuItem selectedItem = displayMenu(this.menuItems); + testSelected(selectedItem); + } + if (player.getHealth() == 0) { + QueueProvider.offer("You died... Start again? (y/n)"); + String reply = QueueProvider.take().toLowerCase(); + while (!reply.startsWith("y") && !reply.startsWith("n")) { + QueueProvider.offer("You died... Start again? (y/n)"); + reply = QueueProvider.take().toLowerCase(); + } + if (reply.startsWith("y")) { + throw new DeathException("restart"); + } else if (reply.startsWith("n")) { + throw new DeathException("close"); + } + } else if (monsterOpponent.getHealth() == 0) { + int xp = monsterOpponent.getXPGain(); + this.player.setXP(this.player.getXP() + xp); + int oldLevel = this.player.getLevel(); + int newLevel = (int) (0.075 * Math.sqrt(this.player.getXP()) + 1); + this.player.setLevel(newLevel); + this.player.getLocation().removeMonster(monsterOpponent); + this.player.setGold(this.player.getGold() + monsterOpponent.getGold()); + QueueProvider.offer("You killed a " + monsterOpponent.getName() + "\nYou have gained " + xp + " XP and " + monsterOpponent.getGold() + " gold"); + if (oldLevel < newLevel) { + QueueProvider.offer("You've are now level " + newLevel + "!"); + } + CharacterChange cc = new CharacterChange(); + cc.trigger(this.player, "kill", monsterOpponent.getName()); } } @@ -63,16 +113,27 @@ private void testSelected(MenuItem m) { switch (m.getKey()) { case "attack": { mutateStats(1, 0.5); - attack(player, opponent); - attack(opponent, player); + if (npcOpponent == null) { + attack(player, monsterOpponent); + attack(monsterOpponent, player); + } else { + attack(player, npcOpponent); + attack(npcOpponent, player); + } resetStats(); break; } case "defend": { - QueueProvider.offer("\nYou get ready to defend against the " + opponent.monsterType + "."); mutateStats(0.5, 1); - attack(opponent, player); - attack(player, opponent); + if (npcOpponent == null) { + QueueProvider.offer("\nYou get ready to defend against the " + monsterOpponent.getName() + "."); + attack(player, monsterOpponent); + attack(monsterOpponent, player); + } else { + QueueProvider.offer("\nYou get ready to defend against the " + npcOpponent.getName() + "."); + attack(player, npcOpponent); + attack(npcOpponent, player); + } resetStats(); break; } @@ -111,8 +172,7 @@ private void attack(Entity attacker, Entity defender) { } QueueProvider.offer(healthReduction + " damage dealt!"); if (attacker instanceof Player) { - Monster m = (Monster) defender; - QueueProvider.offer(m.monsterType + "' health is " + m.getHealth()); + QueueProvider.offer("The " + defender.getName() + "'s health is " + defender.getHealth()); } else { QueueProvider.offer("Your health is " + defender.getHealth()); }