Implementation of JAVA-Knight is complete
This commit is contained in:
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user