diff --git a/.idea/misc.xml b/.idea/misc.xml
index be3fc8d..46d8359 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -8,7 +8,5 @@
-
-
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 00e0d01..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/GameState.java b/Java-Knight/src/main/java/org/project/GameState.java
new file mode 100644
index 0000000..9e016a2
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/GameState.java
@@ -0,0 +1,25 @@
+package org.project;
+
+import org.project.entity.players.Player;
+import org.project.location.Location;
+import java.io.Serializable;
+
+public class GameState implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private Player player;
+ private Location currentLocation;
+
+ public GameState(Player player, Location currentLocation) {
+ this.player = player;
+ this.currentLocation = currentLocation;
+ }
+
+ public Player getPlayer() {
+ return player;
+ }
+
+ public Location getCurrentLocation() {
+ return currentLocation;
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/Main.java b/Java-Knight/src/main/java/org/project/Main.java
index 6bde20e..e8e4180 100644
--- a/Java-Knight/src/main/java/org/project/Main.java
+++ b/Java-Knight/src/main/java/org/project/Main.java
@@ -1,15 +1,301 @@
package org.project;
+import org.project.combat.CombatSystem;
+import org.project.entity.Entity;
+import org.project.entity.enemies.Dragon;
+import org.project.entity.enemies.Goblin;
+import org.project.entity.enemies.Skeleton;
+import org.project.entity.enemies.Vampire;
+import org.project.entity.players.*;
import org.project.location.Location;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Random;
+import java.util.Scanner;
public class Main {
- public static void main(String[] args) {
- // TODO: ADD LOCATIONS TO YOUR GAME
- List locations = new ArrayList<>();
- // TODO: IMPLEMENT GAMEPLAY
+ private static final Scanner scanner = new Scanner(System.in);
+ private static Location currentLocation;
+
+ public static final String RESET = "\u001B[0m";
+ public static final String RED = "\u001B[31m";
+ public static final String GREEN = "\u001B[32m";
+ public static final String YELLOW = "\u001B[33m";
+ public static final String BLUE = "\u001B[34m";
+ public static final String PURPLE = "\u001B[35m";
+ public static final String CYAN = "\u001B[36m";
+
+ public static void main(String[] args) {
+
+ initializeMap();
+
+ while (true) {
+
+ System.out.println(CYAN + "\n===============================" + RESET);
+ System.out.println(YELLOW + " โ JAVA KNIGHT โ" + RESET);
+ System.out.println(CYAN + "===============================" + RESET);
+
+ System.out.println("1. Start Game");
+ System.out.println("2. How To Play");
+ System.out.println("3. Exit");
+
+ System.out.print("> ");
+ int option = scanner.nextInt();
+
+ switch (option) {
+ case 1 -> startGame();
+ case 2 -> showHelpMenu();
+ case 3 -> {
+ System.out.println(GREEN + "Farewell hero!" + RESET);
+ System.exit(0);
+ }
+ default -> System.out.println(RED + "Invalid option!" + RESET);
+ }
+ }
+ }
+
+
+ private static void startGame()
+ {
+
+ showIntro();
+
+ System.out.print("Enter your name: ");
+ String name = scanner.next();
+
+ System.out.println("\nChoose your class:");
+ System.out.println(BLUE + "1. Knight ๐ก" + RESET);
+ System.out.println(PURPLE + "2. Wizard ๐ฎ" + RESET);
+ System.out.println(YELLOW + "3. Assassin ๐ก" + RESET);
+
+ int choice = scanner.nextInt();
+ Player player;
+
+ switch (choice) {
+ case 1 -> player = new Knight(name);
+ case 2 -> player = new Wizard(name);
+ case 3 -> player = new Assassin(name);
+ default -> player = new Knight(name);
+ }
+
+ player.resetKeys();
+ System.out.println(GREEN + "\nWelcome " + name + " to Javanest!" + RESET);
+
+ currentLocation.enter();
+ gameLoop(player);
+ }
+
+ private static void gameLoop(Player player)
+ {
+
+ Random random = new Random();
+
+
+ while (player.isAlive())
+ {
+
+ showPlayerStatus(player);
+
+ System.out.println(CYAN + "\n===== LOCATION: " + currentLocation.getName() + " =====" + RESET);
+ System.out.println("1. Fight Enemy");
+ System.out.println("2. Move Location");
+
+ if (player.hasAllKeys() && currentLocation.getName().equals("Vampire Crypt"))
+ {
+ System.out.println(RED + "3. Enter Dragon Castle ๐" + RESET);
+ }
+
+ System.out.print("> ");
+ int option = scanner.nextInt();
+
+ if (option == 1) {
+ Entity enemy = currentLocation.spawnEnemy();
+
+ System.out.println(RED + "\nA wild " + enemy.getName() + " appears!" + RESET);
+
+ CombatSystem combat = new CombatSystem();
+ combat.startBattle(player, enemy);
+
+ if (!player.isAlive()) {
+ System.out.println(RED + "\nYou have fallen..." + RESET);
+ break;
+ }
+
+ tryToDropKey(player, enemy, random);
+ recoverPlayer(player);
+
+ } else if (option == 2) {
+
+ moveLocation();
+
+ } else if (option == 3 &&
+ player.hasAllKeys() &&
+ currentLocation.getName().equals("Vampire Crypt")) {
+
+ System.out.println(RED + "\nYou enter the Dragon Castle..." + RESET);
+
+ CombatSystem combat = new CombatSystem();
+ combat.startBattle(player, new Dragon());
+
+ if (player.isAlive()) {
+ System.out.println(GREEN + "\n๐ YOU SAVED JAVANEST!" + RESET);
+ } else {
+ System.out.println(RED + "\nThe Dragon has defeated you..." + RESET);
+ }
+
+ showProjectFeatures();
+ break;
+
+ } else {
+ System.out.println(RED + "Invalid option!" + RESET);
+ }
+ }
+ }
+
+ private static void showPlayerStatus(Player player) {
+
+ System.out.println(YELLOW + "\n===== PLAYER STATUS =====" + RESET);
+
+ printBar("HP ", player.getHP(), player.getMaxHP(), RED);
+ printBar("MP ", player.getMP(), player.getMaxMP(), BLUE);
+ System.out.println("XP: " + player.getXP());
+ }
+
+ private static void printBar(String label, int value, int max, String color)
+ {
+
+ int totalBars = 20;
+ int filled = (int)((double)value / max * totalBars);
+
+ StringBuilder bar = new StringBuilder();
+
+ for (int i = 0; i < filled; i++) bar.append("โ");
+ for (int i = filled; i < totalBars; i++) bar.append("โ");
+
+ System.out.println(label + " " + color + bar + RESET + " " + value + "/" + max);
+ }
+
+ private static void moveLocation()
+ {
+
+ System.out.println(YELLOW + "\nWhere do you want to go?" + RESET);
+
+ int index = 1;
+ for (Location loc : currentLocation.getConnectedLocations())
+ {
+ System.out.println(index + ". " + loc.getName());
+ index++;
+ }
+
+ System.out.print("> ");
+ int choice = scanner.nextInt();
+
+ if (choice < 1 || choice > currentLocation.getConnectedLocations().size())
+ {
+ System.out.println(RED + "Invalid location!" + RESET);
+ return;
+ }
+
+ currentLocation = currentLocation.getConnectedLocations().get(choice - 1);
+ currentLocation.enter();
+ }
+
+ private static void tryToDropKey(Player player, Entity enemy, Random random)
+ {
+
+ int chance = random.nextInt(100) + 1;
+
+ if (chance <= 20)
+ {
+
+ if (enemy instanceof Goblin && !player.hasGoblinKey())
+ {
+ player.obtainGoblinKey();
+ System.out.println(YELLOW + "You obtained the Goblin Key!" + RESET);
+ } else if (enemy instanceof Skeleton && !player.hasSkeletonKey()) {
+ player.obtainSkeletonKey();
+ System.out.println(YELLOW + "You obtained the Skeleton Key!" + RESET);
+ } else if (enemy instanceof Vampire && !player.hasVampireKey()) {
+ player.obtainVampireKey();
+ System.out.println(YELLOW + "You obtained the Vampire Key!" + RESET);
+ }
+ }
+ }
+
+ private static void recoverPlayer(Player player)
+ {
+ player.setHealth(player.getMaxHP());
+ player.setMana(player.getMaxMP());
+ System.out.println(GREEN + "You recovered your HP and Mana." + RESET);
+ }
+
+ private static void showIntro()
+ {
+ System.out.println(PURPLE + "\n====================================" + RESET);
+ System.out.println(YELLOW + " LEGEND OF JAVANEST" + RESET);
+ System.out.println(PURPLE + "====================================" + RESET);
+ System.out.println("Defeat enemies, collect keys,");
+ System.out.println("and face the mighty Dragon!");
+ }
+
+ private static void showHelpMenu()
+ {
+ System.out.println(YELLOW + "\nHOW TO PLAY:" + RESET);
+ System.out.println("- Fight enemies to gain XP.");
+ System.out.println("- Collect 3 keys.");
+ System.out.println("- Unlock Dragon Castle.");
+ System.out.println("- Defeat the Dragon to win.");
+ }
+
+ private static void showProjectFeatures()
+ {
+
+ System.out.println(CYAN + "\n====================================" + RESET);
+ System.out.println(YELLOW + " PROJECT FEATURES" + RESET);
+ System.out.println(CYAN + "====================================" + RESET);
+
+ System.out.println(GREEN + "โ Multiple Player Classes" + RESET);
+ System.out.println(GREEN + "โ Location System" + RESET);
+ System.out.println(GREEN + "โ Key Collection System" + RESET);
+ System.out.println(GREEN + "โ Combat System" + RESET);
+ System.out.println(GREEN + "โ Final Boss Battle" + RESET);
+ }
+
+ private static void initializeMap()
+ {
+
+ Location forest = new Location(
+ "Forest",
+ "A dark forest full of goblins.",
+ 1
+ );
+
+ Location graveyard = new Location(
+ "Graveyard",
+ "An abandoned graveyard with skeletons.",
+ 2
+ );
+
+ Location vampireCrypt = new Location(
+ "Vampire Crypt",
+ "A cursed crypt where vampires sleep.",
+ 3
+ );
+
+ Location dragonCastle = new Location(
+ "Dragon Castle",
+ "The castle of the ancient dragon.",
+ 4
+ );
+
+ forest.connectLocation(graveyard);
+ graveyard.connectLocation(forest);
+
+ graveyard.connectLocation(vampireCrypt);
+ vampireCrypt.connectLocation(graveyard);
+
+ vampireCrypt.connectLocation(dragonCastle);
+
+ currentLocation = forest;
}
}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/combat/CombatSystem.java b/Java-Knight/src/main/java/org/project/combat/CombatSystem.java
new file mode 100644
index 0000000..705ddc1
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/combat/CombatSystem.java
@@ -0,0 +1,166 @@
+package org.project.combat;
+
+import org.project.entity.players.Player;
+import org.project.entity.Entity;
+import org.project.entity.enemies.Goblin;
+import org.project.entity.enemies.Skeleton;
+import org.project.entity.enemies.Vampire;
+
+import java.util.Scanner;
+
+public class CombatSystem
+{
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String YELLOW = "\u001B[33m";
+ private static final String BLUE = "\u001B[34m";
+
+ private Scanner scanner = new Scanner(System.in);
+
+ public void startBattle(Player player, Entity enemy)
+ {
+
+ System.out.println(RED + "\nโ๏ธ A battle has started!" + RESET);
+ System.out.println(YELLOW + "Enemy: " + enemy.getName() + RESET);
+
+ while (player.isAlive() && enemy.isAlive())
+ {
+
+ System.out.println("\n" + BLUE + "----- YOUR TURN -----" + RESET);
+ System.out.println("1. Light Attack");
+ System.out.println("2. Heavy Attack");
+ System.out.println("3. Defend");
+ System.out.println("4. Heal");
+ System.out.println("5. Special Ability");
+ System.out.println("6. Exit Game");
+
+ while (!scanner.hasNextInt())
+ {
+ scanner.next();
+ System.out.println("โ Please enter a number between 1-6");
+ }
+
+ int choice = scanner.nextInt();
+
+ switch (choice)
+ {
+
+ case 1:
+ player.lightAttack(enemy);
+ break;
+
+ case 2:
+ player.heavyAttack(enemy);
+ break;
+
+ case 3:
+ player.defend();
+ break;
+
+ case 4:
+ player.specialAbility(enemy);
+ break;
+
+ case 5:
+ if (player.getMP() >= 6)
+ {
+ player.heal(10);
+ player.fillMana(-6);
+ System.out.println("๐ You restored 10 HP at the cost of 6 MP!");
+ } else {
+ System.out.println("โ Not enough MP to heal!");
+ }
+ break;
+
+ case 6:
+ if (player.getXP() >= 10)
+ {
+ player.gainXP(-10);
+ player.fillMana(20);
+ System.out.println("๐ฎ +20 MP restored (Cost: 10 XP)");
+ } else {
+ System.out.println("โ Not enough XP to restore mana!");
+ }
+ break;
+
+ case 7:
+ if (player.getXP() >= 50)
+ {
+ player.gainXP(-50);
+ player.heal(30);
+ System.out.println("โค๏ธ +30 HP restored (Cost: 50 XP)");
+ } else {
+ System.out.println("โ Not enough XP to restore HP!");
+ }
+ break;
+
+ case 8:
+ System.out.println("๐ Exiting game...");
+ System.exit(0);
+
+ default:
+ System.out.println("โ Invalid choice!");
+ }
+
+ if (!enemy.isAlive())
+ {
+
+ System.out.println(GREEN + "\nโ
Enemy defeated!" + RESET);
+
+ player.gainXP(50);
+
+ dropKey(player, enemy);
+
+ recoverPlayer(player);
+
+ break;
+ }
+
+ System.out.println(RED + "\n๐น ENEMY TURN!" + RESET);
+
+ enemy.attack(player);
+
+ if (!player.isAlive())
+ {
+ System.out.println(RED + "\n๐ You were defeated..." + RESET);
+ }
+ }
+ }
+
+ private void dropKey(Player player, Entity enemy)
+ {
+
+ double chance = Math.random();
+
+ if (chance > 0.20) return;
+
+ if (enemy instanceof Goblin && !player.hasGoblinKey())
+ {
+ System.out.println(YELLOW + "๐๏ธ Goblin Key obtained!" + RESET);
+ player.obtainGoblinKey();
+ }
+
+ else if (enemy instanceof Skeleton && !player.hasSkeletonKey())
+ {
+ System.out.println(YELLOW + "๐๏ธ Skeleton Key obtained!" + RESET);
+ player.obtainSkeletonKey();
+ }
+
+ else if (enemy instanceof Vampire && !player.hasVampireKey())
+ {
+ System.out.println(YELLOW + "๐๏ธ Vampire Key obtained!" + RESET);
+ player.obtainVampireKey();
+ }
+ }
+
+ private void recoverPlayer(Player player)
+ {
+
+ player.setHealth(player.getMaxHP());
+ player.setMana(player.getMaxMP());
+
+ System.out.println("\u001B[32mโจ Your HP and Mana have been fully restored!\u001B[0m");
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/Entity.java b/Java-Knight/src/main/java/org/project/entity/Entity.java
index 2a060f9..4146ce7 100644
--- a/Java-Knight/src/main/java/org/project/entity/Entity.java
+++ b/Java-Knight/src/main/java/org/project/entity/Entity.java
@@ -1,6 +1,7 @@
package org.project.entity;
-public interface Entity {
+public interface Entity
+{
void attack(Entity target);
void defend();
@@ -11,9 +12,22 @@ public interface Entity {
void takeDamage(int damage);
+ int getHP();
+ int getMP();
int getMaxHP();
-
int getMaxMP();
+ int getLevel();
+ String getName();
+
+ void setStunned(boolean value);
+ boolean isStunned();
+
+ void setInvisible(boolean value);
+ boolean isInvisible();
+
+ boolean isAlive();
+
+ void gainXP(int xp);
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
diff --git a/Java-Knight/src/main/java/org/project/entity/enemies/Dragon.java b/Java-Knight/src/main/java/org/project/entity/enemies/Dragon.java
new file mode 100644
index 0000000..dbc1e57
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/enemies/Dragon.java
@@ -0,0 +1,38 @@
+package org.project.entity.enemies;
+
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+import java.util.Random;
+
+public class Dragon extends Enemy
+{
+
+ private Random random = new Random();
+
+ public Dragon()
+ {
+ super("Dragon", 200, 50, new BasicWeapon("Flame Breath", 25));
+ }
+
+ @Override
+ public void attack(Entity target)
+ {
+
+ int damage;
+
+ if (random.nextBoolean())
+ {
+ damage = weapon.getDamage() + 20;
+ System.out.println(RED + "๐ฅ Dragon uses FIRE BREATH!" + RESET);
+ } else {
+ damage = weapon.getDamage();
+ System.out.println(YELLOW + "๐ Dragon claws viciously!" + RESET);
+ }
+
+ target.takeDamage(damage);
+
+ System.out.println(RED + "๐ฅ Dragon deals "
+ + damage + " damage!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/enemies/Enemy.java b/Java-Knight/src/main/java/org/project/entity/enemies/Enemy.java
index e019acb..a10e2fe 100644
--- a/Java-Knight/src/main/java/org/project/entity/enemies/Enemy.java
+++ b/Java-Knight/src/main/java/org/project/entity/enemies/Enemy.java
@@ -1,34 +1,140 @@
package org.project.entity.enemies;
+import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
-// TODO: UPDATE IMPLEMENTATION
-public abstract class Enemy {
- Weapon weapon;
- private int hp;
- private int mp;
+public abstract class Enemy implements Entity
+{
- public Enemy(int hp, int mp, Weapon weapon) {
+ protected String name;
+ protected int hp;
+ protected int mp;
+ protected int maxHp;
+ protected int maxMp;
+ protected int level;
+ protected boolean stunned;
+ protected boolean invisible;
+ protected Weapon weapon;
+
+ protected static final String RESET = "\u001B[0m";
+ protected static final String RED = "\u001B[31m";
+ protected static final String YELLOW = "\u001B[33m";
+ protected static final String PURPLE = "\u001B[35m";
+
+ public Enemy(String name, int hp, int mp, Weapon weapon)
+ {
+ this.name = name;
this.hp = hp;
this.mp = mp;
-
+ this.maxHp = hp;
+ this.maxMp = mp;
+ this.level = 1;
+ this.stunned = false;
+ this.invisible = false;
this.weapon = weapon;
}
@Override
- public void takeDamage(int damage) {
- hp -= damage;
+ public void defend()
+ {
+ System.out.println(name + " defends.");
}
- public int getHp() {
+ @Override
+ public void heal(int health)
+ {
+ if (health <= 0) return;
+ hp += health;
+ if (hp > maxHp) hp = maxHp;
+ }
+
+ @Override
+ public void fillMana(int mana)
+ {
+ if (mana <= 0) return;
+ mp += mana;
+ if (mp > maxMp) mp = maxMp;
+ }
+
+ @Override
+ public void takeDamage(int damage)
+ {
+ if (damage <= 0) return;
+ hp -= damage;
+ if (hp < 0) hp = 0;
+ }
+
+ @Override
+ public int getHP()
+ {
return hp;
}
- public int getMp() {
+ @Override
+ public int getMP()
+ {
return mp;
}
- public Weapon getWeapon() {
- return weapon;
+ @Override
+ public int getMaxHP()
+ {
+ return maxHp;
}
+
+ @Override
+ public int getMaxMP()
+ {
+ return maxMp;
+ }
+
+ @Override
+ public int getLevel()
+ {
+ return level;
+ }
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public void setStunned(boolean value)
+ {
+ this.stunned = value;
+ }
+
+ @Override
+ public boolean isStunned()
+ {
+ return stunned;
+ }
+
+ @Override
+ public void setInvisible(boolean value)
+ {
+ this.invisible = value;
+ }
+
+ @Override
+ public boolean isInvisible()
+ {
+ return invisible;
+ }
+
+ @Override
+ public boolean isAlive()
+ {
+ return hp > 0;
+ }
+
+ @Override
+ public void gainXP(int xp)
+ {
+ }
+
+ @Override
+ public abstract void attack(Entity target);
}
diff --git a/Java-Knight/src/main/java/org/project/entity/enemies/Goblin.java b/Java-Knight/src/main/java/org/project/entity/enemies/Goblin.java
new file mode 100644
index 0000000..af0fc86
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/enemies/Goblin.java
@@ -0,0 +1,37 @@
+package org.project.entity.enemies;
+
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+import java.util.Random;
+
+public class Goblin extends Enemy
+{
+
+ private Random random = new Random();
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String PURPLE = "\u001B[35m";
+
+ public Goblin() {
+ super("Goblin", 60, 20, new BasicWeapon("Rusty Dagger", 12));
+ }
+
+ @Override
+ public void attack(Entity target)
+ {
+
+ int damage = weapon.getDamage();
+
+ if (random.nextInt(100) < 25)
+ {
+ damage *= 2;
+ System.out.println(PURPLE + "๐ Goblin CRITICAL strike!" + RESET);
+ }
+
+ target.takeDamage(damage);
+
+ System.out.println(RED + "๐น Goblin attacks for " + damage + " damage!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/enemies/Skeleton.java b/Java-Knight/src/main/java/org/project/entity/enemies/Skeleton.java
index 8a6a555..600faa5 100644
--- a/Java-Knight/src/main/java/org/project/entity/enemies/Skeleton.java
+++ b/Java-Knight/src/main/java/org/project/entity/enemies/Skeleton.java
@@ -1,6 +1,46 @@
package org.project.entity.enemies;
-// TODO: UPDATE IMPLEMENTATION
-public class Skeleton {
- // TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
-}
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+public class Skeleton extends Enemy
+{
+
+ private boolean revived = false;
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String YELLOW = "\u001B[33m";
+
+ public Skeleton()
+ {
+ super("Skeleton", 70, 10, new BasicWeapon("Bone Sword", 15));
+ }
+
+ @Override
+ public void attack(Entity target)
+ {
+
+ int damage = weapon.getDamage();
+
+ target.takeDamage(damage);
+
+ System.out.println(RED + "โ Skeleton slashes for " + damage + " damage!" + RESET);
+ }
+
+ @Override
+ public void takeDamage(int damage)
+ {
+
+ super.takeDamage(damage);
+
+ if (!isAlive() && !revived)
+ {
+
+ revived = true;
+ this.hp = 40;
+
+ System.out.println(YELLOW + "โ Skeleton reassembles itself!" + RESET);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/enemies/Vampire.java b/Java-Knight/src/main/java/org/project/entity/enemies/Vampire.java
new file mode 100644
index 0000000..b9c01e0
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/enemies/Vampire.java
@@ -0,0 +1,30 @@
+package org.project.entity.enemies;
+
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+public class Vampire extends Enemy
+{
+
+ public Vampire()
+ {
+ super("Vampire", 90, 30, new BasicWeapon("Dark Claws", 18));
+ }
+
+ @Override
+ public void attack(Entity target)
+ {
+
+ int damage = weapon.getDamage();
+ target.takeDamage(damage);
+
+ int healAmount = damage / 2;
+ this.hp += healAmount;
+
+ System.out.println(RED + "๐ง Vampire drains "
+ + damage + " HP!" + RESET);
+
+ System.out.println(YELLOW + "๐ฉธ Vampire heals "
+ + healAmount + " HP!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/players/Assassin.java b/Java-Knight/src/main/java/org/project/entity/players/Assassin.java
new file mode 100644
index 0000000..9fef985
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/players/Assassin.java
@@ -0,0 +1,99 @@
+package org.project.entity.players;
+
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+import java.util.Random;
+
+public class Assassin extends Player
+{
+
+ private static final int HEAVY_COST = 15;
+ private static final int SPECIAL_COST = 25;
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String YELLOW = "\u001B[33m";
+ private static final String BLUE = "\u001B[34m";
+ private static final String PURPLE = "\u001B[35m";
+
+ private Random random = new Random();
+
+ public Assassin(String name) {
+ super(name, 90, 80, new BasicWeapon("Dagger", 18));
+ }
+
+ @Override
+ public void lightAttack(Entity target)
+ {
+
+ int dmg = weapon.getDamage() + 12;
+
+ // 25% critical chance
+ if (random.nextInt(100) < 25)
+ {
+ dmg *= 2;
+ System.out.println(PURPLE + "๐ CRITICAL HIT!" + RESET);
+ }
+
+ target.takeDamage(dmg);
+
+ System.out.println(YELLOW + "๐ก๏ธ " + name +
+ " strikes for " + dmg + " damage!" + RESET);
+ }
+
+ @Override
+ public void heavyAttack(Entity target)
+ {
+ if (mp < HEAVY_COST) {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= HEAVY_COST;
+ int dmg = weapon.getDamage() + 30;
+ target.takeDamage(dmg);
+
+ System.out.println(PURPLE + "โก Shadow Slash deals " +
+ dmg + " damage!" + RESET);
+ }
+
+ @Override
+ public void defendAction()
+ {
+ defend();
+ System.out.println(BLUE + "๐ก๏ธ Quick dodge stance!" + RESET);
+ }
+
+ @Override
+ public void healAction()
+ {
+ heal(20);
+ System.out.println(GREEN + "๐ " + name +
+ " uses bandage restoring 20 HP!" + RESET);
+ }
+
+ @Override
+ public void specialAbility(Entity target)
+ {
+ if (mp < SPECIAL_COST)
+ {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= SPECIAL_COST;
+
+ setInvisible(true);
+
+ int dmg = weapon.getDamage() + 50;
+ target.takeDamage(dmg);
+
+ System.out.println(BLUE + "๐ SHADOW STRIKE deals " +
+ dmg + " damage!" + RESET);
+
+ System.out.println(YELLOW + "๐ค " + name +
+ " becomes INVISIBLE!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/players/ICombatActions.java b/Java-Knight/src/main/java/org/project/entity/players/ICombatActions.java
new file mode 100644
index 0000000..d06a014
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/players/ICombatActions.java
@@ -0,0 +1,22 @@
+package org.project.entity.players;
+
+import org.project.entity.Entity;
+
+public interface ICombatActions
+{
+
+ // 1. Light Attack
+ void lightAttack(Entity target);
+
+ // 2. Heavy Attack
+ void heavyAttack(Entity target);
+
+ // 3. Defend
+ void defendAction();
+
+ // 4. Heal
+ void healAction();
+
+ // 5. Special Ability
+ void specialAbility(Entity target);
+}
diff --git a/Java-Knight/src/main/java/org/project/entity/players/Knight.java b/Java-Knight/src/main/java/org/project/entity/players/Knight.java
index 14d8fa2..fe46714 100644
--- a/Java-Knight/src/main/java/org/project/entity/players/Knight.java
+++ b/Java-Knight/src/main/java/org/project/entity/players/Knight.java
@@ -1,6 +1,101 @@
package org.project.entity.players;
-// TODO: UPDATE IMPLEMENTATION
-public class Knight {
- // TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR
-}
+import org.project.entity.Entity;
+import org.project.item.armors.KnightArmor;
+import org.project.item.weapons.Sword;
+
+public class Knight extends Player {
+
+ private static final int LIGHT_BONUS = 15;
+ private static final int HEAVY_COST = 10;
+ private static final int SPECIAL_COST = 25;
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String YELLOW = "\u001B[33m";
+ private static final String BLUE = "\u001B[34m";
+ private static final String PURPLE = "\u001B[35m";
+
+ public Knight(String name)
+ {
+ super(name, 150, 40, new Sword());
+ new KnightArmor();
+ }
+
+ @Override
+ public void lightAttack(Entity target)
+ {
+ int dmg = weapon.getDamage() + LIGHT_BONUS;
+ target.takeDamage(dmg);
+
+ ((Sword) weapon).addCharge(1);
+
+ System.out.println(
+ YELLOW + "โ๏ธ " + name +
+ " slashes the enemy for " + dmg + " damage!" +
+ RESET
+ );
+ }
+
+ @Override
+ public void heavyAttack(Entity target)
+ {
+ if (mp < HEAVY_COST)
+ {
+ System.out.println(RED + "โ Not enough MP for heavy attack!" + RESET);
+ return;
+ }
+
+ mp -= HEAVY_COST;
+ int dmg = weapon.getDamage() + 30;
+ target.takeDamage(dmg);
+
+ ((Sword) weapon).addCharge(2);
+
+ System.out.println(PURPLE + "๐ฅ " + name +
+ " performs a HEAVY STRIKE for " + dmg + " damage!" + RESET);
+ }
+
+ @Override
+ public void defendAction()
+ {
+ defend();
+ System.out.println(BLUE + "๐ก๏ธ " + name +
+ " raises his shield!" + RESET);
+ }
+
+ @Override
+ public void healAction()
+ {
+ heal(30);
+ System.out.println(GREEN + "๐ " + name +
+ " heals for 30 HP!" + RESET);
+ }
+
+ @Override
+ public void specialAbility(Entity target)
+ {
+ if (mp < SPECIAL_COST)
+ {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= SPECIAL_COST;
+
+ int dmg = weapon.getDamage() + 45;
+ target.takeDamage(dmg);
+ target.setStunned(true);
+
+ ((Sword) weapon).addCharge(3);
+
+ System.out.println(
+ BLUE + "๐ " + name +
+ " uses EARTH SHATTERING STRIKE dealing " + dmg + " damage!" +
+ RESET
+ );
+
+ System.out.println(YELLOW + "โ ๏ธ The enemy is STUNNED!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/players/Player.java b/Java-Knight/src/main/java/org/project/entity/players/Player.java
index ff5385c..f5ec8e0 100644
--- a/Java-Knight/src/main/java/org/project/entity/players/Player.java
+++ b/Java-Knight/src/main/java/org/project/entity/players/Player.java
@@ -1,89 +1,159 @@
package org.project.entity.players;
import org.project.entity.Entity;
-import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
-// TODO: UPDATE IMPLEMENTATION
-public abstract class Player {
+import java.io.Serializable;
+
+public abstract class Player implements Entity, ICombatActions, Serializable
+{
+ private static final long serialVersionUID = 1L;
+
protected String name;
- Weapon weapon;
- Armor armor;
- private int hp;
- private int maxHP;
- private int mp;
- private int maxMP;
+ protected int hp, maxHP;
+ protected int mp, maxMP;
+ protected int level = 1;
+ protected int xp = 0;
- public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
+ protected boolean stunned = false;
+ protected boolean invisible = false;
+ protected boolean defending = false;
+
+ private boolean goblinKey = false;
+ private boolean skeletonKey = false;
+ private boolean vampireKey = false;
+
+ protected Weapon weapon;
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String YELLOW = "\u001B[33m";
+ private static final String BLUE = "\u001B[34m";
+ private static final String PURPLE = "\u001B[35m";
+
+ public Player(String name, int maxHP, int maxMP, Weapon weapon)
+ {
this.name = name;
- this.hp = hp;
- this.mp = mp;
-
+ this.maxHP = maxHP;
+ this.hp = maxHP;
+ this.maxMP = maxMP;
+ this.mp = maxMP;
this.weapon = weapon;
- this.armor = armor;
}
@Override
- public void attack(Entity target) {
- target.takeDamage(weapon.getDamage());
+ public void attack(Entity target)
+ {
+ lightAttack(target);
}
@Override
- public void defend() {
- // TODO
- }
-
-
- @Override
- public void takeDamage(int damage) {
- hp -= damage - armor.getDefense();
+ public void defend()
+ {
+ defending = true;
+ System.out.println(BLUE + "๐ก๏ธ " + name + " is defending!" + RESET);
}
@Override
- public void heal(int health) {
- hp += health;
- if (hp > maxHP) {
+ public void heal(int amount)
+ {
+ hp = Math.min(maxHP, hp + amount);
+ }
+
+ @Override
+ public void fillMana(int amount)
+ {
+ mp = Math.min(maxMP, mp + amount);
+ }
+
+ @Override
+ public void takeDamage(int damage)
+ {
+ if (defending)
+ {
+ damage /= 2;
+ defending = false;
+ }
+ hp = Math.max(0, hp - damage);
+ System.out.println(RED + "๐ฅ " + name + " took " + damage + " damage!" + RESET);
+ }
+
+ @Override
+ public int getHP() { return hp; }
+ @Override
+ public int getMP() { return mp; }
+ @Override
+ public int getMaxHP() { return maxHP; }
+ @Override
+ public int getMaxMP() { return maxMP; }
+ @Override
+ public int getLevel() { return level; }
+ @Override
+ public String getName() { return name; }
+
+ @Override
+ public void setStunned(boolean v) { stunned = v; }
+ @Override
+ public boolean isStunned() { return stunned; }
+
+ @Override
+ public void setInvisible(boolean v) { invisible = v; }
+ @Override
+ public boolean isInvisible() { return invisible; }
+
+ @Override
+ public boolean isAlive() { return hp > 0; }
+
+ @Override
+ public void gainXP(int xp)
+ {
+ this.xp += xp;
+ if (this.xp >= level * 100)
+ {
+ level++;
+ this.xp = 0;
+ maxHP += 10;
+ maxMP += 5;
hp = maxHP;
- }
- }
-
- @Override
- public void fillMana(int mana) {
- mp += mana;
- if (mp > maxMP) {
mp = maxMP;
+
+ System.out.println(GREEN + "โญ " + name + " leveled up to level " + level + "!" + RESET);
}
}
+ public boolean hasGoblinKey() { return goblinKey; }
+ public boolean hasSkeletonKey() { return skeletonKey; }
+ public boolean hasVampireKey() { return vampireKey; }
- public String getName() {
- return name;
+ public void obtainGoblinKey() { goblinKey = true; }
+ public void obtainSkeletonKey() { skeletonKey = true; }
+ public void obtainVampireKey() { vampireKey = true; }
+
+ public boolean hasAllKeys()
+ {
+ return goblinKey && skeletonKey && vampireKey;
}
- public int getHp() {
- return hp;
+ public void resetKeys()
+ {
+ goblinKey = false;
+ skeletonKey = false;
+ vampireKey = false;
}
- @Override
- public int getMaxHP() {
- return maxHP;
+ public void setHealth(int hp)
+ {
+ this.hp = Math.min(hp, maxHP);
}
- public int getMp() {
- return mp;
+ public void setMana(int mp)
+ {
+ this.mp = Math.min(mp, maxMP);
}
- @Override
- public int getMaxMP() {
- return maxMP;
+ public int getXP()
+ {
+ return xp;
}
-
- public Weapon getWeapon() {
- return weapon;
- }
-
- public Armor getArmor() {
- return armor;
- }
-
-}
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/entity/players/Wizard.java b/Java-Knight/src/main/java/org/project/entity/players/Wizard.java
new file mode 100644
index 0000000..d3decf5
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/entity/players/Wizard.java
@@ -0,0 +1,96 @@
+package org.project.entity.players;
+
+import org.project.entity.Entity;
+import org.project.item.weapons.BasicWeapon;
+
+public class Wizard extends Player
+{
+
+ private static final int LIGHT_COST = 5;
+ private static final int HEAVY_COST = 15;
+ private static final int SPECIAL_COST = 30;
+
+ private static final String RESET = "\u001B[0m";
+ private static final String RED = "\u001B[31m";
+ private static final String GREEN = "\u001B[32m";
+ private static final String YELLOW = "\u001B[33m";
+ private static final String BLUE = "\u001B[34m";
+ private static final String PURPLE = "\u001B[35m";
+
+ public Wizard(String name) {
+ super(name, 100, 120, new BasicWeapon("Magic Staff", 20));
+ }
+
+ @Override
+ public void lightAttack(Entity target)
+ {
+ if (mp < LIGHT_COST)
+ {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= LIGHT_COST;
+ int dmg = weapon.getDamage() + 10;
+ target.takeDamage(dmg);
+
+ System.out.println(YELLOW + "โจ " + name + " casts Magic Bolt for " + dmg + " damage!" + RESET);
+ }
+
+ @Override
+ public void heavyAttack(Entity target)
+ {
+ if (mp < HEAVY_COST)
+ {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= HEAVY_COST;
+ int dmg = weapon.getDamage() + 35;
+ target.takeDamage(dmg);
+
+ System.out.println(PURPLE + "๐ฅ " + name +
+ " casts FIREBALL for " + dmg + " damage!" + RESET);
+ }
+
+ @Override
+ public void defendAction()
+ {
+ defend();
+ System.out.println(BLUE + "๐ฎ Magical barrier activated!" + RESET);
+ }
+
+ @Override
+ public void healAction()
+ {
+ if (mp < 20)
+ {
+ System.out.println(RED + "โ Not enough MP to heal!" + RESET);
+ return;
+ }
+
+ mp -= 20;
+ heal(40);
+ System.out.println(GREEN + "๐ " + name +
+ " casts HEAL restoring 40 HP!" + RESET);
+ }
+
+ @Override
+ public void specialAbility(Entity target)
+ {
+ if (mp < SPECIAL_COST)
+ {
+ System.out.println(RED + "โ Not enough MP!" + RESET);
+ return;
+ }
+
+ mp -= SPECIAL_COST;
+
+ int dmg = weapon.getDamage() + 60;
+ target.takeDamage(dmg);
+
+ System.out.println(BLUE + "๐ช๏ธ ARCANE BURST hits for " +
+ dmg + " damage!" + RESET);
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/item/Item.java b/Java-Knight/src/main/java/org/project/item/Item.java
index 6d6b5ad..13d746e 100644
--- a/Java-Knight/src/main/java/org/project/item/Item.java
+++ b/Java-Knight/src/main/java/org/project/item/Item.java
@@ -2,10 +2,14 @@ package org.project.item;
import org.project.entity.Entity;
-public interface Item {
+public interface Item
+{
void use(Entity target);
- /*
- TODO: ADD OTHER REQUIRED AND BONUS METHODS
- */
+ String getName();
+
+ String getDescription();
+
+ int getValue();
+
}
diff --git a/Java-Knight/src/main/java/org/project/item/armors/Armor.java b/Java-Knight/src/main/java/org/project/item/armors/Armor.java
index 7ca8774..640d60d 100644
--- a/Java-Knight/src/main/java/org/project/item/armors/Armor.java
+++ b/Java-Knight/src/main/java/org/project/item/armors/Armor.java
@@ -7,36 +7,67 @@ public abstract class Armor {
private int durability;
private int maxDurability;
- private boolean isBroke;
+ private boolean isBroken;
public Armor(int defense, int durability) {
this.defense = defense;
+ this.maxDefense = defense;
this.durability = durability;
+ this.maxDurability = durability;
+ this.isBroken = false;
}
- public void checkBreak() {
+ public void takeHit(int damage)
+ {
+ durability -= damage;
+
+ if (durability < 0)
+ {
+ durability = 0;
+ }
+
+ checkBroken();
+ }
+
+ public void checkBroken() {
if (durability <= 0) {
- isBroke = true;
+ isBroken = true;
defense = 0;
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
- public void repair() {
- isBroke = false;
+ public void repair()
+ {
+ isBroken = false;
defense = maxDefense;
durability = maxDurability;
}
- public int getDefense() {
+ public int getDefense()
+ {
return defense;
}
- public int getDurability() {
+ public int getDurability()
+ {
return durability;
}
- public boolean isBroke() {
- return isBroke;
+ public int getMaxDefense()
+ {
+ return maxDefense;
}
+
+ public int getMaxDurability()
+ {
+ return maxDurability;
+ }
+
+ public boolean isBroken()
+ {
+ return isBroken;
+ }
+
+ public abstract String getArmorName();
}
diff --git a/Java-Knight/src/main/java/org/project/item/armors/KnightArmor.java b/Java-Knight/src/main/java/org/project/item/armors/KnightArmor.java
index eb59a46..5601b45 100644
--- a/Java-Knight/src/main/java/org/project/item/armors/KnightArmor.java
+++ b/Java-Knight/src/main/java/org/project/item/armors/KnightArmor.java
@@ -1,6 +1,16 @@
package org.project.item.armors;
-// TODO: UPDATE IMPLEMENTATION
-public class KnightArmor {
- // TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
-}
\ No newline at end of file
+public class KnightArmor extends Armor
+{
+
+ public KnightArmor()
+ {
+ super(30, 100);
+ }
+
+ @Override
+ public String getArmorName()
+ {
+ return "Knight's Plate Armor";
+ }
+}
diff --git a/Java-Knight/src/main/java/org/project/item/consumables/Consumable.java b/Java-Knight/src/main/java/org/project/item/consumables/Consumable.java
index 028e13d..c5b964b 100644
--- a/Java-Knight/src/main/java/org/project/item/consumables/Consumable.java
+++ b/Java-Knight/src/main/java/org/project/item/consumables/Consumable.java
@@ -1,8 +1,50 @@
package org.project.item.consumables;
-// TODO: UPDATE IMPLEMENTATION
-public abstract class Consumable {
- /*
- TODO: ADD OTHER REQUIRED AND BONUS METHODS
- */
+import org.project.entity.Entity;
+
+public abstract class Consumable
+{
+
+ protected String name;
+ protected String description;
+ protected int restoreAmount;
+ protected boolean percentageBased;
+
+ public Consumable(String name, String description, int restoreAmount, boolean percentageBased)
+ {
+ this.name = name;
+ this.description = description;
+ this.restoreAmount = restoreAmount;
+ this.percentageBased = percentageBased;
+ }
+
+
+ public abstract void use(Entity target);
+
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public int getRestoreAmount()
+ {
+ return restoreAmount;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public boolean isPercentageBased()
+ {
+ return percentageBased;
+ }
+
+ @Override
+ public String toString()
+ {
+ return name + " (" + description + ")";
+ }
}
diff --git a/Java-Knight/src/main/java/org/project/item/consumables/Flask.java b/Java-Knight/src/main/java/org/project/item/consumables/Flask.java
index c0e7a6d..75cbc48 100644
--- a/Java-Knight/src/main/java/org/project/item/consumables/Flask.java
+++ b/Java-Knight/src/main/java/org/project/item/consumables/Flask.java
@@ -2,15 +2,44 @@ package org.project.item.consumables;
import org.project.entity.Entity;
-// TODO: UPDATE IMPLEMENTATION
-public class Flask {
- /*
- THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
- */
+public class Flask extends Consumable
+{
+
+ private static final int HEAL_AMOUNT = 30;
+
+ public Flask()
+ {
+ super(
+ "Health Flask",
+ "A small flask that restores health.",
+ HEAL_AMOUNT,
+ false
+ );
+ }
- // TODO: UPDATE USE METHOD
@Override
- public void use(Entity target) {
- target.heal(target.getMaxHP() / 10);
+ public void use(Entity target)
+ {
+
+ int healValue;
+
+ if (percentageBased)
+ {
+ healValue = target.getMaxHP() * restoreAmount / 100;
+ } else
+ {
+ healValue = restoreAmount;
+ }
+
+ target.heal(healValue);
+
+ System.out.println(
+ target.getName() +
+ " used " +
+ name +
+ " and restored " +
+ healValue +
+ " HP!"
+ );
}
}
diff --git a/Java-Knight/src/main/java/org/project/item/weapons/BasicWeapon.java b/Java-Knight/src/main/java/org/project/item/weapons/BasicWeapon.java
new file mode 100644
index 0000000..5d66de1
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/item/weapons/BasicWeapon.java
@@ -0,0 +1,20 @@
+package org.project.item.weapons;
+
+import org.project.entity.Entity;
+import java.util.ArrayList;
+import java.io.Serializable;
+
+public class BasicWeapon extends Weapon implements Serializable
+{
+
+ private static final long serialVersionUID = 1L;
+
+ public BasicWeapon(String name, int damage)
+ {
+ super(name, damage, 0);
+ }
+
+ @Override
+ public void uniqueAbility(ArrayList targets) {
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/item/weapons/Sword.java b/Java-Knight/src/main/java/org/project/item/weapons/Sword.java
index 96226ee..57602f7 100644
--- a/Java-Knight/src/main/java/org/project/item/weapons/Sword.java
+++ b/Java-Knight/src/main/java/org/project/item/weapons/Sword.java
@@ -1,26 +1,64 @@
package org.project.item.weapons;
import org.project.entity.Entity;
-
import java.util.ArrayList;
+import java.io.Serializable;
-// TODO: UPDATE IMPLEMENTATION
-public class Sword {
- /*
- THIS IS AN EXAMPLE OF A WEAPON DESIGN.
- */
+public class Sword extends Weapon implements Serializable
+{
- int abilityCharge;
+ private static final long serialVersionUID = 1L;
- public Sword() {
- // TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
+ private int abilityCharge;
+ private static final int MAX_CHARGE = 10;
+ private static final int REQUIRED_CHARGE = 5;
+
+ public Sword()
+ {
+ super("Knight Sword", 20, 0);
+ this.abilityCharge = 0;
}
- // TODO: (BONUS) UPDATE THE UNIQUE ABILITY
- public void uniqueAbility(ArrayList targets) {
- abilityCharge += 2;
- for (Entity target : targets) {
- target.takeDamage(getDamage());
+ @Override
+ public void uniqueAbility(ArrayList targets)
+ {
+ if (abilityCharge < REQUIRED_CHARGE)
+ {
+ System.out.println("โ ๏ธ Not enough charge for special ability! (" + abilityCharge + "/" + REQUIRED_CHARGE + ")");
+ return;
}
+
+ if (isBroken)
+ {
+ System.out.println("โ ๏ธ " + name + " is broken and can't use its special ability!");
+ return;
+ }
+
+ System.out.println("โ๏ธ " + name + " special ability: Cleave!");
+ for (Entity target : targets)
+ {
+ if (target != null && target.isAlive())
+ {
+ target.takeDamage((int) (getDamage() * 1.5));
+ }
+ }
+
+ abilityCharge = 0;
+ reduceDurability(5);
}
-}
+
+ public void addCharge(int amount)
+ {
+ this.abilityCharge = Math.min(this.abilityCharge + amount, MAX_CHARGE);
+ }
+
+ public int getAbilityCharge()
+ {
+ return abilityCharge;
+ }
+
+ public int getMaxCharge()
+ {
+ return MAX_CHARGE;
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/item/weapons/Weapon.java b/Java-Knight/src/main/java/org/project/item/weapons/Weapon.java
index cb9fcf2..e84d5c2 100644
--- a/Java-Knight/src/main/java/org/project/item/weapons/Weapon.java
+++ b/Java-Knight/src/main/java/org/project/item/weapons/Weapon.java
@@ -1,35 +1,87 @@
package org.project.item.weapons;
import org.project.entity.Entity;
+import java.util.ArrayList;
+import java.io.Serializable;
-// TODO: UPDATE IMPLEMENTATION
-public abstract class Weapon {
- private int damage;
- private int manaCost;
+public abstract class Weapon implements Serializable
+{
- /*
- TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
- */
+ private static final long serialVersionUID = 1L;
- public Weapon(int damage, int manaCost) {
+ protected String name;
+ protected int damage;
+ protected int manaCost;
+ protected int level;
+ protected int durability;
+ protected boolean isBroken;
+
+ public Weapon(String name, int damage, int manaCost)
+ {
+ this.name = name;
this.damage = damage;
this.manaCost = manaCost;
+ this.level = 1;
+ this.durability = 100;
+ this.isBroken = false;
}
- @Override
- public void use(Entity target) {
+ public void use(Entity target)
+ {
+ if (isBroken)
+ {
+ System.out.println("โ ๏ธ " + name + " is broken and can't be used!");
+ return;
+ }
+
target.takeDamage(damage);
+ reduceDurability(1);
}
- public int getDamage() {
+ public abstract void uniqueAbility(ArrayList targets);
+
+ protected void reduceDurability(int amount)
+ {
+ durability = Math.max(0, durability - amount);
+ if (durability == 0)
+ {
+ isBroken = true;
+ }
+ }
+
+ public void upgrade()
+ {
+ level++;
+ damage += 5;
+ System.out.println("๐ ๏ธ " + name + " upgraded to level " + level + "!");
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getDamage()
+ {
return damage;
}
- public int getManaCost() {
+ public int getManaCost()
+ {
return manaCost;
}
- /*
- TODO: ADD OTHER REQUIRED AND BONUS METHODS
- */
-}
+ public int getLevel()
+ {
+ return level;
+ }
+
+ public int getDurability()
+ {
+ return durability;
+ }
+
+ public boolean isBroken()
+ {
+ return isBroken;
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/src/main/java/org/project/location/Location.java b/Java-Knight/src/main/java/org/project/location/Location.java
index b0b4b98..d55781f 100644
--- a/Java-Knight/src/main/java/org/project/location/Location.java
+++ b/Java-Knight/src/main/java/org/project/location/Location.java
@@ -1,28 +1,64 @@
package org.project.location;
-import org.project.entity.enemies.Enemy;
-
+import org.project.entity.enemies.*;
+import java.io.Serializable;
import java.util.ArrayList;
-public class Location {
+public class Location implements Serializable
+{
+ private static final long serialVersionUID = 1L;
+
private String name;
+ private String description;
+ private int difficulty; // 1 = easy, 2 = medium, 3 = hard
+ private ArrayList connectedLocations;
- private ArrayList enemies;
-
- public Location(ArrayList locations, ArrayList enemies) {
- this.locations = locations;
- this.enemies = enemies;
+ public Location(String name, String description, int difficulty)
+ {
+ this.name = name;
+ this.description = description;
+ this.difficulty = difficulty;
+ this.connectedLocations = new ArrayList<>();
}
- public String getName() {
+ public void connectLocation(Location location)
+ {
+ connectedLocations.add(location);
+ }
+
+ public ArrayList getConnectedLocations()
+ {
+ return connectedLocations;
+ }
+
+ public String getName()
+ {
return name;
}
- public ArrayList getLocations() {
- return locations;
+ public int getDifficulty()
+ {
+ return difficulty;
}
- public ArrayList getEnemies() {
- return enemies;
+ public void enter()
+ {
+ System.out.println("\n==============================");
+ System.out.println("๐ You arrived at: " + name);
+ System.out.println(description);
+ System.out.println("Difficulty: " + difficulty);
+ System.out.println("==============================\n");
+ }
+
+ public Enemy spawnEnemy()
+ {
+ return switch (name)
+ {
+ case "Forest" -> new Goblin();
+ case "Graveyard" -> new Skeleton();
+ case "Vampire Crypt" -> new Vampire();
+ case "Dragon Castle" -> new Dragon();
+ default -> new Goblin();
+ };
}
}
diff --git a/Java-Knight/src/main/java/org/project/utils/SaveLoadManager.java b/Java-Knight/src/main/java/org/project/utils/SaveLoadManager.java
new file mode 100644
index 0000000..491d61d
--- /dev/null
+++ b/Java-Knight/src/main/java/org/project/utils/SaveLoadManager.java
@@ -0,0 +1,27 @@
+package org.project.utils;
+
+import org.project.GameState;
+import java.io.*;
+
+public class SaveLoadManager {
+
+ public static void saveGame(GameState gameState, String filename) {
+ try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filename))) {
+ oos.writeObject(gameState);
+ System.out.println("\u001B[34m\u2714\u001B[0m Game saved successfully.");
+ } catch (IOException e) {
+ System.out.println("\u001B[31m\u2716\u001B[0m Error saving game: " + e.getMessage());
+ }
+ }
+
+ public static GameState loadGame(String filename) {
+ try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filename))) {
+ GameState loadedState = (GameState) ois.readObject();
+ System.out.println("\u001B[32m\u2714\u001B[0m Game loaded successfully.");
+ return loadedState;
+ } catch (IOException | ClassNotFoundException e) {
+ System.out.println("\u001B[31m\u2716\u001B[0m Error loading game: " + e.getMessage());
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Java-Knight/target/classes/org/project/GameState.class b/Java-Knight/target/classes/org/project/GameState.class
new file mode 100644
index 0000000..c62b3ec
Binary files /dev/null and b/Java-Knight/target/classes/org/project/GameState.class differ
diff --git a/Java-Knight/target/classes/org/project/Main.class b/Java-Knight/target/classes/org/project/Main.class
new file mode 100644
index 0000000..6f7bf47
Binary files /dev/null and b/Java-Knight/target/classes/org/project/Main.class differ
diff --git a/Java-Knight/target/classes/org/project/combat/CombatSystem.class b/Java-Knight/target/classes/org/project/combat/CombatSystem.class
new file mode 100644
index 0000000..160abbe
Binary files /dev/null and b/Java-Knight/target/classes/org/project/combat/CombatSystem.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/Entity.class b/Java-Knight/target/classes/org/project/entity/Entity.class
new file mode 100644
index 0000000..6d6853d
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/Entity.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/enemies/Dragon.class b/Java-Knight/target/classes/org/project/entity/enemies/Dragon.class
new file mode 100644
index 0000000..ed569b1
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/enemies/Dragon.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/enemies/Enemy.class b/Java-Knight/target/classes/org/project/entity/enemies/Enemy.class
new file mode 100644
index 0000000..f247d0a
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/enemies/Enemy.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/enemies/Goblin.class b/Java-Knight/target/classes/org/project/entity/enemies/Goblin.class
new file mode 100644
index 0000000..2319d28
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/enemies/Goblin.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/enemies/Skeleton.class b/Java-Knight/target/classes/org/project/entity/enemies/Skeleton.class
new file mode 100644
index 0000000..ff52539
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/enemies/Skeleton.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/enemies/Vampire.class b/Java-Knight/target/classes/org/project/entity/enemies/Vampire.class
new file mode 100644
index 0000000..73dcc22
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/enemies/Vampire.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/players/Assassin.class b/Java-Knight/target/classes/org/project/entity/players/Assassin.class
new file mode 100644
index 0000000..7b7d492
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/players/Assassin.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/players/ICombatActions.class b/Java-Knight/target/classes/org/project/entity/players/ICombatActions.class
new file mode 100644
index 0000000..8f1cdee
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/players/ICombatActions.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/players/Knight.class b/Java-Knight/target/classes/org/project/entity/players/Knight.class
new file mode 100644
index 0000000..3ed14f7
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/players/Knight.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/players/Player.class b/Java-Knight/target/classes/org/project/entity/players/Player.class
new file mode 100644
index 0000000..5663e67
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/players/Player.class differ
diff --git a/Java-Knight/target/classes/org/project/entity/players/Wizard.class b/Java-Knight/target/classes/org/project/entity/players/Wizard.class
new file mode 100644
index 0000000..233a7ba
Binary files /dev/null and b/Java-Knight/target/classes/org/project/entity/players/Wizard.class differ
diff --git a/Java-Knight/target/classes/org/project/item/Item.class b/Java-Knight/target/classes/org/project/item/Item.class
new file mode 100644
index 0000000..f4b4c63
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/Item.class differ
diff --git a/Java-Knight/target/classes/org/project/item/armors/Armor.class b/Java-Knight/target/classes/org/project/item/armors/Armor.class
new file mode 100644
index 0000000..fbe477e
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/armors/Armor.class differ
diff --git a/Java-Knight/target/classes/org/project/item/armors/KnightArmor.class b/Java-Knight/target/classes/org/project/item/armors/KnightArmor.class
new file mode 100644
index 0000000..5c0336c
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/armors/KnightArmor.class differ
diff --git a/Java-Knight/target/classes/org/project/item/consumables/Consumable.class b/Java-Knight/target/classes/org/project/item/consumables/Consumable.class
new file mode 100644
index 0000000..dcbf719
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/consumables/Consumable.class differ
diff --git a/Java-Knight/target/classes/org/project/item/consumables/Flask.class b/Java-Knight/target/classes/org/project/item/consumables/Flask.class
new file mode 100644
index 0000000..f2ab205
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/consumables/Flask.class differ
diff --git a/Java-Knight/target/classes/org/project/item/weapons/BasicWeapon.class b/Java-Knight/target/classes/org/project/item/weapons/BasicWeapon.class
new file mode 100644
index 0000000..5a42d70
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/weapons/BasicWeapon.class differ
diff --git a/Java-Knight/target/classes/org/project/item/weapons/Sword.class b/Java-Knight/target/classes/org/project/item/weapons/Sword.class
new file mode 100644
index 0000000..69b4011
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/weapons/Sword.class differ
diff --git a/Java-Knight/target/classes/org/project/item/weapons/Weapon.class b/Java-Knight/target/classes/org/project/item/weapons/Weapon.class
new file mode 100644
index 0000000..bc426d9
Binary files /dev/null and b/Java-Knight/target/classes/org/project/item/weapons/Weapon.class differ
diff --git a/Java-Knight/target/classes/org/project/location/Location.class b/Java-Knight/target/classes/org/project/location/Location.class
new file mode 100644
index 0000000..eea067f
Binary files /dev/null and b/Java-Knight/target/classes/org/project/location/Location.class differ
diff --git a/Java-Knight/target/classes/org/project/utils/SaveLoadManager.class b/Java-Knight/target/classes/org/project/utils/SaveLoadManager.class
new file mode 100644
index 0000000..a9b5a35
Binary files /dev/null and b/Java-Knight/target/classes/org/project/utils/SaveLoadManager.class differ
diff --git a/README1.md b/README1.md
new file mode 100644
index 0000000..dd351dd
--- /dev/null
+++ b/README1.md
@@ -0,0 +1,162 @@
+# โ๏ธ Java Knight: The Legend of Javanest
+
+
+
+
+
+**Java Knight** is a text-based RPG game developed in Java.
+Embark on an epic adventure through the lands of **Javanest**, battle dangerous enemies, collect ancient keys, and face the ultimate **Dragon Boss** to save the kingdom.
+
+---
+
+## ๐ Core Features
+
+- ๐ญ **Multiple Playable Classes** (Knight, Wizard, Assassin)
+- ๐บ๏ธ **Location-Based Exploration System**
+- โ๏ธ **Turn-Based Combat Mechanics**
+- ๐ **Key Collection & Progression System**
+- ๐พ **Save / Load Ready (Java Serialization)**
+- ๐ **RPG Systems**: HP, MP, XP, Levels
+- ๐ก๏ธ **Weapons, Armor & Durability**
+- ๐ **Final Boss Battle**
+
+---
+
+## ๐ก๏ธ Playable Classes
+
+| Class | HP | MP | Starting Weapon | Playstyle |
+|------|----|----|----------------|-----------|
+| **Knight** | High | Low | Sword | Tank / Physical Damage |
+| **Wizard** | Medium | High | Magic Staff | Magic & Healing |
+| **Assassin** | Medium | Medium | Daggers | Stealth & Burst Damage |
+
+Each class has **unique abilities**, different mana costs, and a distinct combat style.
+
+---
+
+## ๐บ๏ธ World Map
+
+Explore the dangerous regions of Javanest:
+
+1. **Forest (Difficulty 1)**
+ _A dark forest full of Goblins._
+
+2. **Graveyard (Difficulty 2)**
+ _An abandoned graveyard haunted by Skeletons._
+
+3. **Vampire Crypt (Difficulty 3)**
+ _A cursed crypt ruled by Vampires._
+
+4. **Dragon Castle (Difficulty 4)**
+ _The final destination and home of the Dragon._
+
+Locations are connected, allowing the player to move freely between unlocked areas.
+
+---
+
+## ๐ฎ Game Flow
+
+1. Start the game
+2. Enter your player name
+3. Choose a class
+4. Begin in the **Forest**
+5. Fight enemies and gain XP
+6. Collect special keys
+7. Unlock the **Dragon Castle**
+8. Defeat the Dragon and save Javanest
+
+---
+
+## ๐งญ Main Menu
+
+At launch, the player is presented with the main menu:
+```text
+===============================
+โ JAVA KNIGHT โ
+===============================
+1. Start Game
+2. How To Play
+3. Exit
+Menu Options
+Start Game โ Begin a new adventure
+How To Play โ Learn the rules and objective
+Exit โ Close the game
+๐ฐ In-Game Menu
+While exploring a location, the player can choose:
+
+text
+1. Fight Enemy
+2. Move Location
+3. Enter Dragon Castle (if unlocked)
+Fight Enemy โ Starts a battle based on the current location
+Move Location โ Travel to connected locations
+Enter Dragon Castle โ Available only after collecting all keys
+โ๏ธ Combat System
+Combat is turn-based and class-dependent.
+
+Available Actions
+Light Attack
+Heavy Attack
+Defend
+Heal
+Special Ability
+Exit Battle
+Combat Rules
+Attacks may consume MP
+Special abilities are unique per class
+Enemies attack after the playerโs turn
+Winning a battle grants XP
+Enemies may drop keys
+๐ Key System
+To unlock the final area, the player must collect:
+
+๐๏ธ Goblin Key
+๐๏ธ Skeleton Key
+๐๏ธ Vampire Key
+Each key drops from enemies in its respective location.
+
+Once all keys are collected, the Dragon Castle becomes accessible.
+
+๐ Progression System
+HP (Health Points)
+MP (Mana Points)
+XP (Experience Points)
+Level System
+Weapon Durability
+Progression rewards strategic combat and exploration.
+
+๐พ Save & Load System
+The project is prepared for game saving using Java Serialization.
+
+Serializable Components
+Player
+Location
+Weapon
+GameState
+This allows the game to be saved and restored at any point.
+
+๐ Getting Started
+Requirements
+Java JDK 17 or higher
+Terminal or Java IDE (IntelliJ IDEA, Eclipse, VS Code)
+Run the Game
+bash
+javac -d out src/org/project/**/*.java
+java -cp out org.project.Main
+Or simply run Main.java from your IDE.
+
+๐ ๏ธ Project Architecture
+Object-Oriented Design
+Clean separation of concerns
+Interfaces & abstract classes
+Easily extendable structure
+Console-based UI with ANSI colors
+๐ฎ Future Improvements
+Inventory management menu
+More weapons and consumables
+Enhanced armor mechanics
+Expanded world map
+Graphical UI (JavaFX / Swing)
+๐ License
+This project is licensed under the MIT License.
+