Assignment-4

This commit is contained in:
2026-05-20 23:25:48 +03:30
parent 78d4bedb08
commit 7edb9ecee9
27 changed files with 1530 additions and 153 deletions
+617 -6
View File
@@ -1,15 +1,626 @@
package org.project;
import org.project.entity.players.*;
import org.project.entity.enemies.*;
import org.project.location.Location;
import org.project.item.armors.*;
import org.project.item.weapons.*;
import org.project.item.Item;
import org.project.item.consumables.Flask;
import org.project.item.consumables.StaminaPotion;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
public class Main {
public static void main(String[] args) {
// TODO: ADD LOCATIONS TO YOUR GAME
List<Location> locations = new ArrayList<>();
// TODO: IMPLEMENT GAMEPLAY
private static final String RESET = "\033[0m"; // Text Reset
private static final String GREEN = "\033[0;32m"; // HP / Healing
private static final String BLUE = "\033[0;34m"; // Stamina
private static final String RED = "\033[0;31m"; // Enemies
private static final String YELLOW = "\033[0;33m"; // Coins / XP
private static final String PURPLE = "\033[0;35m"; // Events
private static final String CYAN = "\033[0;36m"; // Locations
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Random random = new Random();
ArrayList<Enemy> forestEnemies = new ArrayList<>();
Location forest = new Location("The Dark Forest", forestEnemies);
ArrayList<Enemy> graveyardEnemies = new ArrayList<>();
Location graveyard = new Location("The Forsaken Graveyard", graveyardEnemies);
ArrayList<Enemy> cryptEnemies = new ArrayList<>();
Location crypt = new Location("The Blood Crypt", cryptEnemies);
Location[] standardLocations = {forest, graveyard, crypt};
Enemy dragon = new Dragon(new Flame("Flame", 60, 10));
System.out.println("\n" + PURPLE + "=== WELCOME TO THE GRIM REALM ===" + RESET);
System.out.println("Choose Your Character:");
System.out.println("1. Knight | 2. Assassin | 3. Wizard");
String choice = scanner.nextLine();
System.out.print("Enter Your Hero's Name: ");
String name = scanner.nextLine();
Player player = null;
switch (choice) {
case "1":
player = new Knight(name, new Sword("Sword", 40, 5), new KnightArmor("Knight Plate", 30));
break;
case "2":
player = new Assassin(name, new HiddenBlade("Hidden Blade", 30, 5), new AssassinArmor("Assassin Plate", 30));
break;
case "3":
player = new Wizard(name, new Staff("Staff", 20, 5), new WizardArmor("Wizard Plate", 30));
break;
default:
System.out.println("Invalid Choice.");
}
boolean playing = true;
String currentState = "CAMP";
while (playing && player.isAlive()) {
switch (currentState) {
case "CAMP":
player.fillStats();
System.out.println("\n" + CYAN + "=== CAMP ===" + RESET);
System.out.println("HP: " + GREEN + player.getHP() + "/" + player.getMaxHP() + RESET + " | " +
"Stamina: " + BLUE + player.getStamina() + "/" + player.getMaxStamina() + RESET);
System.out.println("Level: " + player.getLevel() + " | Coins: " + YELLOW + player.getCoins() + RESET + "\n");
System.out.println("1. Step Into The Portal");
System.out.println("2. Visit The Merchant");
System.out.println("3. Rest By The Fire (Quit Game)");
String hubChoice = scanner.nextLine();
switch (hubChoice) {
case "1":
System.out.println("\n" + PURPLE + "The Portal Swirls." + RESET + " Where To?");
System.out.println("1. Hunt The Dragon's Minions (Random Location)");
System.out.println("2. Challenge The Dragon (The Castle)");
String portalChoice = scanner.nextLine();
switch (portalChoice) {
case "1":
currentState = "RANDOM";
break;
case "2":
currentState = "CASTLE";
break;
default:
System.out.println("Invalid Choice.");
}
break;
case "2":
visitMerchant(player, scanner);
break;
case "3":
System.out.println(PURPLE + "You Rest By The Fire. Game Saved." + RESET);
playing = false;
break;
default:
System.out.println("Invalid Choice.");
}
break;
case "RANDOM":
Location currentLoc = standardLocations[random.nextInt(standardLocations.length)];
Enemy areaEnemy = null;
if (currentLoc.getName().contains("Forest")) {
areaEnemy = new Goblin(new Dagger("Dagger", 20, 5));
} else if (currentLoc.getName().contains("Graveyard")) {
areaEnemy = new Skeleton(new Sword("Dagger", 20, 5));
} else if (currentLoc.getName().contains("Crypt")) {
areaEnemy = new Vampire(new Sword("Dagger", 20, 5));
}
System.out.println("\n" + PURPLE + "You Get Out Of The Portal..." + RESET);
System.out.println("You Find Yourself In " + CYAN + currentLoc.getName() + RESET + ".");
System.out.println("A " + RED + areaEnemy.getName() + RESET + " Is Lurking In The Shadows!");
System.out.println("\nWhat Will You Do?");
System.out.println("1. Fight The " + areaEnemy.getName());
System.out.println("2. Step Back Into The Portal (Teleport Elsewhere)");
String portalChoice = scanner.nextLine();
switch (portalChoice) {
case "1":
battle(player, areaEnemy, scanner);
if (!player.isAlive()) {
System.out.println(RED + "\nYOU DIED." + RESET + " Your Soul Remains In The Grim Realm...");
playing = false;
}
System.out.println("\nWhat Will You Do Now?");
System.out.println("1. Continue Hunting The Enemies");
System.out.println("2. Get Back To Camp To Recover");
String victoryChoice = scanner.nextLine();
switch (victoryChoice) {
case "1":
currentState = "RANDOM";
break;
case "2":
currentState = "CAMP";
break;
default:
System.out.println("Invalid Choice.");
}
break;
case "2":
System.out.println("\n" + PURPLE + "The Portal Swirls." + RESET + " Where To?");
System.out.println("1. Hunt The Dragon's Minions (Random Location)");
System.out.println("2. Return To The Camp");
String portalChoice1 = scanner.nextLine();
switch (portalChoice1) {
case "1":
currentState = "RANDOM";
break;
case "2":
currentState = "CAMP";
break;
default:
System.out.println("Invalid Choice.");
}
break;
default:
System.out.println("Invalid Choice.");
}
break;
case "CASTLE":
System.out.println("\nYou Stand Before The Massive Gates Of The Castle.");
if (player.getInventory().hasAllKeys()) {
System.out.println("The Three Keys React To The Dark Magic." + PURPLE + " The Gate Opens!" + RESET);
player.setCanDefend(false);
battle(player, dragon, scanner);
player.setCanDefend(true);
playing = false;
} else {
System.out.println("You Must Have All 3 Keys To Open The Gates.");
System.out.println("\n" + PURPLE + "The Portal Behind You Swirls." + RESET + " Where To?");
System.out.println("1. Hunt The Dragon's Minions (Find The Missing Keys)");
System.out.println("2. Return To Camp");
String castleChoice = scanner.nextLine();
switch (castleChoice) {
case "1":
currentState = "RANDOM";
break;
case "2":
currentState = "CAMP";
break;
default:
System.out.println("Invalid Choice.");
}
}
break;
}
}
}
private static void battle(Player player, Enemy enemy, Scanner scanner) {
System.out.println("\n" + ">>>" + PURPLE + " BATTLE STARTED: " + GREEN + player.getName() + RESET + " VS " + RED + enemy.getName() + RESET + " <<<");
boolean isPlayerTurn = true;
while (player.isAlive() && enemy.isAlive()) {
if (isPlayerTurn) {
boolean actionTaken = false;
while (!actionTaken && player.isAlive()) {
if(!player.isStunned()) {
System.out.println("\n--- YOUR TURN ---");
System.out.println("HP: " + GREEN + player.getHP() + RESET + " | Stamina: " + BLUE + player.getStamina() + RESET +
" |" + PURPLE + "VS" + RESET + "| " +
"Enemy HP: " + RED + enemy.getHP() + RESET + " | " + "Enemy Stamina: " + BLUE + enemy.getStamina() + RESET);
System.out.println("1. Light Attack (" + BLUE + "0" + RESET + ") | " +
"2. Heavy Attack (" + BLUE + player.getWeapon().getStaminaCost() + RESET + ") | " +
"3. Defend (" + BLUE + "5" + RESET + ") | " +
"4. Special (" + BLUE + "20" + RESET + ") | " +
"5. " + YELLOW + "Use Healing Potion" + RESET + " (" + BLUE + "0" + RESET + ") | " +
"6. " + YELLOW + "Use Stamina Potion" + RESET + " (" + BLUE + "0" + RESET + ")");
// Removed Healing By Using Stamina Since It Didn't Really Make Sense.
String choice = scanner.nextLine();
switch (choice) {
case "1":
player.lightAttack(enemy);
actionTaken = true;
break;
case "2":
player.heavyAttack(enemy);
actionTaken = true;
break;
case "3":
player.defend();
actionTaken = true;
break;
case "4":
player.specialAbility(enemy);
actionTaken = true;
break;
case "5":
Item healingFlask = player.getInventory().getMiscItemByName("Healing Flask");
if (healingFlask == null || healingFlask.getQuantity() <= 0) {
System.out.println("You Don't Have Any Healing Flasks Left!");
break;
}
healingFlask.use(player);
break;
case "6":
Item staminaPotion = player.getInventory().getMiscItemByName("Stamina");
if (staminaPotion == null || staminaPotion.getQuantity() <= 0) {
System.out.println("You Don't Have Any Stamina Potions Left!");
break;
}
staminaPotion.use(player);
break;
default: System.out.println("Invalid Selection.");
}
} else {
System.out.println("\n" + PURPLE + "You Are Stunned And Skip Your Turn!" + RESET);
actionTaken = true;
player.setStunned(false);
}
}
isPlayerTurn = false;
} else {
if (!enemy.isStunned()) {
System.out.println("\n--- ENEMY TURN ---");
int enemyMove = enemy.choice();
System.out.println(enemyMove);
switch (enemyMove) {
case 1:
enemy.lightAttack(player);
break;
case 2:
enemy.heavyAttack(player);
break;
case 3:
enemy.defend();
break;
case 4: // Dragon's Special Ability Which Stuns The Player
player.takeDamage(80, enemy);
player.setStunned(true);
System.out.println("The Dragon Has Stunned You!");
break;
}
} else {
System.out.println("\n" + PURPLE + "The Enemy Is Stunned And Skips Their Turn!" + RESET);
enemy.setStunned(false);
}
isPlayerTurn = true;
}
}
if (!enemy.isAlive()) {
handleVictory(player, enemy);
}
}
private static void handleVictory(Player player, Enemy enemy) {
System.out.println("\n" + GREEN + "--- VICTORY! ---" + RESET);
player.addCoins(enemy.getCoinReward());
if (!(enemy instanceof Dragon)) {
if (enemy.hasKey()) {
if (enemy instanceof Goblin && !player.hasGoblinKey()) {
player.findGoblinKey();
} else if (enemy instanceof Skeleton && !player.hasSkeletonKey()) {
player.findSkeletonKey();
} else if (enemy instanceof Vampire && !player.hasVampireKey()) {
player.findVampireKey();
}
} else {
System.out.println("The Enemy Had No Keys With Him.");
}
player.gainXP(enemy.getXpReward());
} else {
System.out.println(PURPLE + "THE DRAGON DESCENDS!" + RESET);
}
}
private static void visitMerchant(Player player, Scanner scanner) {
boolean inShop = true;
ArrayList<Weapon> weaponsForSale = new ArrayList<>();
ArrayList<Integer> weaponPrice = new ArrayList<>();
ArrayList<Armor> armorsForSale = new ArrayList<>();
ArrayList<Integer> armorPrice = new ArrayList<>();
// You Can Add Multiple Armors And Weapons Here
if (player instanceof Knight) {
weaponsForSale.add(new Sword("GreatSword", 50, 0));
weaponPrice.add(100);
armorsForSale.add(new KnightArmor("Templar Plate", 70));
armorPrice.add(200);
} else if (player instanceof Assassin) {
weaponsForSale.add(new HiddenBlade("Dual Hidden Blades", 40, 0));
weaponPrice.add(100);
armorsForSale.add(new KnightArmor("Master Assassin Plate", 70));
armorPrice.add(200);
} else if (player instanceof Wizard) {
weaponsForSale.add(new Staff("GreatStaff", 30, 0));
weaponPrice.add(100);
armorsForSale.add(new KnightArmor("Magician Plate", 70));
armorPrice.add(200);
}
Item healingPotion = new Flask(3);
int healingPotionPrice = 20;
Item staminaPotion = new StaminaPotion(3);
int staminaPotionPrice = 10;
System.out.println("\nWelcome, Stranger!");
while (inShop) {
System.out.println("\n" + CYAN + "=== MERCHANT SHOP ===" + RESET);
System.out.println("1. View and Buy Equipment");
System.out.println("2. Manage Equipment");
System.out.println("0. Exit Shop");
String choice = scanner.nextLine();
switch (choice) {
case "1":
boolean viewingWares = true;
while (viewingWares) {
System.out.println("\n" + PURPLE + "=== FOR SALE ===" + RESET);
System.out.println("Your Coins: " + YELLOW + player.getCoins() + RESET);
System.out.println("1. Weapons");
System.out.println("2. Armors");
System.out.println("3. " + healingPotion.getName() + " (" + healingPotion.getQuantity() + ") " + " - " + YELLOW + healingPotionPrice + RESET + " Coins");
System.out.println("4. " + staminaPotion.getName() + " (" + healingPotion.getQuantity() + ") " + " - " + YELLOW + staminaPotionPrice + RESET + " Coins");
System.out.println("0. Back To Main Shop Menu");
System.out.println("\nEnter Item Number:");
String buyChoice = scanner.nextLine();
switch (buyChoice) {
case "1":
boolean buyingWeapons = true;
while (buyingWeapons) {
for (int i = 0; i < weaponsForSale.size(); i++) {
System.out.println((i + 1) + ". " + weaponsForSale.get(i).getName() + " (Damage: " + weaponsForSale.get(i).getDamage() + ")" + " - " + YELLOW + weaponPrice.get(i) + " Coins" + RESET);
}
System.out.println("0. Back To Buy Menu");
String weaponChoice = scanner.nextLine();
try {
int weaponIdx = Integer.parseInt(weaponChoice) - 1;
if (weaponIdx == -1) {
buyingWeapons = false;
} else if (weaponIdx >= 0 && weaponIdx < weaponsForSale.size()) {
Weapon selectedWeapon = weaponsForSale.get(weaponIdx);
int price = weaponPrice.get(weaponIdx);
if (player.getCoins() >= price) {
player.spendCoins(price);
player.getInventory().addWeapon(selectedWeapon);
System.out.println(GREEN + "Bought " + selectedWeapon.getName() + "!" + RESET);
weaponsForSale.remove(weaponIdx);
weaponPrice.remove(weaponIdx);
} else {
System.out.println(RED + "Not Enough Coins!" + RESET);
}
} else if (weaponIdx != -1) {
System.out.println("Invalid Weapon Selection.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid Selection.");
}
}
break;
case "2":
boolean buyingArmors = true;
while (buyingArmors) {
for (int i = 0; i < armorsForSale.size(); i++) {
System.out.println((i + 1) + ". " + armorsForSale.get(i).getName() + " (Defense: " + armorsForSale.get(i).getDefense() + ")" + " - " + YELLOW + armorPrice.get(i) + " Coins" + RESET);
}
System.out.println("0. Back To Buy Menu");
String armorChoice = scanner.nextLine();
try {
int armorIdx = Integer.parseInt(armorChoice) - 1;
if (armorIdx == -1) {
buyingArmors = false;
} else if (armorIdx >= 0 && armorIdx < armorsForSale.size()) {
Armor selectedArmor = armorsForSale.get(armorIdx);
int price = armorPrice.get(armorIdx);
if (player.getCoins() >= price) {
player.spendCoins(price);
player.getInventory().addArmor(selectedArmor);
System.out.println(GREEN + "Bought " + selectedArmor.getName() + "!" + RESET);
armorsForSale.remove(armorIdx);
armorPrice.remove(armorIdx);
} else {
System.out.println(RED + "Not Enough Coins!" + RESET);
}
} else if (armorIdx != -1) {
System.out.println("Invalid Armor Selection.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid Selection.");
}
}
break;
case "3":
if (player.getCoins() >= healingPotionPrice) {
player.spendCoins(healingPotionPrice);
player.getInventory().addMiscItem(healingPotion);
System.out.println(GREEN + "Bought " + healingPotion.getName() + "!" + RESET);
} else {
System.out.println(RED + "Not Enough Coins!" + RESET);
}
break;
case "4":
if (player.getCoins() >= staminaPotionPrice) {
player.spendCoins(staminaPotionPrice);
player.getInventory().addMiscItem(staminaPotion);
System.out.println(GREEN + "Bought " + staminaPotion.getName() + "!" + RESET);
} else {
System.out.println(RED + "Not Enough Coins!" + RESET);
}
break;
case "0":
viewingWares = false;
break;
default:
System.out.println("Invalid Selection.");
}
}
break;
case "2":
boolean managing = true;
while (managing) {
System.out.println("\n" + PURPLE + "=== MANAGE EQUIPMENT ===" + RESET);
System.out.println("1. Weapons");
System.out.println("2. Armors");
System.out.println("3. View Inventory");
System.out.println("0. Back To Main Shop Menu");
String manageChoice = scanner.nextLine();
switch (manageChoice) {
case "1":
boolean choosingWeapon = true;
while (choosingWeapon) {
System.out.println("\n--- Your Weapons ---");
for (int i = 0; i < player.getInventory().getWeapons().size(); i++) {
Weapon w = player.getInventory().getWeapons().get(i);
String equipped = (w == player.getWeapon()) ? GREEN + " (Equipped)" + RESET : "";
System.out.println((i + 1) + ". " + w.getName() + " (Damage: " + w.getDamage() + ")" + equipped);
}
System.out.println("0. Back To Equipment Menu");
System.out.println("\nEnter Number Of Weapon To Equip:");
try {
int eqW = Integer.parseInt(scanner.nextLine());
if (eqW == 0) {
choosingWeapon = false;
} else if (eqW > 0 && eqW <= player.getInventory().getWeapons().size()) {
player.equipWeapon(eqW - 1);
} else {
System.out.println("Invalid Selection.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid Selection.");
}
}
break;
case "2":
boolean choosingArmor = true;
while (choosingArmor) {
System.out.println("\n--- Your Armors ---");
for (int i = 0; i < player.getInventory().getArmors().size(); i++) {
Armor a = player.getInventory().getArmors().get(i);
String equipped = (a == player.getArmor()) ? GREEN + " (Equipped)" + RESET : "";
System.out.println((i + 1) + ". " + a.getName() + " (Defense: " + a.getDefense() +" | Durability: " + a.getDurability() + ")" + equipped);
}
System.out.println("0. Back To Equipment Menu");
System.out.println("\nEnter Number Of Armor To Equip And Repair If Needed:");
try {
int eqA = Integer.parseInt(scanner.nextLine());
if (eqA == 0) {
choosingArmor = false;
} else if (eqA > 0 && eqA <= player.getInventory().getArmors().size()) {
Armor selectedArmor = player.getInventory().getArmors().get(eqA - 1);
if (selectedArmor.getDurability() < 100) {
if (player.getCoins() > 20) {
selectedArmor.repair();
player.spendCoins(20);
} else {
System.out.println(RED + "Not Enough Coins!" + RESET);
}
}
player.equipArmor(eqA - 1);
} else {
System.out.println("Invalid Selection.");
}
} catch (NumberFormatException e) {
System.out.println("Invalid Selection.");
}
}
break;
case"3":
boolean viewingPotions = true;
while (viewingPotions) {
System.out.println("\n--- Your Items ---");
player.getInventory().showMiscItems();
System.out.println("0. Back To Equipment Menu");
String potionChoice = scanner.nextLine();
if (potionChoice.equals("0")) {
viewingPotions = false;
} else {
System.out.println("Invalid Selection.");
}
}
break;
case "0":
managing = false;
break;
default:
System.out.println("Invalid Selection.");
}
}
break;
case "0":
System.out.println("Come Back Anytime.");
inShop = false;
break;
default:
System.out.println("Invalid Selection.");
}
}
}
}
@@ -1,21 +1,37 @@
package org.project.entity;
public interface Entity {
void attack(Entity target);
void lightAttack(Entity target);
void heavyAttack(Entity target);
void defend();
void heal(int health);
void fillMana(int mana);
void takeDamage(int damage, Entity attacker);
void takeDamage(int damage);
void fillHealth(int health);
void fillStamina(int stamina);
boolean spendStamina(int cost);
boolean isAlive();
boolean isDefending();
boolean isStunned();
void setStunned(boolean status);
String getName();
int getHP();
int getMaxHP();
int getMaxMP();
int getStamina();
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
int getMaxStamina();
}
@@ -0,0 +1,32 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
public class Dragon extends Enemy {
public Dragon(Weapon weapon) {
super("Furious Dragon", 300, 100, weapon, 0.0);
this.xpReward = 200;
this.coinReward = 150;
}
@Override
public int choice() {
double roll = Math.random();
if (this.getStamina() >= 30) {
if (roll < 0.3) {return 1;}
else if (roll < 0.7) {return 2;}
else if (roll < 0.8) {return 3;}
else {return 4;}
} else if (this.getStamina() >= this.weapon.getStaminaCost()) {
if (roll < 0.4) {return 1;}
else if (roll < 0.9) {return 2;}
else {return 3;}
} else {
return 1;
}
}
}
@@ -1,34 +1,154 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
// TODO: UPDATE IMPLEMENTATION
public abstract class Enemy {
Weapon weapon;
private int hp;
private int mp;
public abstract class Enemy implements Entity {
protected String name;
protected int hp;
protected int maxHP;
protected int stamina;
protected int maxStamina;
public Enemy(int hp, int mp, Weapon weapon) {
protected int xpReward;
protected int coinReward;
protected boolean hasKey;
protected boolean isDefending = false;
protected boolean isStunned = false;
protected Weapon weapon;
public Enemy(String name, int hp, int stamina, Weapon weapon, double keyChance) {
this.name = name;
this.hp = hp;
this.mp = mp;
this.maxHP = hp;
this.stamina = stamina;
this.maxStamina = stamina;
this.weapon = weapon;
this.hasKey = Math.random() < keyChance;
}
public boolean isDefending() {
return isDefending;
}
public boolean isStunned() {
return isStunned;
}
public void setStunned(boolean status) {
this.isStunned = status;
}
public boolean hasKey() {
return hasKey;
}
@Override
public void takeDamage(int damage) {
hp -= damage;
public void lightAttack(Entity target) {
target.takeDamage(20, this);
System.out.println(name + " Performs a Light Attack!");
}
public int getHp() {
@Override
public void heavyAttack(Entity target) {
if (spendStamina(weapon.getStaminaCost())) {
target.takeDamage(weapon.getDamage(), this);
System.out.println(name + " Performs a Heavy Attack!");
}
}
@Override
public void defend() {
if (spendStamina(5)) {
this.isDefending = true;
System.out.println(name + " Gets Ready To Block Your Attack...");
}
}
@Override
public void heal(int health) {
if (spendStamina(10)) {
this.hp = Math.min(maxHP, this.hp + health);
System.out.println(name + " Healed " + health + " HP!");
}
}
public abstract int choice();
@Override
public void takeDamage(int damage, Entity attacker) {
if (this.isDefending) {
if (!attacker.isDefending()) {
System.out.println(name + " Defended Your Attack!");
}
this.isDefending = false;
return;
}
this.hp = Math.max(0, this.hp - damage);
}
@Override
public void fillHealth(int health) {
this.hp = Math.min(maxHP, this.hp + health);
}
@Override
public void fillStamina(int stamina) {
this.stamina = Math.min(maxStamina, this.stamina + stamina);
}
@Override
public boolean spendStamina(int cost) {
if (this.stamina >= cost) {
this.stamina -= cost;
return true;
}
System.out.println(name + " Doesn't Have Enough Stamina!");
return false;
}
@Override
public boolean isAlive() {
return this.hp > 0;
}
@Override
public String getName() {
return name;
}
@Override
public int getHP() {
return hp;
}
public int getMp() {
return mp;
@Override
public int getMaxHP() {
return maxHP;
}
public int getStamina() {
return stamina;
}
@Override
public int getMaxStamina() {
return maxStamina;
}
public Weapon getWeapon() {
return weapon;
}
public int getXpReward() {
return xpReward;
}
public int getCoinReward() {
return coinReward;
}
}
@@ -0,0 +1,28 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.item.Item;
public class Goblin extends Enemy {
public Goblin(Weapon weapon) {
super("Goblin", 140, 40, weapon, 0.3);
this.xpReward = 80;
this.coinReward = 10;
}
@Override
public int choice() {
double roll = Math.random();
if (this.getStamina() >= this.weapon.getStaminaCost()) {
if (roll < 0.2) {return 1;}
else if (roll < 0.8) {return 2;}
else {return 3;}
} else {
return 1;
}
}
}
@@ -1,6 +1,39 @@
package org.project.entity.enemies;
// TODO: UPDATE IMPLEMENTATION
public class Skeleton {
// TODO: DESIGN ENEMY AND IMPLEMENT THE CONSTRUCTOR
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
public class Skeleton extends Enemy {
private boolean hasResurrected = false;
public Skeleton(Weapon weapon) {
super("Skeleton", 160, 20, weapon, 1);
this.xpReward = 100;
this.coinReward = 20;
}
@Override
public void takeDamage(int damage, Entity attacker) {
super.takeDamage(damage, attacker);
if (!isAlive() && !hasResurrected) {
fillHealth(getMaxHP() / 2);
this.hasResurrected = true;
System.out.println(name + " Falls To The Ground... But Then Resurrects From The Dead!");
}
}
@Override
public int choice() {
double roll = Math.random();
if (this.getStamina() >= this.weapon.getStaminaCost()) {
if (roll < 0.33) {return 1;}
else if (roll < 0.67) {return 2;}
else {return 3;}
} else {
return 1;
}
}
}
@@ -0,0 +1,42 @@
package org.project.entity.enemies;
import org.project.entity.Entity;
import org.project.item.weapons.Weapon;
import org.project.item.Item;
public class Vampire extends Enemy {
public Vampire(Weapon weapon) {
super("Vampire", 180, 20, weapon, 0.3);
this.xpReward = 120;
this.coinReward = 40;
}
@Override
public void lightAttack(Entity target) {
super.lightAttack(target);
fillHealth(5);
}
@Override
public void heavyAttack(Entity target) {
super.heavyAttack(target);
int lifeStolen = weapon.getDamage() / 4;
fillHealth(lifeStolen);
}
@Override
public int choice() {
double roll = Math.random();
if (this.getStamina() >= this.weapon.getStaminaCost()) {
if (roll < 0.33) {return 1;}
else if (roll < 0.67) {return 2;}
else {return 3;}
} else {
return 1;
}
}
}
@@ -0,0 +1,62 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
public class Assassin extends Player {
private boolean dodgeNext = false;
private boolean counterReady = false;
public Assassin(String name, Weapon weapon, Armor armor) {
super(name, 60, 50, weapon, armor);
}
@Override
public void lightAttack(Entity target) {
if (counterReady) {
target.takeDamage(30, this);
System.out.println(name + " Performs a Light Attack After Dodging Enemy's Attack!");
counterReady = false;
} else {
super.lightAttack(target);
dodgeNext = false;
}
}
@Override
public void heavyAttack(Entity target) {
if (spendStamina(weapon.getStaminaCost())) {
if (counterReady) {
target.takeDamage(weapon.getDamage() * 2, this);
System.out.println(name + " Performs a Heavy Attack After Dodging Enemy's Attack!");
counterReady = false;
} else {
super.heavyAttack(target);
dodgeNext = false;
}
}
}
@Override
public void takeDamage(int damage, Entity attacker) {
if (dodgeNext) {
System.out.println(name + " Dodged Enemy's Attack!");
dodgeNext = false;
counterReady = true;
return;
}
super.takeDamage(damage, attacker);
}
@Override
public void specialAbility(Entity target) {
if (spendStamina(20)) {
this.dodgeNext = true;
this.counterReady = false;
System.out.println(name + " Gets Ready To Dodge Enemy's Attack...");
}
}
}
@@ -1,6 +1,21 @@
package org.project.entity.players;
// TODO: UPDATE IMPLEMENTATION
public class Knight {
// TODO: DESIGN KNIGHT'S WEAPON AND ARMOR AND IMPLEMENT THE CONSTRUCTOR
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
public class Knight extends Player {
public Knight(String name, Weapon weapon, Armor armor) {
super(name, 80, 20, weapon, armor);
}
@Override
public void specialAbility(Entity target) {
if (spendStamina(20)) {
target.takeDamage(weapon.getDamage() * 2, this);
target.setStunned(true);
System.out.println(name + " Strikes The Enemy With His Sword!");
}
}
}
@@ -3,64 +3,159 @@ package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
import org.project.item.Inventory;
public abstract class Player implements Entity {
private static final String RESET = "\033[0m";
private static final String GREEN = "\033[0;32m";
private static final String BLUE = "\033[0;34m";
private static final String YELLOW = "\033[0;33m";
private static final String PURPLE = "\033[0;35m";
// TODO: UPDATE IMPLEMENTATION
public abstract class Player {
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 stamina;
protected int maxStamina;
public Player(String name, int hp, int mp, Weapon weapon, Armor armor) {
private int xp = 0;
private int level = 1;
private int xpToNextLevel = 100;
private int coins = 0;
protected boolean canDefend = true;
protected boolean isDefending = false;
protected boolean isStunned = false;
public Armor armor;
public Weapon weapon;
protected Inventory inventory;
private boolean hasGoblinKey = false;
private boolean hasSkeletonKey = false;
private boolean hasVampireKey = false;
public Player(String name, int hp, int stamina, Weapon weapon, Armor armor) {
this.name = name;
this.hp = hp;
this.mp = mp;
this.maxHP = hp;
this.stamina = stamina;
this.maxStamina = stamina;
this.weapon = weapon;
this.armor = armor;
this.inventory = new Inventory(this);
this.inventory.addWeapon(weapon);
this.inventory.addArmor(armor);
}
public void setCanDefend(boolean status) {
this.canDefend = status;
}
public boolean isDefending() {
return isDefending;
}
public boolean isStunned() {
return isStunned;
}
public void setStunned(boolean status) {
this.isStunned = status;
}
@Override
public void attack(Entity target) {
target.takeDamage(weapon.getDamage());
public void lightAttack(Entity target) {
target.takeDamage(20, this);
System.out.println(name + " Performs a Light Attack!");
}
@Override
public void heavyAttack(Entity target) {
if (spendStamina(weapon.getStaminaCost())) {
target.takeDamage(weapon.getDamage(), this);
System.out.println(name + " Performs a Heavy Attack!");
}
}
@Override
public void defend() {
// TODO
if (!canDefend) {
System.out.println("You Can't Defend Against The Dragon!");
} else {
if (spendStamina(5)) {
this.isDefending = true;
System.out.println(name + " Gets Ready To Block Enemy's Attack...");
}
}
@Override
public void takeDamage(int damage) {
hp -= damage - armor.getDefense();
}
@Override
public void heal(int health) {
hp += health;
if (hp > maxHP) {
hp = maxHP;
if (spendStamina(10)) {
this.hp = Math.min(maxHP, this.hp + health);
System.out.println(name + " Healed " + health + " HP!");
}
}
public abstract void specialAbility(Entity target);
@Override
public void takeDamage(int damage, Entity attacker) {
if (isDefending) {
if (!attacker.isDefending()) {
System.out.println(name + " Defended Enemy's Attack!");
}
isDefending = false;
return;
}
int dmg = armor.damageTaken(damage);
this.hp = Math.max(0, this.hp - dmg);
armor.reduceDurability(dmg / 4);
}
@Override
public void fillMana(int mana) {
mp += mana;
if (mp > maxMP) {
mp = maxMP;
}
public void fillHealth(int health) {
this.hp = Math.min(maxHP, this.hp + health);
}
@Override
public void fillStamina(int stamina) {
this.stamina = Math.min(maxStamina, this.stamina + stamina);
}
public void fillStats() {
this.hp = maxHP;
this.stamina = maxStamina;
}
@Override
public boolean spendStamina(int cost) {
if (this.stamina >= cost) {
this.stamina -= cost;
return true;
}
System.out.println("Not Enough Stamina!");
return false;
}
@Override
public boolean isAlive() {
return this.hp > 0;
}
@Override
public String getName() {
return name;
}
public int getHp() {
@Override
public int getHP() {
return hp;
}
@@ -69,13 +164,14 @@ public abstract class Player {
return maxHP;
}
public int getMp() {
return mp;
@Override
public int getStamina() {
return stamina;
}
@Override
public int getMaxMP() {
return maxMP;
public int getMaxStamina() {
return maxStamina;
}
public Weapon getWeapon() {
@@ -86,4 +182,89 @@ public abstract class Player {
return armor;
}
public int getXP() {
return xp;
}
public int getLevel() {
return level;
}
public int getCoins() {
return coins;
}
public void equipWeapon(int index) {
Weapon newWeapon = inventory.getWeapon(index);
this.weapon = newWeapon;
}
public void equipArmor(int index) {
Armor newArmor = inventory.getArmor(index);
this.armor = newArmor;
}
public Inventory getInventory() {
return inventory;
}
public void gainXP(int amount) {
this.xp += amount;
System.out.println("Gained " + YELLOW + amount + RESET + " XP.");
while (xp >= xpToNextLevel) {
levelUp();
}
}
private void levelUp() {
int oldHP = this.maxHP;
int oldStamina = this.maxStamina;
level++;
xpToNextLevel = (int) (xpToNextLevel * 2.5);
this.maxHP += 20;
this.maxStamina += 10;
fillStats();
System.out.println(PURPLE + "LEVEL UP!" + RESET + " Level: " + level );
System.out.println("HP: " + oldHP + " -> " + GREEN + maxHP + RESET + " | Stamina: " + oldStamina + " -> " + BLUE + maxStamina + RESET);
System.out.println("XP: " + xp + " | XP To Next Level: " + xpToNextLevel);
}
public void addCoins(int amount) {
this.coins += amount;
System.out.println("Found " + YELLOW + amount + RESET + " Coins.");
}
public void spendCoins(int amount) {
this.coins -= amount;
}
public boolean hasGoblinKey() {
return hasGoblinKey;
}
public boolean hasSkeletonKey() {
return hasSkeletonKey;
}
public boolean hasVampireKey() {
return hasVampireKey;
}
public void findGoblinKey(){
hasGoblinKey = true;
System.out.println("Found The" + PURPLE + " Goblin" + RESET + " Key!");
}
public void findSkeletonKey(){
hasSkeletonKey = true;
System.out.println("Found The" + PURPLE + " Skeleton" + RESET + " Key!");
}
public void findVampireKey(){
hasVampireKey = true;
System.out.println("Found The" + PURPLE + " Vampire" + RESET + " Key!");
}
}
@@ -0,0 +1,23 @@
package org.project.entity.players;
import org.project.entity.Entity;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
public class Wizard extends Player {
public Wizard(String name, Weapon weapon, Armor armor) {
super(name, 100, 30, weapon, armor);
}
@Override
public void specialAbility(Entity target) {
if (spendStamina(20)) {
target.takeDamage(weapon.getDamage() * 2, this);
if (!target.isDefending()) {
this.fillHealth(getMaxHP() / 5);
System.out.println(name + " Recites The Special Phrase!");
}
}
}
}
@@ -0,0 +1,90 @@
package org.project.item;
import org.project.entity.players.Player;
import org.project.item.armors.Armor;
import org.project.item.weapons.Weapon;
import java.util.ArrayList;
public class Inventory {
private Player player;
public Inventory(Player player) {
this.player = player;
}
private ArrayList<Weapon> weapons = new ArrayList<>();
private ArrayList<Armor> armors = new ArrayList<>();
private ArrayList<Item> miscItems = new ArrayList<>();
public ArrayList<Weapon> getWeapons() {
return weapons;
}
public ArrayList<Armor> getArmors() {
return armors;
}
public void addWeapon(Weapon weapon) {
weapons.add(weapon);
}
public void addArmor(Armor armor) {
armors.add(armor);
}
public void addMiscItem(Item newItem) {
for (int i = 0; i < miscItems.size(); i++) {
Item existingItem = miscItems.get(i);
if (existingItem.getName().equals(newItem.getName())) {
existingItem.addQuantity(newItem.getQuantity());
return;
}
}
miscItems.add(newItem);
}
public void showMiscItems() {
int listNumber = 1;
for (int i = 0; i < miscItems.size(); i++) {
Item currentItem = miscItems.get(i);
if (currentItem.getName().contains("Healing Flask") && currentItem.getQuantity() > 0) {
System.out.println(listNumber + ". " + currentItem.getName() + " (" + currentItem.getQuantity() + ")");
listNumber++;
}
}
for (int i = 0; i < miscItems.size(); i++) {
Item currentItem = miscItems.get(i);
if (currentItem.getName().contains("Stamina") && currentItem.getQuantity() > 0) {
System.out.println(listNumber + ". " + currentItem.getName() + " (" + currentItem.getQuantity() + ")");
listNumber++;
}
}
}
public Weapon getWeapon(int index) {
return weapons.get(index);
}
public Armor getArmor(int index) {
return armors.get(index);
}
public Item getMiscItemByName(String baseName) {
for (int i = 0; i < miscItems.size(); i++) {
Item item = miscItems.get(i);
if (item.getName().contains(baseName)) {
return item;
}
}
return null;
}
public boolean hasAllKeys() {
return player.hasGoblinKey() && player.hasSkeletonKey() && player.hasVampireKey();
}
}
@@ -3,9 +3,13 @@ package org.project.item;
import org.project.entity.Entity;
public interface Item {
void use(Entity target);
String getName();
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
int getQuantity();
void addQuantity(int amount);
boolean canUse();
void use(Entity target);
}
@@ -1,31 +1,50 @@
package org.project.item.armors;
// TODO: UPDATE IMPLEMENTATION
public abstract class Armor {
private String name;
private int defense;
private int maxDefense;
private int durability;
private int maxDurability;
private boolean isBroken;
private boolean isBroke;
public Armor(int defense, int durability) {
public Armor(String name, int defense) {
this.name = name;
this.defense = defense;
this.durability = durability;
this.durability = 100;
this.maxDurability = durability;
this.isBroken = false;
}
public int damageTaken(int damage) {
if (isBroken) {
return damage;
}
double percent = (100.0 - defense) / 100.0;
return (int) (damage * percent);
}
public void reduceDurability(int amount) {
this.durability -= amount;
checkBreak();
}
public void checkBreak() {
if (durability <= 0) {
isBroke = true;
defense = 0;
if (this.durability <= 0 && !isBroken) {
this.durability = 0;
this.isBroken = true;
System.out.println("Your Armor Has Broken!");
}
}
// TODO: (BONUS) UPDATE THE REPAIR METHOD
public void repair() {
isBroke = false;
defense = maxDefense;
durability = maxDurability;
this.isBroken = false;
this.durability = 100;
}
public String getName() {
return name;
}
public int getDefense() {
@@ -35,8 +54,4 @@ public abstract class Armor {
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(String name, int defense) {
super(name, defense);
}
}
@@ -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(String name, int defense) {
super(name, defense);
}
}
@@ -0,0 +1,8 @@
package org.project.item.armors;
public class WizardArmor extends Armor {
public WizardArmor(String name, int defense) {
super(name, defense);
}
}
@@ -1,8 +1,37 @@
package org.project.item.consumables;
// TODO: UPDATE IMPLEMENTATION
public abstract class Consumable {
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
import org.project.entity.Entity;
import org.project.item.Item;
public abstract class Consumable implements Item {
protected String name;
protected int quantity;
public Consumable(String name, int quantity) {
this.name = name;
this.quantity = quantity;
}
@Override
public String getName() {
return name;
}
@Override
public int getQuantity() {
return quantity;
}
@Override
public void addQuantity(int amount) {
this.quantity += amount;
}
@Override
public boolean canUse() {
return quantity > 0;
}
@Override
public abstract void use(Entity target);
}
@@ -2,15 +2,38 @@ package org.project.item.consumables;
import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION
public class Flask {
/*
THIS IS AN EXAMPLE OF A CONSUMABLE DESIGN.
*/
public class Flask extends Consumable {
public Flask(int quantity) {
super("Healing Flask", quantity);
}
@Override
public String getName() {
return super.getName();
}
@Override
public int getQuantity() {
return super.getQuantity();
}
@Override
public void addQuantity(int amount) {
this.quantity += amount;
}
// TODO: UPDATE USE METHOD
@Override
public void use(Entity target) {
target.heal(target.getMaxHP() / 10);
if (canUse()) {
int healAmount = target.getMaxHP() / 4;
target.fillHealth(healAmount);
quantity--;
System.out.println(target.getName()+ " Used Healing Flask And Healed " + healAmount + " HP!");
System.out.println("Remaining: " + quantity);
} else {
System.out.println("The Flask Is Empty!");
}
}
}
@@ -0,0 +1,39 @@
package org.project.item.consumables;
import org.project.entity.Entity;
public class StaminaPotion extends Consumable {
public StaminaPotion(int quantity) {
super("Stamina Potion", quantity);
}
@Override
public String getName() {
return super.getName();
}
@Override
public int getQuantity() {
return super.getQuantity();
}
@Override
public void addQuantity(int amount) {
this.quantity += amount;
}
@Override
public void use(Entity target) {
if (canUse()) {
int staminaAmount = target.getMaxStamina() / 4;
target.fillStamina(staminaAmount);
quantity--;
System.out.println(target.getName()+ " Used Stamina Potion And Added " + staminaAmount + " To His Stamina!");
System.out.println("Remaining: " + quantity);
} else {
System.out.println("The Flask Is Empty!");
}
}
}
@@ -0,0 +1,8 @@
package org.project.item.weapons;
public class Dagger extends Weapon{
public Dagger(String name, int damage, int staminaCost) {
super(name, damage, staminaCost);
}
}
@@ -0,0 +1,8 @@
package org.project.item.weapons;
public class Flame extends Weapon{
public Flame(String name, int damage, int staminaCost) {
super(name, damage, staminaCost);
}
}
@@ -0,0 +1,8 @@
package org.project.item.weapons;
public class HiddenBlade extends Weapon{
public HiddenBlade(String name, int damage, int staminaCost) {
super(name, damage, staminaCost);
}
}
@@ -0,0 +1,8 @@
package org.project.item.weapons;
public class Staff extends Weapon{
public Staff(String name, int damage, int staminaCost) {
super(name, damage, staminaCost);
}
}
@@ -1,26 +1,8 @@
package org.project.item.weapons;
import org.project.entity.Entity;
public class Sword extends Weapon {
import java.util.ArrayList;
// TODO: UPDATE IMPLEMENTATION
public class Sword {
/*
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(String name, int damage, int staminaCost) {
super(name, damage, staminaCost);
}
}
@@ -1,35 +1,25 @@
package org.project.item.weapons;
import org.project.entity.Entity;
// TODO: UPDATE IMPLEMENTATION
public abstract class Weapon {
private String name;
private int damage;
private int manaCost;
private int staminaCost;
/*
TODO: ADD OTHER REQUIRED AND BONUS ATTRIBUTES
*/
public Weapon(int damage, int manaCost) {
public Weapon(String name, int damage, int staminaCost) {
this.name = name;
this.damage = damage;
this.manaCost = manaCost;
this.staminaCost = staminaCost;
}
@Override
public void use(Entity target) {
target.takeDamage(damage);
public String getName() {
return name;
}
public int getDamage() {
return damage;
}
public int getManaCost() {
return manaCost;
public int getStaminaCost() {
return staminaCost;
}
/*
TODO: ADD OTHER REQUIRED AND BONUS METHODS
*/
}
@@ -1,28 +1,20 @@
package org.project.location;
import org.project.entity.enemies.Enemy;
import java.util.ArrayList;
import java.util.Random;
public class Location {
private String name;
private ArrayList<Enemy> enemies;
private Random random = new Random();
public Location(ArrayList<Location> locations, ArrayList<Enemy> enemies) {
this.locations = locations;
public Location(String name, ArrayList<Enemy> enemies) {
this.name = name;
this.enemies = enemies;
}
public String getName() {
return name;
}
public ArrayList<Location> getLocations() {
return locations;
}
public ArrayList<Enemy> getEnemies() {
return enemies;
}
}