Implementation of JAVA-Knight is complete

This commit is contained in:
2026-06-21 19:48:04 +03:30
parent 78d4bedb08
commit d60b0ca25f
62 changed files with 1660 additions and 348 deletions
@@ -1,15 +1,72 @@
/**
*
*
* @author [Hesam Ghazi]
* @version 1.0
*
* */
package org.project;
import org.project.entity.players.*;
import org.project.game.GameManager;
import org.project.item.weapons.*;
import org.project.location.Location;
import java.util.ArrayList;
import java.util.List;
import org.project.entity.enemies.*;
import org.project.utils.ConsoleColors;
public class Main {
public static void main(String[] args) {
// TODO: ADD LOCATIONS TO YOUR GAME
List<Location> locations = new ArrayList<>();
// Create weapons
Sword sword = new Sword();
Staff staff = new Staff();
Dagger dagger = new Dagger();
// TODO: IMPLEMENT GAMEPLAY
// Create player (choose your class)
Player player = new Knight("Sir Gallahad", sword);
// Player player = new Assassin("Shadow", dagger);
// Player player = new Wizard("Merlin", staff);
// Create locations
GameManager gameManager = getGameManager(player);
// Start the game with colorful intro
System.out.println(ConsoleColors.YELLOW_BOLD + "=== THE CURSE OF THE DRAGON ===" + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "The land is cursed by an ancient dragon!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "Collect the 3 keys to unlock the castle," + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "defeat the Dragon, and break the curse!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.PURPLE + "----------------------------------------" + ConsoleColors.RESET);
gameManager.startGame();
}
private static GameManager getGameManager(Player player) {
Location town = new Location("Town of Beginnings",
"A peaceful town where your journey begins.");
Location forest = new Location("Dark Forest",
"A dense forest filled with dangerous creatures.");
Location cave = new Location("Cave of Echoes",
"A dark cave where the echoes of your footsteps are your only company.");
Location castle = new Location("Castle of Doom",
"The final stronghold of the evil dragon.");
// Connect locations
town.addConnectedLocation(forest);
town.addConnectedLocation(cave);
forest.addConnectedLocation(town);
forest.addConnectedLocation(cave);
cave.addConnectedLocation(town);
cave.addConnectedLocation(forest);
cave.addConnectedLocation(castle);
castle.addConnectedLocation(cave);
// Create game manager
GameManager gameManager = new GameManager(player, town);
// Add all locations to game manager
gameManager.addLocation(town);
gameManager.addLocation(forest);
gameManager.addLocation(cave);
gameManager.addLocation(castle);
return gameManager;
}
}
@@ -3,19 +3,23 @@ package org.project.entity;
public interface Entity {
void attack(Entity target);
void receiveAttack(int damage, boolean ignoreDefense);
void defend();
void heal(int health);
void heal(int amount);
void fillMana(int mana);
void fillMana(int amount);
void takeDamage(int damage);
boolean isAlive();
int getHP();
int getMP();
int getMaxHP();
int getMaxMP();
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
String getName();
}
@@ -0,0 +1,14 @@
package org.project.entity;
// This class implements five possible actions
public interface ICombatActions {
void lightAttack(Entity target);
void heavyAttack(Entity target);
void defend();
void heal();
void specialAbility(Entity target);
}
@@ -0,0 +1,34 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
public class Boss extends Enemy {
public Boss(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
super(name, maxHP, maxMP, damage, weapon, xpReward);
}
@Override
public void attack(Entity target) {
if (stunned) {
System.out.println(name + " is stunned and cannot attack!");
return;
}
int totalDamage = damage;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
// Boss deals extra damage and ignores defense on heavy attacks
if (Math.random() < 0.3) {
totalDamage *= 1.5;
System.out.println("💢 " + name + " uses a powerful heavy attack!");
target.receiveAttack((int)totalDamage, true);
} else {
System.out.println("⚔️ " + name + " attacks!");
target.receiveAttack(totalDamage, false);
}
}
}
@@ -0,0 +1,215 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
/**
* Dragon - A powerful boss enemy with unique abilities
* Subclass of Boss with enhanced combat capabilities
*/
public class Dragon extends Boss {
private int fireBreathCooldown;
private boolean enraged;
private int enrageThreshold;
public Dragon(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
super(name, maxHP, maxMP, damage, weapon, xpReward);
this.fireBreathCooldown = 0;
this.enraged = false;
this.enrageThreshold = maxHP / 3; // Enrages when HP drops below 33%
}
public Dragon() {
this("Ancient Dragon", 250, 100, 30, null, 600);
}
@Override
public void attack(Entity target) {
if (stunned) {
System.out.println(name + " is stunned and cannot attack!");
return;
}
// Check for enrage status
if (!enraged && hp <= enrageThreshold) {
enraged = true;
damage += 10;
System.out.println("🔥 " + name + " has become ENRAGED! Its attack power increases!");
}
// Decrease cooldown
if (fireBreathCooldown > 0) {
fireBreathCooldown--;
}
// Choose attack type based on conditions
double attackChoice = Math.random();
// Fire breath attack (cooldown of 3 turns)
if (attackChoice < 0.25 && fireBreathCooldown == 0 && mp >= 30) {
fireBreath(target);
}
// Tail swipe - area attack (if enraged)
else if (enraged && attackChoice < 0.45 && mp >= 15) {
tailSwipe(target);
}
// Normal attack
else {
normalAttack(target);
}
}
/**
* Fire Breath - Powerful area attack dealing high damage
*/
private void fireBreath(Entity target) {
if (mp < 30) {
System.out.println(name + " tries to breathe fire but lacks mana!");
normalAttack(target);
return;
}
mp -= 30;
fireBreathCooldown = 3;
int totalDamage = (damage * 2) + (weapon != null ? weapon.getDamage() : 0);
boolean ignoreDefense = true; // Fire burns through defenses
System.out.println("🐉 " + name + " unleashes a devastating FIRE BREATH!");
System.out.println("🔥 Flames engulf the battlefield!");
// Extra damage if enraged
if (enraged) {
totalDamage *= 1.5;
System.out.println("💢 Enraged fire breath deals extra damage!");
}
target.receiveAttack(totalDamage, ignoreDefense);
}
/**
* Tail Swipe - Heavy attack that can stun
*/
private void tailSwipe(Entity target) {
if (mp < 15) {
normalAttack(target);
return;
}
mp -= 15;
int totalDamage = (int)((damage * 1.7) + (weapon != null ? weapon.getDamage() * 0.5 : 0));
System.out.println("🐉 " + name + " performs a massive TAIL SWIPE!");
target.receiveAttack(totalDamage, false);
// Chance to stun the target
if (Math.random() < 0.3) {
System.out.println("💫 The tail swipe stuns the target!");
// Note: Would need to implement stun on Player
}
}
/**
* Normal attack with potential for extra effects
*/
private void normalAttack(Entity target) {
int totalDamage = damage + (weapon != null ? weapon.getDamage() : 0);
// Enraged dragons deal additional damage
if (enraged) {
totalDamage += 5;
}
// Chance for critical hit
boolean isCritical = Math.random() < 0.15;
if (isCritical) {
totalDamage *= 1.8;
System.out.println("💥 " + name + " lands a CRITICAL strike!");
}
System.out.println("🐉 " + name + " attacks with its claws!");
target.receiveAttack(totalDamage, false);
}
/**
* Dragon's special ability - Rage Roar (buffs itself)
*/
public void rageRoar() {
if (mp < 20) {
System.out.println("Not enough mana for Rage Roar!");
return;
}
mp -= 20;
damage += 5;
System.out.println("🐉 " + name + " lets out a terrifying RAGE ROAR!");
System.out.println("💪 " + name + "'s attack power increases permanently!");
}
/**
* Dragon's ultimate ability - Inferno (must be used when enraged)
*/
public void inferno(Entity target) {
if (!enraged) {
System.out.println(name + " must be enraged to use Inferno!");
return;
}
if (mp < 50) {
System.out.println("Not enough mana for Inferno!");
return;
}
mp -= 50;
int totalDamage = damage * 3 + (weapon != null ? weapon.getDamage() * 2 : 0);
System.out.println("🔥🐉 " + name + " summons an INFERNO of pure destruction!");
System.out.println("🌋 The ground erupts in flames!");
target.receiveAttack(totalDamage, true);
// After using inferno, dragon becomes exhausted
damage -= 5;
if (damage < 10) damage = 10;
System.out.println("😰 " + name + " is exhausted from the inferno!");
}
@Override
public void nextTurn() {
super.nextTurn();
// Reduce cooldowns
if (fireBreathCooldown > 0) {
fireBreathCooldown--;
}
}
@Override
public void receiveAttack(int damage, boolean ignoreDefense) {
super.receiveAttack(damage, ignoreDefense);
// Check if dragon becomes enraged due to damage
if (!enraged && hp <= enrageThreshold) {
enraged = true;
this.damage += 10;
System.out.println("🔥 " + name + " roars in pain and becomes ENRAGED!");
System.out.println("⚔️ Its damage increases by 10!");
}
}
@Override
public int getXPReward() {
// Enhanced XP reward for defeating a dragon
int baseReward = super.getXPReward();
return enraged ? baseReward + 100 : baseReward + 50;
}
// Getters
public boolean isEnraged() {
return enraged;
}
public int getFireBreathCooldown() {
return fireBreathCooldown;
}
}
@@ -1,34 +1,143 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Enemy {
Weapon weapon;
private int hp;
private int mp;
public Enemy(int hp, int mp, Weapon weapon) {
this.hp = hp;
this.mp = mp;
public abstract class Enemy implements Entity {
protected String name;
protected int hp;
protected int maxHP;
protected int mp;
protected int maxMP;
protected int damage;
protected Weapon weapon;
protected boolean stunned;
protected boolean defending;
protected boolean resurrected;
protected int xpReward;
public Enemy(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
this.name = name;
this.maxHP = maxHP;
this.hp = maxHP;
this.maxMP = maxMP;
this.mp = maxMP;
this.damage = damage;
this.weapon = weapon;
this.stunned = false;
this.defending = false;
this.resurrected = false;
this.xpReward = xpReward;
}
@Override
public void takeDamage(int damage) {
hp -= damage;
public void attack(Entity target) {
if (stunned) {
System.out.println(ConsoleColors.YELLOW + name + " is stunned and cannot attack!" + ConsoleColors.RESET);
return;
}
int total = damage;
if (weapon != null) {
total += weapon.getDamage();
}
System.out.println(ConsoleColors.RED + name + " attacks!" + ConsoleColors.RESET);
target.receiveAttack(total, false);
}
public int getHp() {
@Override
public void receiveAttack(int damage, boolean ignoreDefense) {
if (defending && !ignoreDefense) {
damage /= 2;
defending = false;
}
hp -= damage;
if (hp < 0) {
hp = 0;
}
System.out.println(ConsoleColors.RED + name + " took " + damage + " damage." + ConsoleColors.RESET);
}
@Override
public void defend() {
defending = true;
System.out.println(ConsoleColors.CYAN + name + " is defending." + ConsoleColors.RESET);
}
@Override
public void heal(int amount) {
hp += amount;
if (hp > maxHP) {
hp = maxHP;
}
System.out.println(ConsoleColors.GREEN + name + " healed for " + amount + " HP." + ConsoleColors.RESET);
}
@Override
public void fillMana(int amount) {
mp += amount;
if (mp > maxMP) {
mp = maxMP;
}
System.out.println(ConsoleColors.BLUE + name + " restored " + amount + " Mana." + ConsoleColors.RESET);
}
@Override
public boolean isAlive() {
return hp > 0;
}
@Override
public int getHP() {
return hp;
}
public int getMp() {
@Override
public int getMP() {
return mp;
}
@Override
public int getMaxHP() {
return maxHP;
}
@Override
public int getMaxMP() {
return maxMP;
}
@Override
public String getName() {
return name;
}
public void stun() {
stunned = true;
System.out.println(ConsoleColors.YELLOW + name + " is stunned!" + ConsoleColors.RESET);
}
public boolean isStunned() {
return stunned;
}
public void nextTurn() {
if (stunned) {
stunned = false;
}
defending = false;
}
public int getXPReward() {
return xpReward;
}
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
public Weapon getWeapon() {
return weapon;
}
}
}
@@ -0,0 +1,37 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;
public class Goblin extends Enemy {
public Goblin() {
this("Goblin", 40, 15, 8, null, 35);
}
public Goblin(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
super(name, maxHP, maxMP, damage, weapon, xpReward);
}
// Additional constructor for easier creation without weapon
public Goblin(String name, int maxHP, int maxMP, int damage, int xpReward) {
this(name, maxHP, maxMP, damage, null, xpReward);
}
@Override
public void attack(Entity target) {
if (stunned) {
System.out.println(ConsoleColors.YELLOW + name + " is stunned and cannot attack!" + ConsoleColors.RESET);
return;
}
int totalDamage = damage;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
System.out.println(ConsoleColors.RED + name + " swings a crude club!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
}
}
@@ -1,6 +1,29 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
public class Skeleton extends Enemy {
// TODO: UPDATE IMPLEMENTATION
public class Skeleton {
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
}
public Skeleton() {
this("Skeleton", 50, 20, 10, null, 50);
}
public Skeleton(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
super(name, maxHP, maxMP, damage, weapon, xpReward);
}
@Override
public void attack(Entity target) {
if (stunned) {
System.out.println(name + " is stunned and cannot attack!");
return;
}
// Skeletons have a chance to miss
if (Math.random() < 0.1) {
System.out.println(name + " attacks but misses!");
return;
}
super.attack(target);
}
}
@@ -0,0 +1,42 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;
public class Vampire extends Enemy {
public Vampire() {
super("Vampire", 65, 40, 15, null, 70);
}
public Vampire(String name, int maxHP, int maxMP, int damage, Weapon weapon, int xpReward) {
super(name, maxHP, maxMP, damage, weapon, xpReward);
}
// Additional constructor for easier creation without weapon
public Vampire(String name, int maxHP, int maxMP, int damage, int xpReward) {
this(name, maxHP, maxMP, damage, null, xpReward);
}
@Override
public void attack(Entity target) {
if (stunned) {
System.out.println(ConsoleColors.YELLOW + name + " is stunned and cannot attack!" + ConsoleColors.RESET);
return;
}
int totalDamage = damage;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
// Vampire has lifesteal - heals for 30% of damage dealt
System.out.println(ConsoleColors.RED + name + " strikes with vampiric claws!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
int healAmount = (int)(totalDamage * 0.3);
heal(healAmount);
System.out.println(ConsoleColors.GREEN + name + " drains " + healAmount + " HP!" + ConsoleColors.RESET);
}
}
@@ -0,0 +1,57 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
public class Assassin extends Player {
private boolean invisible;
private boolean criticalAttack;
public Assassin(String name, Weapon weapon) {
super(name, 90, 120, 16, weapon);
this.invisible = false;
this.criticalAttack = false;
}
@Override
public void specialAbility(Entity target) {
if (mp < 22) {
System.out.println("Not enough Mana!");
return;
}
mp -= 22;
invisible = true;
criticalAttack = true;
System.out.println("🗡 Assassin vanished into the shadows.");
}
@Override
public void lightAttack(Entity target) {
int totalDamage = damage;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
if (criticalAttack) {
totalDamage *= 2;
System.out.println("💥 Critical Strike!");
criticalAttack = false;
}
target.receiveAttack(totalDamage, false);
}
@Override
public void receiveAttack(int damage, boolean ignoreDefense) {
if (invisible) {
System.out.println("Attack dodged!");
invisible = false;
return;
}
super.receiveAttack(damage, ignoreDefense);
}
// This method doesn't override anything from Entity interface
// It's just a convenience method that calls receiveAttack
public void takeDamage(int damage) {
receiveAttack(damage, false);
}
}
@@ -1,6 +1,37 @@
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.weapons.Weapon;
import org.project.utils.ConsoleColors;
public class Knight extends Player {
private boolean stunEnemy = false;
public Knight(String name, Weapon weapon) {
super(name, 120, 60, 18, weapon);
}
@Override
public void specialAbility(Entity target) {
if (mp < 20) {
System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
return;
}
mp -= 20;
int totalDamage = damage * 3;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
System.out.println(ConsoleColors.YELLOW_BOLD + "⚔ Shield Bash!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
stunEnemy = true;
}
public boolean shouldStunEnemy() {
return stunEnemy;
}
public void resetStun() {
stunEnemy = false;
}
}
@@ -1,89 +1,186 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.entity.ICombatActions;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Player {
public abstract class Player implements Entity, ICombatActions {
protected String name;
Weapon weapon;
Armor armor;
private int hp;
private int maxHP;
private int mp;
private int maxMP;
protected int hp;
protected int maxHP;
protected int mp;
protected int maxMP;
protected int damage;
protected int level;
protected int xp;
protected Weapon weapon;
protected boolean defending;
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
public Player(String name, int maxHP, int maxMP, int damage, Weapon weapon) {
this.name = name;
this.hp = hp;
this.mp = mp;
this.maxHP = maxHP;
this.hp = maxHP;
this.maxMP = maxMP;
this.mp = maxMP;
this.damage = damage;
this.weapon = weapon;
this.armor = armor;
this.level = 1;
this.xp = 0;
this.defending = false;
}
@Override
public void attack(Entity target) {
target.takeDamage(weapon.getDamage());
lightAttack(target);
}
@Override
public void lightAttack(Entity target) {
int totalDamage = damage;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
System.out.println(ConsoleColors.CYAN_BOLD + name + " used Light Attack!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
}
@Override
public void heavyAttack(Entity target) {
if (mp < 8) {
System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
return;
}
mp -= 8;
int totalDamage = damage * 2;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
System.out.println(ConsoleColors.PURPLE_BOLD + name + " used Heavy Attack!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
}
@Override
public void defend() {
// TODO
}
@Override
public void takeDamage(int damage) {
hp -= damage - armor.getDefense();
if (mp < 5) {
System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
return;
}
mp -= 5;
defending = true;
System.out.println(ConsoleColors.CYAN + name + " is defending." + ConsoleColors.RESET);
}
@Override
public void heal(int health) {
hp += health;
public void heal() {
if (mp < 10) {
System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
return;
}
mp -= 10;
hp += 25;
if (hp > maxHP) {
hp = maxHP;
}
System.out.println(ConsoleColors.GREEN_BOLD + name + " healed for 25 HP." + ConsoleColors.RESET);
}
@Override
public void fillMana(int mana) {
mp += mana;
public void heal(int amount) {
hp += amount;
if (hp > maxHP) {
hp = maxHP;
}
System.out.println(ConsoleColors.GREEN + name + " healed for " + amount + " HP." + ConsoleColors.RESET);
}
@Override
public abstract void specialAbility(Entity target);
@Override
public void receiveAttack(int damage, boolean ignoreDefense) {
if (defending && !ignoreDefense) {
damage /= 2;
defending = false;
}
hp -= damage;
if (hp < 0) {
hp = 0;
}
System.out.println(ConsoleColors.RED + name + " took " + damage + " damage." + ConsoleColors.RESET);
}
// Convenience method
public void takeDamage(int damage) {
receiveAttack(damage, false);
}
@Override
public void fillMana(int amount) {
mp += amount;
if (mp > maxMP) {
mp = maxMP;
}
System.out.println(ConsoleColors.BLUE + name + " restored " + amount + " Mana." + ConsoleColors.RESET);
}
public String getName() {
return name;
@Override
public boolean isAlive() {
return hp > 0;
}
public int getHp() {
public void gainXP(int amount) {
xp += amount;
while (xp >= level * 100) {
xp -= level * 100;
level++;
maxHP += 10;
maxMP += 5;
damage += 3;
hp = maxHP;
mp = maxMP;
System.out.println(ConsoleColors.YELLOW_BOLD + "🌟 " + name + " reached level " + level + "!" + ConsoleColors.RESET);
}
}
@Override
public int getHP() {
return hp;
}
@Override
public int getMP() {
return mp;
}
@Override
public int getMaxHP() {
return maxHP;
}
public int getMp() {
return mp;
}
@Override
public int getMaxMP() {
return maxMP;
}
@Override
public String getName() {
return name;
}
public int getLevel() {
return level;
}
public Weapon getWeapon() {
return weapon;
}
public Armor getArmor() {
return armor;
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
}
public int getDamage() {
return damage;
}
}
@@ -0,0 +1,28 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.utils.ConsoleColors;
public class Wizard extends Player {
public Wizard(String name, Weapon weapon) {
super(name, 140, 100, 12, weapon);
}
@Override
public void specialAbility(Entity target) {
if (mp < 25) {
System.out.println(ConsoleColors.RED + "Not enough Mana!" + ConsoleColors.RESET);
return;
}
mp -= 25;
int totalDamage = damage * 4;
if (weapon != null) {
totalDamage += weapon.getDamage();
}
System.out.println(ConsoleColors.PURPLE_BOLD + "✨ Arcane Explosion!" + ConsoleColors.RESET);
target.receiveAttack(totalDamage, false);
heal(25);
System.out.println(ConsoleColors.GREEN + name + " restored 25 HP." + ConsoleColors.RESET);
}
}
@@ -0,0 +1,550 @@
package org.project.game;
import org.project.entity.enemies.*;
import org.project.entity.players.Player;
import org.project.entity.players.Knight;
import org.project.location.Location;
import org.project.item.consumables.Consumable;
import org.project.item.consumables.Flask;
import org.project.item.consumables.ManaPotion;
import org.project.utils.ConsoleColors;
import java.util.*;
/**
* GameManager.java
* Controls the main game loop, combat system, and progression mechanics.
*
* @author [Your Name]
* @version 1.0
*/
public class GameManager {
// Game state fields
private Player player;
private Location currentLocation;
private List<Location> locations;
private Scanner scanner;
private List<Consumable> inventory;
// Key collection - required to unlock the castle
private Set<Key> collectedKeys;
private boolean dragonDefeated;
private boolean castleUnlocked;
// Random number generator for enemy spawns and drops
private Random random;
/**
* Initializes the game with a player and starting location.
*
* @param player The player character (Knight, Assassin, or Wizard)
* @param startingLocation Where the adventure begins
*/
public GameManager(Player player, Location startingLocation) {
this.player = player;
this.currentLocation = startingLocation;
this.locations = new ArrayList<>();
this.scanner = new Scanner(System.in);
this.inventory = new ArrayList<>();
this.collectedKeys = new HashSet<>();
this.dragonDefeated = false;
this.castleUnlocked = false;
this.random = new Random();
// Starter items
inventory.add(new Flask());
inventory.add(new Flask());
inventory.add(new ManaPotion());
}
/**
* Adds a location to the game world.
*
* @param location New location to add
*/
public void addLocation(Location location) {
locations.add(location);
}
/**
* Starts the game and displays the welcome message.
*/
public void startGame() {
System.out.println(ConsoleColors.YELLOW_BOLD + "=== WELCOME TO THE REALM OF DRAGONS ===" + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "A curse has befallen the land!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "You must collect the 3 ancient keys to unlock the castle," + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "defeat the Dragon, and break the curse!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.PURPLE + "----------------------------------------" + ConsoleColors.RESET);
System.out.println();
gameLoop();
}
/**
* Main game loop - handles player turns and game state.
*/
private void gameLoop() {
boolean running = true;
while (running) {
// Check for game over
if (!player.isAlive()) {
System.out.println(ConsoleColors.RED_BOLD + "💀 You have been defeated! Game Over!" + ConsoleColors.RESET);
break;
}
// Check for victory
if (dragonDefeated) {
System.out.println(ConsoleColors.YELLOW_BOLD + "🎉 CONGRATULATIONS! YOU HAVE DEFEATED THE DRAGON!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN_BOLD + "The curse is broken and the land is saved!" + ConsoleColors.RESET);
break;
}
displayLocationInfo();
System.out.println();
// Spawn enemy if location is empty
if (!currentLocation.hasEnemies()) {
spawnRandomEnemy();
}
checkCastleUnlock();
showMainMenu();
String choice = scanner.nextLine().trim();
switch (choice) {
case "1":
fightEnemy();
break;
case "2":
moveToLocation();
break;
case "3":
if (castleUnlocked) {
fightDragon();
} else {
System.out.println(ConsoleColors.RED + "The castle is locked! You need all 3 keys to enter." + ConsoleColors.RESET);
System.out.println(ConsoleColors.YELLOW + "Keys collected: " + collectedKeys.size() + "/3" + ConsoleColors.RESET);
}
break;
case "4":
useInventory();
break;
case "5":
displayStatus();
break;
case "6":
running = false;
System.out.println(ConsoleColors.YELLOW + "Thanks for playing!" + ConsoleColors.RESET);
break;
default:
System.out.println(ConsoleColors.RED + "Invalid choice. Try again." + ConsoleColors.RESET);
}
}
scanner.close();
}
/**
* Displays current location information and player stats.
*/
private void displayLocationInfo() {
System.out.println(ConsoleColors.CYAN_BOLD + "\n📍 " + currentLocation.getName() + ConsoleColors.RESET);
System.out.println(currentLocation.getDescription());
System.out.println(ConsoleColors.GREEN + "HP: " + player.getHP() + "/" + player.getMaxHP() +
" | " + ConsoleColors.BLUE + "MP: " + player.getMP() + "/" + player.getMaxMP() +
" | " + ConsoleColors.YELLOW + "Level: " + player.getLevel() + ConsoleColors.RESET);
}
/**
* Displays the main menu with all available actions.
* Castle option only appears when unlocked.
*/
private void showMainMenu() {
System.out.println("\n" + ConsoleColors.WHITE_BOLD + "What would you like to do?" + ConsoleColors.RESET);
System.out.println("1. ⚔️ Fight the enemy");
System.out.println("2. 🚶 Move to another location");
if (castleUnlocked) {
System.out.println(ConsoleColors.YELLOW_BOLD + "3. 🏰 Go to the Castle to fight the Dragon" + ConsoleColors.RESET);
} else {
System.out.println("3. 🔒 Castle (Locked - Need all 3 keys)");
}
System.out.println("4. 🎒 Use Inventory");
System.out.println("5. 📊 Check Status");
System.out.println("6. ❌ Quit");
// Show key progress if castle is locked
if (!castleUnlocked) {
System.out.println(ConsoleColors.CYAN + "Keys collected: " + collectedKeys.size() + "/3" + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + " - Goblin Key: " + (collectedKeys.contains(Key.GOBLIN_KEY) ? "" : "") + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + " - Skeleton Key: " + (collectedKeys.contains(Key.SKELETON_KEY) ? "" : "") + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + " - Vampire Key: " + (collectedKeys.contains(Key.VAMPIRE_KEY) ? "" : "") + ConsoleColors.RESET);
}
}
/**
* Spawns a random enemy with randomized stats.
* Enemy types: Goblin, Skeleton, Vampire.
*/
private void spawnRandomEnemy() {
int enemyType = random.nextInt(3);
Enemy enemy;
switch (enemyType) {
case 0:
int goblinHP = 40 + random.nextInt(20);
int goblinMP = 15 + random.nextInt(10);
int goblinDamage = 8 + random.nextInt(5);
int goblinXP = 35 + random.nextInt(20);
enemy = new Goblin("Goblin", goblinHP, goblinMP, goblinDamage, goblinXP);
break;
case 1:
int skeletonHP = 50 + random.nextInt(20);
int skeletonMP = 20 + random.nextInt(10);
int skeletonDamage = 10 + random.nextInt(5);
int skeletonXP = 50 + random.nextInt(25);
enemy = new Skeleton("Skeleton", skeletonHP, skeletonMP, skeletonDamage, null, skeletonXP);
break;
case 2:
int vampireHP = 65 + random.nextInt(25);
int vampireMP = 40 + random.nextInt(15);
int vampireDamage = 15 + random.nextInt(5);
int vampireXP = 70 + random.nextInt(30);
enemy = new Vampire("Vampire", vampireHP, vampireMP, vampireDamage, null, vampireXP);
break;
default:
enemy = new Goblin();
}
currentLocation.addEnemy(enemy);
System.out.println(ConsoleColors.RED_BOLD + "💀 A wild " + enemy.getName() + " appears!" + ConsoleColors.RESET);
}
/**
* Checks if all 3 keys have been collected and unlocks the castle.
*/
private void checkCastleUnlock() {
if (!castleUnlocked && collectedKeys.size() >= 3) {
castleUnlocked = true;
System.out.println(ConsoleColors.YELLOW_BOLD + "🔓 The castle gates have opened!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN + "You have collected all 3 keys! You may now face the Dragon." + ConsoleColors.RESET);
}
}
/**
* Starts combat with the enemy at the current location.
*/
private void fightEnemy() {
if (!currentLocation.hasEnemies()) {
System.out.println(ConsoleColors.YELLOW + "There are no enemies here!" + ConsoleColors.RESET);
return;
}
Enemy enemy = currentLocation.getEnemies().get(0);
combatLoop(enemy);
}
/**
* Moves the player to a connected location.
*/
private void moveToLocation() {
List<Location> connections = currentLocation.getConnectedLocations();
if (connections.isEmpty()) {
System.out.println(ConsoleColors.YELLOW + "There's nowhere to go from here." + ConsoleColors.RESET);
return;
}
System.out.println("\n" + ConsoleColors.CYAN + "Available destinations:" + ConsoleColors.RESET);
for (int i = 0; i < connections.size(); i++) {
System.out.println((i + 1) + ". " + connections.get(i).getName());
}
System.out.println("0. Cancel");
try {
int choice = Integer.parseInt(scanner.nextLine().trim());
if (choice > 0 && choice <= connections.size()) {
currentLocation = connections.get(choice - 1);
System.out.println(ConsoleColors.GREEN + "You travel to " + currentLocation.getName() + "..." + ConsoleColors.RESET);
System.out.println();
}
} catch (NumberFormatException e) {
System.out.println(ConsoleColors.RED + "Invalid input." + ConsoleColors.RESET);
}
}
/**
* Opens the inventory menu for using consumable items.
*/
private void useInventory() {
if (inventory.isEmpty()) {
System.out.println(ConsoleColors.YELLOW + "Your inventory is empty." + ConsoleColors.RESET);
return;
}
System.out.println("\n" + ConsoleColors.CYAN_BOLD + "Inventory:" + ConsoleColors.RESET);
for (int i = 0; i < inventory.size(); i++) {
System.out.println((i + 1) + ". " + inventory.get(i).getName());
}
System.out.println("0. Cancel");
try {
int choice = Integer.parseInt(scanner.nextLine().trim());
if (choice > 0 && choice <= inventory.size()) {
Consumable item = inventory.remove(choice - 1);
item.use(player);
}
} catch (NumberFormatException e) {
System.out.println(ConsoleColors.RED + "Invalid input." + ConsoleColors.RESET);
}
}
/**
* Displays player status including stats, equipment, and key progress.
*/
private void displayStatus() {
System.out.println("\n" + ConsoleColors.YELLOW_BOLD + "=== Player Status ===" + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "Name: " + player.getName() + ConsoleColors.RESET);
System.out.println(ConsoleColors.YELLOW + "Level: " + player.getLevel() + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN + "HP: " + player.getHP() + "/" + player.getMaxHP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.BLUE + "MP: " + player.getMP() + "/" + player.getMaxMP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "Damage: " + player.getDamage() + ConsoleColors.RESET);
System.out.println(ConsoleColors.PURPLE + "Weapon: " + (player.getWeapon() != null ? player.getWeapon().getName() : "None") + ConsoleColors.RESET);
System.out.println("Inventory Items: " + inventory.size());
System.out.println("\n" + ConsoleColors.YELLOW_BOLD + "=== Keys Collected ===" + ConsoleColors.RESET);
System.out.println("Goblin Key: " + (collectedKeys.contains(Key.GOBLIN_KEY) ? "" : ""));
System.out.println("Skeleton Key: " + (collectedKeys.contains(Key.SKELETON_KEY) ? "" : ""));
System.out.println("Vampire Key: " + (collectedKeys.contains(Key.VAMPIRE_KEY) ? "" : ""));
System.out.println("Total: " + collectedKeys.size() + "/3");
System.out.println("Castle: " + (castleUnlocked ? "🔓 UNLOCKED" : "🔒 LOCKED"));
}
/**
* Turn-based combat loop.
*
* @param enemy The enemy being fought
*/
private void combatLoop(Enemy enemy) {
System.out.println("\n" + ConsoleColors.RED_BOLD + "⚔️ Combat with " + enemy.getName() + "!" + ConsoleColors.RESET);
while (enemy.isAlive() && player.isAlive()) {
// Show combat status
System.out.println("\n" + ConsoleColors.RED + enemy.getName() + " HP: " + enemy.getHP() + "/" + enemy.getMaxHP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN + "Your HP: " + player.getHP() + "/" + player.getMaxHP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.BLUE + "Your MP: " + player.getMP() + "/" + player.getMaxMP() + ConsoleColors.RESET);
// Player action menu
System.out.println("\n" + ConsoleColors.WHITE_BOLD + "Choose your action:" + ConsoleColors.RESET);
System.out.println("1. ⚔️ Light Attack");
System.out.println("2. 💥 Heavy Attack (8 MP)");
System.out.println("3. ✨ Special Ability");
System.out.println("4. 🛡️ Defend (5 MP)");
System.out.println("5. 💚 Heal (10 MP)");
System.out.println("6. 🎒 Use Item");
String choice = scanner.nextLine().trim();
// Execute player action
switch (choice) {
case "1":
player.lightAttack(enemy);
break;
case "2":
player.heavyAttack(enemy);
break;
case "3":
player.specialAbility(enemy);
break;
case "4":
player.defend();
break;
case "5":
player.heal();
break;
case "6":
useInventory();
break;
default:
System.out.println(ConsoleColors.RED + "Invalid choice." + ConsoleColors.RESET);
continue;
}
// Enemy turn
if (enemy.isAlive()) {
// Knight's Shield Bash stuns the enemy
if (player instanceof Knight && ((Knight) player).shouldStunEnemy()) {
enemy.stun();
((Knight) player).resetStun();
}
enemy.nextTurn();
enemy.attack(player);
} else {
handleEnemyDefeat(enemy);
break;
}
}
}
/**
* Processes enemy defeat: grants XP, handles key drops, and recovers health.
*
* @param enemy The defeated enemy
*/
private void handleEnemyDefeat(Enemy enemy) {
// Grant XP
int xpReward = enemy.getXPReward();
player.gainXP(xpReward);
System.out.println(ConsoleColors.YELLOW_BOLD + "🏆 Defeated " + enemy.getName() + "! Gained " + xpReward + " XP." + ConsoleColors.RESET);
// Remove enemy from location
currentLocation.removeEnemy(enemy);
// Key drop (20% chance)
Key key = getKeyForEnemy(enemy);
if (key != null && !collectedKeys.contains(key)) {
if (random.nextDouble() < 0.2) {
collectedKeys.add(key);
System.out.println(ConsoleColors.GREEN_BOLD + "🔑 You obtained the " + key.getDisplayName() + "!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.CYAN + "Keys collected: " + collectedKeys.size() + "/3" + ConsoleColors.RESET);
checkCastleUnlock();
} else {
System.out.println(ConsoleColors.YELLOW + "No key dropped this time." + ConsoleColors.RESET);
}
} else if (key != null && collectedKeys.contains(key)) {
System.out.println(ConsoleColors.YELLOW + "You already have the " + key.getDisplayName() + "." + ConsoleColors.RESET);
}
// Item drop (30% chance)
if (random.nextDouble() < 0.3) {
Consumable drop = random.nextBoolean() ? new Flask() : new ManaPotion();
inventory.add(drop);
System.out.println(ConsoleColors.GREEN_BOLD + "💎 " + enemy.getName() + " dropped a " + drop.getName() + "!" + ConsoleColors.RESET);
}
// Full recovery after battle
player.heal(player.getMaxHP());
player.fillMana(player.getMaxMP());
System.out.println(ConsoleColors.GREEN + "🔄 You recovered fully after battle!" + ConsoleColors.RESET);
}
/**
* Determines which key an enemy can drop based on its type.
*
* @param enemy The enemy to check
* @return The key type, or null if no key is dropped
*/
private Key getKeyForEnemy(Enemy enemy) {
if (enemy instanceof Goblin) {
return Key.GOBLIN_KEY;
} else if (enemy instanceof Skeleton) {
return Key.SKELETON_KEY;
} else if (enemy instanceof Vampire) {
return Key.VAMPIRE_KEY;
}
return null;
}
/**
* Final boss battle against the Dragon.
* Only accessible after collecting all 3 keys.
*/
private void fightDragon() {
if (!castleUnlocked) {
System.out.println(ConsoleColors.RED + "The castle is locked! You need all 3 keys." + ConsoleColors.RESET);
return;
}
Dragon dragon = new Dragon("Ember, the Ancient Dragon", 300, 120, 35, null, 800);
System.out.println(ConsoleColors.RED_BOLD + "🐉 THE DRAGON EMERGES FROM THE CASTLE!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "Ember roars: 'You dare challenge me, mortal?'" + ConsoleColors.RESET);
System.out.println(ConsoleColors.YELLOW + "This is the final battle!" + ConsoleColors.RESET);
while (dragon.isAlive() && player.isAlive()) {
System.out.println("\n" + ConsoleColors.RED_BOLD + "🐉 DRAGON BOSS FIGHT!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "Dragon HP: " + dragon.getHP() + "/" + dragon.getMaxHP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN + "Your HP: " + player.getHP() + "/" + player.getMaxHP() + ConsoleColors.RESET);
System.out.println(ConsoleColors.BLUE + "Your MP: " + player.getMP() + "/" + player.getMaxMP() + ConsoleColors.RESET);
if (dragon.isEnraged()) {
System.out.println(ConsoleColors.RED_BOLD + "🔥 The Dragon is ENRAGED!" + ConsoleColors.RESET);
}
System.out.println("\n" + ConsoleColors.WHITE_BOLD + "Choose your action:" + ConsoleColors.RESET);
System.out.println("1. ⚔️ Light Attack");
System.out.println("2. 💥 Heavy Attack (8 MP)");
System.out.println("3. ✨ Special Ability");
System.out.println("4. 🛡️ Defend (5 MP)");
System.out.println("5. 💚 Heal (10 MP)");
System.out.println("6. 🎒 Use Item");
String choice = scanner.nextLine().trim();
switch (choice) {
case "1":
player.lightAttack(dragon);
break;
case "2":
player.heavyAttack(dragon);
break;
case "3":
player.specialAbility(dragon);
break;
case "4":
player.defend();
break;
case "5":
player.heal();
break;
case "6":
useInventory();
break;
default:
System.out.println(ConsoleColors.RED + "Invalid choice." + ConsoleColors.RESET);
continue;
}
// Dragon's turn
if (dragon.isAlive()) {
if (player instanceof Knight && ((Knight) player).shouldStunEnemy()) {
dragon.stun();
((Knight) player).resetStun();
}
dragon.nextTurn();
dragon.attack(player);
} else {
dragonDefeated = true;
System.out.println(ConsoleColors.YELLOW_BOLD + "🏆 YOU HAVE DEFEATED THE DRAGON!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.GREEN_BOLD + "🎉 The curse is broken! The land is saved!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.YELLOW + "You are a true hero!" + ConsoleColors.RESET);
}
}
if (!player.isAlive()) {
System.out.println(ConsoleColors.RED_BOLD + "💀 The Dragon has defeated you!" + ConsoleColors.RESET);
System.out.println(ConsoleColors.RED + "Game Over!" + ConsoleColors.RESET);
}
}
// Getters
public Player getPlayer() {
return player;
}
public Location getCurrentLocation() {
return currentLocation;
}
public Set<Key> getCollectedKeys() {
return collectedKeys;
}
public boolean isCastleUnlocked() {
return castleUnlocked;
}
}
@@ -0,0 +1,17 @@
package org.project.game;
public enum Key {
GOBLIN_KEY("Goblin Key"),
SKELETON_KEY("Skeleton Key"),
VAMPIRE_KEY("Vampire Key");
private final String displayName;
Key(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
}
@@ -2,10 +2,25 @@ package org.project.item;
import org.project.entity.Entity;
public interface Item {
void use(Entity target);
public abstract class Item {
protected String name;
protected int value;
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
public Item(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
@Override
public String toString() {
return name;
}
}
@@ -1,42 +1,17 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Armor {
private int defense;
private int maxDefense;
private int durability;
private int maxDurability;
import org.project.item.Item;
private boolean isBroke;
public abstract class Armor extends Item {
public Armor(int defense, int durability) {
protected int defense;
public Armor(String name, int defense, int value) {
super(name, value);
this.defense = defense;
this.durability = durability;
}
public void checkBreak() {
if (durability <= 0) {
isBroke = true;
defense = 0;
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
public void repair() {
isBroke = false;
defense = maxDefense;
durability = maxDurability;
}
public int getDefense() {
return defense;
}
public int getDurability() {
return durability;
}
public boolean isBroke() {
return isBroke;
}
}
}
@@ -0,0 +1,8 @@
package org.project.item.armors;
public class AssassinArmor extends Armor {
public AssassinArmor() {
super("Shadow Armor", 8, 145);
}
}
@@ -1,6 +1,8 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public class KnightArmor {
// TODO: DESIGN ARMOR'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
public class KnightArmor extends Armor {
public KnightArmor() {
super("Knight Armor", 12, 150);
}
}
@@ -0,0 +1,8 @@
package org.project.item.armors;
public class WizardArmor extends Armor {
public WizardArmor() {
super("Wizard Robe", 6, 140);
}
}
@@ -1,8 +1,10 @@
package org.project.item.consumables;
import org.project.entity.players.Player;
import org.project.item.Item;
// TODO: UPDATE IMPLEMENTATION
public abstract class Consumable {
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
public abstract class Consumable extends Item{
public Consumable(String name, int value) {
super(name, value);
}
public abstract void use(Player player); }
@@ -1,16 +1,19 @@
package org.project.item.consumables;
import org.project.entity.Entity;
import org.project.entity.players.Player;
import org.project.utils.ConsoleColors;
// TODO: UPDATE IMPLEMENTATION
public class Flask {
/*
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
*/
public class Flask extends Consumable {
private final int healAmount = 30;
// TODO: UPDATE USE METHOD
@Override
public void use(Entity target) {
target.heal(target.getMaxHP() / 10);
public Flask() {
super("Healing Flask", 40);
}
}
@Override
public void use(Player player) {
player.heal(healAmount);
System.out.println(ConsoleColors.GREEN + player.getName() +
" recovered " + healAmount + " HP." + ConsoleColors.RESET);
}
}
@@ -0,0 +1,19 @@
package org.project.item.consumables;
import org.project.entity.players.Player;
import org.project.utils.ConsoleColors;
public class ManaPotion extends Consumable {
private final int mana = 30;
public ManaPotion() {
super("Mana Potion", 45);
}
@Override
public void use(Player player) {
player.fillMana(mana);
System.out.println(ConsoleColors.BLUE + player.getName() +
" recovered " + mana + " Mana." + ConsoleColors.RESET);
}
}
@@ -0,0 +1,7 @@
package org.project.item.weapons;
public class Dagger extends Weapon{
public Dagger() {
super("Dagger", 7, 80);
}
}
@@ -0,0 +1,7 @@
package org.project.item.weapons;
public class Staff extends Weapon {
public Staff() {
super("Magic Staff", 8, 120);
}
}
@@ -5,22 +5,12 @@ import org.project.entity.Entity;
import java.util.ArrayList;
// TODO: UPDATE IMPLEMENTATION
public class Sword {
public class Sword extends Weapon {
/*
THIS IS AN EXAMPLE OF A WEAPON DESIGN.
*/
int abilityCharge;
public Sword() {
// TODO: DESIGN SWORD'S ATTRIBUTES IMPLEMENT THE CONSTRUCTOR
}
// TODO: (BONUS) UPDATE THE UNIQUE ABILITY
public void uniqueAbility(ArrayList<Entity> targets) {
abilityCharge += 2;
for (Entity target : targets) {
target.takeDamage(getDamage());
public Sword() {
super("Sword", 10, 100);
}
}
}
@@ -1,35 +1,18 @@
package org.project.item.weapons;
import org.project.entity.Entity;
import org.project.item.Item;
// TODO: UPDATE IMPLEMENTATION
public abstract class Weapon {
private int damage;
private int manaCost;
public abstract class Weapon extends Item {
protected int damage;
/*
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
*/
public Weapon(int damage, int manaCost) {
public Weapon(String name, int damage, int value) {
super(name, value);
this.damage = damage;
this.manaCost = manaCost;
}
@Override
public void use(Entity target) {
target.takeDamage(damage);
}
public int getDamage() {
return damage;
}
public int getManaCost() {
return manaCost;
}
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
@@ -1,28 +1,56 @@
package org.project.location;
import org.project.entity.enemies.Enemy;
import java.util.ArrayList;
import java.util.List;
public class Location {
private String name;
private String description;
private List<Location> connectedLocations;
private List<Enemy> enemies;
private ArrayList<Enemy> enemies;
public Location(String name, String description) {
this.name = name;
this.description = description;
this.connectedLocations = new ArrayList<>();
this.enemies = new ArrayList<>();
}
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) {
this.locations = locations;
this.enemies = enemies;
public Location(String name, String description, List<Enemy> enemies) {
this(name, description);
this.enemies = enemies != null ? enemies : new ArrayList<>();
}
public String getName() {
return name;
}
public ArrayList<Location> getLocations() {
return locations;
public String getDescription() {
return description;
}
public ArrayList<Enemy> getEnemies() {
public List<Location> getConnectedLocations() {
return connectedLocations;
}
public void addConnectedLocation(Location location) {
connectedLocations.add(location);
}
public List<Enemy> getEnemies() {
return enemies;
}
}
public void addEnemy(Enemy enemy) {
enemies.add(enemy);
}
public void removeEnemy(Enemy enemy) {
enemies.remove(enemy);
}
public boolean hasEnemies() {
return !enemies.isEmpty();
}
}
@@ -0,0 +1,55 @@
package org.project.utils;
/**
* ConsoleColors - Utility class for ANSI color codes
* provides colorful console output
*/
public class ConsoleColors {
// Reset
public static final String RESET = "\u001B[0m";
// Regular Colors
public static final String BLACK = "\u001B[30m";
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 final String WHITE = "\u001B[37m";
// Bold
public static final String BLACK_BOLD = "\u001B[1;30m";
public static final String RED_BOLD = "\u001B[1;31m";
public static final String GREEN_BOLD = "\u001B[1;32m";
public static final String YELLOW_BOLD = "\u001B[1;33m";
public static final String BLUE_BOLD = "\u001B[1;34m";
public static final String PURPLE_BOLD = "\u001B[1;35m";
public static final String CYAN_BOLD = "\u001B[1;36m";
public static final String WHITE_BOLD = "\u001B[1;37m";
// Background
public static final String BLACK_BACKGROUND = "\u001B[40m";
public static final String RED_BACKGROUND = "\u001B[41m";
public static final String GREEN_BACKGROUND = "\u001B[42m";
public static final String YELLOW_BACKGROUND = "\u001B[43m";
public static final String BLUE_BACKGROUND = "\u001B[44m";
public static final String PURPLE_BACKGROUND = "\u001B[45m";
public static final String CYAN_BACKGROUND = "\u001B[46m";
public static final String WHITE_BACKGROUND = "\u001B[47m";
// High Intensity
public static final String RED_BRIGHT = "\u001B[91m";
public static final String GREEN_BRIGHT = "\u001B[92m";
public static final String YELLOW_BRIGHT = "\u001B[93m";
public static final String BLUE_BRIGHT = "\u001B[94m";
public static final String PURPLE_BRIGHT = "\u001B[95m";
public static final String CYAN_BRIGHT = "\u001B[96m";
public static final String WHITE_BRIGHT = "\u001B[97m";
// Special
public static final String BOLD = "\u001B[1m";
public static final String ITALIC = "\u001B[3m";
public static final String UNDERLINE = "\u001B[4m";
public static final String BLINK = "\u001B[5m";
}
Binary file not shown.